..
-
Hi.
Sry, aber sowas zu analysieren und zu testen dauert immer ne Weile...
Bei solchen Sachen musst Du dich eben meist etwas gedulden (vor allem in der Woche)
Wie dem auch sei, IMHO liegt der Fehler bei 2 simplen Zeichen im Code.
Folgende Zeiledw gdt_end-gdt-1 ; Length of the gdt
sollte geaendert werden zu
dw gdt_end-gdt ; Length of the gdt
=>einfach die "-1" weg, dann laeufts (zumindest auf meinem Testrechner...)
Wie schliesslich im Protected Mode Tut nachzulesen ist, muss das Limit im GDTR die Laenge der GDT in Byte beinhalten und das kann nur eine durch 8 teilbare Zahl sein. (in diesem Fall 20h statt 1Fh)hth.
-
Danke für den Tipp! Ich habe es sofort geändert und auf 2 Rechnern getestet, leider bei mir ohne Erfolg (Pentium 3 und Pentium 4). Ich sehe kein weißes A, der Rechner bootet, ohne Anzeige des weißen A (Warum bootet er eigentlich? Welcher Befehl ist dafür verantwortlich?).
Folgende Idee: Mit welchem NASM muss man hier assemblieren? Ich habe bisher nasm.exe (Version 0.98) und nasmw.exe (Version 0.98) getestet, alles von MS Windows aus. Beides geht. Wie gesagt, leider ohne echten Erfolg. Kann es an einer falschen NASM-Version liegen?
Befehl "nasm.exe abc.asm" führt zu dem File abc.
Zum Schreiben des Files abc auf Diskette verwende ich von MS Windows aus wdisk.exe (Vers. 0.3). Das dürfte aber keine Probleme machen, da der Boot-Vorgang astrein abläuft.
Ich hoffe, dass der Knackpunkt noch zu finden ist.
-
Original erstellt von Erhard Henkes:
Danke für den Tipp! Ich habe es sofort geändert und auf 2 Rechnern getestet, leider bei mir ohne Erfolg (Pentium 3 und Pentium 4). Ich sehe kein weißes A, der Rechner bootet, ohne Anzeige des weißen A (Warum bootet er eigentlich? Welcher Befehl ist dafür verantwortlich?).Rebooten tut der Rechner sobald beim Behandeln einer Ausnahme, die beim behandeln einer Ausnahme passiert, eine Ausnahme auftritt, die Situation also hoffnungslos ist
Das nennt man einen Triple-Fault. Lass das Ding mal in Bochs laufen und schau danach in die bochsout.txt, in CS/EIP solltest du die fatale Instruktion abgucken können (also ihre adresse).
**
Folgende Idee: Mit welchem NASM muss man hier assemblieren? Ich habe bisher nasm.exe (Version 0.98) und nasmw.exe (Version 0.98) getestet, alles von MS Windows aus. Beides geht. Wie gesagt, leider ohne echten Erfolg. Kann es an einer falschen NASM-Version liegen?**Kann ich mir absolut nicht vorstellen, assemblercode ist ja ziemlich eindeutig.
-
ich habe den Author angeschrieben. Er hat nun geantwortet, und nannte auch den Ausdruck "triple faulting".
-
hm... eigenartig.
Ich habe das ganze compiliert mit NASM16.exe auch Version 0.98
(NASM16.exe -fbin -o...\abc.bin ...\abc.asm)
und habe das ganze mit meiner eigenen Software auf Diskette kopiert (alles von Win98 aus)
Der Testrechner war ein PentiumMMX 233MHz
-
Ist es eigentlich schwer ein "triple faulting" zu erreichen?
-
@Nobuo T:
Konntest Du den Effekt nachvollziehen?
Dann könnte Hilfe heran nahen.
-
Zur Sache mit Tripple Fault:
noe, is leicht
schreib in die Behandlungsroutine fuer die Exception 0D einfach sowas nettes, wie zB.
mov ax,0000h
mov ds,ax
mov ax,[0000h]und fuehre selbiges nochmal in deinem normalen Programmcode aus, um "den Stein" gewissermassen ins Rollen zu bringen - das sollte schon reichen
[edit]ach ja, dabei darf der Doublefault handler (Exception
nicht vergessen werden... das muss auch noch entsprechend manipuliert werden
[/edit]
Zur Sache mit Nachvollziehung des Fehlers:
Einen solchen Effekt, den ich bislang nicht reproduzieren kann (mangels Pentium 3 oder 4) kann ich auch nicht ganz nachvollziehen. Ich werde aber gleich nochmal versuchen, den Code auf einem AMD Thunderbird laufen zu lassen.[ Dieser Beitrag wurde am 08.05.2003 um 20:09 Uhr von Nobuo T editiert. ]
-
@Nobuo T:
Auf einem AMD 1400+ habe ich es jetzt auch noch getestet. Gleicher Effekt.
Hattest Du nicht einen positven Fall? Was hast Du da genau gemacht?
Ich wollte den Code zum Einstieg in das OS-coden verwenden. Liege ich da überhaupt richtig?
-
Ich habe es jetzt auf besagtem AMD TB 1.0GHz getestet und es lief!
Hier erstmal der Code, den ich verwendet habe zum kopieren (Fehlerquelle nr1: )
org 0x07c00 ; Start address 0000:7c00 jmp short begin_boot ; Jump to start of boot routine & skip other data bootmesg db "Our OS boot sector loading ......" pm_mesg db "Switching to protected mode ...." dw 512 ; Bytes per sector db 1 ; Sectors per cluster dw 1 ; Number of reserved sectors db 2 ; Number of FATs dw 0x00e0 ; Number of dirs in root dw 0x0b40 ; Number of sectors in volume db 0x0f0 ; Media descriptor dw 9 ; Number of sectors per FAT dw 18 ; Number of sectors per track dw 2 ; Number of read/write sectors dw 0 ; Number of hidden sectors print_mesg : mov ah,0x13 ; Fn 13h of int 10h writes a whole string on screen mov al,0x00 ; bit 0 determines cursor pos,0->point to start after ; function call,1->point to last position written mov bx,0x0007 ; bh -> screen page ie 0,bl = 07 ie white on black mov cx,0x20 ; Length of string here 32 mov dx,0x0000 ; dh->start cursor row,dl->start cursor column int 0x10 ; call bios interrupt 10h ret ; Return to calling routine get_key : mov ah,0x00 int 0x16 ; Get_key Fn 00h of 16h,read next character ret clrscr : mov ax,0x0600 ; Fn 06 of int 10h,scroll window up,if al = 0 clrscr mov cx,0x0000 ; Clear window from 0,0 mov dx,0x174f ; to 23,79 mov bh,0 ; fill with colour 0 int 0x10 ; call bios interrupt 10h ret begin_boot : call clrscr ; Clear the screen first mov bp,bootmesg ; Set the string ptr to message location call print_mesg ; Print the message call get_key ; Wait till a key is pressed bits 16 call clrscr ; Clear the screen mov ax,0xb800 ; Load gs to point to video memory mov gs,ax ; We intend to display a brown A in real mode mov word [gs:0],0x641 ; display call get_key ; Get_key again,ie display till key is pressed mov bp,pm_mesg ; Set string pointer call print_mesg ; Call print_mesg subroutine call get_key ; Wait till key is pressed call clrscr ; Clear the screen cli ; Clear or disable interrupts lgdt[gdtr] ; Load GDT mov eax,cr0 ; The lsb of cr0 is the protected mode bit or al,0x01 ; Set protected mode bit mov cr0,eax ; Mov modified word to the control register jmp codesel:go_pm bits 32 go_pm : mov ax,datasel mov ds,ax ; Initialise ds & es to data segment mov es,ax mov ax,videosel ; Initialise gs to video memory mov gs,ax mov word [gs:0],0x741 ; Display white A in protected mode spin : jmp spin ; Loop bits 16 gdtr : dw gdt_end-gdt ; Length of the gdt dd gdt ; physical address of gdt gdt nullsel equ $-gdt ; $->current location,so nullsel = 0h gdt0 ; Null descriptor,as per convention gdt0 is 0 dd 0 ; Each gdt entry is 8 bytes, so at 08h it is CS dd 0 ; In all the segment descriptor is 64 bits codesel equ $-gdt ; This is 8h,ie 2nd descriptor in gdt code_gdt ; Code descriptor 4Gb flat segment at 0000:0000h dw 0x0ffff ; Limit 4Gb bits 0-15 of segment descriptor dw 0x0000 ; Base 0h bits 16-31 of segment descriptor (sd) db 0x00 ; Base addr of seg 16-23 of 32bit addr,32-39 of sd db 0x09a ; P,DPL(2),S,TYPE(3),A->Present bit 1,Descriptor ; privilege level 0-3,Segment descriptor 1 ie code ; or data seg descriptor,Type of seg,Accessed bit db 0x0cf ; Upper 4 bits G,D,0,AVL ->1 segment len is page ; granular, 1 default operation size is 32bit seg ; AVL : Available field for user or OS ; Lower nibble bits 16-19 of segment limit db 0x00 ; Base addr of seg 24-31 of 32bit addr,56-63 of sd datasel equ $-gdt ; ie 10h, beginning of next 8 bytes for data sd data_gdt ; Data descriptor 4Gb flat seg at 0000:0000h dw 0x0ffff ; Limit 4Gb dw 0x0000 ; Base 0000:0000h db 0x00 ; Descriptor format same as above db 0x092 db 0x0cf db 0x00 videosel equ $-gdt ; ie 18h,next gdt entry dw 3999 ; Limit 80*25*2-1 dw 0x8000 ; Base 0xb8000 db 0x0b db 0x92 ; present,ring 0,data,expand-up,writable db 0x00 ; byte granularity 16 bit db 0x00 gdt_end times 510-($-$$) db 0 ; Fill bytes from present loc to 510 with 0s dw 0x0aa55 ; Write aa55 in bytes 511,512 to indicate that ; it is a bootable sector.
Dann koenntest Du es auch nochmal mit dem selben Compilerprogramm und gleichen Optionen versuchen...
Als letzte Fehlerquelle bliebe ja sonst nur das Programm, dass Du verwendest, um auf die Diskette zu schreiben.
Original erstellt von Erhard Henkes:**
Ich wollte den Code zum Einstieg in das OS-coden verwenden. Liege ich da überhaupt richtig?
**Als Uebung um zu sehen, wie das mit dem PM grundsaetzlich so laeuft ist ein solcher Bootstrap sicher nicht schlecht, fuer die praktische OS-Entwicklung IMHO aber eher ungeeignet.
KA, ich kann mich einfach net so richtig mit dem Gedanken anfreunden, dass es sinnvoll sein soll, schon vor dem Laden eines groesseren Kernels (vielleicht sogar ueber BIOS-Interrupts, wie es der Microsoft-Bootstrap auch tut) in den PM zu wechseln.
-
@Nobuo T:
Es haut nicht hin.
An WriteDisk (wdisk) kann es nicht liegen, da ich unter Linux mit dd if=abc of=/dev/fd0 das gleiche Ergebnis erhalte.
Also sollte es am Produkt abc liegen. Ich habe den Code aus dem Forum kopiert (sogar über den klassischen edit gezogen, damit aus notepad keine Probleme entstehen, war es auch nicht), habe es mit nasm.exe abc.asm und mit nasm.exe -fbin -o abc abc.asm probiert. Also verwende ich vielleicht doch den falschen Assembler. Ich habe ihn von folgender Adreese kopiert: http://sourceforge.net/project/showfiles.php?group_id=6208
hierbei den 09836.zip, ich probiere jetzt den 09835.zip
-
Kannst Du mir die letzte binarie nicht einfach mal per EMail schicken? (Addy steht im Profil)
Ich glaube so laesst sich das mit der compiler-kompatibilitaet schneller ueberpruefen.
-
Das hilft auch nicht (NASM16 98.35).
Jetzt bin ich mit meinem Latein am Ende.@NobuoT: Du hattest das Problem doch auch nachgestellt, oder etwa nicht?
Ist das irgendwie rechnerabhängig? Würde das gerne kapieren.
-
mail ist bei Dir.
-
Echt nur verwirrend...
Ich hab das bin aus der mail jetzt auf 2 anderen Rechnern getestet (AMD Duron) -- ist normal bis zum Ende durchgelaufen.
Zur sicherheit habe ich das ganze dann nochmal durch die Bochs gejagt - hat auch "normal" funktioniert... (mal abgesehen davon, dass statt Text irgendwie nur eine Reihe @-Zeichen ausgegeben wurde- das tut aber eigentlich nichts zur Sache)
Kurz: Keine Ahnung, wie Du den Code dazu bringst, sich von dir immer mit einem Tripple fault zu verabschieden.
Ich kann dieses Phaenomen beim besten Willen nicht rekonstruieren.
-
Nachtrag:
Ich bin jetzt nochmal an einen AMD XP2000+ gekommen, welcher die gleichen Symptome zeigte: Neustart beim Eintritt in PM. Na mal schaun...
-
Jetzt bleibt mir aber langsam der Verstand stehen ...
Ich hoffe, dass Du die Ursache findest.
Danke erstmal für die tolle Unterstützung.
-
Jo, man kann aber auch echt manchmal auf dem Schlauch stehen
Wer haetts gedacht: Die loesung ist mal wieder ziemlich banal. :oAnscheinend setzen diese Neueren BIOS die Segmentregister anders.
Da diese Register im Bootloader nicht initialisiert werden...mov ax,0x0000 mov ds,ax mov es,ax cli mov ss,ax mov sp,0xfffe sti
Das sollte Abhilfe schaffen.
-
Danke, an welcher Stelle genau einzubauen?
-
Danke für den Tipp! Es klappt hervorragend.
call clrscr ; Clear the screen mov ax,0xb800 ; Load gs to point to video memory mov gs,ax ; We intend to display a brown A in real mode mov word [gs:0],0x641 ; display call get_key ; Get_key again,ie display till key is pressed mov bp,pm_mesg ; Set string pointer call print_mesg ; Call print_mesg subroutine call get_key ; Wait till key is pressed call clrscr ; Clear the screen ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; mov ax,0x0000 ; Einschub Anfang mov ds,ax mov es,ax cli mov ss,ax mov sp,0xfffe sti ; Einschub Ende ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; cli ; Clear or disable interrupts lgdt[gdtr] ; Load GDT mov eax,cr0 ; The lsb of cr0 is the protected mode bit or al,0x01 ; Set protected mode bit mov cr0,eax ; Mov modified word to the control register jmp codesel:go_pm