MichalStrehovsky / zerosharp

Demo of the potential of C# for systems programming with the .NET native ahead-of-time compilation technology.
2k stars 103 forks source link

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

Open FrankRay78 opened 8 months ago

FrankRay78 commented 8 months ago

Hello @MichalStrehovsky,

Ideally, I would have opened a discussion for this, as good etiquette...

Anyway, just to say I've managed to take the no-runtime example from this repo, successfully use it to compile a very basic C# kernel to x86 machine code, and then boot it in QEMU. It's a 13kb and really quite remarkable, particularly since I've only ever known .Net as a managed runtime.

The repo for my kernel is here: PatienceOS (nb. ignore the 'OS' moniker, high ambitions I guess) and an accompanying blog post with more details here: Compiling a C# kernel to bare metal and booting in QEMU.

Thank you for your amazing work with zerosharp and bflat.

Regards, Frank

MichalStrehovsky commented 8 months ago

Hey Frank! That's pretty cool and a very interesting example of mixing various tools! Looking forward to see your progress on this!

FrankRay78 commented 8 months ago

Update - Quite significant improvements have been made to the quality of build steps, located in build.cmd, and also improvements to accompanying documentation in the readme.

All manner of combinations were tested, covering building entirely on Windows, Windows + MSYS2, Windows + WSL, entirely WSL, Windows + MSYS2 + WSL, Linux only. Most of which ended up encountering some kind of snag, to be documented further.

FrankRay78 commented 7 months ago

Update - I've introduced XUnit and written some initial unit tests for several of the kernel classes. Interestingly, it involves building and linking the kernel against the standard .Net BCL, rather than zerosharp ie. being able to multi-target which BCL to use. I took the idea from Building a self-contained game in C# under 8 kilobytes, namely:

For example, parts of the game could be included from an xUnit project to get unit test coverage.

One VS solution builds and links the PatienceOS kernel against the custom .Net BCL (zerosharp based), handy for when you are coding within Visual Studio and want to quickly check building against the custom runtime types.

The other VS solution builds and links the PatienceOS kernel against the standard .Net 8.0 runtime, allowing you to develop and run unit tests within the built-in Visual Studio Test Explorer, as per any other .Net unit test project.

See instructions here: Developing PatienceOS

FrankRay78 commented 5 months ago

Dear @MichalStrehovsky, I'm using ilc.exe with the following switches 'ilc --targetos windows --targetarch x86 --instruction-set base' and it sometimes emits the sse instruction 'xorps'.

Given there are specific instruction set switches for sse (sse, sse2, sse3, ssse3, sse4.1, sse4.2), I can't tell if '--instruction-set base' should be allowing the 'xorps' instruction. I've searched and can't find any documentation on this, apart from the command line help, 'ilc.exe --help'

Before I log an issue with Microsoft, do you happen to know what the correct behaviour should be?

PS. The 'xorps' instruction is emitted when I add a single, declared and initialised, but never used, private byte variable within a struct, which also seems a bit odd.


Update - I decided to ask the same question, here: https://github.com/dotnet/runtimelab/issues/2545

FrankRay78 commented 4 months ago

Update - I'm putting PatienceOS on pause, for the reasons described here.