Autor Thema: Kernel mit GCJ  (Gelesen 19001 mal)

Vogtinator

  • Beiträge: 24
    • Profil anzeigen
Gespeichert
« am: 11. September 2012, 14:26 »
Damit der Artikel http://www.lowlevel.eu/wiki/Java endlich mal einen Beispielkernel erhält, wurde unter http://www.lowlevel.eu/wiki/Diskussion:Java schon eifrig über die Theorie diskutiert. Das ganze kommt jetzt aber ins Forum, weil es einfach keine Diskussion mehr ist  :-D
Hier ist ersteinmal das, was ich getan habe:
-Tutorial-Kernel kopiert
-Makefile für *.java ergänzt
-Init.java erstellt, die in Funktion Init.main() die native Funktion write_char('a') aufruft
-Funktionen von java.lang.Object überschrieben so gut es ging
-Versucht zu linken:
Init.java:1: undefined reference to `java::lang::Object::Object()'
Init.o: In function `void Init::main()':
Init.java:5: undefined reference to `_Jv_InitClass'
Init.java:5: undefined reference to `hidden alias for void Init::write_char(wchar_t)'
Init.o: In function `_Jv_global_static_constructor':
Init.java:13: undefined reference to `_Jv_RegisterResource'
Init.o:(.data+0x24): undefined reference to `void java::lang::Object::throwNoSuchMethodError()'
Init.o:(.data+0x74): undefined reference to `hidden alias for void Init::write_char(wchar_t)'
Init.o:(.data+0x100): undefined reference to `vtable for java::lang::Class'
Init.o:(.data+0x110): undefined reference to `java::lang::Object::class$'

Was also noch getan werden muss:
-write_char nativ implementieren (Mit CNI, das verlangt nix externes, soweit ich weiß)
-C++-Support einbauen, dazu braucht man einen rudimentären Kernel
-herausfinden, was (und wie) man die anderen Funktionen implementieren kann, dazu sollte man sich vllt. mal den GCJ-Quelltext anschauen oder dekompilieren (wer will das schon...).

Projekt-Ordner ist hier: http://ritter-vogt.dyndns.biz/rv/files/gcj-kernel.zip

Viel Spaß beim rumprobieren!
Fabian

Edit: Wenn C++ drin ist, sollte Java kein Problem mehr werden, da GCJ Java C++-Kompatibel kompiliert, soweit ich das verstanden habe.
« Letzte Änderung: 11. September 2012, 14:28 von Vogtinator »

DerHartmut

  • Beiträge: 236
    • Profil anzeigen
    • Mein Blog
Gespeichert
« Antwort #1 am: 11. September 2012, 15:39 »
Welchen Tutorial-Kernel meinst du? Den von taljeth?
$_="krJhruaesrltre c a cnp,ohet";$_.=$1,print$2while s/(..)(.)//;
Nutze die Macht, nutze Perl ;-)

Vogtinator

  • Beiträge: 24
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 11. September 2012, 16:04 »
Ja, http://www.lowlevel.eu/wiki/Teil_4_-_Hello_World.
Was bringts, das neu zu schreiben.

DesL

  • Beiträge: 23
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 11. September 2012, 16:11 »
Zitat
java::lang::Object::class$
Da fängt es schon an, und von den vtables will ich erst gar nicht anfangen.
Und:
Zitat
Edit: Wenn C++ drin ist, sollte Java kein Problem mehr werden, da GCJ Java C++-Kompatibel kompiliert, soweit ich das verstanden habe.
DAS habe ich auch mal gedacht. Ist es aber nicht. Andere Datentypen sind da nur das winzigste Problem, das was C++-Kompatibel Compiliert wird, ist das Name-Mangling. Da hört es auch auf. Und "mal eben" CNI oder JNI reinzubringen wird auch nichts, weill man DANN ganz schnell auf die dutzende unresolved references kommt die ich meinte. Es hat schon seinen Grund warum ich seit Monaten da immer wieder mal Wochenenden reinstecke und noch nichts Ausführbares Kompiliert habe.
Und da fangen wenn du die references auflösen willst gleich schöne Sachen an, wo du dann nen GC brauchst, ne rudimentäre Speicherverwaltung etc. Das ist nicht so einfach getan. Versteh mich nicht falsch, ich will dir das nicht ausreden oder schlecht machen, aber ich war zu dem Thema auch mal so enthusiastisch "das geht schon so und so, ich habe da schon ne idee". Daraus wird schnell ernüchterung und man fängt an GCC/GCJ Quellcode und Docs zu wälzen, weil es für sowas einfach keine referenz Projekte gibt bei denne man sich was abschauen kann.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 11. September 2012, 16:13 »
Wie wär's, wenn du einfach mal alles in ein git-Repo pushst, was du im Moment hast, und dann kann jeder daran weiterbasteln, der sich grad dazu bemüßigt fühlt? Zusammen kommt man vielleicht eher zum Ziel.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

