1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
# Bastion — Custom UEFI Kernel
A dual-architecture operating system kernel written in C++20 with a custom UEFI boot stub.
## Architecture
```
bastion/
├── Makefile Top-level build orchestration
├── config.mk Shared toolchain flags (Clang/LLD)
├── include/
│ └── boot_info.h Loader ↔ kernel handoff contract
├── boot/ UEFI boot loader (PE32+)
│ ├── Makefile
│ ├── common/
│ │ ├── efi.h Standalone UEFI type definitions
│ │ ├── elf.h ELF64 format definitions
│ │ ├── elf_parser.cpp ELF segment loader
│ │ └── efi_loader.cpp Core boot logic (GOP, mmap, ExitBootServices)
│ ├── x86_64/
│ │ ├── entry.cpp efi_main → common loader → jump to kernel
│ │ └── linker.ld
│ └── aarch64/
│ ├── entry.cpp
│ └── linker.ld
├── kernel/ Kernel (ELF64)
│ ├── Makefile
│ ├── arch/
│ │ ├── x86_64/
│ │ │ ├── entry.S Assembly entry: set stack, call kernel_main
│ │ │ └── linker.ld Kernel at 0x100000
│ │ └── aarch64/
│ │ ├── entry.S
│ │ └── linker.ld Kernel at 0x40100000
│ ├── core/
│ │ └── kernel_main.cpp First C++ code: init console, dump info, halt
│ ├── lib/
│ │ ├── kprint.cpp Framebuffer console (8x16 VGA font)
│ │ ├── string.cpp Freestanding memcpy/memset/strlen
│ │ └── cxxabi.cpp C++ ABI stubs
│ └── include/kernel/
│ ├── kprint.h
│ └── types.h
└── scripts/
├── create_disk.sh Creates GPT + FAT32 ESP disk image
└── run_qemu.sh Launches QEMU with OVMF/AAVMF firmware
```
## Boot Flow
```
UEFI Firmware
↓ loads BOOTX64.EFI (PE32+)
EFI Loader (boot/)
├── Opens ESP, reads kernel.elf
├── Parses ELF64, loads PT_LOAD segments
├── Gets GOP framebuffer
├── Finds ACPI RSDP (x86) / FDT (arm64)
├── GetMemoryMap() + ExitBootServices()
└── Jumps to kernel entry with BootInfo*
↓
Kernel entry.S (arch-specific)
├── Sets up 16 KiB stack
└── Calls kernel_main(BootInfo*)
↓
kernel_main (C++)
├── Initializes framebuffer console
├── Prints banner, memory map, kernel info
└── Halts
```
## Build Requirements
- **Clang/LLVM 15+** (clang++, lld-link, llvm-objcopy)
- **QEMU** (qemu-system-x86_64, qemu-system-aarch64)
- **OVMF/AAVMF** firmware for UEFI emulation
- **mtools** + **dosfstools** for disk image creation
### Install (Ubuntu/Debian)
```bash
sudo apt install clang lld llvm qemu-system-x86 qemu-system-arm \
ovmf qemu-efi-aarch64 mtools dosfstools gdisk
```
## Build & Run
```bash
# Build both architectures
make all
# Build x86_64 only
make x86_64
# Build + create disk image + run in QEMU
make run-x86_64
make run-aarch64
# Clean
make clean
```
## Design Decisions
- **C++20, freestanding**: No exceptions, no RTTI, no libstdc++. RAII and templates are available.
- **Custom UEFI stub** (not Limine): Full control over boot process, like Linux's EFI stub.
- **Direct PE32+ compilation**: Clang targets `x86_64-unknown-windows` / `aarch64-unknown-windows`, linked with `lld-link` — no objcopy step needed.
- **Shared BootInfo contract**: Architecture-agnostic handoff struct in `include/boot_info.h`.
- **~80% shared boot code**: Only entry points and firmware table lookups are arch-specific.
## Roadmap
- [x] Phase 0: Project skeleton + dual-arch build system
- [x] Phase 1: UEFI boot loader + ELF loading + framebuffer console
- [ ] Phase 2: GDT/IDT (x86_64), exception vectors (aarch64)
- [ ] Phase 3: Physical + virtual memory management, kernel heap
- [ ] Phase 4: Timer, scheduler, context switching
- [ ] Phase 5: ELF loader, userspace transition, syscalls
- [ ] Phase 6: VFS, initramfs, drivers
|