Autor Thema: Probleme mit Bochs/BIOS disk read  (Gelesen 6350 mal)

BadBeu

  • Beiträge: 28
    • Profil anzeigen
    • http://www.BadBeu.net
Gespeichert
« am: 19. July 2006, 14:44 »
Hallo Leute,

ich habe ein kleines Problem mit meinem Bootloader.

Eigentlich soll er nur einen erweiterten Bootloader in den Speicher laden und ausführen, da das BIOS ja nur 512 bytes läd.
Eigentlich funktioniert das alles auch ganz prima, jedenfalls spuckt er keine Fehler aus. Aber er läd nichts in den Speicher.
Ich weiß jetzt nicht wo der Fehler liegt?
Im Debugger läd er alles in die richtigen Register machten den BIOS int und macht dann normal weiter. Nur das ich an der Speicherstelle nur Nullen hab anstatt mein Programm.

Hier mal mein Code. Ich weiß ... ist ein bischen umfangreich


_start:

;; essential initialization
cli

;; setup a stack
mov ax, 0x9000
mov ss, ax
mov sp, 0xFFFE

sti

;; load boot up message
push cs
pop ds
mov si, msg_bootup
;; print boot up message
call print_string

;; load loaction of position structure
push cs
pop ds
mov si, pos_struct
;; load stage two behind stage one
push 0x7E00
pop es
xor di, di
call load_stage2

;; jump into stage two
push es
push ax
retf

;; loads stage two of the bootloader
;; INPUT:
;; [DS:SI] - location of position structure pointing to bootloader on disk
;; [ES:DI] - location of the bootloader in memory
;; OUTPUT:
;; [ES:DI] - location of the bootloader in memory
;; [AX] - entry point offset of the bootloader
;; AFFECT:
load_stage2:
;; store location of position structure
push si
push ds

;; read header
call read_header

;; restore location of position structure
pop ds
pop si

;; store entry point
push ax

;; load bootloader into memory
mov ax, bx
call disk_read

;; restore entry point
pop ax

;; return to caller
ret

;; loads, verifies and reads values from bootloader header
;; INPUT:
;; [DS:SI] - location of position structure pointing to bootloader header on disk
;; [ES:DI] - location of data buffer
;; OUTPUT:
;; [AX] - entry point
;; [BX] - size of bootloader (in sectors)
;; AFFECT:
;; [AX] - entry point
;; [BX] - size of bootloader (in sectors)
;; [DX] - calculation issue
;; [DS:SI] - end of header
read_header:
;; read header into memory
;; read just one sector
mov ax, 0x0001

;; read from disk
call disk_read

;; move output to input
push di
push es
pop ds
pop si

;; get size of bootloader
lodsw
;; calculate sector count
xor dx, dx
mov bx, 0x0020
div bx
or dx, dx
;; do not increment if even division
jz .no_inc
inc ax

.no_inc:
;; store size
mov bx, ax

;; verify magic number
;; first part
lodsw
xor ax, word [cs:magic_number]
jnz .invalid_header
;; second part
lodsw
xor ax, word [cs:magic_number+2]
jnz .invalid_header

;; get entry point
lodsw

;; return to caller
ret

.invalid_header:
;; load invalid header message
push cs
pop ds
mov si, msg_inv_header
;; panic
call panic

;; reads sectors from disk
;; INPUT:
;; [AX] - number of sectors to read
;; [DS:SI] - location of position structure
;; [ES:DI] - location of data buffer
;; OUTPUT:
;; [AX] - sectors actually read
;; [ES:DI] - location of data
;; AFFECT:
;; [AX] - through function call
;; [ES:DI] - through function call
;; [DS:SI] - through function call
;; [BX] - through function call
disk_read:
;; store number of sectors to read on stack
push ax

;; load drive number from position structure
lodsb
mov dl, al

;; check for floppy
and al, 10000000b
jz .read_floppy

;; read from hard disk
.read_disk:
;; [DS:SI] now already pointing to LBA and [DL] is set correctly
;; restore number of sectors to read from stack
pop ax

;; read from disk
call disk_read_lba

;; return to caller
ret

;; read from floppy disk
.read_floppy:
;; [DL] now already holding drive number

;; [DS:SI] now pointing to CHS value

;; load cylinder number
lodsw
mov bx, ax

