linux-0.11引导启动程序笔记

linux-0.11 的最开始的代码是启动区代码,放在 bootsect.s 文件中。

//代码用到的宏

BOOTSEG  = 0x07c0; original address of boot-sector

INITSEG  = 0x9000; we move boot here - out of the way

SETUPLEN = 4 ; nr of setup-sectors

//entry指定汇编指令入口地点,相当于 C语言中的main函数

entry start

start:

movax,#BOOTSEG //BOOTSEG = 0x07c0

movds,ax

//以上两段代码将 ds 寄存器中的值变为0x07c0,此后数据段基址为0x07c0

movax,#INITSEG //INITSEG = 0x9000

moves,ax //es = 0x9000

movcx,#256

subsi,si //源变址寄存器清零

subdi,di //目的变址寄存器清零

//rep表示重复执行下一条指令 n 次,ncx 寄存器的值

rep

//movw:将dssi的内容复制到esdi,复制过去,原来的代码还在。rep 加上 movw 的使用方法据说是一种古老的汇编语法。

movw

//于是启动区代码被复制到了0x90000位置

jmpigo,INITSEG //跳转到0x9000:go处执行,go的地址取决于编译器。

//go标签处初始化了一些寄存器:ds, es , ss , sp ,

go:movax,cs

movds,ax //ds = 0x9000

moves,ax //es = 0x9000

; put stack at 0x9ff00.

movss,ax //ss = 0x9000

//sp指向0x9ff00

movsp,#0xFF00; arbitrary value >>512

; load the setup-sectors directly after the bootblock.

; Note that 'es' is already set up.

/*load_setup利用 BIOS 中断 INT 0x13 setup 模块从磁盘第二个扇区开始读到0x90200开始处,共读 4 个扇区。读出错,则复位驱动器并重试。INT 0x13的使用方法如下:

读扇区:

ah = 0x02 表示读磁盘扇区到内存,al = 需要读出的扇区数量

ch = 磁道(柱面)号的低 8 位,cl = 开始扇区(0-5位),磁道号高 2

dh = 磁头号,dl = 驱动器号(如果是硬盘则位 7 要置位)

es:bx 指向数据缓冲区。如果出错 CF 标志位置位。

*/

//硬件部分目前对我来说还是黑盒,如果后续有了解的话,会更新在5.9版本的学习笔记里。

load_setup:

movdx,#0x0000; drive 0, head 0

movcx,#0x0002; sector 2, track 0

movbx,#0x0200; address = 512, in INITSEG

movax,#0x0200+SETUPLEN; service 2, nr of sectors

//以上四行应该是int 0x13的参数

int0x13; read it

//jnc: CF = 0 时跳转,可以看成加法没有进位,减法没有借位时跳转

//中断程序执行完后,没出错 CF = 0 ,跳转到 ok_load_setup

jncok_load_setup; ok - continue

//如果出错,复位硬盘

movdx,#0x0000

movax,#0x0000; reset the diskette

int0x13

jload_setup //跳回load_setup

 

未完待续。。。

load_setup

posted @ 2021-11-23 17:36  一只吃水饺的胡桃夹子  阅读(82)  评论(0编辑  收藏  举报