免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1235 | 回复: 0
打印 上一主题 下一主题

BOOT0的主要代码兼Unix下汇编小节 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-10-24 16:24 |只看该作者 |倒序浏览
Boot0的主要作用:

书上说得比较多了,大致的作用就跟MBR差不多,系统安装的时候把它放到硬盘的主引导记录当中,提供一个简单的多操作系统引导功能。如果选择启动FreeBSD,它会在对应的分区里面读“分区引导记录”,也就是Boot1,然后经由Boot1来引导BTX,boot2.bin,最终加载内核。

boot0.s是boot0的源代码,存在两个版本,一个大小是512K,占用一个扇区,还有一个是1024K,占用两个扇区,这两个文件分别是boot0.s,boot0ext.s,存放的目录是:

/usr/src/sys/boot/i386/boot0/boot0.s
在boot0.s这个源文件中采用的是AT&T的汇编语言语法格式,在指令上和windows环境下的汇编语言格式略有不同。
一、读这个代码的预备知识:根据PC机的体系结构,硬件启动的最后一个步骤是读取硬盘上的主引导记录,放到内存:0x0000:0x7c00这个地址,一个jmp跳转指令来执行主引导记录的第一条指令。
二、主要的代码:
boot0.s的主要工作流程是
1、代码搬移,从0x7c00这个地址挪到另外一个地址,主要是为了给后续读取分区引导记录boot1腾出空间。
2、扫描分区表,扫描引导扇区有效标志,打印多系统引导界面。
3、根据选择,读取相应分区的分区引导记录
4、出错处理
主要的代码:
1、变量定义:
        .set ORIGIN,0x600        # Execution address
        .set FAKE,0x800         # Partition entry
        .set LOAD,0x7c00        # Load address
        .set PRT_OFF,0x1be        # Partition table
        .set TBL0SZ,0x3         # Table 0 size
        .set TBL1SZ,0xb         # Table 1 size
        .set MAGIC,0xaa55        # Magic: bootable
        .set B0MAGIC,0xbb66        # Identification
        .set KEY_ENTER,0x1c        # Enter key scan code
        .set KEY_F1,0x3b        # F1 key scan code
        .set KEY_1,0x02            # #1 key scan code
        .set ASCII_BEL,0x07        # ASCII code for BEL>
        .set ASCII_CR,0x0D        # ASCII code for CR>
符号常量定义形式:
.set 符号常量,值 #注释
2、乾坤大挪移
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
/*
* 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
这段代码的作用就是DS:SI内存的数据转移到ES:DI当中,0x200个字节
movw $LOAD,%sp # stack
常量的引用:$常量名  $具体的数值  
寄存器的使用:%寄存器名
指令格式:
操作码 原操作数,目的操作数 #注释
上面那条指令的作用就是把LOAD的值赋给sp寄存器,也就是这段代码运行期间,栈顶是0x7c00,向下增长。不会影响到0x7c00的代码。
movw $start,%di # Destination
start是代码中的标识,实际代表的是代码装载到内存时的地址,因此$start这个引用表示的是地址。
3、中间略去,最后的装载分区引导记录代码:
第312行的main.15
main.15:   
        movw $LOAD,%bx            # Address for read
        movb $0x2,%ah             # Read sector
        callw intx13              # from disk
        jc main.10                # If error
        cmpw $MAGIC,0x1fe(%bx)        # Bootable?
        jne main.10               # No
        movw $crlf,%si            # Leave some
        callw puts                # space
        jmp *%bx                  # Invoke bootstrap
这段代码的作用:使用BIOS系统调用读扇区操作,读取分区引导记录扇区,这里设定是读取FreeBSD分区的分区引导记录boot1,放到DS:BX=0x0000:0x7c00处,如果读取成功,检测读取扇区的最后两个字节,如果成功jmp *%bx
两个寻址方式:
cmpw $MAGIC,0x1fe(%bx)
我的理解是:bx(=0x7c00)+0x1fe   把这个数值作为地址,把这个地址内的数值和$MAGIC对比,也就是检测可引导扇区有效标志。
jmp *%bx
很显然是无条件跳转到0000:0x7c00处,但是这条指令比较难理解,%bx表示寄存器引用,但是寄存器不能作为jmp的操作数,类似于C语言的做法,用到了地址求值,因为bx=0x7c00,我的理解就是“把BX寄存器的值作为操作数,作为跳转地址”——这种写法很类似C语言。
读boot1.s的代码,可知boot1.s汇编之后的二进制代码和BTX、boot2.bin在安装时是存放在FreeBSD可引导“Silce”中的前16个扇区里面,Jmp $0x7c00,就是运行boot1.s,然后加载BTX,然后运行boot2.c里面的程序,实现内核加载。



本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/12258/showart_189716.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP