Skip to content

Jashk120/JOS

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

JOS

A bare-metal x86 kernel written from scratch in C and x86 Assembly, running on QEMU. Built to understand how operating systems actually work at the hardware level — no abstractions, no OS beneath you.

Platform Language Emulator Status


What it does

  • Boots from scratch via a custom two-stage bootloader (Real Mode → Protected Mode)
  • Initializes GDT (Global Descriptor Table) with kernel code/data segments
  • Remaps the PIC (8259A) and sets up a full 256-entry IDT (Interrupt Descriptor Table)
  • Handles hardware interrupts: keyboard (IRQ1), timer (IRQ0), and default fallback
  • Catches CPU exceptions: divide by zero (#0), general protection fault (#13), page fault (#14)
  • Drives a VGA text mode terminal with scrolling, hardware cursor, and direct memory writes
  • Runs an interactive shell with command history, arrow key navigation, insert-mode editing

Shell commands

Command Description
help List available commands
hello Print a greeting
version Show OS version string
clear Clear the terminal screen

Shell features:

  • Up/Down arrow keys to scroll through command history (last 10 commands)
  • Left/Right arrow keys to move cursor within the current line
  • Insert mode — characters insert at cursor position, not just append
  • Home/End keys to jump to start/end of line
  • Delete key support
  • Screen scrolls when output reaches the bottom

Architecture

myOS/
├── boot.asm       # Stage 1: 16-bit bootloader
│                  # Loads kernel from disk via BIOS int 0x13
│                  # Sets up GDT, switches CPU to 32-bit Protected Mode
│                  # Jumps to kernel at 0x1000
│
├── entry.asm      # Kernel entry point
│                  # Sets up stack, calls kernel_main()
│
├── kernel.c       # Kernel main
│                  # Clears VGA buffer, remaps PIC, initializes IDT
│                  # Flushes keyboard buffer, enables interrupts, starts shell
│
├── idt/
│   ├── idt.h      # IDT entry and descriptor structs (packed)
│   ├── idt.c      # IDT setup, gate registration, exception handlers
│   │              # TTY state, VGA terminal, shell logic, keyboard handler
│   ├── pic.h      # Port I/O inline asm (outb/inb/sti)
│   └── pic.c      # 8259A PIC remapping (master 0x20, slave 0x28)
│
├── isr.asm        # Low-level ISR/IRQ stubs that call C handlers
├── linker.ld      # Linker script — places .text.start at correct address
└── Makefile       # Build system

How the boot process works

Power on
   │
   ▼
BIOS loads sector 1 → 0x7C00          (boot.asm, Real Mode 16-bit)
   │
   ├─ Zero segment registers
   ├─ Load kernel sectors 2-21 → 0x1000 via BIOS int 0x13
   ├─ Load GDT (null + code + data descriptors)
   ├─ Set CR0 PE bit → enter Protected Mode
   └─ Far jump to flush pipeline → 32-bit mode
   │
   ▼
entry.asm                              (Protected Mode 32-bit)
   │
   └─ Set up kernel stack at 0x9F000
   └─ Call kernel_main()
   │
   ▼
kernel.c → kernel_main()
   │
   ├─ Clear VGA buffer (0xB8000)
   ├─ pic_remap()     — remap IRQs above CPU exceptions
   ├─ idt_init()      — register 256 gates, set exception + IRQ handlers
   ├─ Flush keyboard buffer
   ├─ sti()           — enable hardware interrupts
   └─ shell_prompt()  — hand control to interactive shell

Interrupt map

Vector Source Handler
0x00 Divide by zero Print exception, halt
0x0D General Protection Fault Print exception, halt
0x0E Page Fault Print exception, halt
0x20 IRQ0 — Timer irq0_handler() (stub)
0x21 IRQ1 — Keyboard irq1_handler() — full keyboard driver
0x22–0xFF All others irq_default fallback

Running it

Requirements:

# Arch Linux
sudo pacman -S nasm gcc qemu nasm binutils

Build and run:

make        # builds kernel.bin
make run    # launches in QEMU

Clean:

make clean

What I learned building this

  • How the BIOS boot sequence works and why the bootloader lives at 0x7C00
  • Real Mode vs Protected Mode — segment registers, GDT, privilege rings
  • How the CPU uses the IDT to dispatch interrupts and exceptions
  • Why the PIC needs to be remapped (IRQs 0-7 clash with CPU exception vectors by default)
  • Direct VGA memory-mapped I/O at 0xB8000 — no OS, no syscalls, just write to memory
  • How keyboard scancodes work and how to build an in-kernel keyboard driver
  • Inline assembly in C (outb, inb, sti, lidt)
  • Linker scripts — controlling exactly where code lands in memory

Roadmap

  • Physical memory manager (bitmap allocator)
  • Paging — virtual memory, page tables
  • kmalloc / kfree
  • Process management and basic scheduler
  • Userspace and privilege level switching (ring 0 → ring 3)
  • Simple filesystem (read from disk)
  • Port to Rust (rewrite kernel components in Rust, keep ASM boot)

References


Built from scratch. No tutorials copied. Just reading docs and making it work.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors