A Go unikernel running on x86 bare metal
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
fanbingxin c3bf7c6dfc
Merge pull request #46 from icexin/ci
7 days ago
.github/workflows upgrade go version of github action to go1.16.x 7 days ago
.vscode fix dhcp h.isValid on qemu 6.0 (#26) 3 weeks ago
app add support for go version >= 1.14 1 week ago
assets change cursor (#35) 1 week ago
boot clear boot code (#28) 3 weeks ago
cga Update readme (#1) 10 months ago
clock add cmos clock (#37) 1 week ago
console console:fix windows name (#18) 9 months ago
debug print kernel panic (#42) 1 week ago
docs update doc (#5) 10 months ago
e1000 change netstack from netstack => gvisor 1 week ago
fs add support for go version >= 1.14 1 week ago
inet change netstack from netstack => gvisor 1 week ago
kbd add mouse and gui (#32) 2 weeks ago
kernel fix env 1 week ago
kmain add go version check 7 days ago
mm remove pdet notinheap (#44) 1 week ago
multiboot init 10 months ago
pci init 10 months ago
pic add mouse and gui (#32) 2 weeks ago
ps2 add mouse and gui (#32) 2 weeks ago
sys add fpu support (#31) 2 weeks ago
uart add fbcga cursor 10 months ago
vbe replace syscall const (#40) 1 week ago
.gdbinit init 10 months ago
.gitignore update magefile.go 3 weeks ago
LICENSE add LICENSE 10 months ago
README.md update readme 7 days ago
bochsrc add fpu support (#31) 2 weeks ago
go.mod change netstack from netstack => gvisor 1 week ago
go.sum change netstack from netstack => gvisor 1 week ago
magefile.go add go version check 7 days ago
sym init 10 months ago




A Go unikernel running on x86 bare metal

Run a single Go applications on x86 bare metal, written entirely in Go (only a small amount of C and some assembly), support most features of Go (like GC, goroutine) and standard libraries, also come with a network stack that can run most net based libraries.

The entire kernel is a go application running on ring0. There are no processes and process synchronization primitives, only goroutines and channels. There is no elf loader, but there is a Javascript interpreter that can run js script files, and a WASM interpreter will be added to run WASM files later.


Go's runtime provides some basic operating system abstractions. Goroutine corresponds to processes and channel corresponds to inter-process communication. In addition, go has its own virtual memory management, so the idea of running Go programs on bare metal was born.

It turns out that Go has the ability to manipulate hardware resources, thanks to Go's controllable memory layout, the ability to directly translate hardware instructions without a virtual machine, and C-like syntax. These all make it possible for Go to write programs that run on bare metal. However, there are also some challenges. Go piling in many instructions to perform coroutine scheduling and memory GC, which brings some troubles in some places that cannot be reentrant, such as interrupt handling and system calls.

In general, writing kernel in Go is a very interesting experience. On the one hand, it gave me a deep understanding of Go's runtime. On the other hand, it also provided an attempt to write the operating system kernel on bare metal in addition to the C language.


js nes

Feature list

  • Basic Go features, such as GC, goroutine, channel.
  • A simple console support basic line editting.
  • Network stack support tcp/udp.
  • Go style vfs abstraction using afero
  • A nes game emulator using nes
  • A Javascript interpreter using otto
  • VBE based frame buffer.
  • Some simple network apps(httpd, sshd).


  • Go 1.16.x (higher versions may not work)
  • gcc
  • qemu
  • mage


$ go get github.com/magefile/mage
$ brew install x86_64-elf-binutils x86_64-elf-gcc x86_64-elf-gdb
$ brew install qemu


$ go get github.com/magefile/mage
$ sudo apt-get install build-essential qemu


$ mage qemu


You can directly use the gdb command to debug, or use vscode for graphical debugging.

First you need to install gdb, if you are under macos, execute the following command

brew install x86_64-elf-gdb

Use the extension Native Debug in vscode to support debugging with gdb

First execute the mage qemudebug command to let qemu start the gdb server, and then use the debug function of vscode to start a debug session. The debug configuration file of vscode is built into the project.

Go provides simple support for gdb, see Debugging Go Code with GDB for details


Running on bare metal

If you want eggos to run on bare metal, it is recommended to use grub as the bootloader.

The multiboot.elf generated after executing the make command is a kernel image conforming to the multiboot specification, which can be directly recognized by grub and booted on a bare metal. The sample configuration file refer to boot/grub.cfg


For some design details see docs/internal.md


  • WASM runner
  • GUI support
  • 3D graphic
  • x86_64 support
  • SMP support


The program still has a lot of bugs, and often loses response or panic. If you are willing to contribute, please submit a PR, thank you!

Special thanks

The birth of my little daughter brought a lot of joy to the family. This project was named after her name xiao dan dan. My wife and mother also gave me a lot of support and let me update this project in my spare time. ❤️ ❤️ ❤️