Linux0.11内核--引导程序分析

1.简介

本文主要介绍三个文件bootsect.s、setup.s、head.s,主要是做了些从软盘加载内核和设置32位保护模式的操作。

2.程序分析

当PC电源打开后,BIOS自检后将bootsect读入内存绝对地址0x7c00处,因为bootsect.s的结尾是:

1
.word 0xAA55

然后跳转到0x7c00处并把执行权交给此处的代码,从start:处开始执行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
BOOTSEG  = 0x07c0  
INITSEG  = 0x9000
 
start:
     mov ax,#BOOTSEG
     mov ds,ax
     mov ax,#INITSEG
     mov es,ax
     mov cx,#256
     sub si,si
     sub di,di
     rep
     movw
     jmpi    go,INITSEG

BOOTSEG是当前程序的起始内存地址的段地址,INITSEG表示是bootsect将要移动要的内存地址的段地址,这段代码的意思是重复执行movw指令256次,每次从BOOTSEG(0x7c0段地址)+si的地址处移动一个字(2个字节)的数据到INITSEG(0x9000段地址)+di地址处,挨个移动256次,所以总共就是256字(512字节),bootsect.s编译出来也就是512字节的大小。所以这段代码执行完之后就是把自己拷贝到0x90000地址处,然后jmpi跳转到0x9000的偏移地址为go的地方执行。

所以接下来程序执行到go:处,但是整个程序的起始段地址变成了0x9000,go处的代码设置了下堆栈,接着是load_setup:

1
2
3
4
5
6
7
8
9
10
11
12
13
SETUPLEN = 4   
 
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

利用BIOS中断int 0x13将setup从磁盘第2个扇区开始读到0x90200开始处,共SETUPLEN(setup 程序的扇区数)读4个扇区。成功后跳转到ok_load_setup。

1
2
3
4
5
6
7
8
9
10
11
SETUPSEG = 0x9020
 
ok_load_setup:
...
     mov ax,#SYSSEG
     mov es,ax       ! segment of 0x010000
     call    read_it
     call    kill_motor
 
...
     jmpi    0,SETUPSEG

省略的代码都是一些读硬盘和驱动器的数据。这里比较关键的是call read_it,调用read_it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
SYSSIZE = 0x3000
SYSSEG   = 0x1000
ENDSEG   = SYSSEG + SYSSIZE
 
read_it:
     mov ax,es
     test ax,#0x0fff
die:    jne die         ! es must be at 64kB boundary
     xor bx,bx       ! bx is starting address within segment
rp_read:
     mov ax,es
     cmp ax,#ENDSEG      ! have we loaded all yet?
     jb ok1_read
     ret
ok1_read:
     ...

SYSSIZE是编译后system模块的大小,SYSSEG是system模块将加载到的内存段地址处,所以ENDSEG的值就是system模块停止加载的段地址。那么read_it的作用就是先判断一下es是不是到了system模块停止加载的段地址处,如果没有则跳转去读取system模块到这个地址。加载完成后就ret返回。然后关闭马达后读一些驱动器的信息,最后jmpi 0,SETUPSEG跳转到0x9020:0000也就是setup.s程序的开始处。

bootsect.s就此结束,到现在为止内核各个模块在内存中的位置如下图的第3步:

接下来进入setup.s。

未完待续

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值