Autor Thema: C-Kernel laden  (Gelesen 7239 mal)

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #20 am: 30. April 2010, 13:01 »
Hallo,


Mein Hauptproblem ist, dass ich keine Ahnung hab, wie man in Turbo C einen FAR-CALL erzeugt.
Gar nicht! Das ist Aufgabe des Compilers. Dazu muss man dem Compiler natürlich sagen was für ein Speicher-Model er benutzen soll. Wenn Du z.B. Large oder Huge auswählst werden die Funktionsaufrufe oft (also für Funktionen die als extern deklariert sind) als FAR-CALL generiert und in den betreffenden Funktionen als letztes ein RETF eingebaut.

Zitat
FAR CALLs haben den Nachteil das sie immer absolute Adressen benutzen (zumindest im RM) und die stehen zur Compile-/Link-Zeit noch nicht fest sondern werden erst beim laden des Executables reloziert. Normalerweise macht dass das OS aber in Deinem Fall müsste es der Assembler-Teil des Boot-Loaders erledigen.
Meinst Du, dass ich eine (als GLOBAL deklarierte) ASM-Funktion für FAR-JUMPS im Bootloader schreiben soll? Wenn sich mein OS in nem anderen Segment befindet, kann ich damit aber trotzdem nix anfangen.
Nein, ich meine das der Linker noch nicht die entgültigen Segmente in die FAR-CALLs einträgt, die weiß er einfach nicht. Das macht normalerweiser der EXE-Loader von DOS, das nennt sich dann relozieren. Mit diesem Vorgang solltest Du Dich mal genauer beschäftigen. Da Du ein eigenes OS entwickeln willst musst Du das selber machen. Alternativ kannst Du Dich natürlich auch auf ein einzelnes Segment mit max. 64 kBytes beschränken.

Zitat
Kennst Du den Unterschied zwischen .COM und .EXE bei DOS?
Den kenn ich. COM hat Daten- und Code im selben Segment, EXE bekommt verschiedene Segmente.
Fast. Der wesentliche Unterschied ist das .EXE relozierbar sind und .COM eben nicht.

Es geht nicht darum, dass mein OS Executables ausführen soll. Die Programme für mein OS schreib ich alle selber.
Diese 2 Sätze wiedersprechen sich. Erst soll Dein OS keine Programme (also die Dinge die nicht direkt fest im Kernel mit drin sind) ausführen können und dann willst Du diese Programme selber schreiben. :?

Mein OS soll nur eine FAT12-Diskette auslesen können. Nicht auf Disk schreiben, keine Dateien öffnen können, nur den Inhalt der Disk anzeigen.
Also quasi ein 'dir'-Befehl ausführen. Das ist wahrlich nicht schwer. Wenn Du dich auf die kurzen 8.3 Dateinamen beschränken kannst dann ist das in 1 oder 2 Tagen in C programmiert. Alle nötigen Infos finden man bei Wikipedia.


MS-DOS ist in Assembler geschrieben
Das stimmt nicht! Selbst von der IO.SYS und MSDOS.SYS ist nur ein kleiner Teil in Assembler geschrieben. Die meisten Programme in MS-DOS in ganz normal in C (oder einer anderen Hoch-Sprache). HIMEM.SYS und EMM386.EXE könnten noch einen erheblichen Assembler-Anteil haben.

Assembler hat den Nachteil der Unportabilität und Unlesbarkeit - es sei denn, die Kommentare machen den Gutteil des Codes aus - und Hochsprachen haben Vorteile.
Da muss ich Dir entschieden wiedersprechen! Außer bei der Portabilität natürlich. Mann kann in Assembler sehr wohl eleganten, lesbaren und wartbaren Code schreiben. Natürlich muss man den etwas besser Kommentieren aber das bedeuten nicht das man mehr Kommentare als Befehle benötigt. Mann muss das als Programmierer nur wollen und dann auch konsequent durchziehen. Ordentlich programmieren können muss man natürlich auch. ;)


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #21 am: 30. April 2010, 14:44 »
Na gut.

Was MS-DOS in Assembler angeht, so habe ich die OEM-Sourcen für MS-DOS 3.30 da, inklusive Referenzanleitung, um eine eigene IO.SYS (die einzige systemabhängige Datei) in Assembler zu basteln, am Beispiel des IBM-PC. In dem Dokument steht auch drin, dass MS-DOS vollständig in Assembler geschrieben ist.

Über die Programme kann ich nichts sagen, auch nicht über spätere Versionen von MS-DOS. Die gab es nur noch für den IBM-PC und kompatible, also auch keine OEM-Quelltexte mehr. Ich vermute trotzdem, dass die das nicht komplett umgeschrieben haben...

Gruß,
Svenska

bscreator

  • Gast
Gespeichert
« Antwort #22 am: 30. April 2010, 15:39 »
OK, wo fang ich an?  :?

Zitat
Gar nicht! Das ist Aufgabe des Compilers. Dazu muss man dem Compiler natürlich sagen was für ein Speicher-Model er benutzen soll. Wenn Du z.B. Large oder Huge auswählst werden die Funktionsaufrufe oft (also für Funktionen die als extern deklariert sind) als FAR-CALL generiert und in den betreffenden Funktionen als letztes ein RETF eingebaut.
Nene, das ist nicht das Problem. Ich möchte nur in C auf entfernte Segmente und absolute Speicherstellen z.B. Videospeicher (0xB8000) zugreifen.
Bei NASM: ca. 3 Zeilen (mov bx,0xB800; mov es,bx; xor bx,bx) -> schon beim Videospeicher
Bei 16-Bit-C: noch keine Ahnung.

