Sprung in den Protected Mode klappt nicht
-
Hallo,
ich habe mir einen Bootloader gebastelt der den Kernel lädt, den PMode anmacht
und dann zum Kernel springt.
er Kernel gibt einfach eine Meldung auf dem Bildschrim aus.Sollte er zumindestens, stattdessen startet er immer neu
Bootloader:
extern _main [BITS 16] mov ax, 0219h mov cx, 02h xor dx, dx mov bx, 1000h mov es, bx xor bx, bx int 13h ;rest laden cli lgdt [gdtr] ;gdt laden mov eax,cr0 or al,1 mov cr0,eax jmp codesel:PMode ;spung in den Protected Mode [BITS 32] PMode: mov ax,datasel mov ds,ax mov ss,ax mov esp,0x90000 ;Stack einrichten call _main ;und die Hauptfunktion aufrufen STOP: jmp STOP gdtr: ; Desktiptortabelle dw gdt_end-gdt ; Limit dd gdt ; Basisadresse gdt: dd 0,0 ; Null-Deskriptor codesel equ $-gdt dw 0xFFFF ; Segmentgrösse 0..15 dw 0x0000 ; Segmentadresse 0..15 db 0x00 ; Segmentadresse 16..23 db 0x9A ; Zugriffsberechtigung und Typ db 0xCF ; Zusatzinformationen und Segmentgrösse 16...19 db 0x00 ; Segmentadresse 24..31 datasel equ $-gdt dw 0xFFFF ; Segmentgrösse 0..15 dw 0x0000 ; Segmentadresse 0..15 db 0x00 ; Segmentadresse 16..23 db 0x92 ; Zugriffsberechtigung und Typ db 0xCF ; Zusatzinformationen und Segmentgrösse 16...19 db 0x00 ; Segmentadresse 24..31 gdt_end: TIMES 510-($-$$) db 0x00 dw 0xAA55
Kernel:
int main() { char *Text = "Hallo"; char *ptr = Text; short *VideoMem = (short*)0xB8000; while(*ptr) *VideoMem++ = (*ptr++ << 8) | 7; return 0; }
Assembler ist NASM
compiler der turboC++
und Linker JLoc mit folgendem scriptALL: start.obj kernel.obj DATA: 0F0000 MAIN.after MAIN.i_after *,DGROUP ,,,FONT FINAL: 0F0000 100000-FINAL.length FINAL.start-0F0000 *,kernel.obj MAIN: 0F0000 0F0000 0 *
Als Emulator verwende ich Bochs
Frage: warum startet er immerwieder neu und gibt keinen text aus?
ich vermute dass der PMode fehlschlägt und er wegen einer exeption neustartet
bin am verweifeln und JA ich habe gegoogelt und auch das forum durchsucht
(wo einer ein ähnliches problem hatte, aber die lösung nicht hingeshrieben hat)
-
Nur aus reiner Neugier, wie kommt man auf die Idee, einen eigenen Kernel mit Bootloader zu realisieren? Ist das etwa eine Schulaufgabe?
Und wie kommt man auf die (exotische) Werkzeugauswahl:Assembler ist NASM
compiler der turboC++
und Linker JLoc mit folgendem scriptIch behaupte mal vorsichtig, kein Mensch hier im Forum, kennt den Compiler turboC++, geschweige denn einen Linker JLoc, wenn doch, dann habe ich was verpasst
Wie kompilierst du das Zeug eigentlich? Gibt es ein Makefile, eine Batch-Datei, ein Skript o.ä., wo man sieht, wie, in welcher Reihenfolge, mit welchen Parametern der Assembler, der Compiler und die anderen aufgerufen werden? Vielleicht läuft da schon was falsch...
-
@x86:
Poste schnell mal den Assemblercode von der main() bzw. dem Kernel bevor hier noch mehr Amateurmoderatoren auftauchen.
-
Poste schnell mal den Assemblercode von der main() bzw. dem Kernel...
Ist der Code, den x86 gepostet hat, etwa unvollständig... für mich persönlich sieht er ok aus, abgesehen von der potentiell gefährlichen Schleife in der main (wegen Pointer-Arithmetik und der Abbruchbedingung):
while(*ptr) *VideoMem++ = (*ptr++ << 8) | 7;
...bevor hier noch mehr Amateurmoderatoren auftauchen.
Falls ich hier jemanden durch meine Postings schmerzlich berührt oder beleidigt habe, biete um Entschuldigung, war spät gestern, hab viel erfolglos gedebuggt, und der Rechner war noch an.
Trotzdem denke ich, ein Makefile o.ä. wäre hilfreich, um das Problem zu reproduzieren...
-
Ja, Neustart deutet idR. auf "Triple Fault", also 3 unbehandelte Exceptions hintereinander, hin.
Kannst ja mal den Debugger in Bochs bemuehen und dir die Sache genauer ansehen.abc.w schrieb:
für mich persönlich sieht er ok aus, abgesehen von der potentiell gefährlichen Schleife in der main (wegen Pointer-Arithmetik und der Abbruchbedingung)
Da wuerde ich noch anfuegen, dass dieser Code insbesondere verdaechtig aussieht, weil ES nach dem PM-Uebergang nicht auf den datasel gesetzt wurde.
abc.w schrieb:
Falls ich hier jemanden durch meine Postings schmerzlich berührt oder beleidigt habe...
Ich denke, der einzige ist evtl. dein "hilfsbereiter" Vorposter aus Nuernberg... KA, ob da so viel Text angebracht ist...
(Kommentare dazu nur per eMail!)
-
kompiliert wird das ganze über eine batch also
erst die bootloader.asm
und dann die kernel.cdie exotischen kompiler...
das teil ist schön klein und so muss ich nicht die riesigen gnu teile installieren.
und der linker...
der wurde ich dem (ich weiß nicht mehr welches) tutorial beschrieben.allerdings habe ich mit diesem duo schonmal ein lauffähigen bootloader hinbekommen, es kann also nicht daran liegen.
allerdings kam er nie bis in die main-funktion. ob der PMode geklappt hat konnte ich nicht herrausfinden, aber vllt. ist auch beim aufrufen ein fehler.
und die schleife
was ist den daran gefährlich ? im kernel muss man halt optimiteren und daran kann es einfach nicht liegen (ring-0 != access violation)
-
dafür kann man in boch doch schön in einzelschritten durch den assembler code gehen, und sich die register/GDT/etc. anzeigen lassen.
-
Hallo,
und die schleife
was ist den daran gefährlich ? im kernel muss man halt optimiteren und daran kann es einfach nicht liegen (ring-0 != access violation)Gefährlich nicht, unschön. Wenns hobbymässig ist - ok, beruflich - kostet vielleicht deinen Arbeitsplatz. Vielleicht bin ich auch zu paranoid.
Wie dem auch sei, habe mir aus Neugier Borland TurboC++ heruntergeladen und installiert (wieder etwa 1 GByte auf der Festplatte weg, Faktor 10 verglichen mit MinGW, mal so nebenbei). Auch NASM runtergeladen und entpackt, wie es aussieht, muss man da nichts installieren?
Weiss jetzt nicht, wo finde ich den Linker JLoc? Ist er mit dem TurboC++ dabei?
Ansonsten könnte ich deinen Code kompilieren. Wie gesagt, nur aus reiner Neugier. Bräuchte nur den Inhalt deiner der Batchdatei...
-
Hallo,
also wie du auf 1GB kommst weiß ich nicht. bei mir hat der ganze ordner mit linker kkompiler und allem 7 mb.
JLoc ist nichtmehr erhältlich weil der entwickler den link rausgenommen hat. irgentwie hab ich den aber gefunden.
und die schleife ist hobbymäßig
die .bat ist
cd C:\TC\BIN nasm -f obj start.asm -o start.obj tcc -c kernel.cpp jloc make.txt kernel.bin copy C:\TC\BIN\kernel.bin D:\Programme\Bochs-2.3.7\kernel\kernel.bin pause
ich kann es auch kompillieren doch er stürzt immer beim ausführen ab.
-
sorry das die antwort jetzt so spät kommt
hab jetzt gefunden wo er rausfliegt,
es liegt tatsächlich am far jump0000:7C17 mov eax, cr0 0000:7C1A or al, 1 0000:7C1C mov cr0, eax 0000:0000000000007C1F jmp far 0008:0024
die ersten befehle sehen noch gut aus aber der jump geht doch zu einer völlig falschen addresse(sollte um 7C23 liegen)
ich vermute (keine ahnung nur vermutet) das liegt daran dass der linker
die addressen nicht an 0x7C00 ausrichtetdaher meine frage:
welchen linker und/oder compiler würdet ihr mir dafür empfehlen (muss auf windows laufen)
mfg x86
-
ich mach das folgendermaßen:
jmp codesel:0x7c00+do_pmwobei do_pm ein label an der zielstelle ist und codesel ist 0008
-
Die NASM-Docs mal zu lesen koennte auch helfen. Tipp: "org" Schluesselwort.
-
ich krieg aber das
org 7c00h
nicht assembliert egal ob mit klammern oder ohne, mit h oder 0x
er machts nicht
(praser: instruction expected)und
jmp codesel:0x7c00+do_pm
macht er auch nicht
(expression syntax error)man muss doch wenigstens eins zum laufen bekommen
google hat mir dann das hier beschehrt
db 0xEA dw PMode dw 8
also die opcodes, doch da fehlen noch die +7c00....
-
mittlerweile habe ich herrausgefunden, dass der org-befehl nur im binären format(bin) funktionert.
da ich aber externe funktionen verwende, muss ich das al obj. datei assemblieren
-
Da du zum Erstellen der Binärdatei JLoc verwendest liegt es an diesem die Adressen richig auszurichten. Das unterstützt eigentlich auch jeder anständige Linker, da heißt es wohl Doku studieren.