mbr只有512字节,不能装下整个内核,所以我们要读取loader,把loader放到内存中哪里?
在实模式下0x5000x7bff和0x7e0009fbff是可以使用的内存。
注意,在loader中要存放一些数据结构,loader被加载后就不能覆盖,内核也会越来越大,所以loader要较低位,这里就选择0x900吧。
SECTION MBR vstart = 0x7c00
LOADER_BASE_ADDR equ 0x900
LOADER_START_SECTOR equ 0x2
mov ax,cs
mov ds,ax
mov es,ax
mov ss,ax
mov fs,ax
mov sp,0x7c00
mov ax,0xb800
mov gs,ax
mov ax,0600h
mov bx,0700h
mov cx,0
mov dx,184fh
int 10h ;清屏
mov byte [gs:0x00],'h'
mov byte [gs:0x01],0xA4
mov byte [gs:0x02],'e'
mov byte [gs:0x03],0xA4
mov byte [gs:0x04],'l'
mov byte [gs:0x05],0xA4
mov eax,LOADER_START_SECTOR ;开始扇区lba地址
mov bx,LOADER_BASE_ADDR ;写入的地址
mov cx,1 ;读入扇区数
call rd_disk_m_16 ;以下读取程序开始的部分
jmp LOADER_BASE_ADDR
rd_disk_m_16:
mov esi,eax
mov di,cx
;设置要读取的扇区数
mov dx,0x1f2
mov al,cl
out dx,al
mov eax,esi
mov dx,0x1f3
out dx,al
mov cl,8
shr eax,cl
mov dx,0x1f4
out dx,al
shr eax,cl
mov dx,0x1f5
out dx,al
shr eax,cl
and al,0x0f
or al,0xe0
mov dx,0x1f6
out dx,al
mov dx,0x1f7
mov al,0x20
out dx,al
.not_ready:
nop
in al,dx
and al,0x88
jnz .not_ready
mov ax,di
mov dx,256
mul dx
mov cx,ax
mov dx,0x1f0
.go_on_read:
in ax,dx
mov [bx],ax
add bx,2
loop .go_on_read
ret
times 510-($-$$) db 0
db 0x55,0xaa
说明:
对于写入操作解释:
eax是32位,eax = LBA扇区号:二号扇区。
然后把扇区号写入0x1f3(硬盘的端口,通过端口进行读写操作)
用shr操作,每次读完8位,就讲整个eax中数据向右位移8位,al存的就是后八位的地址
举个例子:
eax:
44444444 33333333 22222222 1111111
此时al:11111111
shr eax,8
eax:
00000000 44444444 33333333 22222222
al:22222222
然后从扇区读取数据
ds:[bx]对应的地址 0:0x900
一次读取2个字节
176

被折叠的 条评论
为什么被折叠?



