Autor Thema: Eigenartiger Fehler im OS  (Gelesen 8798 mal)

Hunter

  • Beiträge: 28
    • Profil anzeigen
Gespeichert
« am: 05. January 2007, 16:52 »
Hallo,

Mein Betriebssystem ist in drei Teile aufgeteilt (bootloader,system,kernel)
Der Bootloader lädt dabei die Datein system und kernel.bin ... nun tritt bei mit ein sehr seltsamer Fehler auf:

Wenn der Kernel eine größe unter 65536 Bytes hat funktioniert alles wunderbar ... doch wenn ich jetzt eine Codezeile hinzufüge (bsp. Textausgabe) wird der kernel größer als 65536 und bochs startet sofort neu bevor überhaup der Kernel aufgerufen wurde ... meine Vermutung ist dass es am Bootloader liegt ... ich glaube mal gehört zu haben, dass das Bios nur 64KB über die DMA laden kann ...

Ich verzweifle an diesem Problem bitte helft mir ...

Hunter

Homix

  • Beiträge: 138
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 05. January 2007, 16:59 »
hi,
na ja es ist schwierig das ohne Code zu sagen, aber die Segmentgröße beträgt 64 KB im RealMode, deshalb kann das BIOS nicht mehr als 64 KB hintereinander von einem Datenträger in den RAM lesen.
Liegt die Datei direkt hintereinander auf dem Datenträger oder verwendest du ein Dateisystem wie FAT ?
Bei ersterem trifft warscheinlich das oben beschriebene Problem auf. Eine Möglichkeit dies zu beheben wäre einfach die Datei in mehreren Schritten dann einzulesen (erst bis 64 KB, dann die nächsten 64 KB, usw ...).

Grüsse,
Stefan

Termite

  • Beiträge: 239
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 05. January 2007, 17:02 »
Ohne code bringt das nicht viel. (wie bereits erwähnt) interesant währe hier der booter insbesondere die rotine die den kernel in den speicher copieren soll. bzw eine grobe erklährung was dein code da so macht. Welche ints verwendest du? von was bootest du? FD, HD oder CD? , ...

In welchen mode copierst du deinen kernel in den speicher? daran gedacht das ein segment nur 64k gross ist (RM)? und du somit nen lustigen überlauf produzierst? zumindest meine vermutung

gruss.

Hunter

  • Beiträge: 28
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 05. January 2007, 17:08 »
Also ich verwende eine Floppy Laufwerk mit FAT12 Dateisystem ... Der Bootloader lädt die Datein Kernel.bin und System.bin, anschließend springt er zur System Datei ... hier werden Vesa,A20,GDT,... initialisiert und dann in den PM geschalten ... der Kernel ist an die Adresse 0x10000 geladen .. dorthin springt er wenn in PM geschalten wurde ... wie gesagt wenn die datei kleiner als 64K ist funznt alles (CD,FD,Paging,Multitasking...)

Hier der Boot-Code

;##########################################################
;###########         Bootloader starten         ###########
;##########################################################

    jmp short start
    nop

;##########################################################
;###########         FAT Tabelle holen          ###########
;##########################################################

    %include "FAT.inc"

;##########################################################
;###########         ------------------         ###########
;##########################################################
   
    start:
        jmp 0x7C0:write_cs

;##########################################################
;###########         ------------------         ###########
;##########################################################

    write_cs:
         mov ax,cs
         mov ds,ax
         mov es,ax
         mov gs,ax
         mov fs,ax
       
         mov ax,0xAC0
         mov ss,ax
         mov sp,0x200 ; stack linear addr 0x7BFF

;##########################################################
;###########      Lade-Nachricht ausgeben       ###########
;##########################################################

     mov si, Loading
     call PrintMsg


;##########################################################
;###########      Rootverzeichnis festlegen     ###########
;##########################################################

     mov cx,[Root_Groesse]      ; Größe des Rootverzeichnisses
     call Sektor_Lesen       ; Rootverzeichnis laden


;##########################################################
;#########      1 Prozess ( System.sys ) Laden     ########
;##########################################################

    mov  si,KernelName     
    mov [DateiSegment] , word 0xFFF
    mov [DateiOffset]  , word 0x10
    call Lade_Sektor        ; Lade_Sektor funktion ausführen

;##########################################################
;#########      2 Prozess ( Kernel.sys ) Laden     ########
;##########################################################
     
    mov  si,SystemName     
    mov [DateiSegment] , word 0x240
    mov [DateiOffset]  , word 0x0
    call Lade_Sektor        ; Lade_Sektor funktion ausführen
     
    jmp 0x240:0x0
    hlt


;##########################################################
;###########            Sektor Laden            ###########
;###########                                    ###########
;###########   - Suchen auf A:\                 ###########
;###########   - Gefundenen Eintrag laden       ###########
;##########################################################

    Lade_Sektor:
mov bx,0x7C0           ; Segment auf 0x7C0 festlegen ( 0x7C0:0x000 )
mov es,bx              ; ES das Segment zuweisen
   
             mov cx , word [MaxRootEntries]
             mov di , 0x200
        .1:
             pusha
             mov  cx , 0x000B       ; CX = 11 weil Fat-Eintrag aus 11 Zeichen besteht
             rep  cmpsb
             popa
             je   Gefunden          ; Wenn Datei gefunden zu Gefunden hüpfen
             add  di , 32
             loop .1
             jmp Error
             ret

        Gefunden:
             mov  ax , [di+26]
             call FAT_2_LBA            ; FAT Adresse (DI) in LBA konvertieren
             mov  [Datei_Start] , ax      ; AX (LBA-Adresse) in Datei_Start kopieren
             mov  ax , [di+28]
             call Bytes_2_Sektors      ; Berechnen wieviel Sektoren die Bytes in AX entsprechen
             mov  cx , ax
             mov  ax , [Datei_Start]
             mov  [LBA] , ax
   
;mov si, Datei_Start
;call PrintMsg
   
             call Sektor_Lesen
             ret

;##########################################################
;###########        Bytes auf Sektoren          ###########
;###########            aufteilen               ###########
;##########################################################

    Bytes_2_Sektors:
             xor dx,dx                      ; DX = 0
             div word [BytesPerSector]
             cmp dx , 0                     ; DX mit 0 vergleichen
             jz .1                          ; Wenn DX = 0 springe zu .1
             inc ax
         .1
            ret

;##########################################################
;###########       Wenn Fehler auftritt         ###########
;###########    alles Ordnungsgemäß beenden     ###########
;##########################################################

    Error:
         mov si , ErrorMsg      ; Error Nachricht in SI kopieren
         call PrintMsg          ; Text ausgeben
         xor ax , ax
         int 0x16               ; Warte auf Tastendruck (int 16h)
         mov ax , 0x64          ; HEX-Wert 0x64 in AX schreiben
         out 0x64 , ax          ; Computer neu starten
         cli
         hlt                    ; Alles anhalten

;##########################################################
;###########        Ausgabe von Texten          ###########
;##########################################################

    PrintMsg:
             mov ah , 0x0E
             mov bh , 0
             mov bl , 15
        .1
             lodsb
             cmp al , 0
             je .2
             int 0x10
             jmp .1
        .2
             ret

;##########################################################
;###########         Sektoren einlesen          ###########
;##########################################################

    Sektor_Lesen:
             mov ax , [LBA]
        .1:
             push cx                     ; CX in Stack sichern
             call LBA_2_CHS
        .2
             mov es , [DateiSegment]     ; Datei Segment in ES kopieren
             mov bx , [DateiOffset]      ; Datei Offset in BX kopieren
             mov ax , 0x0201             ; AH = 02-Sektor laden | AL = 01-Sektor1
             mov dl , [DriveNumber]      ; Laufwerknummer ( 00 für A: )
             int 0x13                    ; Lesen des Sektors
             
             jc .2 
                                 
             add  bx , [BytesPerSector]  ; BX = BX + 0x200 ( 1 Sektor - 512 Bytes )
             mov  [DateiOffset] , bx     ; Dateioffset ist BX ( Um 512 Bytes größer )
             mov  si , Ladezeichen               ; Punkt für Laden zeichnen
             call PrintMsg               ; Ausgeben des Punktes
             mov  ax , [LBA]             ; AX = LBA
             inc  ax                     ; AX = AX + 1
             mov  [LBA] , ax             ; LBA = AX ( LBA = LBA + 1 )
             pop  cx                     ; CX aus Stack wieder auslesen
             loop .1                     ; CX gibt an wie oft wiederholt wird
             
             mov [DateiOffset] , word 0  ; Wenn fertig, Dateioffset auf 0 setzen
             
             mov dx , 0x3F2          ; Floppy stoppen
             mov al , 0x0C
             out dx , al
             ret

;##########################################################
;###########       LBA in CHS umwandeln         ###########
;###########  LBA auf Tracks,Heads,. aufteilen  ###########
;##########################################################

    LBA_2_CHS:
         xor  dx , dx                   ; DX = 0
         mov  bx , [SectorsPerTrack]    ; BX = 0x0012 ( 18 Sektoren )
         div  bx
         inc  dx                        ; DX = DX + 1
         push dx                        ; DX im Stack zwischenspeichern
         xor  dx , dx                   ; DX = 0
         mov  bx , [NumHeads]           ; BX = 0x0002 ( 2 Tracks )
         div  bx
         mov  ch , al                   ; CH = Track
         mov  dh , dl                   ; DH = Head
         pop  ax
         mov  cl , al                   ; CL = Sektor
         ret

;##########################################################
;###########       FAT in LBA umwandeln         ###########
;###########    alles Ordnungsgemäß beenden     ###########
;##########################################################

    FAT_2_LBA:
         sub ax,0x2             ; AX = AX - 0x2
         add ax,[Data_Start]    ; AX = AX + 33
         ret