DesL

  • Beiträge: 23
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 11. September 2012, 16:47 »
Das ist vermutlich das kaputteste was ich je gebaut habe, und dass ich da ständig (meist erfolglos) was dran geändert habe, hat es sicherlich nicht  besser gemacht. Schwer lesbar dürfte es  auf jeden Fall sein :D
Ich habe schon länger nichts mehr dran gemacht, aber ich glaube ich habe die meisten Compilierfehler ausgemerzt und stand da zu letzt vor dem Problem eines Compilererrors, guckt selber, probierts aus, es wird keine Garantie für Mentale- oder Softwareschäden geboten ;D
https://www.gitorious.org/java-kernel/java-kernel/trees/master
Viel Spass damit....

Vogtinator

  • Beiträge: 24
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 11. September 2012, 17:04 »
Im Grunde genommen muss man sich ja gar nicht mit so einem "Dreck" wie GC beschäftigen, das hat GCJ schon alles nativ implementiert.
Das OS bekommt davon ja nichts mit.
Es kann eigentlich nicht so schwer sein, von libgcj die OS-Abhängigen Dinge zu ändern und neu zu kompilieren, wenn man die Stellen gefunden hat.
So etwas wie http://cs.nyu.edu/rgrimm/teaching/fa11-oop/1108/java_lang.h sieht da schon ganz gut aus.
Am Ende hat man eine Art libgcj.so für das eigene OS, nur dann halt statisch gelinkt...

Wenn CVS auch gehen würde (Ich hasse git, das will nie so wie ich :x) schickt mir ne PM oder eine Mail (mit Benutzer/Passwort) und ich schick euch Daten.

Edit: Da habe ich wohl zu langsam getippt und den Beitrag über mir nicht gelesen..  :roll:

DesL

  • Beiträge: 23
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 11. September 2012, 17:25 »
Zitat
Im Grunde genommen muss man sich ja gar nicht mit so einem "Dreck" wie GC beschäftigen, das hat GCJ schon alles nativ implementiert. Das OS bekommt davon ja nichts mit.
Bitte was? Wie willst du GCC/libgcj code in dein OS direkt einbauen? Einfach dagegen linken ist ja wohl nicht. Und was heisst "Das OS bekommt davon ja nichts mit"? Wenn nicht das OS (es geht hier immerhin um den Kernel) wer dann?

Versteh das bitte nicht falsch, aber wie lange machst du schon OS-Dev, bzw wie viel Erfahrung hast du schon gesammelt? Und nein, ich will damit nicht sagen "Ich habe vor X Jahren angefangen, ich weiss es besser", ich habs mit epOS bislang selbst nicht so unglaublich weit geschafft, mich interessierts einfach um zu sehen ... sagen wir mal, auf welcher Basis du deine Annahmen triffst.

Vogtinator

  • Beiträge: 24
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 11. September 2012, 17:42 »
Ich sags mal so:
Viel OS-Dev habe ich noch nicht gemacht (Ich mach nur abundzu mal weiter, wenn ich gerade Lust dazu habe, habe letztes mal am Diskettentreiber (glaube ich) weitergemacht).
Und ich nehme mal an, GCJ arbeitet so:
Es kompiliert den Java-Source-Code soweit wie möglich und benötigt dann nur noch die libgcj.so für die (jetzt nicht mehr) "Java-VM".
Diese Executable benötigt ja keine weitere Unterstützung vom Betriebssystem für GC etc. darum muss sie sich ja schon selbst kümmern.
Mit OS habe ich nicht den Java-Kernel gemeint, sondern z.B. Linux, wenn eine (statisch gelinkte) GCJ-Anwengung ausgeführt wird.
Linux muss die Anwendung nur in den Speicher laden und bekommt von dem Java-spezifischem Zeug nichts mehr mit.
-> Wir müssen "nur" die libgcj zerlegen, um an die Java-Bestandteile zu kommen und diese in unseren Kernel-Kern integrieren. Danach sollten wir ohne riesige Probleme die Dateien als (fast) C++ behandeln können.
Oder sehe ich das jetzt komplett falsch?
« Letzte Änderung: 11. September 2012, 17:47 von Vogtinator »

