Autor Thema: Rechner neu start, Fehler im Kernel  (Gelesen 4433 mal)

syxce

  • Beiträge: 45
    • Profil anzeigen
Gespeichert
« am: 06. December 2005, 19:57 »
Hallo,
Ich habe wie immer meinen Bootloader und meinen Kernel, ich habe nur meinen Kernel ein bisschen umgestaltet und nun folgendes Problem, jedes mal wenn ich meine bootloader.bin und kernel.bin zusammen auf .img kopiere und dann auf die Diskette schreibe und den Rechner neu starte dann liest er kurz von der Diskette und startet aber sofort neu, da muss im Kernel irgendwo ein Fehler sein, ich bitte um hilfe.

bootloader.bin:

org 0x7C00

start:

cli
mov ax, 0x9000
mov ss, ax
mov sp, 0
sti

mov [bootdrv], dl

call kernel

mov ax, 0x1000
mov es, ax
mov ds, ax
push ax
mov ax,0
push ax
retf

bootdrv db 0
loadmsg db "Loading...",13,10,0

putstr:
lodsb
or al, al
jz short putstrd

mov ah, 0x0E
mov bx,0x0007
int 0x10
jmp putstr
putstrd:
retn

kernel:

push ds
mov ax, 0
mov dl, [bootdrv]
int 13h
pop ds
jc kernel

load:
mov ax,0x1000
mov es, ax
mov bx,0

mov ah, 2
mov al, 5
mov cx, 2
mov dx, 0
int 13h
jc load
mov si, loadmsg
call putstr
retn

times 512-($-$$)-2 db 0
dw 0AA55h


Kernel.bin:
[BITS 16]       ; We need 16-bit intructions for Real mode

        cli                     ; Disable interrupts, we want to be alone

        xor ax, ax
        mov ds, ax              ; Set DS-register to 0 - used by lgdt

        lgdt [gdt_desc]         ; Load the GDT descriptor

        mov eax, cr0            ; Copy the contents of CR0 into EAX
        or eax, 1               ; Set bit 0
        mov cr0, eax            ; Copy the contents of EAX into CR0

        jmp 08h:clear_pipe      ; Jump to code segment, offset clear_pipe


[BITS 32]                       ; We now need 32-bit instructions

clear_pipe:
        mov ax, 10h             ; Save data segment identifyer
        mov ds, ax              ; Move a valid data segment into the data segment register
        mov ss, ax              ; Move a valid data segment into the stack segment register
        mov esp, 090000h        ; Move the stack pointer to 090000h

        mov byte [ds:0B8000h], 'X'      ; Move the ASCII-code of 'P' into first video memory
        mov byte [ds:0B8001h], 1Bh      ; Assign a color code

hang:
        jmp hang                ; Loop, self-jump


gdt:                    ; Address for the GDT

gdt_null:               ; Null Segment
        dd 0
        dd 0

gdt_code:               ; Code segment, read/execute, nonconforming
        dw 0FFFFh
        dw 0
        db 0
        db 10011010b
        db 11001111b
        db 0

gdt_data:               ; Data segment, read/write, expand down
        dw 0FFFFh
        dw 0
        db 0
        db 10010010b
        db 11001111b
        db 0

gdt_end:                ; Used to calculate the size of the GDT



gdt_desc:                       ; The GDT descriptor
        dw gdt_end - gdt - 1    ; Limit (size)
        dd gdt                  ; Address of the GDT

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 06. December 2005, 20:24 »
Ich weiss nicht, aber du kannst im Kernel nach dem PM-Jump vieleicht mal anstatt:mov ax,10h sowas schreiben (bei mir gab es deswegen auch diverse Fehler)mov eax,2 ;das ist der 2. Deskriptor und das Register 32-Bit
shl eax,3 ;Deskriptor errechnen
mov ds,ax


Könnte es sein, dass der Code von dir auf Bochs läuft.

Gruss Noooooooos

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 06. December 2005, 20:31 »
An dem mov ax, 10h dürfte es eigentlich nicht liegen. An welcher Stelle stürtzt der Kernel denn ab? Nach oder vor dem clear_pipe?

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 06. December 2005, 20:39 »
mov sp, 0
der stack wächst nach unten. das heisst bei einem push, call oder einem interrupt wird sp = sp - 2, also 0xfffe. das heisst es gibt einen stack overflow. auf jedenfall wird was an die adresse SS:FFFFh geschrieben. das löst einen stack fault aus. ich würde sp mit 0xfffe laden.


-----
mov ax, 0x1000
push ax
mov ax,0
push ax
retf

der nasm kann auch
jmp word 0x1000:0


-----
       xor ax, ax
        mov ds, ax              ; Set DS-register to 0 - used by lgdt

        lgdt [gdt_desc]         ; Load the GDT descriptor

der kernel wird doch nach 0x1000:0000 (0x10000 linear) geladen. da würde ich ds mit 0x1000 laden.

-----
jmp 08h:clear_pipe      ; Jump to code segment, offset clear_pipe
wird zu einer adresse < 0x10000 springen, weil das ein 16 bit jump ist. da ist aber nicht der kernel. außerdem denkt nasm, dass clear_pipe auch an einer adresse < 0x10000 ist. das kann man folgendermaßen ändern:


; dem assembler sagen, dass wir an die adresse 0x00010000 linear geladen wurden
; ich hoffe der 16 bit teil kann das ignorieren, denn der kann mit so
; großen adressen nicht um. (ich hoffe er denkt wir wären an adresse
; (0x10000 and 0xffff), also 0. ds macht das dann schon ^^)
org 0x10000
[Bits 16]

...

jmp dword 08h:clear_pipe
[BITS 32]
clear_pipe:

...



ist natürlich alles nur aus dem kopf, weil ich gerade meinen assembler nicht auspacken möchte.
Dieser Text wird unter jedem Beitrag angezeigt.

syxce

  • Beiträge: 45
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 06. December 2005, 20:57 »
Es geht nicht, bochs schreibt immer nur ganz kurz das Loading.... vom Bootloader dann ist er sofort wieder weg, also er startet neu.
Wenn mir jemand den direkt im ganzen code das ändern würde wäre es leichter verständlicher für mich, danke schon mal

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 06. December 2005, 21:08 »
du kannst es doch mit jmp $ mal eingrenzen, an welcher stelle das system neustartet.
Dieser Text wird unter jedem Beitrag angezeigt.

syxce

  • Beiträge: 45
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 06. December 2005, 21:22 »
Ich glaube das der nicht einmal den Kernel findet.
Sonst würde er ihn laden, doch was muss ich ändern damit er ihn lädt ?
Edit: Ich habs jetzt mit dem jmp $ probiert, bis hier:
       mov eax, cr0            ; Copy the contents of CR0 into EAX
        or eax, 1               ; Set bit 0
        mov cr0, eax            ; Copy the contents of EAX into CR0
jmp $

geht noch alles, er hängt und schreibt nur Loading auf den Schirm doch sobal ich den Befehl nach diesem code:
jmp 08h:clear_pipe      ; Jump to code segment, offset clear_pipeeinfüge ist schluss, dann resetet er immer gleich, wiso ?

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 06. December 2005, 21:33 »
Ok ich hab mal meine änderungen in den Code eingefügt. Dann gehts (zumindest in Bochs).

Kernel.bin:
org 0x10000
[BITS 16]       ; We need 16-bit intructions for Real mode

        cli                     ; Disable interrupts, we want to be alone

        mov ax, 0x1000
        mov ds, ax              ; Set DS-register to 0 - used by lgdt

        lgdt [gdt_desc]         ; Load the GDT descriptor

        mov eax, cr0            ; Copy the contents of CR0 into EAX
        or eax, 1               ; Set bit 0
        mov cr0, eax            ; Copy the contents of EAX into CR0

        jmp dword 08h:clear_pipe      ; Jump to code segment, offset clear_pipe


[BITS 32]                       ; We now need 32-bit instructions

clear_pipe:
        mov ax, 10h             ; Save data segment identifyer
        mov ds, ax              ; Move a valid data segment into the data segment register
        mov ss, ax              ; Move a valid data segment into the stack segment register
        mov esp, 090000h        ; Move the stack pointer to 090000h

        mov byte [ds:0B8000h], 'X'      ; Move the ASCII-code of 'P' into first video memory
        mov byte [ds:0B8001h], 1Bh      ; Assign a color code

hang:
        jmp hang                ; Loop, self-jump


gdt:                    ; Address for the GDT

gdt_null:               ; Null Segment
        dd 0
        dd 0

gdt_code:               ; Code segment, read/execute, nonconforming
        dw 0FFFFh
        dw 0
        db 0
        db 10011010b
        db 11001111b
        db 0

gdt_data:               ; Data segment, read/write, expand down
        dw 0FFFFh
        dw 0
        db 0
        db 10010010b
        db 11001111b
        db 0

gdt_end:                ; Used to calculate the size of the GDT



gdt_desc:                       ; The GDT descriptor
        dw gdt_end - gdt - 1    ; Limit (size)
        dd gdt                  ; Address of the GDT


Den Bootloader kannst du ohne Änderungen nutzen. Scheinbar ist das mit dem sp = 0 doch nicht so schlimm, wie ich angenommen habe.
Dieser Text wird unter jedem Beitrag angezeigt.

syxce

  • Beiträge: 45
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 06. December 2005, 21:42 »
Vielen Dank jetzt gehts, das nenne ich hilfe :wink:

greetings syxce

 

Einloggen