现在的位置: 首页 >> 操作系统 >> FreeBSD >> FreeBSD 5.2.1 boot0(启动扇区代码分析)
添加时间:2005-8-21 来源:网教中国 作者:
FreeBSD 5.2.1 boot0(启动扇区代码分析)


.set _FAKE,0x0 # Fake partition entry
.set _MNUOPT,0xc # Menu options


以上是定义相关的参数值,例如“.set NHRDRV,0x475”类似于C语言中的“#define NHRDRV 0x475”

.globl start # Entry point
.code16 # This runs in real mode

#
# Initialise segments and registers to known values.
# segments start at 0.
# The stack is immediately below the address we were loaded to.
#
start:
cld # String ops inc
xorw %ax,%ax # Zero
movw %ax,%es # Address
movw %ax,%ds # data
movw %ax,%ss # Set up
movw $LOAD,%sp # stack


以上代码:
1)首先使用“cld”指令清除方向标志,使得以下的进行“rep”操作时SI和DI的值递增。
2)使ax清零,并使除代码段cs外的另外两个数据段寄存器es、ds和堆栈段ss清零。当然,此时cs
由于reset或初始上电已经为零了。
3)BIOS已经把引导扇区的512字节的内容读入到了0:0x7c00处,movw $LOAD,%sp 使得堆栈指针指向扇区
代码(或曰本段代码 0:0x7c00)的顶部。虽然堆栈向下生长可能会影响代码的内容,但下面我
们马上就把位于0:7c00处代码移到其他地方去执行。


#
# Copy this code to the address it was linked for
#
movw %sp,%si # Source
movw $start,%di # Destination
movw $0x100,%cx # Word count
rep # Relocate
movsw # code

把位于0:7c00处的代码搬移到0:0x600处。注意,此时由于代码连接的重定向,$start=0x600。

#
# Set address for variable space beyond code, and clear it.
# Notice that this is also used to point to the values embedded in the block,
# by using negative offsets.
movw %di,%bp # Address variables
movb $0x8,%cl # Words to clear
rep # Zero
stosw # them

通过以上一段代码的执行,本代码已被搬移到0:0x600处,此时si=di=0x600+0x100, 以上代码
把di的值保存到bp,bp此时指向本程序搬移后的未用的空间的首部,且把此bp所指的16字节空间
清零。以上过程如下图所示:

┏>0:0x600 ┏━━━━━┓
┃ ┃ ┃
┃ ┃ 搬 ┃
┃ ┃ 移 ┃
┃ ┃ 之 ┃
┃ ┃ 后 ┃
┃ ┃ 的 ┃
┃ ┃ 代 ┃
┃ ┃ 码 ┃
┃ ┃ ┃
┃ 0:0x7ff ┣━━━━━┫
┃ ┃ 0 ┃<-bp指向这里(0:0x800), 以此开始的16字节被清零。
┃ ┣━━━━━┫以下所称的fake partition entry就是指这里。
┃ ┃ 0 ┃
┃ ┣━━━━━┫
┃ ┃ 0 ┃
┃ ┣━━━━━┫
┃ ┃ 0 ┃
┃ ┣━━━━━┫
┃ ┃ 0 ┃
┃ ┣━━━━━┫
┃ ┃ 0 ┃
┃ ┣━━━━━┫
┃ ┃ 0 ┃
┃ ┣━━━━━┫
┃ ┃ 0 ┃
┃ ┣━━━━━┫
┃ ┃ 0 ┃
┃ ┣━━━━━┫
┃ ┃ 0 ┃
┃ ┣━━━━━┫
┃ ┃ 0 ┃
┃ ┣━━━━━┫
┃ ┃ 0 ┃
┃ ┣━━━━━┫
┃ ┃ 0 ┃
┃ ┣━━━━━┫
┃ ┃ 0 ┃
┃ ┣━━━━━┫
┃ ┃ 0 ┃
┃ ┣━━━━━┫
┃ ┃ 0 ┃
┃ ┗━━━━━┛
0:0x7c00 ┏━━━━━┓ ┛
┃ ┃
┃ 搬 ┃
┃ 移 ┃
┃ 之 ┃
┃ 前 ┃
┃ 的 ┃
┃ 代 ┃
┃ 码 ┃
┃ ┃
0:0x7dff ┗━━━━━┛

图(二)
#
# Relocate to the new copy of the code.
#
incb -0xe(%di) # Sector number
jmp main-LOAD+ORIGIN # To relocated code

