Autor Thema: Bochs meldet: >>PANIC<< Not a bootable disk  (Gelesen 6560 mal)

fnord23

  • Beiträge: 5
    • Profil anzeigen
Gespeichert
« am: 07. December 2005, 16:04 »
Hallo,
ich habe versucht in Anlehnung an das C-Kernel Tutorial hier im Magazin einen Bottloader+Kernel zu programmieren. Linken und Compilen geht auch ohne Fehlermeldungen, Bochs meldet mir jedoch einfach, dass es keine 'bootable disk' wäre. Eine Debug-File will er nicht erzeugen.

Da das OS noch sehr klein ist, poste ich hier einfach mal die Quelltexte und ich hoffe das sich jemand die Mühe macht es zu lesen und den Fehler zu finden.

Der Bottloader besteht aus einer 16-bit und einer 32-bit Variante:
Erst wird der Protectet-Mode gestartet,
es ist der selbe Quellcode wie im 'PM-Grundlagen Turorial

;**************** boot16.asm ********
[BITS 16] ;16 Bit Code erstellen
jmp start ;GDT überspringen

NULL_Desc:
dd 0
dd 0

CODE_Desc:
dw 0xFFFF ;Segmentgröße Byte 0/1
dw 0 ;Segmentbasisadresse Byte 0/1
db 0 ;Segmentbasisadresse Byte 2
db 0x9A ;Zugriffsberechtigungen
db 0xCF ;Zusatz + Segmentgröße Bits 16 - 19
db 0 ;Segmentbasisadresse Byte 3


DATA_Desc:
dw 0xFFFF
dw 0
db 0
db 0x92
db 0xCF
db 0

gdt:
Limit dw 0 ;Größe der GDT (wird später eingetragen)
Base dd 0 ;Adresse der GDT (wird später eingetragen)


start:

cli ;Interrupts ausschalten

mov eax, cs ;EAX auf derzeitiges Codesegment setzen
mov ds, ax ;DS auf Codesegment setzen

shl eax, 4 ;EAX mit 16 multiplizieren (Lineare Adresse
;des Codesegments errechnen)
mov [CODE_Desc+2], ax ;Lineare Adresse des Codesegmentes als
mov [DATA_Desc+2], ax ;Startadresse des Code- und Datendeskriptors
shr eax, 16 ;eintragen
mov [CODE_Desc+4], al
mov [DATA_Desc+4], al

mov eax, cs ;Startadresse der GDT errechnen
shl eax, 4
add eax, NULL_Desc

mov [Base], eax ;Startadresse der GDT eintragen
mov [Limit], WORD gdt - NULL_Desc -1 ;Größe der GDT errechnen und eintragen

lgdt [gdt] ;GDT laden

mov eax, cr0 ;In den Protected Mode schalten,
or eax, 1 ;indem Bit 0 des CR0 Registers auf 1
mov cr0, eax ;gesetzt wird

db 0xea ;FAR-JUMP zum Codesegment
dw PMODE
dw 0x8


[BITS 32] ;32 Bit Code erstellen

PMODE:
mov WORD [CODE_Desc+2], 0 ;Code Segmentstartaddresse auf 0 setzen
mov WORD [DATA_Desc+2], 0 ;Daten Segmentstartadresse auf 0 setzen
mov BYTE [CODE_Desc+4], 0 ;Code Segmentstartaddresse auf 0 setzen
mov BYTE [DATA_Desc+4], 0 ;Daten Segmentstartadresse auf 0 setzen

mov eax, 2 ;Selektor für das Datensegment erstellen
shl eax, 3

mov ds, ax ;Daten- Stack- und Extrasegment mit
mov ss, ax ;Datensegmentdeskriptor laden
mov es, ax
mov eax, 0 ;FS und GS mit Null-Deskriptor laden
mov fs, ax
mov gs, ax
mov esp, 0x1FFFFF ;Stack auf unterhalb der 2 MB Grenze setzen

jmp 0x8:0x10000 + PMODE2 ;Sprung in das "neue" Codesegment

PMODE2:
jmp END ;Zum Ende Springen

times 512-($-$$) db 0; ;Da der Linker sich nicht mit ungeraden
;Dateigrößen verträgt, wird diese Datei auf 512
;gepaddet.

END:


Jetzt kommt der Code, der die Main-Funktion des Kernels aufruft:
Die Unterstriche vor 'main' musste ich weglassen, dazu aber gleich mehr.

;********* boo32.asm ******
[Bits 32]
extern main
global start

start:

