Autor Thema: Problem mit Datenzugriff im Kernel  (Gelesen 8153 mal)

TPSeverino

  • Beiträge: 33
    • Profil anzeigen
Gespeichert
« am: 26. May 2004, 20:42 »
Hi,
Ich programmiere seit einiger Zeit mit NASM und habe, nachdem ich das Low-Level-Tutorial gelesen habe, auch ein kleines OS geschrieben. Mein Bootloader funktioniert und lädt den Kernel von Diskette in den Speicher. Nach dem Sprung zum Kernel wird der Code des Kernels auch ausgeführt (der Computer wartet wie vorgesehen auf einen Tastendruck und rebootet anschließend). Das einzige Problem ist, dass die Variablen die ich ausgeben will, nicht auf dem Bildschirm erscheinen! (Im Bootloader hats funktioniert). Nun wurde in allen Tutorial, die ich gefunden habe, ds auf die Segmentadresse gesetzt, an die der Kernel geladen wurde. Also wenn der Kernel bei 1000h:0000h steht, wurde im Kernel immer ds auf 1000h gesetzt. Das führt aber bei mir zu keiner Ausgabe.
Ich habe jetzt schon unzählige Tutorials gelesen und alles mögliche probiert aber meine Strings werden nicht ausgegeben. Was muss ich tun?? Helft mir!! *fleh*

joachim_neu

  • Beiträge: 1 228
    • Profil anzeigen
    • http://www.joachim-neu.de
Gespeichert
« Antwort #1 am: 26. May 2004, 20:50 »
du darfst keine variablen aus dem bootloader benutzen, weil bei denen die adressen ja nicht stimmen und dann kommt nichts. alle strings, die du im kernel ausgeben willst, müssen auch da erstellt werden....
http://www.joachim-neu.de | http://www.orbitalpirates.de | http://www.middleageworld.de

System: 256 RAM, GeForce 2 MX 400, AMD Athlon XP 1600+, Windows XP, 1x Diskette, 1x DVD-ROM, 1x CD-R(W) Brenner,...

TPSeverino

  • Beiträge: 33
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 26. May 2004, 20:51 »
Aber die Variablen stehen doch im Kernel! das ist ja das ganze Problem

joachim_neu

  • Beiträge: 1 228
    • Profil anzeigen
    • http://www.joachim-neu.de
Gespeichert
« Antwort #3 am: 26. May 2004, 20:58 »
dann nimm doch einfach mal den code vom Mag und schau, ob es da geht, wenn nicht, weiß ich es auch nicht. wenns geht, schau doch mal alle register usw. durch, vielleicht wird ja die stringadresse falsch angegeben...
http://www.joachim-neu.de | http://www.orbitalpirates.de | http://www.middleageworld.de

System: 256 RAM, GeForce 2 MX 400, AMD Athlon XP 1600+, Windows XP, 1x Diskette, 1x DVD-ROM, 1x CD-R(W) Brenner,...

TPSeverino

  • Beiträge: 33
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 26. May 2004, 21:05 »
ich hab den code 1:1 kopiert und es geht nicht!! (hab ein p4 da sollte es doch gehen oder???)

TeeJay

  • Beiträge: 630
    • Profil anzeigen
    • http://www.jay-code.de
Gespeichert
« Antwort #5 am: 26. May 2004, 22:19 »
Poste doch einfach mal deinen Code :)
----------------------
Redakteur bei LowLevel

TPSeverino

  • Beiträge: 33
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 27. May 2004, 07:27 »
Hier ist der Code meines Kernels der sich an 1000h:0000h befindet:

mov ax, 1000h
mov ds, ax
mov es, ax

mov si, welcomemsg
call _putstr
mov si, insertmsg
call _putstr
call _waitforkey
jmp _reboot

; Bildschirm löschen
_clrscr:
mov ah, 0fh
int 10h
mov ah, 00h
int 10h
ret

; auf Tastendruck warten
_waitforkey:

