简介
假高大上,所谓突破512字节,就是读取硬盘,然后跳到第二块扇间
- 第一个扇区是boot
- 读取硬盘
- 第二个扇区我们写setup(用户读取硬盘,启动保护模式,跳转到内核kernel)
- 写入镜像文件,就结束了
问题:既然要做第二个扇区,我们应该思考,扇区加载到哪块内存
有两个地方可以选择,0x7e00和0x500 这个两个地方
哪选哪个呢
随便,博主也不知道选哪个,如果有大佬知道,欢迎指导
不说废话,上代码
[org 0x7c00]
[SECTION .DATA]
BOOT_MAIN_ADDR EQU 0x500
[SECTION .TEXT]
[BITS 16]
global _start
call clear_screen
_start:
```
mov ax,0
mov ss,ax
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov si,ax
;清屏
mov ax,3
int 10h
mov si,jmp_to_setup
call print
call read_fd
jmp BOOT_MAIN_ADDR
jmp $
clear_screen:
mov ax,3
int 10h
print:
mov ah,0x0e
mov bh,0
mov bl,0x10
.loop:
mov al,[si]
cmp al,0
jz .done
int 10h
inc si
jmp .loop
.done:
ret
read_fd:
xor ax,ax
xor dx,dx
mov dx,0x1f2
mov al,1
out dx,al
;0x1f3
inc dx
mov al,2
out dx,al
;0x1f4
inc dx
mov al,0
out dx,al
;0x1f5
inc dx
mov al,0
out dx,al
;0x1f6
inc dx
and al,0b11100000
out dx,al
;0x1f7
inc dx
mov al,0x20
out dx,al
.read_check:
nop
mov dx,0x1f7
in al,dx
and al,0x88
cmp al,0x08
jnz .read_check
mov dx,0x1f0
mov ecx,256
;硬盘的数据加载到BOOT_MAIN_ADDR
mov edi,BOOT_MAIN_ADDR
.read_data:
in ax,dx
mov [edi],ax
add edi,2
loop .read_data
ret
jmp_to_setup:
db "jump to setup...",10,13,0
times 510-($-$$) db 0
dw 0xaa55
-
0x1f0 读写数据的位置
-
0x1f1 错误信息的位置
-
0x1f2 读取几个扇间
-
0x1f3 读取硬盘起始地址的low 8位
-
0x1f4 读取硬盘起始地址的mid 8位
-
0x1f5 读取硬盘起始地址的hid 8位
解析 0x1f6 1110 0000
- 第七位和第五位固定 1
- 第六位是chs还是lba读取方式 0就是chs读取 1就是lba读取
- 第四位是主盘还是从盘
- 0-3位是读取硬盘起始24-27位
问题:
我要从第5块扇间开始读取,连续读取2块
- 读取两块 解析成汇编 mov al,0x1f2
- 从第五块开始读取 0000000000000000000000000101
5的28位地址
- 0x1f3 00000101
- 0x1f4 00000000
- 0x1f5 00000000
- 0x1f6 1110 0000
0x1f7 mov al 0x20
检测
read_check:
in ax,dx
and al,0x88
cmp al,0x08
jnz read_check
读取到内存哪里 mov edi,boot_main_start
清空ecx,要不然容易读取很大
xor ecx,ecx
读取多少次2B
mov ecx,256
read_data:
in ax,dx
mov [edi],ax
add edi,2
loop .read_data
ret
问题: and al,0b11100000 这里很奇怪