Zitat
Nein, ich meine das der Linker noch nicht die entgültigen Segmente in die FAR-CALLs einträgt, die weiß er einfach nicht. Das macht normalerweiser der EXE-Loader von DOS, das nennt sich dann relozieren.
Mein OS soll lediglich die einfachsten Dinge können, d.h. Single Task und ein konstanter Speicherbereich (z.B. 0x30000) für Programme. Da ist nichts mit Paging oder relozieren. Das werd ich erst viel später realisieren.

Zitat
Diese 2 Sätze wiedersprechen sich. Erst soll Dein OS keine Programme (also die Dinge die nicht direkt fest im Kernel mit drin sind) ausführen können und dann willst Du diese Programme selber schreiben.
OK, falsch ausgedrückt. Meine simplen "Programme" schreib ich in Assembler. Mein OS lädt das Programm z.B. von der Floppy in den Arbeitsspeicher (um beim Bsp. zu bleiben, nach 0x30000). Dann wird das Programm durchs OS ausgeführt. Aber EXE und COM oder andere ausführbare Dateiformate muss mein OS nicht ausführen können.

Zitat
Wenn Du dich auf die kurzen 8.3 Dateinamen beschränken kannst dann ist das in 1 oder 2 Tagen in C programmiert.
Aber wenn ich in C keine Chance hab, auf andere Segmente zuzugreifen, dann muss ichs in ASM machen. Nocheinmal: wie?  :?

Zitat
MS-DOS ist in Assembler geschrieben
Ach Leute, darum gehts doch gar nicht. Aber soviel ich weiss, ist auf jeden Fall der Kernel komplett in ASM gehalten.


Grüsse,
bsc
« Letzte Änderung: 30. April 2010, 19:15 von bscreator »

bscreator

  • Gast
Gespeichert
« Antwort #23 am: 01. May 2010, 13:34 »
Wisst ihr, wie man in C auf andere Segmente zugreift ? Gibt es vielleicht eine andere Möglichkeit, als mit einem FAR-JUMP ?

Zitat
Dazu muss man dem Compiler natürlich sagen was für ein Speicher-Model er benutzen soll. Wenn Du z.B. Large oder Huge auswählst werden die Funktionsaufrufe oft (also für Funktionen die als extern deklariert sind) als FAR-CALL generiert und in den betreffenden Funktionen als letztes ein RETF eingebaut.
1. Wenn ich so ein Speichermodell wie HUGE oder LARGE hab, kann ich dann auch FAR-JUMPS zu absoluten Adressen machen?
2. Wenn ich so ein Speichermodell möchte, dann steht das bei Turbo C in der Linker-Anleitung, oder ?
« Letzte Änderung: 02. May 2010, 00:04 von bscreator »

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #24 am: 02. May 2010, 17:17 »
Ich kenne mich mit Turbo C nicht wirklich aus, soviel vorweg. Wenn du als Speichermodell HUGE oder LARGE einträgst, dann erzeugt er dir standardmäßig eine EXE-Datei, die von DOS reloziiert wird und dann aus mehreren Segmenten besteht. Was wo in welchem Segment ist, darum kümmert sich der Compiler auch selbst.

Du möchtest aber die Segmentinhalte einzeln haben, also musst du dem Compiler(!) sagen, dass er far-pointer erzeugen muss. Das steht also in der Anleitung zum Compiler, evtl sogar in der Hilfe. In jedem Fall sind verschiedene Pointergrößen compiler- & systemabhängig.

Alternativ kannst du auch einfach eine "flat binary" erzeugen, die genau ein Segment darstellt und lädst dann halt mehrere dieser Dinger in verschiedene Segmente. Die Symbole musst du dann allerdings selbst auflösen und das reloziieren darfst du auch machen. Das hilft dir aber trotzdem nicht für absolute Adressen. Guck mal in den Beispielprogrammen zum Compiler, da dürfte bestimmt ein Zugriff auf den Video-RAM dabei sein; und wenn es über eine LIB geht, dann musst du halt da reingucken. Wenn sie im Source vorliegt.

Unter Linux kannst du als Compiler immernoch den bcc angucken, der erzeugt auch 16-Bit-Code und wird für den Pseudo-Linux-Port auf 8086 benutzt (ELKS-Projekt).

Ich kann dir sonst nicht weiterhelfen. Tut mir Leid.

Gruß,
Svenska

bscreator

  • Gast
Gespeichert
« Antwort #25 am: 03. May 2010, 09:43 »
Hallo, hab das hier gefunden:

Video output doesn't work
Perhaps you are accessing video memory like this:
        *(unsigned char *)0xB8000 = 'A';
This works only if the base address of the kernel data segment is 0.
Meinen die mit Kernel Data Segment die Offset-Adresse oder die Segment-Adresse des Kernels ?

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #26 am: 03. May 2010, 10:46 »
Damit meinen die die Basisadresse des Kerneldatensegments (im Realmode der Wert der in ds steht mal 16). Wobei es eh fraglich ist wie das obere von einem 16Bit-Compiler kompiliert wird, da es ja kein 16Bit-Offset ist...
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

 

Einloggen