mov ah, 00h        
int 16h              
ret              

; String ausgeben
_putstr:

lodsb            
or al,al
jz _putstr_ende        
mov ah, 0Eh    
mov bh, 00h        
mov bl, 07h        
int 10h            
jmp _putstr
_putstr_ende:
ret            

_reboot:
db 0EAh
dw 0000h
dw 0FFFFh

welcomemsg db "Welcome to ...",13,10,0
insertmsg db "Press any key.",13,10,0

TPSeverino

  • Beiträge: 33
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 29. May 2004, 16:20 »
Kann vielleicht iregndjemand den Code bei sich testen und mir saegn obs funktioniert??? irgendwo muss doch ein fehler sein!!
danke

traexx

  • Beiträge: 6
    • Profil anzeigen
    • http://home.dp-world.net
Gespeichert
« Antwort #8 am: 07. June 2004, 08:46 »
hast du org 0x0 gesetzt? Damit meine ich folgendes:

der Kernelcode liegt in einer Extra-Datei und hat [org 0x00] am Dateianfang stehen, wurde kompiliert und nach den 512 Bytes de bootloaders auf die Diskette geschrieben.

TPSeverino

  • Beiträge: 33
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 07. June 2004, 19:40 »
also das org 0x00 hat die sache leider auch nicht gelöst ... kann bitte mal kemand meinen code testen und sagen ob er bei ihm funktioniert!? ich bin schon leicht am verzweifeln

traexx

  • Beiträge: 6
    • Profil anzeigen
    • http://home.dp-world.net
Gespeichert
« Antwort #10 am: 08. June 2004, 19:17 »
stell mal bitte alles rein; *zu faul zum suchen des Quelltextes ist* dann test ichs nachher aus ^.^

TPSeverino

  • Beiträge: 33
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 09. June 2004, 23:45 »
ok, also hier alles in allem (ist alles noch sehr primitiv)
mein Bootloader:

org 7C00h         ; Startadresse

_start:

mov ax, 0h
mov es, ax        ; Segmenregister setzen
mov ds, ax
            ; Stack einrichten
cli                 ; Interrputs verbieten
mov ax, 0x9000      ; Stackadresse
mov ss, ax          ; Stacksegment setzen
mov sp, 0           ; Stackpointer auf 0
sti                 ; Interrupts wieder zulassen

mov si, loadmsg        ; Offset von loadmsg nach si
call _putstr        ; String ausgeben
call _waitforkey    ; auf Tastendruck warten
jmp _reboot        ; Rebooten

;************************************************
;           FUNKTIONEN / VARIABLEN
;************************************************
; Einen String ausgeben:
_putstr:

lodsb            ; Byte von DS:SI nach al laden
or al,al
jz _putstr_ende        ; Wenn 0-Byte springe zum Ende
mov ah, 0Eh        ; Funktionsnummer nach al
mov bh, 00h        ; Bildschirmseite nach bh
mov bl, 07h        ; Attribut nach bl
int 10h            ; Interrupt 10h aufrufen
jmp _putstr
_putstr_ende:
ret            ; Return

; auf Tastendruck warten
_waitforkey:

mov ah, 00h        ; Funktionsnummer nach al
int 16h            ; Interrupt 16h aufrufen
ret            ; Return

; Rebooten (HEX Dump).
_reboot:
db 0EAh
dw 0000h
dw 0FFFFh

loadmsg db "Loading Test-Kernel 0.7 ...",13,10,0

times 512-($-$$)-2 db 0   ; Dateigröße von 512 Bytes erzeugen
dw 0AA55h                 ; Bootsignatur

ok so viel dazu, den kernel hatte ich ja schon mal gepostet (einfach weiter oben gucken ...)
ich hoffe, dass du mir helfen kannst! also thx!!
falls es dir immer noch zu anstrengend ist, schicke ich dir die dateien auch per e-mail :-) thx...

gurru

  • Beiträge: 42
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 10. June 2004, 22:53 »
hi

