Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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 — Assembly gdt_flush function to load the GDT and reload segment registers
  • NPS Shell — Interactive command interpreter
  • vga::printc() — Print with specific colour without changing the global colour state
  • vga::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