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 script

    ALL:
    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 script

    Ich 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.c

    die 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 jump

    0000: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 ausrichtet

    daher 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_pm

    wobei 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.


Anmelden zum Antworten