Vogtinator

  • Beiträge: 24
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 11. September 2012, 20:29 »
So, ich habs jetzt zumindest mal geschafft, mit einer statischen Java-Funktion "Hello World!" auszugeben...
Jetzt gehts wohl los mit dem Durchreichen der Speicherverwaltung für Java.
Ich bin mal gespannt, obs was wird.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 11. September 2012, 21:04 »
Aber noch auf Linux, also nicht komplett freistehend?
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Vogtinator

  • Beiträge: 24
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 11. September 2012, 21:36 »
Doch, komplett freistehend (qemu -kernel kernel).
"kernel" ist in etwa 11 kib groß.

Komplett freistehend halt im Sinne von mit noch ein paar Zeilen ASM, C und C++.
« Letzte Änderung: 11. September 2012, 21:40 von Vogtinator »

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 12. September 2012, 09:23 »
Klar, um ein paar Zeilen in anderen Sprachen wird man nicht herumkommen. Hast du deine Version auch irgendwo online?
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Vogtinator

  • Beiträge: 24
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 12. September 2012, 13:12 »
Habs hochgeladen.
http://ritter-vogt.dyndns.biz/lowlevel/
Einen CVS-Server hab ich auch mal aufgesetzt.
Im Moment passiert aber noch nicht viel besonderes, es wird einfach mit C++ eine (statische) Java-Funktion aufgerufen, die dann eine (als nativ deklarierte und mit C++ erstellte) Funktion mehrfach aufruft.
Ich hätte nicht gedacht, dass sich GCJ auch mit Stubs zufrieden gibt.
Aber das ist ersteinmal egal, hauptsache es Funktioniert.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #14 am: 12. September 2012, 14:18 »
Einen CVS-Server hab ich auch mal aufgesetzt.
Ui! Aber keinen öffentlichen, oder? Egal, ich fühl mich trotzdem ins letzte Jahrtausend zurückversetzt. :)

Zitat
Im Moment passiert aber noch nicht viel besonderes, es wird einfach mit C++ eine (statische) Java-Funktion aufgerufen, die dann eine (als nativ deklarierte und mit C++ erstellte) Funktion mehrfach aufruft.
Besonders schön ist das ja alles noch nicht. Bevor du mit Speicherverwaltung anfängst (von der ich möglichst viel auch in Java schreiben würde), wäre es vielleicht nett, erstmal den vorhandenen Code aufzuräumen. Solche Sachen wie...

diff --git a/Init.h b/Init.h
index 02d4dcb..9625f2a 100755
--- a/Init.h
+++ b/Init.h
@@ -1,6 +1,13 @@
+extern "Java" {
+
+typedef __java_char jchar;
+
+
 class Init {
 
 public:
        static void main();
-       static void write_char(wchar_t c);
+       static void write_char(jchar c);
 };
+
+}
diff --git a/main.cpp b/main.cpp
index 7694792..b1d5c69 100644
--- a/main.cpp
+++ b/main.cpp
@@ -23,7 +23,7 @@ extern "C" void init_cpp()
 }
 
 //Native Funktion aus Init.java
-extern "C" void _ZGAN4Init10write_charEJvw(char c)
+extern "Java" void Init::write_char(jchar c)
 {
        screen->putc(c);
 }
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Vogtinator

  • Beiträge: 24
    • Profil anzeigen
Gespeichert
« Antwort #15 am: 12. September 2012, 16:13 »
Ui! Aber keinen öffentlichen, oder? Egal, ich fühl mich trotzdem ins letzte Jahrtausend zurückversetzt. :)
Kein öffentlicher. Ich kann mit git überhaupt nicht und der svn-Support in Eclipse ist einfach nur krank.
Und eclipse mag ich :D
Zitat
Besonders schön ist das ja alles noch nicht. Bevor du mit Speicherverwaltung anfängst (von der ich möglichst viel auch in Java schreiben würde), wäre es vielleicht nett, erstmal den vorhandenen Code aufzuräumen. Solche Sachen wie...

