wrote a basic bootloader

This commit is contained in:
2025-02-25 01:14:52 +00:00
commit 012b0454ed
36 changed files with 1667 additions and 0 deletions
+95
View File
@@ -0,0 +1,95 @@
# BIOS Boot Process and Disk Layout
## Disk Layout
```
Sector 0 (MBR):
+-----------------------------------+ 0x000
| |
| Bootstrap Code |
| (Stage 1 Bootloader) |
| |
| |
+-----------------------------------+ 0x1BE (446)
| Partition Entry 1 (16 bytes) |
+-----------------------------------+ 0x1CE (462)
| Partition Entry 2 (16 bytes) |
+-----------------------------------+ 0x1DE (478)
| Partition Entry 3 (16 bytes) |
+-----------------------------------+ 0x1EE (494)
| Partition Entry 4 (16 bytes) |
+-----------------------------------+ 0x1FE (510)
| Boot Signature (0x55AA) |
+-----------------------------------+ 0x200 (512)
Sectors 1-2047:
+-----------------------------------+ 0x200
| |
| Stage 2 Bootloader |
| (Up to 1023.5 KB) |
| |
+-----------------------------------+ 0x100000 (Sector 2048)
Sector 2048 onwards:
+-----------------------------------+ 0x100000
| |
| FAT32 Partition |
| (Rest of disk) |
| |
+-----------------------------------+
```
## Partition Entry Format (16 bytes)
```
Offset Size Description
0x00 1 Boot flag (0x80 = bootable, 0x00 = non-bootable)
0x01 3 Starting CHS address
0x04 1 Partition type
0x05 3 Ending CHS address
0x08 4 Starting sector (LBA)
0x0C 4 Number of sectors
```
## Boot Process
1. **BIOS Power-On**
- BIOS performs POST (Power-On Self Test)
- Looks for bootable devices
2. **MBR Load**
- BIOS loads Sector 0 (MBR) into memory at 0x7C00
- Verifies 0x55AA signature
- Executes Stage 1 Bootloader
3. **Stage 1 Bootloader**
- Runs in 16-bit real mode
- Limited to 446 bytes
- Main task: Load Stage 2 Bootloader
- Typically contains minimal disk I/O code
4. **Stage 2 Bootloader**
- Located in sectors 1-2047
- Has more space for complex operations
- Tasks:
- Switch to 32-bit protected mode
- Set up basic memory management
- Parse FAT32 filesystem
- Switch to long mode
- Load and execute kernel
5. **Kernel Load**
- Stage 2 loads kernel from FAT32 partition
- Sets up necessary environment
- Transfers control to kernel
## Memory Layout During Boot
```
0x00000000 - 0x000003FF: Interrupt Vector Table
0x00000400 - 0x000004FF: BIOS Data Area
0x00000500 - 0x00007BFF: Free Memory
0x00007C00 - 0x00007DFF: Stage 1 Bootloader (MBR)
0x00007E00 - 0x0007FFFF: Free Memory (Stage 2 can be loaded here)
0x00080000 - 0x0009FFFF: Extended BIOS Data Area
0x000A0000 - 0x000FFFFF: BIOS ROM, Video Memory, etc.
0x00100000 onwards: Free Memory (Kernel typically loaded here)
```
+77
View File
@@ -0,0 +1,77 @@
# BIOS Interrupt Vector Table (IVT)
## Overview
The BIOS Interrupt Vector Table (IVT) is a crucial data structure in real mode that maps interrupt numbers to their handler routines. It is located at the very beginning of memory, starting at physical address 0x0000:0x0000.
## Structure
- The IVT contains 256 entries (0x00 to 0xFF)
- Each entry is 4 bytes long:
- 2 bytes for the offset
- 2 bytes for the segment
- Total size: 256 * 4 = 1024 bytes (0x400)
```
Memory Layout:
0x0000:0x0000 - Int 0x00 vector (Divide by zero)
0x0000:0x0004 - Int 0x01 vector (Single step)
0x0000:0x0008 - Int 0x02 vector (NMI)
...
0x0000:0x0040 - Int 0x10 vector (Video services)
...
0x0000:0x03FC - Int 0xFF vector (Last vector)
```
## Common BIOS Interrupts
- **Int 0x10**: Video Services
- AH=0x00: Set video mode
- AH=0x0E: Write character in TTY mode
- AH=0x13: Write string
- **Int 0x13**: Disk Services
- AH=0x00: Reset disk system
- AH=0x02: Read sectors
- AH=0x03: Write sectors
- AH=0x41: Check extensions present
- AH=0x42: Extended read sectors
- AH=0x43: Extended write sectors
- **Int 0x16**: Keyboard Services
- AH=0x00: Read keystroke
- AH=0x01: Check for keystroke
## How It Works
1. When an interrupt occurs (via hardware or `int` instruction):
- CPU pushes FLAGS, CS, and IP onto stack
- CPU disables further interrupts
- CPU looks up handler address in IVT
- CPU jumps to handler address
2. Example of int 0x10 call:
```nasm
mov ah, 0x0E ; TTY output function
mov al, 'A' ; Character to print
int 0x10 ; Call BIOS video interrupt
```
3. The BIOS handler:
- Receives control
- Reads parameters from registers
- Performs requested operation
- Returns via IRET instruction
## Important Notes
1. BIOS interrupts are only available in real mode
2. When transitioning to protected mode:
- BIOS interrupts become unavailable
- Must set up new Interrupt Descriptor Table (IDT)
- Must provide own interrupt handlers
3. Some BIOS operations require interrupts to be enabled:
- Disk I/O (int 0x13)
- Keyboard input (int 0x16)
- Some video operations (int 0x10)
4. Memory Map Considerations:
- IVT: 0x0000 - 0x03FF
- BIOS Data Area: 0x0400 - 0x04FF
- Your code should not overwrite these areas
+164
View File
@@ -0,0 +1,164 @@
# Boot Process and System Layout
## Disk Layout
```
FAT32 Partition
┌─────────────────────────┐
│ / │
├─────────────────────────┤
│ ├── EFI/ │
│ │ └── BOOT/ │
│ │ └── BOOTX64.EFI│ <- UEFI bootloader
├─────────────────────────┤
│ ├── boot/ │
│ │ └── bootloader.bin │ <- BIOS bootloader
├─────────────────────────┤
│ └── kernel │ <- Main kernel binary
└─────────────────────────┘
```
## Kernel Binary Format
```
Kernel Header Structure
┌─────────────────────────┐
│ Magic Number (4 bytes) │ 0x00
├─────────────────────────┤
│ Entry Point (8 bytes) │ 0x04
├─────────────────────────┤
│ Stack Pointer (8 bytes) │ 0x0C
├─────────────────────────┤
│ Flags (4 bytes) │ 0x14
├─────────────────────────┤
│ Text Offset (4 bytes) │ 0x18
├─────────────────────────┤
│ Text Size (4 bytes) │ 0x1C
├─────────────────────────┤
│ Data Offset (4 bytes) │ 0x20
├─────────────────────────┤
│ Data Size (4 bytes) │ 0x24
└─────────────────────────┘
```
## Memory Layout (After Boot)
```
Virtual Memory Layout
┌─────────────────────┐ 0xFFFFFFFF_FFFFFFFF
│ Higher Half │
├─────────────────────┤ 0xFFFFFFFF_FF600000
│ Recursive │
│ Page Mapping │
├─────────────────────┤ 0xFFFFFFFF_C0000000
│ Kernel Stacks │
├─────────────────────┤
│ Kernel Heap │
├─────────────────────┤ 0xFFFFFFFF_80000000
│ Kernel Code │
├─────────────────────┤ 0x00007FFF_FFFFFFFF
│ Guard │
├─────────────────────┤ 0x00007FFF_00000000
│ User Space │
├─────────────────────┤ 0x0000000000400000
│ Guard │
└─────────────────────┘ 0x0000000000000000
Physical Memory Layout
┌─────────────────────┐
│ Available RAM │
├─────────────────────┤
│ Kernel Binary │ <- Loaded at 1MB (0x100000)
├─────────────────────┤
│ Reserved/BIOS │
└─────────────────────┘ 0x00000000
```
## Boot Process
### BIOS Boot Flow
1. BIOS loads MBR (stage1.bin)
2. Stage 1 bootloader:
- Loads Stage 2 bootloader (stage2.bin) starting at sector 2048
3. Stage 2 bootloader:
- Switches to protected mode
- Sets up initial page tables
- Finds and loads kernel from FAT32
- Enables long mode
- Jumps to kernel entry point
### UEFI Boot Flow
1. UEFI firmware loads BOOTX64.EFI
2. UEFI bootloader:
- Gets memory map
- Finds and loads kernel
- Exits boot services
- Sets up page tables
- Enables long mode
- Jumps to kernel entry point
### Kernel Entry Point
```rust
extern "C" {
fn kmain(magic: u64, boot_info: *const BootInfo) -> !;
}
```
## Common Boot Environment
Both bootloaders must provide:
### CPU State
```
- Long mode enabled
- Paging enabled
- Interrupts disabled
- GDT set up for long mode
- IDT not required (kernel will set up)
```
### Register State
```
RAX = Boot magic value (e.g., 0xCAFEBABE)
RBX = Pointer to boot info structure
RCX = 0
RDX = 0
RSI = 0
RDI = 0
RBP = 0
RSP = Valid stack pointer (as specified in kernel header)
```
### Boot Info Structure
```c
struct BootInfo {
uint64_t magic; // Boot info magic number
uint64_t mem_map_addr; // Physical address of memory map
uint64_t mem_map_size; // Size of memory map
uint64_t fb_addr; // Framebuffer address (if available)
uint32_t fb_width; // Framebuffer width
uint32_t fb_height; // Framebuffer height
uint32_t fb_pitch; // Framebuffer pitch
uint8_t fb_bpp; // Bits per pixel
uint8_t boot_type; // 0 = BIOS, 1 = UEFI
uint8_t reserved[6]; // Padding to 64-bit align
};
```
## Required Kernel Features
1. Position-independent code (PIC)
2. No assumptions about physical memory layout beyond boot info
3. Own interrupt handling
4. Own memory management after boot
## Development Notes
1. Kernel must be compiled with:
- No red zone
- No MMX/SSE initially
- Position-independent code
- No standard library dependencies
2. Testing can be done with:
```bash
# BIOS boot
qemu-system-x86_64 disk.img
# UEFI boot
qemu-system-x86_64 -bios /usr/share/OVMF/OVMF_CODE.fd disk.img
```
+55
View File
@@ -0,0 +1,55 @@
# x86_64 Virtual Memory Layout
┌─────────────────────┐ 0xFFFFFFFF_FFFFFFFF
│ Higher Half │
├─────────────────────┤ 0xFFFFFFFF_FF600000
│ Recursive │ (Optional: for page table manipulation)
│ Page Mapping │
├─────────────────────┤ 0xFFFFFFFF_C0000000
│ Kernel Stacks │ (Multiple 16KB or 32KB stacks, guard pages between)
├─────────────────────┤
│ Kernel Heap │ (Dynamic allocation for kernel)
├─────────────────────┤ 0xFFFFFFFF_80000000
│ Kernel Code │ (Loaded by bootloader)
├─────────────────────┤ 0x00007FFF_FFFFFFFF
│ Guard │ (Prevent user->kernel pointer errors)
├─────────────────────┤ 0x00007FFF_00000000
│ User Stacks │ (Grows down)
├─────────────────────┤
│ ... │ (Available for mmap, shared libraries, etc.)
├─────────────────────┤
│ User Heap │ (Grows up)
├─────────────────────┤
│ Program .bss │ (Uninitialized data)
│ Program .data │ (Initialized data)
│ Program .rodata │ (Read-only data)
│ Program .text │ (Code)
├─────────────────────┤ 0x0000000000400000
│ Guard │ (Catch null pointer dereference)
└─────────────────────┘ 0x0000000000000000
## Memory Regions Explanation
### Kernel Space (Higher Half)
- **Kernel Code**: Fixed location at -2GB
- **Kernel Heap**: Dynamic memory for kernel operations
- **Kernel Stacks**: Multiple stacks for different CPU modes/tasks
- **Recursive Mapping**: Optional region for page table manipulation
### User Space (Lower Half)
- **Guard Pages**: Protect against null pointer dereference (0-4MB)
- **Program Sections**: Start at 0x400000
- .text: Program code
- .rodata: Read-only data
- .data: Initialized data
- .bss: Uninitialized data
- **User Heap**: Grows upward from end of program sections
- **Dynamic Region**: Space for mmap allocations, shared libraries
- **User Stacks**: Grows downward from 0x00007FFF_00000000
### Key Features
- Full 48-bit addressing support (256TB virtual address space)
- Clear separation between user and kernel space
- Protected null pointer dereference
- Room for stack/heap growth
- Space for dynamic libraries and mappings
+141
View File
@@ -0,0 +1,141 @@
# UEFI Boot Process and Disk Layout
## Disk Layout with ESP (EFI System Partition)
```
Sector 0 (MBR/GPT):
+-----------------------------------+ 0x000
| Protective MBR |
| (For BIOS compatibility) |
+-----------------------------------+ 0x200
EFI System Partition (FAT32):
+-----------------------------------+ Sector 2048
| FAT32 Filesystem |
| /EFI/ |
| /BOOT/ |
| BOOTX64.EFI |
+-----------------------------------+
Main Partition (FAT32):
+-----------------------------------+
| FAT32 Filesystem |
| (Kernel and other files) |
+-----------------------------------+
```
## UEFI Boot Process
1. **System Startup**
- Firmware initializes hardware
- Loads UEFI runtime services
- Sets up initial page tables and long mode
- CPU already in 64-bit mode
2. **Boot Manager**
- Scans for bootable devices
- Looks for EFI System Partition (ESP)
- Searches for bootloader at `/EFI/BOOT/BOOTX64.EFI`
3. **UEFI Bootloader**
- Already in long mode (64-bit)
- Has access to UEFI services:
- File operations
- Memory management
- Video output
- ACPI tables
- Tasks:
- Load kernel from main partition
- Set up memory map
- Exit boot services
- Jump to kernel
4. **Kernel Load**
- Bootloader passes:
- Memory map
- Framebuffer info
- ACPI tables
- Kernel takes control
## Key Differences from BIOS
1. **Initial State**
- BIOS: 16-bit real mode
- UEFI: 64-bit long mode
2. **Services**
- BIOS: Limited interrupt-based services
- UEFI: Rich API for system services
3. **Memory Management**
- BIOS: Manual memory detection needed
- UEFI: Provides memory map and allocation services
4. **File Access**
- BIOS: Manual disk I/O and filesystem parsing
- UEFI: Built-in filesystem support
5. **Graphics**
- BIOS: VGA/VBE modes
- UEFI: GOP (Graphics Output Protocol)
## UEFI Boot Services
```
Available until ExitBootServices() is called:
- Memory allocation
- File system access
- Graphics output
- Timer services
- Environment variables
Runtime Services (available after boot):
- Time services
- Variable services
- Reset system
- Virtual memory services
```
## Memory Map Example
```
Type Physical Address Range
EfiLoaderCode 0x0000000000000000-0x0000000000100000
EfiLoaderData 0x0000000000100000-0x0000000000200000
EfiBootServicesCode 0x0000000000200000-0x0000000000300000
EfiBootServicesData 0x0000000000300000-0x0000000000400000
EfiConventionalMemory 0x0000000000400000-...
EfiACPIReclaimMemory ...
EfiACPIMemoryNVS ...
EfiReservedMemoryType ...
```
## Required UEFI Protocols
```
- EFI_LOADED_IMAGE_PROTOCOL: Access to bootloader image info
- EFI_SIMPLE_FILE_SYSTEM_PROTOCOL: File operations
- EFI_GRAPHICS_OUTPUT_PROTOCOL: Display output
- EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL: Text output
```
## Boot Flow Control
```
UEFI Firmware
Boot Manager
BOOTX64.EFI
├── Get System Info
│ ├── Memory Map
│ ├── ACPI Tables
│ └── GOP Info
├── Load Kernel
│ └── Parse FAT32
├── ExitBootServices()
└── Jump to Kernel
└── Pass Boot Info
```