Hobby project to dig deeper into how an OS works by writing the bare essentials of a kernel in Go. Only the kernel lives here (gccgo, x86_64 long mode); BIOS and bootloader are handled by battle-tested tools (GRUB with a Multiboot2 header). No reinvention of those pieces.
-
Boot:
boot/boot.sexposes the Multiboot2 header and_start, sets up a 16 KB stack, enables long mode, and jumps intokernel.Main- The Multiboot2 info pointer is passed to
kernel.Main(...)inRDI - Freestanding helpers live in
boot/as well (minimal stubs +memcmpto keep the build libc-free)
- The Multiboot2 info pointer is passed to
-
Kernel:
kernel/in Go, freestanding build with gccgo- IDT + PIC remap + PIT init
- Tick counter from the PIT and a
hlt-based idle loop when there’s no input
-
Terminal:
terminal/writes to VGA text mode 80x25, manages cursor, scroll, and backspace -
Keyboard:
keyboard/reads from PS/2 and maps keys with the Italian layout only (temporary) -
Tiny shell: interactive prompt + basic line editing, commands are mostly for debugging
-
Memory:
mem/- Multiboot2 memory map parsing (
mmapandmmapmaxcommands) - A minimal 4KB page frame allocator backed by a bitmap placed inside usable memory (
pfa/alloc/free)
- Multiboot2 memory map parsing (
-
Filesystem:
fs/- Minimal in-memory FS backed by allocated pages (
ls/write/cat/rm/stat)
- Minimal in-memory FS backed by allocated pages (
-
Persistent Storage:
drivers/ata+fs/fat16- ATA PIO driver for disk I/O
- FAT16 filesystem with file create/read/list operations
- Data persists across reboots on a 20MB disk image
- Experimental, single-core
- 64-bit only (x86_64 long mode); 32-bit is no longer supported
- Basic paging (identity map), FAT16 persistent storage driver
- Runs in x86_64 long mode, meant for QEMU/GRUB, no UEFI
- Go runtime pared down: freestanding build (no standard library) with just the stubs the toolchain ends up expecting
- Via Docker (recommended): Docker with
--platform=linux/amd64 - Native (if you want to do it manually): cross toolchain
x86_64-elf-{binutils,gccgo},grub-mkrescue,xorriso,mtools,qemu-system-x86_64
docker build --platform=linux/amd64 -t go-dav-os-toolchain .
docker run --rm --platform=linux/amd64 \
-v "$PWD":/work -w /work go-dav-os-toolchain \
make # builds build/dav-go-os.iso
qemu-system-x86_64 -cdrom build/dav-go-os.isoQuick targets from the Makefile
make docker-build-onlybuilds the image and the ISOmake run(outside Docker) runs QEMU on an existing ISO
Assuming an x86_64-elf-* toolchain is installed
make
qemu-system-x86_64 -cdrom build/dav-go-os.isoTo force cross binaries: make CROSS=x86_64-elf
- On boot the prompt
>shows up helplists commands,clearwipes the screen,aboutprints kernel info- The kernel idles with
hltwhen nothing is happening
help,clear,about,echoticks(PIT tick counter)mem <hex_addr> [len](hexdump)mmap,mmapmax(Multiboot memory map and highest usable end)pfa,alloc,free <hex_addr>(page allocator)ls,write <name> <text...>,cat <name>,rm <name>,stat <name>(in-memory filesystem)version(OS name and version)
fatformat- Initialize disk with FAT16 structurefatinit- Mount the filesystemfatinfo- Show filesystem layoutfatls- List files in root directoryfatcreate <name> <content>- Create a filefatread <name>- Read a filedisk read|write <lba>- Raw sector access
Example:
fatformat
fatinit
fatcreate hello Hello World
fatls
fatread helloiso/: GRUB config and ISO packaging bits (grub.cfg)boot/: also contains the linker script (linker.ld) and a couple of freestanding helpers used by the buildbuild/: build output (ISO + ELF)
Contributions are welcome! This project is still early-stage and intentionally minimal, so small PRs are the best way to help.
- Review CONTRIBUTING.md for guidelines
- Check issues labeled
good first issueorhelp wanted - Open a Discussion to propose an idea or ask a question
Personal, open-source, work-in-progress. I’m building pieces as I learn them—the goal is understanding, not chasing modern-OS feature lists
Thanks to:
@metacatdudfor taking care of the entire migration from 32 to 64 bit architecture - really amazing work!
@ranjan42for the useful documentation added and the implementation of the scheduled and the command history
@jgafnea for improving the shell and documenting the contributing section
@soorya38for taking care of a missing part of the project - the unit tests!