Erweiterte 13 Interrupt, eine unformatierte Plattenlese
-
22-09-2019 - |
Frage
Es ist eine Weile her, seit ich war jede ASM tat, und beschlossen, noch einmal versuchen und einen kleinen Bootloader zu schreiben, mit Qemu zu testen. Mein Problem ist, mit Interrupt 13, aus irgendeinem Grunde der Carry-Flag gesetzt wird, so dass die Lese ausfällt. Derzeit meine Scheibe Bild sieht aus wie:
512 Byte Bootloader <- Das (soweit ich weiß) Ist Block 0 in LBA
Hauptfunktion <- Dies wäre Block 1
Im Grunde genommen mit der 512 des BIOS in den Speicher geladen Bytes, möchte ich die nächsten 512 Bytes aus dem gleichen Laufwerk laden. Ich kann nicht herausfinden, was jedoch falsch läuft. Hoffe, dass ich habe genug Informationen gegeben.
Hier ist der Code, das Problem mit dem zweiten 0x13 Interrupt, kurz vor dem Sprung zu 0x7E00:
[bits 16]
[org 0x7C00]
; Prepare Stack Segment
;-----------------------------------------------------------------
mov sp, 0x7A00 ; Move Stack into SP
mov bp, sp ; Store current Stack Base
; Print Character to Make Sure Bootloader Has Reached this Point
;-----------------------------------------------------------------
mov ah, 0x0E ; Print Character to Screen
mov bh, 0x00 ; No Page Numbering
mov bl, 0x07 ; White Text, Black Background
mov al, 65 ; Print Letter A
int 0x10
; Check if INT0x13 Extentions are Supported
;-----------------------------------------------------------------
mov ah, 0x41 ; Set Function 0x41
mov word bx, 0x55AA
push dx ; Save old Drive Identifier
mov dl, 0x80 ; Load 'Active' ID Into dl
int 0x13 ; Call Interupt
jc short unsupported ; If Extentions aren't Supported, Jump
xor ax, ax
add ax, 1 ; Clear Carry Bit
mov si, DAPS ; Load DAPS Struct to DS:SI
mov ah, 0x42 ; Read Functions (AL Ignored)
mov dl, 0x80 ; Active Boot Drive (Commented Out Due to Line 24)
int 0x13
jc short unsupported ; If something goes wrong...
jmp 0x7E00 ; Jump to main
; Errors
;-----------------------------------------------------------------
unsupported:
mov ah, 0x0E ; Print Letter F, Gives Indication of Failure
mov bh, 0x00
mov bl, 0x07
mov al, 70
int 0x10
success:
pop dx ; Pop Original Drive Identifier
jmp $
; Fill Out Rest of Bootloader
;-----------------------------------------------------------------
times 494-($-$$) db 0
; Memory Data Structures and Other Variables
;-----------------------------------------------------------------
; Disk Address Packet Structure (Used For Loading Rest of OS)
DAPS: db 0x10 ; Size of Structure (16 bytes)
db 0 ; Always 0
db 1 ; Number of Sectors to Read (1x512)
db 0 ; Always 0
dw 0x7E00 ; Target Location for Reading To
dw 0 ; Page Table (0, Disabled)
dd 1 ; Read from Second Block
dd 0 ; Large LBAs, ignore
db 0x55, 0xAA ; Add Boot Record Signature
main:
mov ah, 0x0E ; Print Character to Screen
mov bh, 0x00 ; No Page Numbering
mov bl, 0x07 ; White Text, Black Background
mov al, 66 ; Print Letter B
int 0x10
jmp $
Lösung
Problem am Ende einfach zu sein, war der Code richtig. Aber weil das endgültige Bild 525 Bytes war, anstelle eines Vielfachen von 512 Bytes, brach die Lese. Gerade hatte mein Bild-Pad mit 0s aus der Bildgröße 1024B zu machen, damit die Lese alle 512 Bytes bekommen.
(Offensichtlich wahrscheinlich eine viel bessere Idee, nicht eine winzige unformatierte Platte wie diese haben, aber zu Lernzwecken ist dies alles, was ich wirklich erforderlich)