A basic bootloader for Linux on x86, written in C and assembly.
Important
This project is a work in progress.
First, install the required packages:
dnf install make nasm gcc binutils glibc-devel.i686Then, build the bootloader:
makeTo build the installer:
make installerTo run the bootloader, you can use QEMU:
make testThis will build both of the bootloader stages, prepare a disk image with ext2 filesystem, install the bootloader stages, copy the testing kernel, initramfs and config to the image and run it using QEMU.
You will need to compile the testing kernel yourself.
I used version 6.17.0 (git tag v6.17.0) for testing, example kernel config can
be found in test/kernel.config.
To build the testing initramfs, you can use the provided Makefile:
make -C test/initramfsWarning
This will donwnload the busybox precompiled binary from the internet.
The paths to test kernel and initramfs are hardcoded in the test/Makefile, you can change them if needed. Defaults are test/bzImage and test/initramfs.cpio.gz. Configuration file is also hardcoded to test/liboot.conf.
The bootloader can be configured with the liboot.conf file which should be
place at the root of the boot partition. The following options are available:
| Variable | Description | Default |
|---|---|---|
KERNEL |
path to the kernel bzImage file | /boot/bzImage |
INITRD |
path to the initrd file | empty |
CMDLINE |
kernel command line | root=/dev/sda1 rw console=ttyS0 |
Most of these limitations are self-imposed to limit the scope of the project (and to focus on the fun and interesting parts).
- Only the 32-bit x86 architecture is supported.
- Only the revision 0 of the ext2 filesystem is supported.
- Only a MBR partition table, with primary partitions only is supported.
- All of the boot files (config, kernel, initramfs) must be located on any partition on the same disk as the bootloader.
- No graphics support, only text mode or serial is supported. Early stages only use the VGA output, but the later stages can switch to serial output if compiled with the
-DSERIAL(default). This will be made configurable via config in the future.
0x0 - real mode IVT and Bios Data Area (BDA) - unusable
0x500 - E820 memory map (passed to the struct boot_params of the Linux boot proto)
0x7C00 - MBR; stack top (both stages)
0x8200 - stage 2 load address and entry point
0x10000 - --- low memory ---
0x70000 - heap start
0x80000 - heap end
0xA0000 - --- video memory ---
0xb8000 - VGA memory
...
Video BIOS
...
Motherboard BIOS
0x100000 - --- high memory ---
- Linux kernel load address (if not relocatable)
0xF00000 - ISA memory hole
0x1000000 - More extended memory
See OSDev wiki page on memory layout for more details on general x86 memory layout. Also see the Linux boot protocol documentation for more details on the memory layout expected by the Linux kernel.