Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet von: Creeky am 08. January 2006, 11:50
-
Ich wollte einmal den Kernel aus dem 1. Lowlevel-Magazin ausprobieren.
Leider erhalte ich, wenn ich das OS unter Qemu starte, nur das "Loading..." aus dem Bootloader auf den Bildschirm. Die Ausgaben, die der Kernel übernehmen sollte, kommen nicht und das System bleibt stehen.
Weis jemand was ich falsch gemacht habe?
-
Btw, ich hab mit diesem Tutorial angefangen. Das entspricht ziemlich genau dem in Lowlevel 1, hat aber (bei mir) problemlos funktioniert:
http://www.tutorials.de/tutorials20706.html
-
Danke für die schnellen Antworten.
Hier mein Code:
bootloader.asm:
org 0x7C00 ; Unsere Startadresse
; -----------------------------------------
; Unser Bootloader
; -----------------------------------------
start:
; Erst brauchen wir einen Stack.
cli ; Keine Interrupts!
mov ax, 0x9000 ; Stackadresse
mov ss, ax ; SS = 9000 (unser Stack)
mov sp, 0 ; SP = 0000 (der Stackpointer)
sti ; Interrupts zulassen
; Bootlaufwerk aus DL speichern
mov [bootdrv], dl
;Lade unseren Kernel
call load
;Springe zu diesem Kernel
mov ax, 0x1000 ; Die Adresse des Programms
mov es, ax ; Segmentregister updaten
mov ds, ax
push ax
mov ax, 0
push ax
retf
; ----------------------------------------------
; Funktionen und Variablen
; ----------------------------------------------
bootdrv db 0 ;Das Bootlaufwerk
loadmsg db "Loading...",13,10,0
; Einen String ausgeben:
putstr:
lodsb ; Byte laden
or al,al
jz short putstrd ; 0-Byte? -> Ende!
mov ah,0x0E ; Funktion 0x0E
mov bx,0x0007 ; Attribut-Byte (wird nicht benötigt)
int 0x10 ; schreiben
jmp putstr ; Nächstes Byte
putstrd:
retn
; Lade den Kernel vom Bootlaufwerk
load:
; Diskdrive reset (Interrupt 13h, 0)
push ds ; Sichere DS
mov ax, 0 ; Die gewünschte Funktion (reset)
mov dl, [bootdrv] ; Dieses Laufwerk ist gewünscht
int 13h ; Den Interrupt ausführen
pop ds ; DS wiederherstellen
jc load ; Geht nicht? -> Noch mal!
load1:
mov ax,0x1000 ; ES:BX = 10000
mov es,ax
mov bx, 0
; Sektoren lesen (Interrupt 13h, 2)
mov ah, 2 ; Funktion 2 (Lesen)
mov al, 5 ; Lese 5 Sektoren
mov cx, 2 ; Cylinder=0, Sector=2
mov dx, 0 ; Head=0, Laufwerk=0
int 13h ; ES:BX = Daten vom Laufwerk
jc load1 ; Fehler? Noch mal!
mov si,loadmsg
call putstr ; Meldung ausgeben
retn
times 512-($-$$)-2 db 0 ; Dateilänge: 512 Bytes
dw 0AA55h ; Bootsignatur
kernel.asm:
; ---------------------------------------------------
; Unser Kernel
; ---------------------------------------------------
mov ax, 1000h ; Segmentregister updaten
mov ds, ax
mov es, ax
start:
mov si, msg
call putstr ; Schicke Bootmessage :)
mov si,msg_boot
call putstr ; Noch eine Message :D
call getkey ; Warte auf einen Tastendruck
jmp reboot ; Reboot
; -------------------------------------------------
; Funktionen und Variablen
; -------------------------------------------------
msg db "Welcome to StupidOS 1.0",13,10,0
msg_boot db "Press any key...",10,0
; Stringausgabe
putstr:
lodsb ; Byte laden
or al,al
jz short putstrd ; 0-Byte? -> Ende!
mov ah,0x0E ; Funktion 0x0E
mov bx,0x0007 ; Atrribut-Byte
int 0x10 ; schreiben
jmp putstr ; nächstes Byte
putstrd:
retn
; Warte auf einen Tastendruck
getkey:
mov ah, 0 ; Funktion 0
int 016h ; Ausführen
ret
; Rebooten (HEX Dump).
reboot:
db 0EAh
dw 0000h
dw 0FFFFh
Die zwei Assembler-Datei kompiliere ich unter Linux per:
nasm -f bin -o boot.bin boot.asm
nasm -f bin -o kernel.bin kernel.asm
Und schreibe sie per:
cat boot.bin kernel.bin > OS.img
in ein Qemu-Image. Wenn ich nun über Qemu das OS starte, bleibt es nach "Loading..." stehen und springt somit ja gar nicht in den Kernel. Ich weis selber nicht weiter.
Könnte es vielleicht sein, dass das Problem an Qemu liegt?
Ich habe nämlich auch schnell das Tutorial von DarkThing ausprobiert: auch dort wird in Qemu nur der Bootloader und dann nicht mehr der Kernel geladen.
-
Also der Code wird mindestens bis zum jump zum Kernel ausgeführt. Da das zum Kernel springen kein Problem sein sollte kanns nur noch am Kernel liegen. Vermutlich stimmt irgendwas mit den Segmenten nicht - wie T0ast3r ja schon gesagt hat: Das Problem hatten schon anderen, such am besten einfach mal im Forum.
-
@Creeky: Hi, ich habe den Code ausprobiert. Der funktioniert 100%ig. Also wird es wohl am kopieren der Dateien liegen. Da ich Windows User bin, kenne ich mich mit den Linux Befehlen nicht so gut aus. Aber bei Windows gibt es den Befehl copy. Da muss man aber den Parameter /b (wars glaube ich) angeben, damit er weiß das es binärdateien sind. Vielleicht gibt es so einen Parameter ja auch für Linux.
bitmaster
PS: Ich würde am Anfang die Segmentregister ES und DS auf Null setzten. Das sind sie nämlich nicht immer standardmäßig. z.B. bei VMware nicht.
-
Unter Linux wird nicht zwischen Binär und Textdateien unterschieden.
-
Unter Windows ist /b auch nicht unbedingt nötig. Bei mir geht es reibungslos auch ohne.
Gruss
Noooooooooos
-
Vielen Dank erstmal für die ganzen Antworten.
Leider habe ich das Problem immer noch nicht beseitigt. Habe einmal die Idee von bitmaster ausprobiert, die Segmentregister ES und DS auf Null zu setzen. Ohne Veränderung. Qemu bleibt immer noch bei "Loading..." stehen. Nachdem der Code bei vielen funktioniert: könnte das Problem vll auch an Qemu liegen?
Hab das neulich erst drauf gemacht und hab somit noch keine Ahnung davon.
-
@Creeky: Schick mir mal dein zusammenkopiertes Image an privat@osm-page.de. Dann kann ich dir sagen ob es an dem Image liegt oder nicht.
bitmaster
-
@Creeky: Also die Imagedatei die du mir geschickt hast funktioniert. Ich habe sie mit einem Hexeditor durchgeguckt, alles richtig. Also liegt es wohl an den Emulator den du nutzt.
bitmaster
-
Vielen Dank für die Bemühungen. Werde das Ganze dann man mit nem andren Emulator ausprobieren.
-
Mir ist jetzt noch etwas aufgefallen. Der Bootloader alleine besitzt doch eine Größe von 512Bytes, worauf dann noch mein Kernel folgt.
Wende ich jetzt aber 'qemu-img info test.img' an, so erhalte ich folgende Ausgabe:
*****@ubuntu:~/OS$ qemu-img info test.img
image: test.img
file format: raw
virtual size: 512 (512 bytes)
disk size: 4.0K
Da stimmt doch etwas nicht oder? Das müsste doch größer sein als 512Bytes.[/quote]
-
Mir ist jetzt noch etwas aufgefallen. Der Bootloader alleine besitzt doch eine Größe von 512Bytes, worauf dann noch mein Kernel folgt.
Wende ich jetzt aber 'qemu-img info test.img' an, so erhalte ich folgende Ausgabe:
*****@ubuntu:~/OS$ qemu-img info test.img
image: test.img
file format: raw
virtual size: 512 (512 bytes)
disk size: 4.0K
Da stimmt doch etwas nicht oder? Das müsste doch größer sein als 512Bytes.
Vielleicht teilt der Emulator die automatisch in 512 Byte Blöchken ein. Gib mir deine E-Mail und ich schicke dir die Datei als 1,44 MByte.
bitmaster
-
hab den gleichen fehler
waere mal super wenn jemand sagen koennte wie man dann das ganze zum laufen bekommt, ich suche und suche und finde einfach die antwort (auch hier im forum) nicht!
-
hm wuerd mich ueber ne antwort sehr frueen :wink:
-
Unter Windows ist /b auch nicht unbedingt nötig. Bei mir geht es reibungslos auch ohne.
Gruss
Noooooooooos
sry, wenns grad nicht zum thema passt, aber bei mir hat copy anfangs auch ohne /b funktioniert und dann auf einmal nicht mehr.
ich vermute mal, dass es nur unter speziellen bedingungen auch ohne /b funktioniert und würde deshalb empfehlen, es zu benutzen.
threads hier im forum zum thema copy:
http://www.lowlevel.brainsware.org/forum/viewtopic.php?t=1222
http://www.lowlevel.brainsware.org/forum/viewtopic.php?t=1201
beim eigentlichen problem kann ich leider nicht helfen.
-
Also... Wie bitmaster schon gesagt hat wird das Image in 512byte Blöcke eingeteilt. Das heißt dein Image ist (gerundet) 512byte groß, das heißt das Laden des 2. Sektors schlägt fehl, weil er praktisch nicht vorhanden ist. Du musst also dafür sorgen dass deine kernel.bin auch genau 512byte groß wird. Dazu hängst du ans Ende diesen Code:
times 512-($-$$) db 0
Bei mir funktionierts so! Später wenn dein Kernel größer wird musst du natürlich die 512 anpassen, z.B. auf 8192.