Speicherverwaltung in Java schreiben? Geht nicht. Java-Objekte (keine einfachen Datentypen wie int, char, float, double) werden erst zur Laufzeit erstellt und von irgendwo muss der Speicherplatz ja kommen.
Zumindest nehme ich das mal an, denn wenn ich ein Array erstellen will, brauche ich eine _Jv_alloc(oder so ähnlich)-Funktion.
Was man natürlich machen könnte, ist das Array als native Funktionen zu Java durchzureichen, aber dann kann man auch die ganze Speicherverwaltung in C++ coden. Und Pointer überhaupt könnten ein kleines Problem werden, da wäre eine lowlevel-Klasse für Java wohl angebracht, um wenigstens Ansatzweise mit Pointern arbeiten zu können.

"extern 'Java'" kannte ich noch nicht. Mangelt GCC die Namen dann anders? GCJ hält sich doch an GCC-Regeln?
Was ist denn bitteschön __java_char? Wird intern in der libgcj verwendet, ich weiß aber nicht, wo das herkommt.
Und den Unterschied zw. "_ZGAN4Init10write_charEJvw"(GCJ) und "_ZN4Init10write_charEw"(G++) verstehe ich nicht. besonders das am Ende reingeschmissene "Jv".

Und im Moment ist das ganze eh nur ein Test, bis da was wirklich brauchbares (und sauberes) am Besten komplett ohne Stubs rauskommt, kann das noch ein Weilchen dauern. Am Ende braucht man ja eine minimale GCJ-Runtime im Kernel. (Ohne Exceptions, die sind im Kernel bis zu einem bestimmten Punkt sinnlos).

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #16 am: 12. September 2012, 16:30 »
Kein öffentlicher. Ich kann mit git überhaupt nicht und der svn-Support in Eclipse ist einfach nur krank.
Und eclipse mag ich :D
Dass du mit git nicht klarkommst, solltest du bei Gelegenheit mal ändern. Mit CVS kommt nämlich der Rest der Welt nicht klar. ;)

Eclipse als Editor darfst du meinetwegen benutzen, das ist ja dein eigenes Problem.

Zitat
Speicherverwaltung in Java schreiben? Geht nicht. Java-Objekte (keine einfachen Datentypen wie int, char, float, double) werden erst zur Laufzeit erstellt und von irgendwo muss der Speicherplatz ja kommen.
Zumindest nehme ich das mal an, denn wenn ich ein Array erstellen will, brauche ich eine _Jv_alloc(oder so ähnlich)-Funktion.
Hm, stimmt, das könnte sein. Möglicherweise heißt das, dass der physische MM komplett in C sein muss, oder aber dass man erstmal einen frühen Allokator hat, der z.B. für eine Bitmap benutzt wird, der aber später nicht mehr verwendet wird, wenn man alles initialisiert ist.

Zitat
Und Pointer überhaupt könnten ein kleines Problem werden, da wäre eine lowlevel-Klasse für Java wohl angebracht, um wenigstens Ansatzweise mit Pointern arbeiten zu können.
Das wird kaum zu vermeiden sein, ja. Object könnte bei der Gelegenheit wahrscheinlich auch eine Methode brauchen, die die Adresse zurückgibt.

Zitat
"extern 'Java'" kannte ich noch nicht. Mangelt GCC die Namen dann anders? GCJ hält sich doch an GCC-Regeln?

Und den Unterschied zw. "_ZGAN4Init10write_charEJvw"(GCJ) und "_ZN4Init10write_charEw"(G++) verstehe ich nicht. besonders das am Ende reingeschmissene "Jv".
Ich gehe davon aus, dass extern "Java" aus einem bestimmten Grund besteht und dass man es dann auch verwenden sollte. Was es genau ändert, weiß ich nicht, aber deine unterschiedlich gemangelten Namen sprechen ja auch dafür. Ansonsten, Aufrufkonventionen usw. könnten theoretisch auch unterschiedlich sein und sich darauf zu verlassen, dass es zufällig auch anders tut, halte ich für keine gute Idee.

