This is a simple operating system I'm building, so I can learn how operating systems work and how they are made. It's written in assembly and C, targeting x86_64.
The bootloader is GRUB 2, configured in grub.cfg
. The kernel is linked together using the kernel.ld
linker script.
Execution begins in loader.s
, which checks that multiboot is supported and sets up the stack. long_mode.s
sets up the paging tables (512 2MiB tables), Global Descriptor Table, and enables long mode (64-bit code execution).
The kernel begins in kmain.c
's kmain
function.
The interrupt descriptor table is defined and set up in idt.c
, with the interrupt handlers in idt.s
.
vga.c
is a basic wrapper around the VGA text mode, allowing characters to be drawn on the screen. term.c
extends this to provide simple terminal-like printing, where characters or strings can be printed in sequence.
-
GCC cross compiler (including binutils and libgcc without red zone) targeting
x86_64-elf
are required for building.The makefile expects the cross-compiler to be in
$HOME/opt/cross/bin
; a different directory can be specified with thecross_dir
variable:export cross_dir=/my/cross/compiler/directory/bin
-
GRUB 2 is used as the bootloader; make sure you have the
grub2-mkrescue
command -
mformat from GNU mtools is required by GRUB
-
QEMU is needed if the OS is emulated (rather than being run on real hardware). The command
qemu-system-x86_64
is needed. -
xorriso for building the ISO image
-
nasm to assemble the assembly files
make kernel
will build the kernel binarymake iso
will build an ISO image
This project is tested by running it in a QEMU virtual machine. make run
will run the OS in the virtual machine:
qemu-system-x86_64 -cdrom build/os-x86_64.iso
GDB can be connected to QEMU for debugging. make debug
will launch QEMU in debug mode, and the OS will wait for GDB before starting:
qemu-system-x86_64 -s -S -cdrom build/os-x86_64.iso
The .gdbinit
file will set up GDB to debug the kernel binary and connect to QEMU. You may need to allow GDB to load this file by adding the following line to $HOME/.gdbinit
(substituting in the path to this directory):
add-auto-load-safe-path $path-to-my-hobby-os/.gdbinit
Alternatively, the GDB commands can be run manually:
file build/kernel-x86_64.bin
target remote localhost:1234
- OSDev Wiki: a comprehensive collection of articles on many topics relating to OS development
- Writing an OS in Rust by Philipp Oppermann: despite being primarily in Rust, this book (including the first edition was very useful for getting the OS to the point where it can run 64-bit C code
- Intel Software Developer's Manual: comprehensive reference for x86_64 CPUs