首先,你好!
我正在尝试制作一个简单的启动加载程序,从USB(FAT 16)闪存驱动器启动一个简单的操作系统。但我无法在13小时内阅读"正确"。我的正确含义是它总是读取零(我已经确定读取的内容确实是缓冲区的整个长度,通过尝试将其打印出来,这样我就可以通过使用_print_string过程来验证是否存在某些内容在下面,没有打印出任何东西,我可能是不正确的。)
第一步是阅读根目录
;All variables that start with "bpb" or "bs" are part of the Bios Parameter Block
mov ax, 488 ; Root directory
mov bx, ds
mov es, bx
mov bx, si
mov cx, 32 ; Read 32 sectors (the entire root directory
call ReadSectors
.
.
.
.
我确定根目录位于扇区488,只需在十六进制编辑器中读取它(我不想在这里制作世界级软件......至少目前为止)
; PROCEDURE ReadSectors
; reads CX sectors from disk starting at AX into
;memory location ES:BX
ReadSectors:
.MAIN:
mov di, 0x0005 ; five retries for error
.SECTORLOOP:
push ax
push bx
push cx
call CHS12
mov ah, 0x02 ; BIOS read sector
mov al, 0x01 ; read one sector
mov dl, BYTE [bsDriveNumber] ; drive
int 0x13 ; invoke BIOS
jnc .SUCCESS ; test for read error
xor ax, ax ; BIOS reset disk
int 0x13 ; invoke BIOS
dec di ; decrement error counter
pop cx
pop bx
pop ax
jnz .SECTORLOOP ; attempt to read again
int 0x18
.SUCCESS:
pop cx
pop bx
pop ax
add bx, WORD [bpbBytesPerSector] ; queue next buffer
inc ax ; queue next sector
loop .MAIN ; read next sector
ret
;The procedure expects the LBA in AX
;The output is correctly set registers CH,CL,DH for int 13h
;I am pretty sure that it doesn't matter which file system is in place for LBA to CHS conversion
CHS12:
push bx
push ax
mov bx, ax ; Save LBA
mov dx, 0
div word [bpbSectorsPerTrack]
add dl, 01h ; Physical sectors begin at 1
mov cl, dl ; Sectors are being forwarded by CL
mov ax, bx
mov dx, 0 ; Calulate head
div word [bpbSectorsPerTrack]
mov dx, 0
div word [bpbHeadsPerCylinder]
mov dh, dl ; Head
mov ch, al ; Cylindar
pop ax
pop bx
mov dl, byte [bsDriveNumber]
ret
;The procoedure expects a pointer to the bufer in SI
_print_string:
pusha
mov ah, 0Eh ; BIOS INT 10h teletype (TTY)
.Repeat:
lodsb ; Take a character from the string
cmp al, 0
je .End ; if it's zero, its the end of the string
int 10h ; If it's not zero invoke the BIOS
jmp .Repeat ; and go to the next character
.End:
popa
ret
我得到这个.bin代码的过程非常难看。我将这个代码(由于447-512是分区表和引导签名,最长可达446个字节)与分区表和引导签名相结合,并将其直接写入USB的第一个扇区,小C程序。
EDIT1:
; Interupt vector table 0000
; -------------------------------
; BIOS Data Area 0040
; -------------------------------
; PrtScr Status / Unused 0050
; -------------------------------
; Boot sector 07C0
; -------------------------------
; Bafer 8KB 07E0
; -------------------------------
; Boot stack 16KB 09E0
; -------------------------------
; Segment where the kernel is loaded 2000 (ImageLoadSeg)
; ------------------------------- <- OS aplications are loaded 2800
; Unused 3000 do A000 28 KB
; -------------------------------
; A000