免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1338 | 回复: 0

MINIX引导过程分析(二) [复制链接]

论坛徽章:
0
发表于 2007-03-15 18:12 |显示全部楼层
PC加电自检完成后,会自动在磁盘第一个扇区的最后两个字节查找是否存在标识数0xAA55。如果存在,BIOS会将该扇区加载到内存的0x7C00处,并执行其代码。

masterboot.s文件存放在源代码树的boot目录中,其编译好的二进制代码会被放置在硬盘的MBR中,在系统引导时执行以下操作:如果是通过硬盘引导,且该硬盘的一个分区被设置成为活动分区,则从该活动分区引导;否则,查找下一块硬盘,直到成功。对该文件的源代码分析如下:

    LOADOFF    =    0x7C00    ! 本段代码被加载的地址
    BUFFER    =    0x0600    ! 第一块空闲内存空间
    PART_TABLE    =     446    ! 分区表位置
    PENTRYSIZE    =     16    ! 分区表项大小
    MAGIC    =     510    ! 标识数0xAA55的位置
    bootind    =     0
    sysind    =     4
    lowsec    =     8
.text
! 寻找活动分区,载入其第一个分区并运行之
master:
    ! 将ax、ds、es、ss置0,将LOADOFF载入sp
    xor    ax, ax
    mov    ds, ax
    mov    es, ax
    cli                ! 关中断
    mov    ss, ax
    mov    sp, #LOADOFF
    sti                ! 开中断
    ! 将从ds:si(0x0000:0x7C00)开始的512个字节拷贝到es:di(0x0000:0x0600)
    mov    si, sp            ! 将0x7C00装入si
    push    si            ! 将si(即0x7C00)压栈
    mov    di, #BUFFER
    mov    cx, #512/2
    cld
    rep    movs
    jmpf    BUFFER+migrate, 0        ! 远跳转到拷贝后的migrate处开始执行
migrate:
    ! 查找活动分区
findactive:
    testb    dl, dl            ! 如果dl最高位为0(即不存在引导分区)
    jns    nextdisk            ! 则跳转到nextdisk
    mov    si, #BUFFER+PART_TABLE        ! 将分区表地址保存到si中
find:    cmpb    sysind(si), #0        ! 如果该分区未使用则跳转到nextpart
    jz    nextpart
    testb    bootind(si), #0x80        ! 如果不是引导分区则跳转到nextpart
    jz    nextpart
loadpart:
    call    load            ! 载入bootstrap
    jc    error1            ! 错误处理
bootstrap:
    ret                ! 跳转到载入的bootstrap执行
nextpart:
    ! 检查下一个分区,如果不存在引导分区则显示错误信息并跳转到reboot
    add    si, #PENTRYSIZE
    cmp    si, #BUFFER+PART_TABLE+4*PENTRYSIZE
    jb    find
    call    print
    .ascii    "No active partition\0"
    jmp    reboot
    ! 该磁盘上没有活动分区,查找下一块磁盘
nextdisk:    incb    dl
    testb    dl, dl
    js    nexthd            ! dl最高位为1(为硬盘)则跳转到nexthd
    int    0x11            ! 将软驱数量保存到ah中
    shl    ax, #1
    shl    ax, #1
    andb    ah, #0x03
    cmpb    dl, ah            ! 如果dl大于ah则跳转到nextdisk
    ja    nextdisk
    call    load0            ! 尝试读取bootstrap
    jc    nextdisk            ! CF=1(即读取失败)则跳转到nextdisk
    ret                ! 返回程序开始处执行
nexthd:    call    load0            ! 读取硬盘的bootstrap
error1:    jc    error            ! 错误处理
    ret
    ! 从第一个扇区中读取bootstrap
load0:
    mov    si, #BUFFER+zero-lowsec
load:
    mov    di, #3        ! 进行三次尝试
retry:    push    dx
    push    es
    push    di
    movb    ah, #0x08        ! 读取dl(最高位为1表示为硬盘)指定的磁盘的参数
    int    0x13
    pop    di
    pop    es
    andb    cl, #0x3F        ! 在cl中保存每磁道扇区数
    incb    dh        ! 在dh中保存每柱面磁头数
    movb    al, cl
    mulb    dh        ! 在bx中保存每柱面扇区数(磁头数*扇区数)
    mov    bx, ax
    mov    ax, lowsec+0(si)    ! 在dx:ax中保存磁盘的总扇区数(即地址为zero的变量)
    mov    dx, lowsec+2(si)
    cmp    dx, #[1024*255*63-255]>>16    ! 如果分区超过8G则跳转到bigdisk
    jae    bigdisk
    %3


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

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP