分享
 
 
 

linux源代码阅读-系统启动bootsect.s

王朝system·作者佚名  2006-01-31
窄屏简体版  字體: |||超大  

系统启动bootsect.S

一般PC在电源一开时,是由内存中地址FFFF:0000开始执行(这个地址一定在ROM BI

OS中,ROM BIOS一般是在FEOOOh到FFFFFh中),而此处的内容则是一个jump指令,jump到另一个位於ROM BIOS中的位置,开始执行一系列的动作,包括了检查RAM,keyboard,显示器,软硬磁盘等等,这些动作是由系统测试代码 (POST,system test code)来执行的,随着制作BIOS厂商的不同而会有些许差异,但都是大同小异,读者可自行观察自家机器开机时,萤幕上所显示的检查讯息。

紧接着系统测试码之后,控制权会转移给ROM中的启动程序(ROM bootstrap routine),这个程序会将磁盘上的第零轨第零扇区读入内存中(这就是一般所谓的boot sector,如果你曾接触过电脑病毒,就大概听过它的大名),至於被读到内存的哪里呢? --绝对位置07C0:0000(即07C00h处),这是IBM系列PC的特性。而位在linux开机磁盘的boot sector上的正是linux的bootsect程序,也就是说,bootsect是第一个被读入内存中并执行的程序。现在,我们可以开始来看看到底bootsect做了什么。

第一步

首先,bootsect将它"自己"从被ROM BIOS载入的绝对地址0x7C00处搬到0x90000处,

然后利用一个jmpi(jump indirectly)的指令,跳到新位置的jmpi的下一行去执行,

movw $BOOTSEG, %ax #$BOOTSEG = 0x07C0

movw %ax, %ds

movw $INITSEG, %ax #$INITSEG = DEF_INITSEG=0x0x9000

movw %ax, %es

movw $256, %cx #256word s== 512bytes

subw %si, %si

subw %di, %di

cld

rep

movsw

ljmp $INITSEG, $go

第二步

接着,将其他segment registers包括DS,ES,SS都指向0x9000这个位置,与CS看齐

。另外将SP及DX指向一任意位移地址( offset ),这个地址等一下会用来存放磁盘参数

表(disk para- meter table )

go: movw $0x4000-12, %di # 0x4000 is an arbitrary value >=

# length of bootsect + length of

# setup + room for stack;

# 12 is disk parm size.

movw %ax, %ds # ax and es already contain INITSEG

movw %ax, %ss

movw %di, %sp # put stack at INITSEG:0x4000-12.sp=0x94000-12,12byte放磁盘参数

第三步

接着利用BIOS中断服务int 13h的第0号功能,重置磁盘控制器,使得刚才的设定发

挥功能。主要是为了一次读扇区数目增加,增加效率。

# Many BIOS's default disk parameter tables will not recognize

# multi-sector reads beyond the maximum sector number specified

# in the default diskette parameter tables - this may mean 7

# sectors in some cases.

#

# Since single sector reads are slow and out of the question,

# we must take care of this by creating new parameter tables

# (for the first disk) in RAM. We will set the maximum sector

# count to 36 - the most we will encounter on an ED 2.88.

#

# High doesn't hurt. Low does.

#

# Segments are as follows: ds = es = ss = cs = INITSEG, fs = 0,

# and gs is unused.

movw %cx, %fs # set fs to 0

movw $0x78, %bx # fs:bx is parameter table address,磁盘参数已经由BIOS读到这个地址了,就是物理地址0x78

pushw %ds

ldsw %fs:(%bx), %si # ds:si is source ds:si==0x0000:0x78

movb $6, %cl # copy 12 bytes

pushw %di # di = 0x4000-12.

rep # don't need cld -> done on line 66

movsw #ds:si--àes:di

popw %di

popw %ds

movb $36, 0x4(%di) # patch sector count,用36重置

movw %di, %fs:(%bx)

movw %es, %fs:2(%bx)

xorb %ah, %ah # reset FDC

xorb %dl, %dl

int $0x13

第四步

完成重置磁盘控制器之后,bootsect就从磁盘上读入紧邻着bootsect的setup程序,

也就是setup.S,此读入动作是利用BIOS中断服务int 13h的第2号功能。setup的image将

会读入至程序所指定的内存绝对地址0x90200处,也就是在内存中紧邻着bootsect 所在

的位置。待setup的image读入内存后,利用BIOS中断服务int 13h的第2号功能读取目前

