无法读取CD INT 13h AH = 42H的扇区

时间:2014-07-25 02:43:42

标签: assembly bootloader

我一直在尝试编写一个BootLoader来读取CD而不是软盘上的扇区,我已经开始只读取第一个扇区了但是当我运行它时,Carry标志仍然设置并且根据来自此处的文档:http://en.wikipedia.org/wiki/INT_13H#INT_13h_AH.3D42h%3a_Extended_Read_Sectors_From_Drive 这意味着它无法从Image中读取扇区这是我的完整启动代码:

BITS   16

ORG  0x00

Start: jmp main


;Colors for text
%DEFINE TEAL 0x03
%DEFINE RED 0x04
%DEFINE PURPLE 0x05
COL: db 0
ROW:  db 0

;macro for print
%macro Print 2
    xor dx, dx
    mov dh, BYTE[ROW];puts the row into the dh register
    xor bx, bx
    mov bl, %2
    mov si, %1
    call cPrint


    mov ah, 0x02            ;set cursor pos
    mov bh, 0x00            ;page 00
    inc dh                  ;row 00
    mov dl, 0x00            ;col. 00    
    int 0x10

    mov BYTE[ROW], dh;saves the rows for the next time we need to print
%endmacro


cPrint:                   ; Routine: output string in SI to screen


 .top:
    ;Paramaters for Input 
    mov ah, 09h             ; Must be 9 to print color
    mov cx, 0x01            ;x position
    lodsb                   ; Get character from string
    test al, al
    je .done                ; If char is zero, end of string
    int 0x10                 ; Otherwise, print it

    mov ah, 0x02            ;set cursor position
    mov bh, 0x00            ;page
    inc dl      ;column
    int 0x10                ;changes the cursor position so the next char can be written at the new location
    jmp .top

 .done:
    ret

;clears the screen and sets the cursor position to the top left 
 clear:
    mov ah, 0x0F            ;get current video mode
    mov al, 0x00            ;reset register
    int 0x10                ;get video mode
    mov ah, 0x00            ;set video mode
    int 0x10                ;reset screen
    mov ah, 0x02            ;set cursor pos
    mov bh, 0x00            ;page 00
    mov dh, 0x00            ;row 00
    mov dl, 0x00            ;col. 00
    int 0x10                ;set pos
ret




Read_Extended_Sector:
    pusha
    xor ax, ax
    xor dx, dx
    xor bx, bx
    ;read in the sector


    .ForLoop:
        MOV DL,BYTE[CDDriveNumber]              ; Set it up again 
        MOV AH,42h                          ; Read from drive function 
        MOV SI,DiskAddressPacket            ; Load SI with address of the Disk Address Packet 
        INT 13h    
        jnc .Success


        Print Read_Sector_Error_MSG, PURPLE
        cli
        hlt

    .Success:
        Print READ_SUCCESS, TEAL
        cmp ah, Stage2
        jz .DONE
        Print FILE_NOT_FOUND, RED
        cli
        hlt
    .DONE:
    popa
ret


main:

    cli; disable interrupts
    mov ax, 0x07c0  ;adjust the segment registers
    mov ds, ax
    mov gs, ax
    mov fs, ax


Create_Stack:
    xor ax, ax
    mov es, ax
    mov ss, ax
    mov sp ,0x0FFFE
    sti ; enable interrupts

    call clear


    Print W_MSG, TEAL;prints the loading message in colour


    call Read_Extended_Sector; Reads the first sector of the drive 
    ;the read in data is stored in AH














cd_signature: db "CD001"        
cd_Version:   db 0x01
CDDriveNumber: db 80h

;Disk Address Packet


DiskAddressPacket:          db 16,0 
.SectorsToRead:             dw 1                              ; Number of sectors to read (read size of OS) 
.Offset:                    dw 0                              ; Offset :0000 
.Segment:                   dw 0200h                          ; Segment 0200
.End:                       dq 16                             ; Sector 16 or 10h on CD-ROM 



W_MSG: db "Loading Z-Boot...........", 0
Stage2: db "STAGE2 BIN"
Read_Sector_Error_MSG: db "Failed to read sector ......",0
READ_SUCCESS: db "Reading the first sector was a success .......",0
FILE_NOT_FOUND: db "Error, File not found......."
times 2046 - ($ - $$) db 0; padd out the rest of the file to 0
DW 0xAA55

修改

显然我在设置片段后忘记保存驱动器号码:

Create_Stack:
    xor ax, ax
    mov es, ax
    mov ss, ax
    mov sp ,0x0FFFE
    sti

    mov     [CDDriveNumber],dl

带有驱动器号,该功能无效。我还是新手,所以也许其他人可以深入解释这个问题?

1 个答案:

答案 0 :(得分:4)

BIOS提供在DL寄存器中启动的驱动器数量。驱动器00h是第一个软盘驱动器,驱动器01h是第二个。驱动器80h是第一个硬盘,随后是硬盘驱动器。从CD-ROM启动时,只有从CD-ROM启动时,BIOS才会模拟CD-ROM,就好像它是硬盘一样。这就是为什么你可以使用INT 13h, AX=42扩展读取BIOS调用来读取它。 BIOS分配模拟CD-ROM的驱动器号因系统而异,因此您无法对其进行硬编码。