;; load head number
lodsb
mov dh, al

;; load sector number
lodsb
mov cl, al

;; restore number of sectors to read
pop ax

;; read from disk
call disk_read_chs

;; return to caller
ret

;; reads sectors from disk via CHS referencing
;; INPUT:
;; [AL] - number of sectors to read
;; [BX] - cylinder number (only bit 0-9 used)
;; [DH] - head number
;; [CL] - sector number (only bit 0-6 used)
;; [DL] - drive number to access
;; [ES:DI] - location of data buffer
;; OUTPUT:
;; [AX] - sectors actually read
;; [ES:DI] - location of data
;; AFFECT:
;; [AX] - sectors actually read
;; [ES:DI] - location of data
;; [BX] - offset of data
disk_read_chs:
;; protect against false input
and bx, 0000001111111111b
and cl, 00111111b

;; pack cylinder and sector number correctly
mov ch, bl
sal bh, 0x06
or cl, bh

;; store data buffer offset in [BX] for function call
mov bx, di

;; select DISK function (READ SECTOR(S) INTO MEMORY)
mov ah, 0x02

;; reset disk
call disk_reset

;; read disk
.read_disk:
;; BIOS interrupt
int 0x13

;; store flags
pushf

;; check for read error
xor ah, 0x04
jz .read_error

;; restore flags
popf

;; retry on error
jc .read_disk

.end_read:
;; store sectors read into [AX]
xor ah, ah

;; return to caller
ret

.read_error:
;; load read error message
push cs
pop ds
mov si, msg_readerror
call print_warning

;; complete function call
jmp .end_read

;; reads sectors from disk via LBA referencing
;; INPUT:
;; [DS:SI] - location of 64 bit LBA
;; [AX] - number of sectors to read into memory
;; [DL] - drive to access
;; [ES:DI] - location of data buffer
;; OUTPUT:
;; [AX] - sectors actually read
;; [ES:DI] - location of data
;; AFFECT:
;; [AX] - sectors actually read
;; [DS:SI] - location of the disk address packet
disk_read_lba:
;; fill in number of sectors to read into DAP
mov [dap_sec2read], ax

;; fill in LBA into DAP
lodsw
mov [dap_lba], ax
lodsw
mov [dap_lba+2], ax
lodsw
mov [dap_lba+4], ax
lodsw
mov [dap_lba+6], ax

;; fill in location of data buffer into DAP
mov [dap_data_buf], di
mov [dap_data_buf+2], es

;; load DAP
push cs
pop ds
mov si, dap

;; reset disk
call disk_reset

;; select DISK function (EXTENDED READ SECTOR(S))
mov ah, 0x42

;; read data from disk
.read_disk:
;; BIOS interrupt (DISK)
int 0x13

;; store flags
pushf

;; check for function error
push ax
xor ah, 0x01
jz .not_available
pop ax

;; check for read error
xor ah, 0x04
jz .read_error

;; restore flags
popf

;; retry on error
jc .read_disk

;; return to caller
.end_read:
;; store sectors actually read to [AX]
mov ax, [dap_sec2read]
;; return
ret

.not_available:
;; load error message
push cs
pop ds
mov si, msg_int13_ex_abs
;; panic
call panic

.read_error:
;; load read error message
push cs
pop ds
mov si, msg_readerror
;; print read error message
call print_warning

;; complete function call
jmp .end_read

;; resets disk drive
;; INPUT:
;; [DL] - dirve number to reset
;; OUTPUT:
;; [AH] - status of operation
;; AFFECT:
;; [AX] - status of operation
disk_reset:
;; select DISK function (RESET DISK SYSTEM)
mov ah, 0x00

.reset_disk:
;; BIOS interrupt (DISK)
int 0x13

;; retry on  error
jc .reset_disk

;; return to caller
ret

;; prints error message to screen and halts CPU
;; INPUT:
;; [DS:SI] - location of error message
;; OUTPUT:
;; none
;; AFFECT:
;; [AX] - through function call
;; [BX] - through function call
;; [SI] - through function call
panic:
;; store location of error message to stack
push si
push ds

;; load panic sign
push cs
pop ds
mov si, msg_panic
;; output panic sign
call print_string

;; restore location of error message from stack
pop ds
pop si
;; output error message
call print_string

;; halt CPU
.halt:
hlt
jmp .halt

