KFS_2 — Stack & Segments
On today’s episode of ~~~“Why the hell do I do this to myself”~~~ “I’m having so much fun”, we are going to learn how to code a stack and integrate it with GDT.
Now you’re probably asking yourself “But Michael, I have a stack”, “What’s GDT?” and maybe “It’s 5am, can I go to sleep yet?”.
Firstly, we did include a stack in our bootloader. Check ✓
Secondly, GDT stands for “Global Descriptor Table”. It is a data structure used to define different memory areas: the base address, the size, and access privileges like execute and write.
And lastly, no… of course we don’t sleep, this is way too much fun.
What We Want to Achieve
-
Build, fill, and link a Global Descriptor Table into the kernel. The GDT must contain:
- Kernel Code
- Kernel Data
- Kernel Stack
- User Code
- User Data
- User Stack
GDT must be declared to the BIOS and set to address
0x00000800.Code a tool to print the kernel stack in a human-friendly way. We already built
printk(), so that’s great. -
Understand how memory works — how the stack and RAM work, how to use them, how to fill them, and how to link them with the BIOS.
REMEMBER TO KEEP IT UNDER 10MB
Bonus: A Shell
Because we have keyboards working, let’s build a Shell. Prototype name: NPS — Not a POSIX Shell.
Suggested commands: print-kernel-stack, reboot, halt, and similar.
Project Structure
kfs_2/kfs/
├── Cargo.toml
├── boot.asm # Multiboot header (same as KFS_1)
├── kb.asm # Keyboard handler wrapper
├── exc.asm # Exception handler wrappers
├── gdt.asm # GDT flush assembly
├── linker.ld
├── Makefile
└── src/
├── lib.rs # Kernel entry
├── vga.rs # Enhanced VGA (added printc, backspace)
├── idt.rs # IDT (from KFS_1, enhanced)
├── pic.rs # PIC (from KFS_1, enhanced with ISR/IRR reading)
├── kb.rs # Keyboard (now routes to shell)
├── exc.rs # Exception handlers
├── gdt.rs # GDT implementation
└── nps.rs # NPS Shell
What’s New vs KFS_1
- GDT — Global Descriptor Table with six entries
gdt.asm— Assemblygdt_flushfunction to load the GDT and reload segment registers- NPS Shell — Interactive command interpreter
vga::printc()— Print with specific colour without changing the global colour statevga::backspace()— Delete previous character- Enhanced PIC — Added ISR/IRR register reading, proper mask functions
- Keyboard routes to shell — Key presses go to
nps::handle_input()instead of printing directly