JBootloader
- 4 Devlogs
- 8 Total hours
A bootloader to boot things
A bootloader to boot things
One of the biggest changes in this update was reorganising the kernel into individual components rather than keeping everything inside a single source file.The project now contains dedicated modules for:
VGA text output
Interrupt Descriptor Table (IDT)
Interrupt Service Routines (ISR)
Hardware Interrupt Requests (IRQ)
Programmable Interrupt Controller (PIC)
Programmable Interval Timer (PIT)
Keyboard driver
Low-level I/O helpers
The kernel now builds and installs a complete Interrupt Descriptor Table (IDT) containing all 256 entries. CPU exceptions (ISR 0-31) are fully registered, while IRQs from the Programmable Interrupt Controller occupy vectors 32-47 after remapping. Once the IDT has been loaded using lidt, the kernel is capable of safely responding to both processor exceptions and hardware interrupts.
Proper exception handling has now been implemented. Instead of the CPU immediately crashing with no feedback, exceptions are caught and displayed on screen with useful debugging information including:
Exception name
Interrupt number
Error codeInstruction pointer (EIP)
Code segment
CPU flags
After reporting the error the kernel safely halts, making debugging much easier during development.
The legacy PIC is now fully initialised and remapped away from the CPU exception vectors .Support has also been added for:
Sending End Of Interrupt (EOI) commands
Masking individual IRQ lines
Unmasking IRQs when drivers are ready
The PIT has now been configured as the kernel’s first hardware timer. It generates periodic interrupts at a configurable frequency and maintains a continuously increasing tick counter. While simple for now, this timer will eventually become the basis for delays
Perhaps the most noticeable improvement in this update is the addition of the first real hardware driver. The keyboard driver:
Receives hardware interrupts on IRQ1
Reads raw PS/2 scancodes
Translates scancodes into ASCII characters
Buffers incoming keystrokes
Allows the kernel to read characters without directly accessing hardware every time
The VGA text driver has also been rewritten into its own module.
I added Cursor updates, Automatic scrolling, Backspace support, Colour control, Decimal output and Hexadecimal output
I rewrote the bootloader into two stages.
Each item in stage 2 is
Disk loader: disk_read_lba in stage2 is fully reusable (LBA, count, drive, destination segment:offset via a Disk Address Packet), checks for INT 13h extensions first, and retries 3 times with a disk reset between attempts, same pattern in stage1’s simpler loader.
Print routine: print_string prints status lines at each stage (“loading kernel…”, “enabling A20…”, etc) plus explicit disk error and unsupported extensions messages.
A20: now enabled in real mode before the protected mode switch, using the BIOS function and the fast A20 gate together.
Boot drive: saved from DL at both stage1 and stage2 entry rather than hardcoded.
Magic numbers: sector counts, load addresses, and buffer addresses all moved into src/config.inc, shared by both stages.
E820 memory map: collected in real mode into a fixed buffer before switching to protected mode.
Boot info struct: built in 32-bit mode and handed to the kernel via EBX. Matching BootInfo struct is in kernel.h.
Load/execute address mismatch: The kernel now loads to physical 0x10000 in real mode, then once in flat 32-bit protected mode, stage2 copies it to 0x100000 with rep movsd before jumping there, so the linker script’s link address and the actual jump target now agree.
Got the bootloader to load kernel.c which is empty but you can see in the gdb log in the terminal that it does load void kernel_main. Next I am going to rewrite the bootloader into a two stage bootloader so it can have a print routine, retrying disk reads, A20 handling and an E820 memory map. Since all of this isnt possible in just 510 bytes (last two bytes reserved for the boot sector signature being 0x55 and 0xAA) I will split it into two stages.
Created a basic assembly project that prints hello world to the terminal and tested it by booting the built .bin file in qemu.