call main

STOP:
jmp STOP

;############


So, nun der Kernel, die Minimal-Version:

/* ******* kernel.c ********** */
int main()
{
/*char *Text = "Welcome to Protected Mode";
char *VideoMem = (char*)0xB8000;

while(*Text)
{
*VideoMem = *Text;
*VideoMem++;
*VideoMem = 7;
*VideoMem++;
*Text++;
}*/

return(0);
}


Dann habe ich das ganze mit folgenden Befehlen compiliert:
Ich benutze die neuste DJGPP-Version für C und NASMW 0.98.39

nasmw -f bin -o boot16.bin boot\boot16.asm
nasmw -f aout -o boot32.obj boot\boot32.asm

set PATH=c:\djgpp\bin;%PATH%
set DJGPP=c:\djgpp\djgpp.env

gcc  -fno-leading-underscore -ffreestanding -c -Os -o ckernel.obj kernel\kernel.c
ld -T link.txt -o kernel32.bin
MergeKernel testos.img boot16.bin kernel32.bin


link.txt sieht so aus:

OUTPUT_FORMAT("binary")
INPUT(boot32.obj ckernel.obj)
ENTRY(start)
SECTIONS
{
  .text  0x200 : {
    code = .; _code = .; __code = .;
    *(.text)
    . = ALIGN(1);
  }
  end = .; _end = .; __end = .;
}



So, als ich den Kernel zum ersten mal compiliert habe, erhielt ich die Meldung das '_main' ein unreferenziertes Objekt wäre. Nur wenn ich in der boot32.asm den die underscores weglasse und gcc mit dem Argument -fno-leading-underscore starte gibt es diese Meldung nicht. Ich weiss ehrlich gesagt nicht warum das so ist, vielleicht ist das auch einer der Gründe das Bochs einen Fehler ausgibt. Vielleicht wird die bott32.asm auf 'meine Art' nicht richtig mit kernel.c verbunden???
Ich weiss es nicht.

So, nun starte ich das ganze mit Bochs und bekomme sofort die Fehlermeldung. In der Logfile steht Folgendes:

00000480000i[WGUI ] dimension update x=720 y=400 fontheight=16 fontwidth=9 bpp=8
00000726744e[HD   ] device set to 0 which does not exist
00000727037e[HD   ] device set to 1 which does not exist
00000777733i[BIOS ] Boot from Floppy 0 failed
00000799506p[BIOS ] >>PANIC<< Not a bootable disk
00000799506i[SYS  ] Last time is 1133969226
00000799506i[CPU0 ] real mode
00000799506i[CPU0 ] CS.d_b = 16 bit
00000799506i[CPU0 ] SS.d_b = 16 bit
00000799506i[CPU0 ] | EAX=ffff040a  EBX=0000d738  ECX=000f0001  EDX=00000402
00000799506i[CPU0 ] | ESP=0000ffa6  EBP=0000ffaa  ESI=0000733c  EDI=00007362
00000799506i[CPU0 ] | IOPL=0 NV UP DI PL ZR NA PE NC
00000799506i[CPU0 ] | SEG selector     base    limit G D
00000799506i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00000799506i[CPU0 ] |  CS:f000( 0000| 0|  0) 000f0000 0000ffff 0 0
00000799506i[CPU0 ] |  DS:0000( 0000| 0|  0) 00000000 0000ffff 0 0
00000799506i[CPU0 ] |  SS:0000( 0000| 0|  0) 00000000 0000ffff 0 0
00000799506i[CPU0 ] |  ES:07c0( 0000| 0|  0) 00007c00 0000ffff 0 0
00000799506i[CPU0 ] |  FS:0000( 0000| 0|  0) 00000000 0000ffff 0 0
00000799506i[CPU0 ] |  GS:0000( 0000| 0|  0) 00000000 0000ffff 0 0
00000799506i[CPU0 ] | EIP=00000542 (00000541)
00000799506i[CPU0 ] | CR0=0x00000010 CR1=0 CR2=0x00000000
00000799506i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00000799506i[     ] restoring default signal behavior
00000799506i[CTRL ] quit_sim called with exit code 1


Wer weiss weiter, wo und wieso der Fehler auftritt ?? Und was heisst für Bochs eigentlich 'not bootable', es muss ja was anderes sein als einfach ein 'fatal error'??

So, ist ja ganz schön viel geworden ich hoffe jemand kann mir helfen und vielen Dank schonmal im Voraus :)
 -fnord

maumo

  • Beiträge: 182
    • Profil anzeigen
    • http://maumo.50webs.com/
