Aus Assembler C-Funktion aufrufen
-
Sers,
Also: Da das Interesse an Assembler gewachsen ist, wollte ich mal wieder was damit machen´.
Hab jetzt einen Bootloader gemacht, der den Kernel läd.
Um jetzt weiter zu machen, will ich mit C weiterprogrammieren. Wie ich dabei vorgehen sollte, (denk ich zu wissen) weiss ich.
Ich zeig einfach mal ein wenig Code her:
kernel.asm
; ------------------ ; Externe Funktionen ; ------------------ extern _main mov ax, 1000h mov ds, ax mov es, ax ; ------------ ; Kernel Start ; ------------ start: ; Kernel starten call _main ; Reset jmp reset ; -------------------- ; Unterprogramm: reset ; -------------------- reset: db 0Eah dw 0000h dw 0FFFFh
Jetzt die ckernel.c mit der main Funktion
void main(void) { getch(); }
Sodele, jetzt noch die input.c die getch zur Verfügung
stellen soll:int getch(void) { int buf; asm("mov $0x0, %ah"); asm("int $0x16"); asm("mov %al, buf"); return buf; }
So, vorgehen tu ich dann so:
Die *.c Dateien hab ich in einem Projekt von Dev-Cpp.
Projekttyp: Statische Bibliothek.
Wenn ich kompiliere, erhalte ich die Bibliothek "bdOS.a"Weiterhin habe ich die Datei kernel.asm
Das tu ich jetzt ohne Fehlermeldung so zusammenführen:
nasm -f coff -o kernel.out -l bdOS.a kernel.asmNormalerweise sollte nach dem Bootvorgang (klappt wunderbar) der Kernel laden, die main() Funktion aufrufen, eine Taste einlesen und rebooten...
Macht er aber nicht! Er bootet, läd Kernel und dann geht nix mehr, also er hängt irgentwie, aber ohne Auslastung, keine Ahnung.
Wo ist der verdammte Fehler?!?!
Hoffe ihr könnt mir helfen.
ciao
paranoiac
-
Hast du mal gecheckt, ob dien Bootloader den Code wirklich an die gewünschte Stelle packt etc.? Trace doch mal z.B. mitm Bochs-Debugger durch.
-
Mmmh,
Hab leider keine Ahnung von Bochs.
Aber ich kann mal schnell den Bootloader noch hier reinpacken:org 0x7C00 ; BL starten jmp start ; ----- ; Daten ; ----- iBootDrive db 0 szBootMsg00 db "- Bootloader [ bdOSLoader ] gestartet -",10,13,10,13,0 szBootMsg01 db "Stack wird erstellt...",10,13,0 szBootMsg02 db "Kernel wird geladen...",10,13,0 ; -------- ; BL Start ; -------- start: ; Bildschirm löschen call cls ; Textausgabe mov si, szBootMsg00 call _printstring ; Stack aufbauen mov si, szBootMsg01 ; Info call _printstring cli mov ax, 0x9000 ; Adresse des Stack speichern mov ss, ax ; Stackadresse festlegen mov sp, 0 ; Stackpointer auf 0 setzen sti ; Bootlaufwerk sichern mov [iBootDrive], dl ; Kernel laden mov si, szBootMsg02 ; Info call _printstring call LoadKernel ; Shell aufrufen mov ax, 1000h mov es, ax mov ds, ax push ax mov ax, 0 push ax retf ; ------------------- ; Unterprogramm - cls ; ------------------- cls: mov ax, 600h mov cx, 0h mov dx, 174fh mov bh, 0h int 10h ret ; --------------------------- ; Unterprogramm - PrintString ; --------------------------- _printstring: mov ah, 0eh mov bx, 7h _printstringloop: lodsb int 10h cmp al, 0h je _printstringend jmp _printstring _printstringend: ret ; -------------------------- ; Unterprogramm - LoadKernel ; -------------------------- LoadKernel: ; Reset des Bootlaufwerkes push ds mov ax, 0 mov dl, [iBootDrive] int 13h pop ds jc LoadKernel ; Bei Fehler nochmal probieren load: mov ax,0x1000 mov es,ax mov bx, 0 mov ah, 2 mov al, 5 mov cx, 2 mov dx, 0 int 13h jc load retn ; Auf 512 Byte auffüllen times 512-($-$$)-2 db 0 dw 0AA55h
Und nicht wundern....
-
Okay, dein Kernel liegt also ab 0x10000. Weiß der Linker das auch, dass die Adressen da anfangen müssen? Weil wenn der das nicht weiß, nimmt der die fürs Betriebssystem typischen Adressen schätze ich mal.
-
TriPhoenix schrieb:
Okay, dein Kernel liegt also ab 0x10000. Weiß der Linker das auch, dass die Adressen da anfangen müssen? Weil wenn der das nicht weiß, nimmt der die fürs Betriebssystem typischen Adressen schätze ich mal.
Mmmh, hört sich logisch an, aber wie sag ich ihm das jetzt??
Sorry, aber ich hab leider nicht so viel Ahnung!
-
Hab noch mal ne allgeimeine Frage, ich hab ja mein bootloader.asm.
Wie tu ich den jetzt assemblieren?!?!
Bisher mit: nasm -f bin -o bootloader.o bootloader.asm
Hab ich mit dem Kernel genauso gemacht.
Da ich aber jetzt den Kernel aus der Bibliothek in *.c und der kernel.asm zusammensetze, dann ich für das assemblieren des Kernels nicht den Typ "bin" benutzen. auch nicht "coff". Da nehm ich jetzt "aout".Jetzt wird aber beides verschieden assembliert. Macht das was??
Ich weiss es nicht, bitte sagt es mir!Danke!
[wissen]TEsT[/wissen]
Google: ASM
-
Also ich habs jetzt geschafft, dass er zum Kernel springt.
Dabei hab ich die Sache mit C weggelassen zum Testen.Jetzt will ich das wieder mit rein nehmen und gehe so vor, dass ich alle *.c Dateien kompiliere:
gcc -c -o 1.o 1.c
gcc -c -o 2.o 2.c
gcc -c -0 3-o 3.cDann hab ich 3 *.o Dateien: 1.o 2.o 3.o
Jetzt hab ich noch die Datei 4.asm, die ich so kompilier:
nasm -f bin -o 4.o 4.asmDann will ich alle zusammenfügen mit:
gcc -o kernel.bin 1.o 2.o 3.o 4.oAber es kommt dieser Fehler:
4.o: file not recognized: File format not recognizedWas zum Henker mach ich falsch?
-
Per nasm -f bin erzeugst du ein binary,. was keien Linkerinformationen enthält. Deswegen schriet der Linker dann. Nimm lieber elf oder coff, das evrsteht de Linker danna uch.
-
TriPhoenix schrieb:
Per nasm -f bin erzeugst du ein binary,. was keien Linkerinformationen enthält. Deswegen schriet der Linker dann. Nimm lieber elf oder coff, das evrsteht de Linker danna uch.
Dann sagt er aber:
D:\Projekte\bdOS\source>nasm -f coff -o kernel.o kernel.asm
kernel.asm:20: COFF format does not support non-32-bit relocationsD:\Projekte\bdOS\source>nasm -f elf -o kernel.o kernel.asm
kernel.asm:20: ELF format does not support non-32-bit relocations
-
Irgendwie konnte man eine .obj datei daraus erstellen ich glaub mit -f obj
die sollte er schon erkennenMFG
LordHoto
PS: Ist etwas umst]ndlich hier mit links zu schreiben
-
Also ich hab hier meine 2 Dateien, bootloader.asm und kernel.asm
bootloader.asmorg 0x7C00 ; BL starten jmp start ; ----- ; Daten ; ----- iBootDrive db 0 ; -------- ; BL Start ; -------- start: ; Stack aufbauen cli mov ax, 0x9000 ; Adresse des Stack speichern mov ss, ax ; Stackadresse festlegen mov sp, 0 ; Stackpointer auf 0 setzen sti ; Bootlaufwerk sichern mov [iBootDrive], dl ; Kernel laden call LoadKernel ; Shell aufrufen mov ax, 1000h mov es, ax mov ds, ax push ax mov ax, 0 push ax retf ; -------------------------- ; Unterprogramm - LoadKernel ; -------------------------- LoadKernel: ; Reset des Bootlaufwerkes push ds mov ax, 0 mov dl, [iBootDrive] int 13h pop ds jc LoadKernel ; Bei Fehler nochmal probieren load: mov ax,0x1000 mov es,ax mov bx, 0 mov ah, 2 mov al, 5 mov cx, 2 mov dx, 0 int 13h jc load retn ; Auf 512 Byte auffüllen times 512-($-$$)-2 db 0 dw 0AA55h
kernel.asm
mov ax, 1000h mov ds, ax mov es, ax jmp start szInfo db 'Kernel geladen', 0 ; ------------ ; Kernel Start ; ------------ start: mov si, szInfo call _printstring hang: jmp hang ; Reset jmp reset ; -------------------- ; Unterprogramm: reset ; -------------------- reset: db 0Eah dw 0000h dw 0FFFFh ; --------------------------- ; Unterprogramm - PrintString ; --------------------------- _printstring: mov ah, 0eh mov bx, 7h _printstringloop: lodsb int 10h cmp al, 0h je _printstringend jmp _printstring _printstringend: ret
Wird so assembliert:
D:\Projekte\bdOS\source>nasm -f bin -o bootloader.bin bootloader.asm D:\Projekte\bdOS\source>nasm -f bin -o kernel.bin kernel.asm
Dann och zu einem Image gemacht und mit RawWrite auf Diskette geschrieben.
Funktioniert einwandfrei, d.h. "Kernel geladen" wird angezeigt, dann häng der PC in der Schleife...Jetzt würd ich aber gerne aus meiner kernel.asm eine C-Funktion aufrufen, die da wäre:
void kmain(void) { for(;;){} }
Sprich, die C-Funktion ersetzt mein
hang: jmp hang
Wie mach ich das jetzt. Probier schon das ganze Wochenende und bin anscheinend zu dumm dazu.
Könnte mir nicht irgentjemand erklären mit welchen Programmen ich was wie assemblier kompilier und linke, damit das nachher funktioniert???
Wäre echt cool
Danke!
-
Mmmmh, kann mir denn wirklich niemand helfen?!
Ich möchte ganz einfach zu meiner C-Funktion springen und dort Code ausführen! Es kann doch nicht sein, dass es niemand weiss!PS: Alles im RealMode...
BITTE HELFT MIR!!
Danke!
-
Tjo, mit dem GCC kenne ich mich nicht aus.
So beim einfachen Rumprobieren habe ich es zumindest nicht hinbekommen, das Teil einfache 16Bit binaries ausspucken zu lassen... Und das wird's wohl sein, was du erstmal brauchst, um dein C-Kernel vernuenftig starten zu koennen...
-
Nobuo T schrieb:
Tjo, mit dem GCC kenne ich mich nicht aus.
So beim einfachen Rumprobieren habe ich es zumindest nicht hinbekommen, das Teil einfache 16Bit binaries ausspucken zu lassen... Und das wird's wohl sein, was du erstmal brauchst, um dein C-Kernel vernuenftig starten zu koennen...Ahh, könnte es dann mit dem tc++ gehen??
-
Vielleicht, wenn er DOS .com-Dateien erstellen kann. Die sind zunaechst 16Bit und haben einen festgelegten Code-entry-point (Offset 100h) und keinen Header oder sonstiges stoerendes Zeug. Nachteil ist, dass die Dinger nicht groesser als 64kB sein koennen.
Hoffe das hilft dir irgendwie weiter.
(Wundert mich eigentlich auch ein wenig, dass hier keiner weiter etwas zu schreibt... Ich habe jedenfalls keine Zeit/Lust, mir vor dem Wochenende irgendwelche C-Compiler auszugraben und daran rumzuspielen o.ae.)
-
mmmh, okay, danke erstmal, meld mich dann halt nochmal
ciao