C Sharp Bare Bones: Difference between revisions

From OSDev.wiki
Jump to navigation Jump to search
[unchecked revision][unchecked revision]
Content added Content deleted
No edit summary
No edit summary
Line 26: Line 26:


==Directory layout==
==Directory layout==
eiriley

We will create a directory to build our OS and ISO file in. Something like mkdir -p barebones/iso/boot/grub should suffice. Enter the barebones directory and start creating some files.


===loader.asm===
===loader.asm===
eiriley

This is the assembly stub which will contain a Multiboot header.

<source lang="asm">
global sthrow

extern kmain

MODULEALIGN equ 1<<0
MEMINFO equ 1<<1
FLAGS equ MODULEALIGN | MEMINFO
MAGIC equ 0x1BADB002
CHECKSUM equ -(MAGIC + FLAGS)

section .text

align 4
dd MAGIC
dd FLAGS
dd CHECKSUM

sthrow:
hlt
jmp sthrow
</source>


===kernel.cs===
===kernel.cs===
eiriley

This is the actual simple kernel - it just prints a message to the screen.

<source lang="csharp">
namespace BareBones
{
class Program
{
static int pos = 0;

unsafe static void Main()
{
// Clear the screen
for(int i = 0; i < 80 * 25 * 2; i++)
*(byte *)(0xb8000 + i) = 0;

// Say hi
Print("Hello World!");
}

static void Print(string s)
{
foreach(char c in s)
Print(c);
}

unsafe static void Print(char c)
{
*(byte *)(0xb8000 + pos) = (byte)c;
*(byte *)(0xb8000 + pos + 1) = 0x0f;
pos += 2;
}
}
}
</source>

===linker.ld===

The linker script

<source lang="c">
ENTRY (_start)

SECTIONS
{
. = 0x00100000;

.text ALIGN(0x1000) :
{
*(.text)
}

.rodata ALIGN(0x1000) :
{
*(.rodata*)
}

.data ALIGN(0x1000) :
{
*(.data)
}

.bss ALIGN(0x1000) :
{
*(COMMON)
*(.bss)
}
}
</source>

===iso/boot/grub/grub.cfg===
This is a short file to tell grub where to find our kernel
<source lang="c">
multiboot /kernel.bin
boot
</source>

==Building it all==
The following commands should build your new C# kernel. First, assemble the multiboot stub:
<source lang="bash">nasm -felf -o loader.o loader.asm</source>
To compile the .cs file to a .exe you have a choice of three options (depending on your architecture):
<source lang="bash">
gmcs /target:exe /out:kernel.exe /unsafe kernel.cs
csc /target:exe /out:kernel.exe /unsafe kernel.cs
tybuild.exe /unsafe kernel.cs
</source>
To compile kernel.exe to machine code we use tysila:
<source lang="bash">tysila2.exe --arch i586-elf-tysos -fno-rtti -o kernel.o kernel.exe</source>
Here, the -fno-rtti switch disables run-time type information, support for which would greatly enlarge the size of your kernel and require you to provide a great number of run time functions to support this.

To link:
<source lang="bash">ld -m elf_i386 -T linker.ld -o iso/kernel.bin loader.o kernel.o</source>

Then we make a bootable iso image with:
<source lang="bash">grub-mkrescue -o barebones.iso iso</source>

And run it on qemu with:
<source lang="bash">qemu-system-i386 -cdrom barebones.iso</source>

[[Category:Bare bones tutorials]]
[[Category:CSharp]]

Revision as of 17:04, 6 June 2024

WAIT! Have you read Getting Started, Beginner Mistakes, and some of the related OS theory?
Difficulty level

Medium

This tutorial is intended to help you write a simple 'Hello World' OS in C# which you can then compile to machine code for the IA32 architecture and boot via GRUB. There are a number of tools for compiling C# to CIL, including Microsoft's csc (distributed with Microsoft.NET) and mcs/gmcs/dmcs (distributed with Mono). In addition there are a number of tools for compiling CIL to native machine code in an ahead-of-time manner, including Microsoft's ngen, mono (with the --aot option), Cosmos' IL2CPU, mosacl from the MOSA project and tysila from the tysos project. Given the author's familiarity with tysos, that is what we will focus on here.

File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg File:Eiriley.jpg

Prerequisites

You will need a binutils which can target the elf_i386 emulation, mono (for the gmcs compiler) or csc from .net, grub and its xorriso dependency (for generating iso images), NASM/YASM/something similar for the assembly stub and of course tysila. For debian-based systems try sudo apt-get install nasm xorriso qemu mono-devel.

For tysila, you can download pre-compiled binaries from http://www.tysos.org/files/tysila/tysila-latest.tar.bz2 (http://web.archive.org/web/20170317154703/http://www.tysos.org/files/tysila/tysila-latest.tar.bz2) and extract them to somewhere in your path. Please note these binaries will not work on 64-bit Windows due to a bug in the current Microsoft CLR (see here) so instead you must build it from source.

Building tysila

This is only required if you have not downloaded the pre-compiled binaries above. Use subversion to get the latest sources 'svn co http://www.tysos.org/svn/trunk tysos' (not in Wayback Machine), or download the latest tar ball from http://www.tysos.org/files/src/tysos-latest.tar.bz2 (http://web.archive.org/web/*/http://www.tysos.org/files/src/tysos-latest.tar.bz2). Tysos is a project developing a full OS kernel and drivers in C#, however we only want the compiler from it therefore we only want to compile part of the build tree. Enter the tysos directory and run

cd tybuild && make && cd ..
cd mono/corlib && make mscorlib.dll && cd ../..
cd tysila2 && make && cd ..

You will need to put the mono/corlib/mscorlib.dll, tysila2/bin/Release/tysila2.exe, tysila2/bin/Release/libsupcs.dll, tysila2/bin/Release/libtysila.dll, tysila2/bin/Release/tydbfile.dll, tysila2/bin/Release/tydisasm.dll and tybuild/bin/Release/tybuild.exe files somewhere in your path.

You may need to enable binfmt_misc support for mono (if trying this on linux). How to do this is outside the scope of this document but the answer is easily obtained via Google.

Directory layout

eiriley

loader.asm

eiriley

kernel.cs

eiriley