Gespeichert
« Antwort #1 am: 07. December 2005, 17:51 »
am ende des bootloaders muss die bootsignatur stehen:
0xaa55.
dein "bootloader" läd aber doch gar keinen kernel, er spring in den pmode und spring in leeren speicher.
copy und paste kann ja jeder...  :?

du solltest vl den bootloader aus lowlevel1 nutzen und damit deinen kernel laden.

fnord23

  • Beiträge: 5
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 07. December 2005, 18:05 »
Ich gebe zu das ich keine Ahnug von assembler habe, dewegen will ich ja einen C-Kernel laden :)

als am ende der ersten Datei steht "times 512-($-$$)   db   0;" ich vermute das sorgt dafür das die Datei 512 Bytes groß ist??
Naja die compilierte Datei ist auch genau 512 groß, ich denke da liegt das Problem nicht (?)

Ich dachte eigentlich, dadurch das man die Dateien am Schluss einfach mit Copy (oder MergeKernel) zusammenkopiert, wird der Kernel nach 'END:' eingefügt. Also das der über mehrere Dateien verteilte Quelltext zusammenkommt.

Wenn das nicht so ist, heisst das das Tutorial über den C-Kernel ist einfach nur Quatsch ???

//der Kernel aus LL1 bringt mich aber nicht in den Protected

fnord23

  • Beiträge: 5
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 08. December 2005, 21:10 »
kann jemand bitte den code nochmal durchgucken ob ihm was auffällt, ich weiss sonst nicht was ich machen soll  :(

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 08. December 2005, 21:15 »
Wenn du dich nicht mit dem Realmode beschäftigen willst kannst du GRUB als Bootloader nehmen, der schaltet automatisch in den PM.

Ja, der Kernel wird hinter END eingefügt, jedoch läd das BIOS nur den ersten Sektor (die ersten 512 Byte) des Bootmediums in den Speicher. Den Kernel musst du vom Bootloader selbst laden lassen, er befindet sich dann ja in den nachfolgenden Sektoren. Der Bootloader in Lowlevel1 läd z.B. den 2. Sektor in den Speicher.

Homix

  • Beiträge: 138
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 08. December 2005, 21:58 »
hi,
ich glaube bei "times 512-($-$$) db 0" liegt das problem
es muss so heißen:

times 510-($-$$) db 0            ; bis 510 Bytes auffüllen
dw 0xAA55                        ; 2 Byte als Bootsignatur


mfg,
stefan

fnord23

  • Beiträge: 5
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 10. December 2005, 15:41 »
Zitat
hi,
ich glaube bei "times 512-($-$$) db 0" liegt das problem
es muss so heißen:


Dankeschön, ich liebe dich!

Mit dieser kleinen Änderung gibt es keine Fehlermeldungen mehr, aber leider gibt das OS keine Nachricht "Welcome to Protected Mode" aus, sondern startet in einer Endlosschleife immer wieder neu. Auch wenn ich ich in kernel.c die Zeile
while (1) {};
einfüge ändert sich daran nichts! ich habe das Gefühl das der eigentliche Kernel garnicht startet sondern das schon im Bootloader resetet wird.
Verdammt warum ist das denn so schwer??

Gibt es in Bochs vielleicht ein Line-per-Line debugger?

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 10. December 2005, 15:55 »
Ja, es gibt eine Debug.exe. Dort kannst du jeden Befehle einzeln durch gehen. Dazu gibt es ein gutes Tutorial von WhiteDragon: http://www.chris-soft.de/tutorials/bochs/

Du kannst aber auch einfach zwischen zwei Befehle "jmp $" einfügen. Das bewirkt eine Endloschschleife. Wenn dann nicht resettet wird, dann ist die Endlosschleife vor dem Fehler. Dann nimmst du den nächsten Befehl, bis dann doch resettet wird. Dann weisst du wo der Fehler liegt.

Gruss
Nooooooooos

Homix

  • Beiträge: 138
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 10. December 2005, 19:00 »
hi,
ist das oben noch dein alter Code ?
Weil dort eigentlich nirgendwo dein Kernel in den Arbeitsspeicher geladen wird  :D

mfg,
stefan

fnord23

  • Beiträge: 5
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 11. December 2005, 13:34 »
hmm, wisst ihr was? Ich glaube ich fang nochmal mit dem Kernel an :)
Das heisst ich suche mir ein anderes Tutorial - hab' leider ja keine Ahnung von Assembler.

 

Einloggen