【发布时间】:2014-09-16 19:21:00
【问题描述】:
我一直在尝试编写一个从 CD 而不是软盘读取扇区的 BootLoader,我开始时只读取第一个扇区,但是当我运行它时,进位标志仍然设置,并且根据来自这里的文档:http://en.wikipedia.org/wiki/INT_13H#INT_13h_AH.3D42h%3a_Extended_Read_Sectors_From_Drive 这意味着它无法从图像中读取扇区这是我的完整启动代码:
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
如果没有驱动器号,该功能将不起作用。我还是新手,所以也许其他人可以深入解释一下?
【问题讨论】:
-
太棒了,这是我有一天一直想做的练习。我希望你能找到更多的细节,并用你的知识丰富互联网。其他人经历过这些(bsd 作家、grub 作家、lilo 作家......)并且经常有关于这些东西的私人新组交换或邮件交换。但其中很多是前流行的互联网时代,不像 stackoverflow 那样容易访问。
-
只有一个警告:我看到错误的 BIOS 假定 ES 寄存器包含来自磁盘访问数据包的“段”。您应该将 ES 设置为 0200h 以与此类 BIOS 兼容。
-
@MartinRosenau 感谢您的警告,我在查找根目录时遇到了另一个问题,您可以看看吗?看来您对这类事情了解很多。
-
@MartinRosenau 差点忘了问题的链接:stackoverflow.com/questions/24949598/…
标签: assembly bootloader