Zitat
Was ist denn bitteschön __java_char? Wird intern in der libgcj verwendet, ich weiß aber nicht, wo das herkommt.
Compiler-Builtin, würde ich sagen. War nötig wegen:
main.cpp:27:43: Fehler: Java-Methode »void Init::write_char(char)« hat Nicht-Java-Parametertyp »char«
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Vogtinator

  • Beiträge: 24
    • Profil anzeigen
Gespeichert
« Antwort #17 am: 12. September 2012, 21:08 »
Dass du mit git nicht klarkommst, solltest du bei Gelegenheit mal ändern. Mit CVS kommt nämlich der Rest der Welt nicht klar. ;)
Ich komme mit git in der Konsole schon halbwegs gut klar, nur mein Server und eclipse nicht.
Und es ist im Verhältnis zu cvs so lahm, das ist unglaublich.
Während git die Dateien zählt, ist mit cvs schon alles angekommen...

Zitat
Ich gehe davon aus, dass extern "Java" aus einem bestimmten Grund besteht und dass man es dann auch verwenden sollte. Was es genau ändert, weiß ich nicht, aber deine unterschiedlich gemangelten Namen sprechen ja auch dafür. Ansonsten, Aufrufkonventionen usw. könnten theoretisch auch unterschiedlich sein und sich darauf zu verlassen, dass es zufällig auch anders tut, halte ich für keine gute Idee.
Seltsam, ich finde im Internet kaum irgendetwas über 'extern "Java"'..
Aber solange es funktioniert, ist mir das egal  :-D

Zitat
main.cpp:27:43: Fehler: Java-Methode »void Init::write_char(char)« hat Nicht-Java-Parametertyp »char«
:-o
Bei mir kompiliert das ganze sogar ohne Warnungen..
Welche Version benutzt du?
Mein GCC beschwert sich mit __java_char über einen unbekannten Typ..
« Letzte Änderung: 12. September 2012, 21:10 von Vogtinator »

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #18 am: 12. September 2012, 22:33 »
Während git die Dateien zählt, ist mit cvs schon alles angekommen...
Das ist IMO nicht vergleichbare. cvs lädt nur eine Version. Und das jedes mal. Git lädt einmal alle Version und befreit dich damit vom Netzwerk zwang, für commits, logs, checkout von allen Versionen (bis zum letzten pull), bisect, grep usw, und ist damit im Endeffekt viel schneller.
« Letzte Änderung: 12. September 2012, 22:37 von MNemo »
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #19 am: 13. September 2012, 08:53 »
Und es ist im Verhältnis zu cvs so lahm, das ist unglaublich.
Während git die Dateien zählt, ist mit cvs schon alles angekommen...
Öhm, was? CVS braucht für jede einzelne Aktion Netzwerkzugriff, das ist lahm und behindert mich beim Arbeiten. Was den ersten Checkout angeht, hat MNemo über die Datenmenge ja schon was gesagt, aber ehrlichgesagt kommt mir da in den meisten Fällen git trotzdem sogar schneller vor.

Zitat
Seltsam, ich finde im Internet kaum irgendetwas über 'extern "Java"'..
Ich schätze, es ist kein besonders verbreitetes Hobby, Java-Standardbibliotheken zu schreiben... ;)

Zitat
Zitat
main.cpp:27:43: Fehler: Java-Methode »void Init::write_char(char)« hat Nicht-Java-Parametertyp »char«
:-o
Bei mir kompiliert das ganze sogar ohne Warnungen..
Welche Version benutzt du?
Mein GCC beschwert sich mit __java_char über einen unbekannten Typ..
Die Warnung kommt in deinem ursprünglichen Code mit dem manuell gemangelten Namen nicht (weil der Compiler dann halt nicht blickt, was du vorhast), aber wenn du Init::write_char schreiben willst, dann brauchst du auch das extern "Java" und dann kommt die Meldung.

$ gcj --version
gcj (GCC) 4.6.3 20120306 (Red Hat 4.6.3-2)

Die Definition habe ich so in gcj/javaprims.h gefunden. Wenn __java_char bei dir nicht tut, kannst du ja mal schauen, was da bei dir steht.
« Letzte Änderung: 13. September 2012, 08:56 von taljeth »
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

 

Einloggen