Announcement: All software requirements services are now delivered through Better Software UK.

Compiling a C# kernel to bare metal and booting in QEMU

I’ve managed to compile a very basic C# kernel to x86 machine code, and then successfully boot it in QEMU.

It’s not much more than ‘hello world’, but a minimal set of custom base classes were developed, including Object() and structs for value types, for linking to instead of the BCL (or the hosted C runtime library). The standard .Net AOT compiler shipped with .Net 7 was then able to produce an entirely self-contained, 13kb kernel capable of running without requiring the .Net runtime to be installed.

A multiboot compliant loader written in minimal ASM was also linked to, allowing QEmu to successfully boot directly into 32-bit protected mode and execute the kernel, printing ‘hello world’ by writing directly to the VGA video memory. This would normally cause a segmentation fault if attempted in a user space application. It’s quite extraordinary that modern CPUs are still just registers and memory, like the 8086 was.

The build toolchain is currently a mixture of the Windows .Net compiler and MSYS2/Ming for linking, PE to ELF conversion and QEMU. Having to switch between environments isn’t great, but equally, I think the current setup is truly capable of cross-compiling to different targets since I’m compiling an x86 binary on a 64-bit machine. And I’ve avoided having to compile my own GCC so far.

The next goal is probably to work out how hardware interrupts work, so keyboard keystrokes can be outputted somehow. Also, I’m not entirely sure how the initial stack relates to .Net’s ‘new’ operator, or whether I’m even able to instantiate reference types yet.

None of what I’ve done is entirely new, rather a mashup of ideas from 4 or 5 different sources and from similar attempts in languages other than C. The GitHub repository for my work is here: PatienceOS (nb. ignore the ‘OS’ moniker, just high ambitions for now), and I’ve also put a few useful links below for those interested in learning more.

Making the kernel testable through fairly low of level DI, eg. IWriteableVideoMemory and the like, seems an interesting concept to explore further, one that I’ve not seen in the various other reference kernels so far.

Further Reading

Frank Ray Consulting. Software requirements for agile development teams, particularly remote, outsourced and offshore development teams working in financial services.

Get in touch if you need our help

Woking, Surrey, GU22, United Kingdom