BIOS
检测,初始化硬件。挑一些重要的,能保证计算机能运行那些硬件的基本IO操作。
唤醒BIOS
唤醒BIOS需要知道其入口地址,在最后将跳转到0x7c00处
接电的一瞬间,cs:ip寄存器被初始化为0xF000:0xFFF0,所以等效地址是0xFFFF0(BIOS入口地址)
抓一张bochs图来分析
- 第一个框:cs值(段基址)为0xf000,ip值(段内偏移地址)为0xfff0,组合出的地址是0xffff0(BIOS入口地址)
- 第二个框:在内存0xffff0地址处是一条跳转指令,cpu根据该指令跳转至0xfe05b处(BIOS真正的地方)
- 第三个框:接电强制将cs置为0xf000
MBR
BIOS最后的工作就是检验0盘0道1扇区的内容,因为mbr要离BIOS最近,
在检验过程中,若BIOS检验出该磁盘末尾两个字节是0x55和0xaa则认定其为MBR,便加载到物理地址0x7c00,然后跳转过去,即可开始执行MBR。
- MBR大小为512字节
- 第511以及512字节必须是0xaa,0x55,这是由于咱们模拟的是x86平台,所以采用小端序
编写MBR
;主引导程序
;----------------------------
SECTION MBR vstart=0x7c00 ;起始地址为0x7c00
mov ax,cs
mov ds,ax ;由于BIOS通过 0:0x7c00跳转MBR,所以此时cs为0,因此借他来初始化寄存器
mov es,ax
mov ss,ax
mov fs,ax
mov sp,0x7c00
;清屏利用0x06号子功能,上卷全部行,则可清屏
;------------------------
;INT 0x10 功能号:0x06 功能:上卷窗口
;------------------------
;输入:
;AH 功能号:0x06
;AL = 上卷行数(若为0则表示全部行,太适合我们辣)
;BH = 上卷行属性
;(CL,CH) = 窗口左上角的(X,Y)位置
;(DL,DH) = 窗口右下角的(X,Y)位置
;无返回值
mov ax,0x600
mov bx,0x700
mov cx,0
mov dx,0x184f
int 0x10
;;;;;;;;;;;下面三行获取光标位置 ;;;;;;;;;;;
;.get_cursor获取当前光标位置,并在光标位置打印字符
mov ah,3
mov bh,0
int 0x10
;;;;;;;;;;;获取光标位置结束 ;;;;;;;;;;;
;;;;;;;;;;;打印字符串 ;;;;;;;;;;;
;还是用10h中断,不过这次调用13号子功能打印字符串
mov ax,message
mov bp,ax ;es:bp为串首地址,es此时同cs一致
;开头时已经为sreg初始化
;光标位置要用到dx寄存器中内容,cx中的光标位置可hulue
mov cx,5
mov ax,0x1301
mov bx,0x2
int 0x10
;;;;;;;;;;;; 打印字符串结束 ;;;;;;;;;;;;;;;
jmp $
message db "1 MBR"
times 510-($-$$) db 0
db 0x55,0xaa
- 4~8行:
运行结果
CMD
mkdir OS
cd OS
vim mbr.S
nasm -I include/ -o loader.bin loader.S
sudo dd if=./mbr.bin of=/usr/local/hd60M.img bs=512 count=1 conv=notrunc
cd /usr/local
sudo bin/bochs -f bochsrc.disk