Autor Thema: C# als Sprache  (Gelesen 5526 mal)

Beatkiller

  • Beiträge: 17
    • Profil anzeigen
Gespeichert
« am: 17. May 2007, 13:00 »
Hallo,

ich möchte hier Ideen austauschen und evtl eine Lösung für ein noch nicht diskutiertes Problem finden oder aber Gewissheit erhalten, dass es SO nicht funktioniert.

Nach dem ich sämtliche Videos über Singularity (http://research.microsoft.com/os/singularity/) gesehen hab, und im allgemeinen die Sprache C# sehr geeignet für jede Menge Projekte halte, machte ich mir Gedanken, wie man das wohl angehen kann. Da C# einen unsafe-Mode hat, kann man damit auch mit Pointern arbeiten, was für die OS-Entwicklung unerlässlich ist.

Das Hauptproblem ist, einen Compiler zu finden, der flache Binaries erzeugt, die statisch sind, also keine zusätzlichen Libs für die Ausführung benötigen. Der Grund wurde ja in den Low-Level-Ausgaben ausreichend erörtert.

Ich suchte nach einer Möglichkeit, Binaries so zu erstellen, das sie kein .Net-Framework bzw. Mono benötigen. Unter Windows wurde ich enttäuscht, mit Mono ist es aber möglich. Mit dem Tool mkbundle (Teil der mono-devel-Pakete) ist es möglich, sämtliche notwendige Libs in eine Binary zu übernehmen.

Darauf hin erstellte ich 2 Dateien und ein Makefile, welche hier hier gern zur Verfügung stellen will:

Makefile:
all:
gcc -c -ffreestanding -nostdinc -O3 -Wall loader.c
gmcs -unsafe+ core.cs
mkbundle2 --static -z -c -oo bundle.o core.exe -o core.c
gcc -Wall -c `pkg-config --clfags mono` core.c
ld `pkg-config --libs-only-L mono` -Wl,-Bstatic -lmono -Wl,-Bdynamic `pkg-config --libs-only-l mono | sed -e "s/-lmono //"` -lz loader.o bundle.o core.o -o kernel

clean:
rm -rf bundle.o core.exe loader.o core.o core.c kernel

core.cs:
namespace kernel
{
public unsafe class core
{
public static void Main(string[] args)
{
// Don't use Console.WriteLine, because we don't have a c#-Lib
}
}
}

loader.c:
extern int main( int argc, char* argv[]);

const unsigned MultibootHeader[12] __attribute__ ((section(".text"))) = {
0x1BADB002,
0x00000000,
0xE4524FFE,
(unsigned)MultibootHeader,
(unsigned)main,
0x00000000,
0x00000000,
(unsigned)main,
0x00000000,
0x00000050,
0x00000019,
0x00000000
};

Die loader.c existiert nur, weil ich mit C# keinen MB-Header erzeugen kann, der auch als solcher anerkannt wird. Vielleicht hat hier jemand ne andere Idee, würde das Thema ungemein vereinfachen.

Grundsätzlich kompiliert und linkt es gut, es gibt noch eine align-Warning für den mb-header in der .text-section, das habe ich aber erstmal ignoriert.

Das Vorgehen kann folgendermaßen erklärt werden:

1. Es wird ein simpler Loader in C erstellt, der dafür verwendet wird, das der Kernel mit Grub gebootet werden kann (dafür gibts mehrere Gründe)
2. Die C#-Sources (hier erstmal nur eine) werden in eine Assembly kompiliert
3. Die Assembly wird durch mkbundle (http://www.die.net/doc/linux/man/man1/mkbundle.1.html) gejagt, und daraus ein Bundle-Object (bundle.o) und ein C-Quelltext (core.c) erzeugt, der das Bundle lädt.
4. Der Bundle-Lader wird zu einem Object kompiliert
5. Alle Objects werden zu einer flachen Binary gelinkt

Das Resultat lässt sich direkt aufrufen, mit mbchk erhalte ich aber keine Meldung, das der MB-Header gefunden wurde.


Vielleicht gibts die/den eine(n) oder andere(n) hier, den das Thema ebenfalls interessiert und Ideen hat, wie das zu lösen wäre.

Grüße
BK

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 17. May 2007, 13:14 »
Mit dem Tool mkbundle (Teil der mono-devel-Pakete) ist es möglich, sämtliche notwendige Libs in eine Binary zu übernehmen.
Ich denke, hier liegt der große Denkfehler. Du hast die Libs dann zwar statisch reingelinkt, aber es sind immer noch die Mono-Libs, die selbstverständlich versuchen werden, (Linux|Windows)-Kernelfunktionen anzusprechen. Spätestens an dieser Stelle fällst du damit auf die Schnauze.

Alles andere wäre wohl irgendwie lösbar, aber das Vorgehen ergibt keinen Sinn. Wenn du C# benutzen willst, mußt du entweder selbst eine VM dafür schreiben oder tatsächlich einen Native Compiler für C# finden (mir wäre momentan keiner bekannt).
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Beatkiller

  • Beiträge: 17
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 17. May 2007, 20:42 »
Hmm, du hast recht, allerdings hab ich am Makefile geschraubt:

all:
gcc -c -ffreestanding -nostdinc -O3 -Wall loader.c
gmcs -unsafe+ core.cs
mkbundle2 --static -z -c -oo bundle.o core.exe -o core.c
gcc -static -Wall `pkg-config --cflags mono` core.c `pkg-config --libs-only-L mono` -lmono `pkg-config --libs-only-l mono | sed -e "s/\-lmono //"` -lz -lrt loader.o bundle.o -o sharpkernel

Nun bekomm ich folgendes hin:

ldd sharpkernel
       not a dynamic executable

Ausführbar is die Binary aber. Zugegeben das Teil is mörder-groß (3MB), funktioniert aber.


EDIT: Ok, ich seh, was du meinst, es genügt nicht, die Runtime in eine Binary zu embedden, man benötigt natürlich noch einen Kernel, der den Runtime-Code versteht. Das Henne-Ei-Problem. Mein Kernel hat die Runtime mit drin, kann sie aber nicht ausführen, weil er die Befehle nicht hat, die die Runtime benötigt... Man benötigt an dieser Stelle tatsächlich einen Compiler für native Binaries. MS hat so einen Compiler, aber sie geben ihn nicht raus. Er heißt Bartok.
« Letzte Änderung: 17. May 2007, 21:14 von Beatkiller »

C#ris

  • Beiträge: 47
    • Profil anzeigen
    • http://www.xerxys.org
Gespeichert
« Antwort #3 am: 19. May 2007, 17:44 »
Statt C# könntest du das ganze in Java wiederholen. Für Java gibt es nämlich einen entsprechenden Compiler, den gcj.
Du müsstest "nur" die libc und libgcj portieren...;)

Nachteil ist natürlich, dass es in Java keinen "unsafe" Code gibt, aber über das Java Native Interface könnte man auch dieses Problem lösen.

Gruß,
Chris

 

Einloggen