ich hab mal drüber geguckt. was mir aufgefallen ist:

Zum Bootloader:
ist das der komplette Bootloader, mit dem du den Kernel laden willst?
Wenn ja, im Bootloader wird niergendwo ein kernel geladen noch wird zu diesem gesprungen - was deinen oben beschriebenen Programmablauf zum Ergebnis hätte

mfg gurru

traexx

  • Beiträge: 6
    • Profil anzeigen
    • http://home.dp-world.net
Gespeichert
« Antwort #13 am: 11. June 2004, 19:47 »
Zitat
gurru postete
hi

ich hab mal drüber geguckt. was mir aufgefallen ist:

Zum Bootloader:
ist das der komplette Bootloader, mit dem du den Kernel laden willst?
Wenn ja, im Bootloader wird niergendwo ein kernel geladen noch wird zu diesem gesprungen - was deinen oben beschriebenen Programmablauf zum Ergebnis hätte

mfg gurru
mir scheints auch so. Du musst den Kernel manuell mit Interrupt 0x13 vom bootloader aus in den Speicher laden. Oder hast du ne alte Version deines bootloaders genommen?

TPSeverino

  • Beiträge: 33
    • Profil anzeigen
Gespeichert
« Antwort #14 am: 12. June 2004, 10:02 »
oh ja verzeiht ... mein fehler!!!
mein bootloader (jetzt wirklich) :-)

;*************************************************
;                  BOOTLOADER
;*************************************************

org 0h            ; Startadresse

jmp 07c0h:_start    ; Springe zu _start im Segment 07c0h

;************************************************
;                  VARIABLEN
;************************************************

loadmsg  db    "Loading "TEST-Kernel 0.7...  ",0
resetmsg db    "Reseting bootdrive...      ",0
readymsg db    "ready",13,10,0
keymsg   db    "Press any key to start TEST-OS 0.7.",13,10,0

;************************************************
;                    MAIN
;************************************************

_start:
    mov ax, cs        ; Segmenregister setzen
    mov ds, ax
    mov es, ax
                ; Stack einrichten
    cli                 ; Interrputs verbieten
    mov ax, 9000h          ; Stackadresse
    mov ss, ax          ; Stacksegment setzen
    mov sp, 0           ; Stackpointer auf 0
    sti                 ; Interrupts wieder zulassen

    call _clrscr
    call _reset        ; Bootlaufwerk resten / Kernel laden
    mov si, keymsg        ; String ausgeben
    call _putstr

    mov ax, 1000h
    push ax
    mov ax, 0h
    push ax
    retf

;    jmp 1000h:0000h        ; Springe zum Kernel

;************************************************
;                  FUNKTIONEN
;************************************************

; Einen String ausgeben:
_putstr:
    lodsb            ; Byte von ds:si nach al laden
    or al,al        ; Wenn al= 0 dann wird ZF gesetzt
    jz _putstr_ende        ; Wenn 0-Byte springe zum Ende
    mov ah, 0Eh        ; Funktionsnummer nach al
    mov bh, 00h        ; Bildschirmseite nach bh
    mov bl, 07h        ; Attribut nach bl
    int 10h            ; Interrupt 10h aufrufen
    jmp _putstr
    _putstr_ende:
ret                ; Return

; auf Tastendruck warten
_waitforkey:
    mov ah, 00h        ; Funktionsnummer nach al
    int 16h            ; Interrupt 16h aufrufen
ret                ; Return

; Bildschirm löschen
_clrscr:
    mov ah, 0fh        
    int 10h            
    mov ah, 00h        
    int 10h            
ret                

; Bootlaufwerk reseten
_reset:
    mov si, resetmsg    
    call _putstr        

    push ds            ; ds sichern
    mov ah, 00h        ; Funktionsnummer nach al
    mov dl, 00h        ; Bootlaufwerk nach dl (0)
    int 13h            ; Interrupt 13h aufrufen
    pop ds            ; ds vom Stapel holen
    jc _reset        ; bei Fehler, erneuter Versuch

    mov si, readymsg    
    call _putstr        

    mov ax, 1000h        ; Adresse für Kernel von Diskette:
    mov es, ax        ; es:bx = 1000h:0000h
    mov bx, 0