磁盘的参数。

xorw %dx, %dx # drive 0, head 0

movb $0x02, %cl # sector 2, track 0

movw $0x0200, %bx # address = 512, in INITSEG ,0x90200

movb $0x02, %ah # service 2, "read sector(s)"

movb setup_sects, %al # (assume all on head 0, track 0) setup_sects=4,读取的扇区数

int $0x13 # read it,setup.S位于内存物理地址0x90200,

jnc ok_load_setup # ok – continue

#读盘错误处理

pushw %ax # dump error code 出错处理,ax得到错误码

call print_nl

movw %sp, %bp

call print_hex

popw %ax

jmp load_setup

ok_load_setup:

# Get disk drive parameters, specifically number of sectors/track.

# It seems that there is no BIOS call to get the number of sectors.

# Guess 36 sectors if sector 36 can be read, 18 sectors if sector 18

# can be read, 15 if sector 15 can be read. Otherwise guess 9.

movw $disksizes, %si # table of sizes to try 在文件末尾定义了数据disksizes: .byte 36, 18, 15, 9

probe_loop:

lodsb #(AL)<-((SI)),(SI)<-(SI)+1

cbtw # extend to word,al->ax

movw %ax, sectors #sectors: .word 0

cmpw $disksizes+4, %si

jae got_sectors #jae不低于,或者高于或者等于,或进位位为0则转移If all else fails, try 9。就是36,18,15,9都测试过了,就跳到got_sectors

xchgw %cx, %ax # cx = track and sector

xorw %dx, %dx # drive 0, head 0

xorb %bl, %bl

movb setup_sects, %bh

incb %bh

shlb %bh # address after setup (es = cs)

movw $0x0201, %ax # service 2, 1 sector

int $0x13

jc probe_loop # try next value,就是从0头,0磁道,读取第36,18,15号扇区,看能否成功,如果成功就跳到got_sectors,否则就再测试下一个数。把内容读到setup.S后面的内存中,这些扇区内容没有什么意义,只是为了测试sectors/track。

第五步

再来,就要读入真正linux的kernel了,也就是你可以在linux的根目录下看到的"v

mlinuz" 。在读入前,将会先呼叫BIOS中断服务int 10h 的第3号功能,读取游标位置,

之后再呼叫BIOS 中断服务int 10h的第13h号功能,在萤幕上输出字串"Loading",这个

字串在boot linux时都会首先被看到,相信大家应该觉得很眼熟吧。

got_sectors:

movw $INITSEG, %ax

movw %ax, %es # set up es

movb $0x03, %ah # read cursor pos

xorb %bh, %bh

int $0x10 #调用10号中断,功能3,读取光标的位置

movw $9, %cx

movw $0x0007, %bx # page 0, attribute 7 (normal)

movw $msg1, %bp

movw $0x1301, %ax # write string, move cursor

int $0x10 # tell the user we're loading..在光标处打印msg1的内容,msg1=’loading…..’;

movw $SYSSEG, %ax # ok, we've written the message, now ,$SYSSEG=0x1000

movw %ax, %es # we want to load system (at 0x10000)

call read_it #读取vmlinux到0x10000,大小为0x7f00,会已最快的速度去读,方法就是用前面测试的sectors/track,一次读完整个磁道。

call kill_motor

call print_nl

第六步

接下来做的事是检查root device,之后就仿照一开始的方法,利用indirect jump

跳至刚刚已读入的setup部份

# After that we check which root-device to use. If the device is

# defined (!= 0), nothing is done and the given device is used.

# Otherwise, one of /dev/fd0H2880 (2,32) or /dev/PS0 (2,28) or /dev/at0 (2,8)

# depending on the number of sectors we pretend to know we have.

movw root_dev, %ax

orw %ax, %ax

jne root_defined

movw sectors, %bx

movw $0x0208, %ax # /dev/ps0 - 1.2Mb

cmpw $15, %bx

je root_defined

movb $0x1c, %al # /dev/PS0 - 1.44Mb

cmpw $18, %bx

je root_defined

movb $0x20, %al # /dev/fd0H2880 - 2.88Mb

cmpw $36, %bx

je root_defined

movb $0, %al # /dev/fd0 - autodetect

root_defined:

movw %ax, root_dev

# After that (everything loaded), we jump to the setup-routine

# loaded directly after the bootblock:

ljmp $SETUPSEG, $0 #jmp to 0x90200

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有