*/-->
pre.src {background-color: Black; color: White;}
bootsect
全局变量
SYSSIZE = 0x3000 # nr of clicks (16 bytes) to be loaded. 0x3000 is 0x30000 bytes = 196kB
SETUPLEN = 4 # nr of setup-sectors setup.s
SETUPSEG = 0x9020 # setup starts here setup.s
BOOTSEG = 0x07c0 # original address of boot-sector bootsect 一开始的位置
INITSEG = 0x9000 # we move boot here - out of the way bootsect 后来的位置
SYSSEG = 0x1000 # system loaded at 0x10000 (65536) kernel 被加载的位置
ENDSEG = SYSSEG + SYSSIZE # where to stop loading kernel 的终止位置
ROOTDEV = 0x306 # 根文件系统设备 设置为第二个硬盘第一个分区
为什么要移动 bootsect.s 到别的地方:因为加载 bootsect.s 后,BIOS 还会继续提取 系统数据,如果不移动会覆盖 bootsect 所在的部分区域
实模式下的内存规划
bootsect 要完成的功能有:
- 复制自己 bootsect.s 的内容从 0x07C00 到 0x9000
- 使用 jmpi go, INITSEG 指令,使 CS 指向内存 0x9000 (INITSEG),IP 指向 go 标签对应的指令
- 调整因为复制自己之后,所改变的 ds,ex 寄存器的值
- 在 0x9000 开一个栈,栈底是 0xFF00,也就是 位于 0x9FF00
- 加载 setup
load_setup: mov dx,#0x0000 ! drive 0, head 0 mov cx,#0x0002 ! sector 2, track 0 mov bx,#0x0200 ! address = 512, in INITSEG mov ax,#0x0200+SETUPLEN ! service 2, nr of sectors int 0x13 ! read it jnc ok_load_setup ! ok - continue mov dx,#0x0000 mov ax,#0x0000 ! reset the diskette int 0x13 j load_setup
- 加载 system 模块