;; prints a warning message to screen
;; INPUT:
;; [DS:SI] - location of warning message
;; OUTPUT:
;; none
;; AFFECT:
;; [AX] - through function call
;; [BX] - through function call
;; [SI] - through function call
print_warning:
;; store location of warning message to stack
push si
push ds

;; load warning sign
push cs
pop ds
mov si, msg_warning
;; print warning sign
call print_string

;; restore warning message
pop ds
pop si
;; print warning message
call print_string

;; return to caller
ret

;; prints a zero-terminated, teletype formated string to screen
;; INPUT:
;; [DS:SI] - location of string
;; OUTPUT:
;; none
;; AFFECT:
;; [AX] - BIOS function and character
;; [BX] - page and color selection
;; [SI] - advances during execution
print_string:
;; select VIDEO function (TELETYPE OUTPUT)
mov ah, 0x0E
;; select active page and default color
mov bx, 0x0007

;; process characters
.process_char:
;; load character into [AL]
lodsb

;; check for zero termination
or al, al
jz .end_process

;; BIOS interrupt (VIDEO)
int 0x10

;; process next character
jmp .process_char

;; return to caller
.end_process:
ret

;; data

;; magic number for header verification
magic_number dw 0xE64D, 0xBB40

;; Disk Address Packet for LBA disk access
dap:
dap_size db 0x10
dap_reserved db 0
dap_sec2read dw 0
dap_data_buf dw 0, 0
dap_lba dw 0, 0, 0, 0

;; messages
msg_bootup db "DSMOS bootloader starting...", 13, 10, 0
msg_panic db "BOOTLOADER PANIC: ", 0
msg_warning db "BOOTLOADER WARNING: ", 0
msg_readerror db "Read error encountered!", 13, 10, 0
msg_int13_ex_abs db "BIOS INT13h extensions not available!", 13, 10, 0
msg_inv_header db "Invalid header encountered!", 13, 10, 0

;; fill up to one sector (512 bytes)
times 512-($-$$)-11 db 0

;; position structure pointing to bootloader stage two
pos_struct:
db 0
dw 0
db 0, 0x02
dw 0, 0

;; boot signature
dw 0xAA55


Von besonderem Interesse wird wohl disk_read_chs sein. Da disk_read_lba ja nicht ausgeführt wird bei Disketten.

Ich hoffe der Code ist nicht zu umfangreich.

Schonmal danke für die Hilfe.

FPS**

  • Beiträge: 6
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 19. July 2006, 16:27 »
Zitat von: BadBeu

times 512-($-$$)-11 db 0

;; position structure pointing to bootloader stage two
pos_struct:
db 0
dw 0
db 0, 0x02
dw 0, 0

;; boot signature
dw 0xAA55


-.- ja sind tatsaechlich 11 bytes

BadBeu

  • Beiträge: 28
    • Profil anzeigen
    • http://www.BadBeu.net
Gespeichert
« Antwort #2 am: 19. July 2006, 16:49 »
Also ich zähle 11 Bytes. Außerdem ist die kompilierte Datei auch 512 bytes lang.
Und richtig aus der Struktur auslesen tut er ja auch. Nur der BIOS Interrupt funktioniert nicht.

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #3 am: 19. July 2006, 19:12 »
Zitat von: BadBeu
Also ich zähle 11 Bytes. Außerdem ist die kompilierte Datei auch 512 bytes lang.
Und richtig aus der Struktur auslesen tut er ja auch. Nur der BIOS Interrupt funktioniert nicht.
Daran liegt es auch nicht. Denn du hast recht, es ist richtig so wie du es machst.
In the Future everyone will need OS-64!!!

BadBeu

  • Beiträge: 28
    • Profil anzeigen
    • http://www.BadBeu.net
Gespeichert
« Antwort #4 am: 20. July 2006, 18:25 »
Okay. Endlich hab ich den Fehler gefunden. Nämlich hier:


;; select DISK function (READ SECTOR(S) INTO MEMORY)
   mov   ah, 0x02

   ;; reset disk
   call   disk_reset

   ;; read disk
   .read_disk:
      ;; BIOS interrupt
      int   0x13


Die "disk_reset" Funktion überschreibt mein [AH].

Einfach Instruktionen umgetauscht und jetzt funktionierts perfekt.

 

Einloggen