; Kernel von Diskette laden
_loadkernel:
    mov si, loadmsg        ; Offset von loadmsg nach si
    call _putstr        ; String ausgeben

    mov ah, 2        ; Funktionsnummer nach al
    mov al, 5        ; Anzahl der zulesenden Sektoren
    mov ch, 0        ; Nummer des Cylinders
    mov cl, 2        ; Nummer des Startsektors
    mov dx, 0        ; Head, Drive = 0
    int 13h            ; Interrupt 13h aufrufen
    jc _loadkernel        ; bei Fehler, erneuter Versuch

    mov si, readymsg    
    call _putstr        
ret                

times 512-($-$$)-2 db 0   ; Dateigröße von 510 Bytes erzeugen
dw 0AA55h               ; + 2 Bytes Bootsignatur --> 512 Bytes

zacK

  • Beiträge: 216
    • Profil anzeigen
    • http://www.domae.ch
Gespeichert
« Antwort #15 am: 25. June 2004, 15:03 »
hi,

Meiner Meinung nach ist hier schon ein Fehler:

loadmsg db "Loading "TEST-Kernel 0.7... ",0
                           ^------Dieses Anführungszeichen.

Bei anderen Sprachen lösst man das so:
loadmsg db "Loading \"TEST-Kernel 0.7... ",0
aber bei Assembly bin ich mir nicht sicher

mfg

GhostCoder

  • Beiträge: 187
    • Profil anzeigen
Gespeichert
« Antwort #16 am: 25. June 2004, 17:13 »
Hi,

unter umständen kann es auch an folgenden Dingen liegen:
Du setzt sp auf 0. Beim nächsten push (z.B. bei jedem call) gibt es einen Überlauf in sp. Muss aber nicht sein.
Btw, warum resettest du den fdc controller nochmal? das macht das BIOS schon vorm booten... Brauchst du also garnicht.

MfG GhostCoder
A man, a legend!

TPSeverino

  • Beiträge: 33
    • Profil anzeigen
Gespeichert
« Antwort #17 am: 11. July 2004, 13:20 »
also ich habs! der code funktioniert so wie er oben steht. ich habe nur immer unter linux kompiliert (was auf jeden fall keinen unterschied machen sollte) und habe das image auf diskette mit dem Befehl
cat boot.bin kernel.bin > /dev/fd0
erzeugt. das schient nicht 100% sauber zu sein. da es aber immer teilweise funktioniert hat, bin ich nicht davon ausgegangen, dass es daran liegt. unter windows mit rawrite funktionierts. wenn mit trotzdem jemand sagen kann, wie man unter linux das image sauber schreibt, wär das cool :-)! thx für die hilfe

TeeJay

  • Beiträge: 630
    • Profil anzeigen
    • http://www.jay-code.de
Gespeichert
« Antwort #18 am: 11. July 2004, 14:49 »
Ich bin zwar kein Linux-Freak aber soweit ich weiß kann man mit dem Befehl "dd" Daten direkt in Sektoren kopieren.

"cat" wird eher nur verwendet um Dateien zusammenzufügen. Wäre mir da nicht so sicher das man die Ausgabe dann so ohne weiteres auf fd0 umleiten kann und es dann direkt in den Bootsektor kopiert wird.
----------------------
Redakteur bei LowLevel

caga

  • Beiträge: 22
    • Profil anzeigen
Gespeichert
« Antwort #19 am: 11. July 2004, 16:28 »
um TeeJay's gedanken weiterzuführen:
dd if=image of=/dev/fd0
bei mir gings auch mit
cat boot.bin kernel.bin > image;cat image > /dev/fd0

 

Einloggen