PatienceOS
A baremetal C# kernel.
Install / Use
/learn @FrankRay78/PatienceOSREADME
PatienceOS
A baremetal C# kernel - Frank Ray, Better Software UK.
Built using a combination of Microsoft's C# IL and native AOT compilers, and the GNU toolchain.
Learnings from PatienceOS are being captured in a series of blog posts, and a project wiki does exist, although remains largely a collection of working notes. The following README remains the best source of infrequently changing, production quality documentation.
[!IMPORTANT]
PatienceOS has been superseded by InstructionOS, an ANSI C kernel, for reasons described here.
Table of contents
- Commentary on the name
- Progress
- Playing with PatienceOS
- Developing PatienceOS
- Contributing
- Build toolchain
Commentary on the name
PatienceOS was chosen to remind Frank this is a 12-month initial project (at least), as part of his 2024 professional development goals. The dopamine hit from quickly pushing out PR's, like he regularly enjoys from contributing to other open-source repos (eg. spectre.console), simply won't be possible with OS development. Hence the need for patience, and perseverance.
Progress
PatienceOS isn't a fully-fledged 'operating system', but it does boot and is being actively developed. The obligatory screenshot (which is pretty underwhelming at the moment) is here:
As of 15 April 2024, PatienceOS is a 32-bit kernel that boots in protected mode on an emulated x86 machine. The bootstrap is written in assembly and supports the Multiboot Specification, version 2. The main kernel is written in C#, linked against a custom runtime library, and compiled to bare metal using the Microsoft .Net AOT compiler. There is a basic console class that supports writing characters to the screen in VGA text mode. Extensive unit tests have been written for the console and the underlying framebuffer video memory.
See the description of each Release for the most accurate list of features supported by the PatienceOS kernel.
[!TIP]
Please upvote :+1: the issues you are most interested in, the Top Issues Dashboard tracks community interest.
Playing with PatienceOS
Windows 10 Host
I love Visual Studio and find it a far superior IDE compared to VS Code. Unfortunately, the lack of a Linux Visual Studio version means I'm tied to Windows, at least for now (probably forever). This is my primary reason for using Windows as my development machine ('nix users, don't hate on me).
Installation
Perform the following one-off installs, ideally in a virtual machine:
- Microsoft .Net 8, Visual Studio 2022
- MSYS2 MINGW64, see: MSYS2-Installation
- QEMU, the native Windows binaries, see: Download QEMU, nb. I used the latest Stefan Weil 64-bit Windows installer
Configuration
ILC, the Native .Net AOT compiler
ILC needs to be installed locally. It's a nuget package and will be present if you have configured and built at least one C# .Net project that emits native AOT code. I'm using version 8.0.1 of the IL compiler and so expect to see it installed in the nuget cache for my user, info, here: C:\Users\info\.nuget\packages\runtime.win-x64.microsoft.dotnet.ilcompiler\8.0.1\tools. If you don't see something similar, then perform the following steps in a temporary directory to create a temporary application, simply for the purpose of installing ILC locally:
dotnet new console -n MyConsoleApp
cd MyConsoleApp
dotnet add package Microsoft.DotNet.ILCompiler
EITHER:
- Load the project in Visual Studio and enable 'Publish native AOT', or
- Edit the csproj file and add <PublishAot>True</PublishAot> within the PropertyGroup
dotnet build
ilc.exe should now be installed here: C:\Users\info\.nuget\packages\runtime.win-x64.microsoft.dotnet.ilcompiler\8.0.1\tools
MSYS2 MINGW64
Open the MSYS2 MINGW64 console and perform the following actions:
- A full package upgrade:
pacman -Syuu, - Install binutils:
pacman -S mingw-w64-x86_64-binutils(required to get a Windows compiledobjcopy) - Install NASM:
pacman -S mingw-w64-x86_64-nasm
Build tool paths
Several tools are required in the build and link process. Update src\setpath.cmd to point to the correct install locations on your machine. The existing entries in the file will give you a good idea of where to find them, if you have followed the instructions above and accepted default install locations.
Booting
- Open
x64 Native Tools Command Prompt for VS 2022 - Set the correct tool paths in the console session,
src\setpath.cmd(only do this once, after opening the command prompt) - Compile, link and boot,
src\build.cmd
Patience OS, a baremetal C# kernel, should boot in QEMU.
Developing PatienceOS
There are three different ways to build PatienceOS, each with a very different purpose in mind. These are:
File | Type | Purpose |
--- | --- | ---
build\build.cmd | Windows Command script | Builds the kernel and boots in QEMU (see Playing with PatienceOS above for instructions)
src\PatienceOS.NoStdLib.sln | Visual Studio 2022 solution; only contains the PatienceOS project | Builds and links the kernel against the custom .Net runtime, zerosharp.cs. Handy for when you are coding PatienceOS within Visual Studio and want to quickly check building against the custom runtime types.
src\PatienceOS.sln | Visual Studio 2022 solution; contains the PatienceOS project and accompanying unit test project | Builds and links the kernel against the standard .Net 8.0 runtime. Allows you to run the PatienceOS unit tests within the built-in Visual Studio Test Explorer, as per any other unit test project.
Contributing
[!IMPORTANT]
I'm not currently accepting pull requests as this is a personal learning project.
Please upvote :+1: any existing issues you are interested in being worked on. You can also contribute to discussions with your fellow GitHub users and me by commenting on existing issues, and by raising new issues you want to be considered for development.
All reasonable interactions are welcomed but please don't be offended if I close or delete issues or comments etc, as I see fit, as this is my personal learning project. You are welcome to fork the repository for your own purposes.
Build toolchain
Commentary on the build process
Relying on Visual Studio specific, MSBuild or csproj files to build the kernel has been avoided in favour of directly calling the individual build tools. I want fine-grained control over the compile and link process, MSBuild feels like a poorly documented 'black box' that changes every .Net release in subtle ways that aren't clear, and I don't want to invest a huge amount of time developing a C# kernel only to find I can't build it in some future .Net release.
I would have sincerely loved to use bflat as my IL to native compiler, but even that didn't seem to allow intermediate object file output for class libraries, and I didn't want to raise an issue requesting the CLI options expose more of the underlying compiler switches. And so I've stuck to the approach demo'd in zerosharp, namely a Windows command/batch file (build.cmd).
The following lines in the PatienceOS src\build.cmd are of particular note:
C# IL Compiler
csc /debug:embedded /noconfig /nostdlib /runtimemetadataversion:v4.0.30319 ../src/kernel.cs ../src/zerosharp.cs /out:kernel.ilexe /langversion:latest /unsafe
/noconfig: Don't reference the standard set of assemblies and configuration files.
/nostdlib: Don't reference the standard library assemblies.
/unsafe: Allow unsafe code blocks in C#, enabling pointers and other low-level constructs that aren't type-safe.
C# AOT Compiler
ilc --targetos windows --targetarch x86 kernel.ilexe -g -o kernel.obj --systemmodule kernel --map kernel.map -O
--targetos windows: The code is intended to run on the Windows operating system.
--targetarch x86: The code is being compiled for the x86 architecture, typically used in 32-bit Windows systems.
Targeting machine-specific architectures can be done at the compiler call (eg. csc /platform:x64 or ilc --targetarch x86) and/or the linker call (eg. link /machine:x64)
Commentary on the build environment
Believe me, I really did try to have a single environment for the end-to-end build process. It was much harder than I thought, and unfortunately, I've not managed to do it (