;##########################################################
;###########      Variablen deklarieren         ###########
;##########################################################

     Root_Groesse  dw 14
     Root_Start    dw 19
     Data_Start    dw 33
   
     LBA           dw 19
   
     DateiSegment  dw 0x7E0
     DateiOffset   dw 0x0
   
     Datei_Start   dw 0
     SystemName    db "SYSTEM  BIN"
     KernelName    db "KERNEL  BIN"
   
     Loading       db 13,10,"OS wird geladen ",0
     ErrorMsg      db 13,10,"Datei nicht gefunden!",0
     Ladezeichen   db '²',0

;##########################################################
;###########     Datei mit 0er ausfüllen        ###########
;##########################################################

 times 510-($-$$)  db 0             ; Mit 0er ausfüllen
 sign              dw 0xAA55        ; Bootsignatur



MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 05. January 2007, 17:24 »
dein problem liegt in der segment größe von 64k
Sector_Laden:
...
add  bx , [BytesPerSector]  ; BX = BX + 0x200 ( 1 Sektor - 512 Bytes )
mov  [DateiOffset] , bx     ; Dateioffset ist BX ( Um 512 Bytes größer )
...
wenn du mehr als 64k größe datein lädst, dann wird bx irgendwasnn von 0xffff(64k) auf 0x0000 umspringen dabei wir d aber das Cary-Flag gesetzt, du kanst dies also durch eine korrektur des segments wieder wett machen
..
add  bx , [BytesPerSector]  ; BX = BX + 0x200 ( 1 Sektor - 512 Bytes )
mov  [DateiOffset] , bx     ; Dateioffset ist BX ( Um 512 Bytes größer )
jnc  .0001
add word [DateiSegment], 0x1000
.0001
...

„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

Hunter

  • Beiträge: 28
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 05. January 2007, 17:34 »
Danke M.Nemo , hab jetzt die Codezeilen geändert  ... doch das Problem ist trotzdem noch vorhanden ...  :|

Hunter

  • Beiträge: 28
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 05. January 2007, 17:40 »
Sorry ... hab nochn anderen kleinen Fehler von mir gefunden ... doch wenn ich jetzt die änderung von M.Nemo vornehme hängt das OS beim Laden der Datein ...

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #7 am: 05. January 2007, 17:43 »
Überschreibt die kernel.sys nicht die system.sys?

bitmaster
In the Future everyone will need OS-64!!!

Hunter

  • Beiträge: 28
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 05. January 2007, 17:48 »
Wiso soll Kernel.sys die system.sys überschreiben ?? Die System Datei ist auf 0x2400 geladen der Kernel startet bei 0x10000 .. oder was meinst du? :?

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #9 am: 05. January 2007, 17:53 »
Nja,

FFFh * 16 = FFF0h + 10h = 10000h

240h * 16 = Start = 2400h + 65536 (z.B. wenn der kernel 64 KByte groß ist) = Ende = 12400h

bitmaster
In the Future everyone will need OS-64!!!

Hunter

  • Beiträge: 28
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 05. January 2007, 18:02 »
Versteh ich jetzt nicht ... die Datei System.sys ist ja nur ca. 2K groß

System:
0x2400 + 0x800 = 0x2C00

Kernel:
0x10000

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #11 am: 05. January 2007, 18:06 »
Achso, weil in deinem geposteten code bzw. in den Kommentaren steht das die sysem.sys ab 10000h geladen wird und nicht die kernel.sys. Da habe ich mich vertan, habe mir jetzt nicht die Dateinamen angeguckt. sorry

bitmaster
In the Future everyone will need OS-64!!!

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 05. January 2007, 18:09 »
Gefunden:
             ....
             mov  ax , [di+28]
             call Bytes_2_Sektors      ; Berechnen wieviel Sektoren die Bytes in AX entsprechen
             mov  cx , ax
            ....
wenn die datei größer als 64k ist, dann passt die größe nicht in ax und somit stimmt auch nicht die anzahl der zu lessenden sectoren

und noch ein paar sachen die mir aufgefallen sind:
1. dein bootloader geht davon aus, dass alle sectoren einer datei schön hintereinander angereit sind, dass ist aber nur selten der fall

2.write_cs:
...
mov ax, 0xAC0
mov ss, ax
mov sp, 0x200 ; stack linear addr 0x7bff

;0x0AC0:0x0200 liner = 0xAE00 nicht 0x7bff

3. du hast oftermal so sachen wie
jmp   blabla
ret
das ret wird aber nie ausgefürt
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

Hunter

  • Beiträge: 28
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 06. January 2007, 20:10 »
Hallo,

so hab das Problem mit der Anzahl der Sektoren behoben ... doch leider wird das System (od. Emulator) nach aufruf des Kernels neu gestartet ... VM-Ware meldet einen "Kernel Stack Fault (HW reset)" ... hätte vl. noch jemand eine Vermutung woran es liegen könnte ??

Hunter

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #14 am: 07. January 2007, 01:40 »
Der Fehler liegt wohl dann im Kernel. Kanst du das ma posten? Lauft dein Kernel im PM oder RM?
Das Problem mit dem Neustarten hatte ich auch schon. Woran es genau gelegen hat hab ich nicht raus bekommen. Ich schätze ma das es Fehler mit den Diskriptoren war.
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

 

Einloggen