把以上清零的16字节的第二个字节置为1,表示我们已经读取了一个分区。然后跳转到搬
移之后的新代码的main处执行。

#
# Check what flags were loaded with us, specifically, Use a predefined Drive.
# If what the bios gives us is bad, use the '0' in the block instead, as well.
#
main:
testb $0x20,_FLAGS(%bp) # Set number drive?
jnz main.1 # Yes
testb %dl,%dl # Drive number valid?
js main.2 # Possibly (0x80 set)
main.1:
movb _SETDRV(%bp),%dl # Drive number to use
上面说过,BIOS把磁盘的引导扇区读入到内存之后,其dl的内容表示启动设备,但我们 安装好FreeBSD
之后,我们可以改变此引导扇区的内容,其中的一个改变就是可以使我们可以“手动指定”我们实际安
装FreeBSD的分区,如果我们希望指定FreeBSD所在的boot分区,那么我们在bp-0x45处的位置
(即_FLAGS(%bp)处)的bit 0x20置1,那么上面的“movb _SETDRV(%bp),%dl”一句中movb
_SETDRV(%bp),%dl(即bp-0x46)即指向我们“手动指定”FreeBSD所在分区 代码,例如,IDE的C、D
盘(严格来说是第一个物理磁 盘的第一个和第二个分区)的代码分别为 0x80和0x81。如果没有“手动指
定”启动分区,那么,我们 缺省使用机器当前启动的分区,上面说过,机器当前启动的分区代码放在dl中。

因为FreeBSD Boot Manager 不可能安装到软盘(如果从软盘启动则dl为0),所以,使用testb %dl,%dl
来判断驱动器代码是否合法(volid)。

有关_FLAGS(%bp)中其他bit位表示的意义,在随后的代码分析中慢慢给你道来。

#
# Whatever we decided to use, now store it into the fake
# partition entry that lives in the data space above us.
#
main.2:
movb %dl,_FAKE(%bp) # Save drive number
callw putn # To new line
pushw %dx # Save drive number

以上第一句把FreeBSD启动分区的代码保存到_FAKE(%bp)(bp-0)处,也就是说,上图(二)的bp
处保存的是FreeBSD启动分区的代码(_FAKE=0)。

“callw putn”一句在屏幕上打印“回车”和“换行”,“pushw %dx”一句把启动分区
的值压入堆栈。
#
# Start out with a pointer to the 4th byte of the first table entry
# so that after 4 iterations it's beyond the end of the sector.
# and beyond a 256 byte boundary and has overflowed 8 bits (see next comment).
# (remember that the table starts 2 bytes earlier than you would expect
# as the bootable flag is after it in the block)
#
movw $(partbl+0x4),%bx # Partition table (+4)
xorw %dx,%dx # Item number

以上代码首先把%bx指向分区表partbl的的第四个字节,这里存放的是分区类型,如82表示
Linux Native分区83表示Linux Swap 分区,有关分区表的细节请详见本文的尾部。然后dx清零 ,
此后,dx将作为遍历磁盘分区的列举代号使用。 启动分区代码dl的原来的值在上面已经压入
了堆栈保存。

#
# Loop around on the partition table, printing values until we
# pass a 256 byte boundary. The end of

上一页 [1] [2] [3] [4] [5] [6]  下一页


上一篇:网桥原理及源代码详解 下一篇:FreeBSD中的设备命名规则
大部分文章摘自网上,如有侵犯您的权益请与我们联系,我们会第一时间进行处理,谢谢! [ 打印文章 ] [ 关闭窗口 ]
推荐文章
·FreeBSD handbook中文版 9 配制F
·FreeBSD 升级系统
·Ports & Package
·FreeBSD kernel 编译大法(二)ker
·FreeBSD 上使用Kerberos 5认证
·FreeBSD 5.x 中 gbfs 的修正,及
·FreeBSD 安装Linuxigd
·FreeBSD 使用cvsd创建安全的cvs
·FreeBSD trafcount命令介绍
·FreeBSD入门安装及汉化
相关文章
 
最新文章
·FreeBSD连载(94):基于NAT的负载
·FreeBSD连载(93):反向代理负载
·FreeBSD连载(92):基于DNS的负载
·FreeBSD连载(91):提升静态网页
·FreeBSD连载(90):单服务器性能
·FreeBSD连载(89):CGI和SSI的安
·FreeBSD连载(88):安全连接方式S
·FreeBSD连载(87):基于用户的访
·FreeBSD连载(86):对IP地址和域
·FreeBSD连载(85):配置Apache服(
Google