亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 2454 | 回復: 0
打印 上一主題 下一主題

FreeBSD7.0 /sys/boot/i386/mbr/mbr.s源代碼分析 [復制鏈接]

論壇徽章:
0
跳轉到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2008-06-27 17:06 |只看該作者 |倒序瀏覽
分析數據采集自bochs+FreeBSD7.0環(huán)境,分析過程中參考了Luonix Luo和qiuhanty關于boot0.s的分析文章。

#
# Copyright (c) 1999 Robert Nordier
# All rights reserved.
#
# Redistribution and use in source and binary forms are freely
# permitted provided that the above copyright notice and this
# paragraph and the following disclaimer are duplicated in all
# such forms.
#
# This software is provided "AS IS" and without any express or
# implied warranties, including, without limitation, the implied
# warranties of merchantability and fitness for a particular
# purpose.
#
# $FreeBSD: src/sys/boot/i386/mbr/mbr.s,v 1.7 2004/08/28 08:39:35 yar Exp $
# A 512 byte MBR boot manager that simply boots the active partition.
        .set LOAD,0x7c00 # Load address
        .set EXEC,0x600 # Execution address
        .set PT_OFF,0x1be # Partition table
        .set MAGIC,0xaa55 # Magic: bootable
        .set FL_PACKET,0x80 # Flag: try EDD
        .set NHRDRV,0x475 # Number of hard drives
        .globl start # Entry point
        .code16
#
# Setup the segment registers for flat addressing and setup the stack.
#
                                                    # 在/sys/boot/i386/mbr/Makefile中定義的LDFLAGS包含了
                                                    # "-e start -Ttext ${ORG}",即指定程序入口為"start",
                                                    # 并指定.text section的起始為止在絕對地址ORG處,而ORG
                                                    # 在同一Makefile中被定義為0x600,因此,出現在匯編指令
                                                    # 中的"$start"即表示0x600。這部分引導代碼是被bios加載到
                                                    # 0x7c00的,所以此處"start:"標號對應的"cld"指令的地址
                                                    # 就是0x7c00,這是第一條引導指令。此時,cpu主要寄存器的
                                                    # 內容如下:
                                                    # rax: 0x00000000:0000aa55 rcx: 0x00000000:00000000
                                                    # rdx: 0x00000000:00000080 rbx: 0x00000000:00000000
                                                    # rsp: 0x00000000:0000ffda rbp: 0x00000000:00000000
                                                    # rsi: 0x00000000:ffff0000 rdi: 0x00000000:0008ffac
                                                    # r8 : 0x00000000:00000000 r9 : 0x00000000:00000000
                                                    # r10: 0x00000000:00000000 r11: 0x00000000:00000000
                                                    # r12: 0x00000000:00000000 r13: 0x00000000:00000000
                                                    # r14: 0x00000000:00000000 r15: 0x00000000:00000000
                                                    # rip: 0x00000000:00007c00
                                                    # eflags 0x00000082
start: cld # String ops inc # 保證后續(xù)字符串操作為增向。
        xorw %ax,%ax # Zero
        movw %ax,%es # Address
        movw %ax,%ds # data
        movw %ax,%ss # Set up
        movw $LOAD,%sp # stack # 將ax、es、ds、ss清0,并將sp指向"LOAD",LOAD在本文中被
                                                    # 定義為0x7c00,這是bios加載引導扇區(qū)的地址,也即"start:"
                                                    # 標號處的"cld"指令的地址。此時,cpu主要寄存器的內容如下:
                                                    # rax: 0x00000000:00000000 rcx: 0x00000000:00000000
                                                    # rdx: 0x00000000:00000080 rbx: 0x00000000:00000000
                                                    # rsp: 0x00000000:00007c00 rbp: 0x00000000:00000000
                                                    # rsi: 0x00000000:ffff0000 rdi: 0x00000000:0008ffac
                                                    # r8 : 0x00000000:00000000 r9 : 0x00000000:00000000
                                                    # r10: 0x00000000:00000000 r11: 0x00000000:00000000
                                                    # r12: 0x00000000:00000000 r13: 0x00000000:00000000
                                                    # r14: 0x00000000:00000000 r15: 0x00000000:00000000
                                                    # rip: 0x00000000:00007c0c
                                                    # eflags 0x00000046
#
# Relocate ourself to a lower address so that we are out of the way when
# we load in the bootstrap from the partition to boot.
#
        movw $main-EXEC+LOAD,%si # Source
        movw $main,%di # Destination
        movw $0x200-(main-start),%cx # Byte count
        rep # Relocate
        movsb # code # 由于bios將本段引導代碼的入口加載至0x7c00,而本段代碼鏈接時
                                                    # 指定的絕對入口地址是0x600,因此須將本段代碼拷貝至0x600處才能
                                                    # 正確執(zhí)行后續(xù)與地址相關的指令。下面的jmp指令是在0x7c00區(qū)域
                                                    # 執(zhí)行的最后一條指令,jmp之后就開始在0x600區(qū)域繼續(xù)執(zhí)行新建的
                                                    # 引導代碼復本了,而在0x600區(qū)域執(zhí)行的第一條語句就是"main:"標號
                                                    # 對應的xorw指令,因此0x7c00區(qū)域中從"start:"到"main:"之間的
                                                    # 內容是不用拷貝到0x600的。EXEC在本文件中定義為0x600,這是
                                                    # "start:"標號的鏈接地址,LOAD則是bios對本段引導代碼的初始加載
                                                    # 位置,即0x7c00,因此,main-EXEC+LOAD就是0x7c00加上"main:"距
                                                    # "start:"的偏移,即"xorw %si,%si"指令在0x7c00區(qū)域的地址,引導
                                                    # 代碼的拷貝從這里開始?截惖哪康牡貏t直接使用"main:"標號的鏈接
                                                    # 地址,即"xorw %si,%si"指令在0x600區(qū)域的地址。在計算需要拷貝的
                                                    # 字節(jié)數時需要從引導扇區(qū)尺寸512字節(jié)(0x200)中減去
                                                    # "main:"和"start:" 之間的內容。執(zhí)行實際拷貝指令之前cpu主要
                                                    # 寄存器的內容如下:
                                                    # rax: 0x00000000:00000000 rcx: 0x00000000:000001e6
                                                    # rdx: 0x00000000:00000080 rbx: 0x00000000:00000000
                                                    # rsp: 0x00000000:00007c00 rbp: 0x00000000:00000000
                                                    # rsi: 0x00000000:ffff7c1a rdi: 0x00000000:0008061a
                                                    # r8 : 0x00000000:00000000 r9 : 0x00000000:00000000
                                                    # r10: 0x00000000:00000000 r11: 0x00000000:00000000
                                                    # r12: 0x00000000:00000000 r13: 0x00000000:00000000
                                                    # r14: 0x00000000:00000000 r15: 0x00000000:00000000
                                                    # rip: 0x00000000:00007c15
                                                    # eflags 0x00000046
                                                    # 此時,源地址是0x7c1a,目的地址是0x061a,分別是0x7c00和0x600
                                                    # 偏移0x1a的位置,這正是"main:"和"start:"之間的距離?截愅瓿
                                                    # 之后cpu主要寄存器的內容如下:
                                                    # rax: 0x00000000:00000000 rcx: 0x00000000:00000000
                                                    # rdx: 0x00000000:00000080 rbx: 0x00000000:00000000
                                                    # rsp: 0x00000000:00007c00 rbp: 0x00000000:00000000
                                                    # rsi: 0x00000000:ffff7e00 rdi: 0x00000000:00080800
                                                    # r8 : 0x00000000:00000000 r9 : 0x00000000:00000000
                                                    # r10: 0x00000000:00000000 r11: 0x00000000:00000000
                                                    # r12: 0x00000000:00000000 r13: 0x00000000:00000000
                                                    # r14: 0x00000000:00000000 r15: 0x00000000:00000000
                                                    # rip: 0x00000000:00007c17
                                                    # eflags 0x00000046
#
# Jump to the relocated code.
#
        jmp main-LOAD+EXEC # To relocated code # 跳轉至0x600區(qū)域中"main:"標號對應的指令位置,這是在0x7c00
                                                    # 區(qū)域執(zhí)行的最后一條指令。跳轉完成之后cpu主要寄存器的內容如下:
                                                    # rax: 0x00000000:00000000 rcx: 0x00000000:00000000
                                                    # rdx: 0x00000000:00000080 rbx: 0x00000000:00000000
                                                    # rsp: 0x00000000:00007c00 rbp: 0x00000000:00000000
                                                    # rsi: 0x00000000:ffff7e00 rdi: 0x00000000:00080800
                                                    # r8 : 0x00000000:00000000 r9 : 0x00000000:00000000
                                                    # r10: 0x00000000:00000000 r11: 0x00000000:00000000
                                                    # r12: 0x00000000:00000000 r13: 0x00000000:00000000
                                                    # r14: 0x00000000:00000000 r15: 0x00000000:00000000
                                                    # rip: 0x00000000:0000061a
                                                    # eflags 0x00000046
#
# Scan the partition table looking for an active entry. Note that %ch is
# zero from the repeated string instruction above. We save the offset of
# the active partition in %si and scan the entire table to ensure that only
# one partition is marked active.
#
main: xorw %si,%si # No active partition
        movw $partbl,%bx # Partition table
        movb $0x4,%cl # Number of entries # 首先清除si寄存器。然后將位于本段引導扇區(qū)代碼尾端的分區(qū)表
                                                    # 的地址寫入bx寄存器,將分區(qū)表的條目數寫入cl。此時cpu主要
                                                    # 寄存器的內容如下:
                                                    # rax: 0x00000000:00000000 rcx: 0x00000000:00000004
                                                    # rdx: 0x00000000:00000080 rbx: 0x00000000:000007be
                                                    # rsp: 0x00000000:00007c00 rbp: 0x00000000:00000000
                                                    # rsi: 0x00000000:ffff0000 rdi: 0x00000000:00080800
                                                    # r8 : 0x00000000:00000000 r9 : 0x00000000:00000000
                                                    # r10: 0x00000000:00000000 r11: 0x00000000:00000000
                                                    # r12: 0x00000000:00000000 r13: 0x00000000:00000000
                                                    # r14: 0x00000000:00000000 r15: 0x00000000:00000000
                                                    # rip: 0x00000000:00000621
                                                    # eflags 0x00000046
                                                    # 此處寫入bx的分區(qū)表地址是0x7be,這是距引導扇區(qū)尾端66字節(jié)
                                                    # 的地方,分區(qū)表一共四個條目,因此cl的值是4。每個條目占用
                                                    # 16字節(jié),共64字節(jié),最后的2個字節(jié)是用來存放幻數0xaa55的。
                                                    # 參見本文末尾對"partbl:"的定義。
                                                    # 此時,0x7be之后66個字節(jié)的內容如下:
                                                    # 0x7be : 0x80 0x01 0x01 0x00 0xa5 0x0f 0xff 0xff
                                                    # 0x7c6 : 0x3f 0x00 0x00 0x00 0xa1 0xff 0x7f 0x00
                                                    # 0x7ce : 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
                                                    # 0x7d6 : 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
                                                    # 0x7de : 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
                                                    # 0x7e6 : 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
                                                    # 0x7ee : 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
                                                    # 0x7f6 : 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
                                                    # 0x7fe : 0x55 0xaa
main.1: cmpb %ch,(%bx) # Null entry? # 通過分區(qū)條目第一字節(jié)判斷該分區(qū)是否為活動分區(qū),0x80為是,0為否
        je main.2 # Yes # 此分區(qū)非活動分區(qū),準備查詢下一分區(qū)
        jg err_pt # If 0x1..0x7f # 分區(qū)條目第一字節(jié)的合法值只能是0x80或0,否則報錯
        testw %si,%si # Active already found? # 通過si是否為0判斷是否已找到一個活動分區(qū)
        jnz err_pt # Yes # 只能有一個活動分區(qū),否則報錯
        movw %bx,%si # Point to active # 讓si指向活動分區(qū)表條目
                                                    # 對于示例情況,分區(qū)表第一條目第一字節(jié)為0x80,為活動分區(qū),
                                                    # 因此在這里對si進行設置,此時cpu主要寄存器的內容如下:
                                                    # rax: 0x00000000:00000000 rcx: 0x00000000:00000004
                                                    # rdx: 0x00000000:00000080 rbx: 0x00000000:000007be
                                                    # rsp: 0x00000000:00007c00 rbp: 0x00000000:00000000
                                                    # rsi: 0x00000000:ffff07be rdi: 0x00000000:00080800
                                                    # r8 : 0x00000000:00000000 r9 : 0x00000000:00000000
                                                    # r10: 0x00000000:00000000 r11: 0x00000000:00000000
                                                    # r12: 0x00000000:00000000 r13: 0x00000000:00000000
                                                    # r14: 0x00000000:00000000 r15: 0x00000000:00000000
                                                    # rip: 0x00000000:0000062d
                                                    # eflags 0x00000046
main.2: addb $0x10,%bl # Till # 讓bx指向下一個分區(qū)表條目
        loop main.1 # done # "main.1:"一共執(zhí)行4次,依次分析分區(qū)表中的4個條目
        testw %si,%si # Active found? # 判斷是否找到了一個活動分區(qū)(有多個活動分區(qū)的情況已在前面報錯)
        jnz main.3 # Yes # 找到活動分區(qū)則跳轉至"main.3"
        int $0x18 # BIOS: Diskless boot # 沒有找到活動分區(qū)則嘗試無盤引導
#
# Ok, we've found a possible active partition. Check to see that the drive
# is a valid hard drive number.
#
main.3: cmpb $0x80,%dl # Drive valid? # dl中存放的是bios傳入的引導設備編號,從0x80開始表示硬盤
        jb main.4 # No # 若bios傳入的不是硬盤則將之前找到的活動分區(qū)的第一字節(jié)存入dl
        movb NHRDRV,%dh # Calculate the highest # bios將硬盤數目保存在NHRDRV,即0x475處,此處將其寫入dh
        addb $0x80,%dh # drive number available # 硬盤號從0x80開始,加上硬盤數目即得到最大可能硬盤號的上限
        cmpb %dh,%dl # Within range? # 判斷bios傳入的硬盤號是否在合法范圍之內
        jb main.5 # Yes # 硬盤及分區(qū)有效,準備讀入對應扇區(qū)
main.4: movb (%si),%dl # Load drive # 若bios傳入的不是硬盤或者硬盤號非法則將之前找到的活動分區(qū)的
                                                    # 第一字節(jié)存入dl
#
# Ok, now that we have a valid drive and partition entry, load the CHS from
# the partition entry and read the sector from the disk.
#
                                                    # 執(zhí)行至此已經找到了一個有效的硬盤分區(qū)入口,此時cpu主要
                                                    # 寄存器的內容如下:
                                                    # rax: 0x00000000:00000000 rcx: 0x00000000:00000000
                                                    # rdx: 0x00000000:00008180 rbx: 0x00000000:000007fe
                                                    # rsp: 0x00000000:00007c00 rbp: 0x00000000:00000000
                                                    # rsi: 0x00000000:ffff07be rdi: 0x00000000:00080800
                                                    # r8 : 0x00000000:00000000 r9 : 0x00000000:00000000
                                                    # r10: 0x00000000:00000000 r11: 0x00000000:00000000
                                                    # r12: 0x00000000:00000000 r13: 0x00000000:00000000
                                                    # r14: 0x00000000:00000000 r15: 0x00000000:00000000
                                                    # rip: 0x00000000:0000064a
                                                    # eflags 0x00000097
                                                    # 此時si指向的是之前找到的有效分區(qū)條目
main.5: movw %sp,%di # Save stack pointer # 將sp保存到di
        movb 0x1(%si),%dh # Load head # 分區(qū)條目第1(從0開始計算)字節(jié)存放的是磁頭號,將其存入dh
        movw 0x2(%si),%cx # Load cylinder:sector # 分區(qū)條目第2、3字節(jié)存放的是柱面號和扇區(qū)號,其中,第2字節(jié)的
                                                    # 低6位存儲扇區(qū)號,第2字節(jié)的高2位和第3字節(jié)的8位共同存儲
                                                    # 柱面號。之前找到的有效分區(qū)條目的起始地址是0x7be,它的前
                                                    # 4個字節(jié)的內容如下:
                                                    # 0x00000000000007be : 0x80 0x01 0x01 0x00
                                                    # 表示的就是第0柱面第1磁頭第1扇區(qū)。此處將這兩個字節(jié)的內容
                                                    # 存入cx,此時cpu主要寄存器的內容如下:
                                                    # rax: 0x00000000:00000000 rcx: 0x00000000:00000001
                                                    # rdx: 0x00000000:00000180 rbx: 0x00000000:000007fe
                                                    # rsp: 0x00000000:00007c00 rbp: 0x00000000:00000000
                                                    # rsi: 0x00000000:ffff07be rdi: 0x00000000:00087c00
                                                    # r8 : 0x00000000:00000000 r9 : 0x00000000:00000000
                                                    # r10: 0x00000000:00000000 r11: 0x00000000:00000000
                                                    # r12: 0x00000000:00000000 r13: 0x00000000:00000000
                                                    # r14: 0x00000000:00000000 r15: 0x00000000:00000000
                                                    # rip: 0x00000000:00000652
                                                    # eflags 0x00000097
        movw $LOAD,%bx # Transfer buffer # 把bios初始加載引導代碼的地址0x7c00賦給bx
                                                    # 至此已基本完成使用0x13中斷的0x02功能讀入磁盤扇區(qū)的準備,
                                                    # 即cx存放柱面號和扇區(qū)號,dh存放磁頭號,dl存放磁盤號,
                                                    # es:bx指向用于存放讀入的扇區(qū)數據的緩沖區(qū)地址。不過在決定
                                                    # 使用0x13中斷的0x02功能之前,此處要先嘗試是否能使用0x13
                                                    # 中斷的0x42功能讀入相應的扇區(qū)數據。在無法使用0x42功能的
                                                    # 情況下才會到"main.7:"去使用0x02功能。
        testb $FL_PACKET,flags # Try EDD? # 判斷是否需要嘗試BIOS Enhanced Disk Drive Services。
                                                    # "flags:"標號在本文尾端定義,位于緊鄰分區(qū)表之前的一個字節(jié),
                                                    # 內容為FLAGS,這個宏在/sys/boot/i386/mbr/Makefile中定義為
                                                    # BOOT_MBR_FLAGS,即0x80。BOOT_MBR_FLAGS在本文開始處定義為0x80。
        jz main.7 # No. # 若上述標志的設置決定不去判斷能否使用EDD功能讀入扇區(qū),則跳轉
                                                    # 至"main.7"使用0x13中斷的0x02功能讀入扇區(qū)。由于到此為止的
                                                    # 判斷尚未對cx和bx進行壓棧,所以可以直接跳轉至"main.7:",
                                                    # 而后續(xù)判斷中發(fā)現無法使用EDD功能時,由于已經對cx、bx進行了
                                                    # 壓棧和修改,則需跳轉至"main.6:"先恢復cx、bx的內容再到
                                                    # "main.7:"處使用0x13中斷的0x02功能。
        pushw %cx # Save %cx # 測試是否支持EDD擴展功能,中斷號0x13,入參ah存放功能號0x41,
        pushw %bx # Save %bx # bx存放幻數0x55aa。部分返回結果需要寫入cx,因此先保存cx、bx。
        movw $0x55aa,%bx # Magic
        movb $0x41,%ah # BIOS: EDD extensions
        int $0x13 # present?
        jc main.6 # No. # CF為1表示不支持
        cmpw $0xaa55,%bx # Magic ok? # 回寫至bx的幻數應為0xaa55
        jne main.6 # No. # 幻數不正確則跳轉至"main.6:"
        testb $0x1,%cl # Packet mode present? # 返回值cl第1位表示是否使用packet結構訪問設備
        jz main.6 # No. # 不使用packet結構則跳轉至"main.6:"
        popw %bx # Restore %bx # 恢復bx。此時cpu主要寄存器的內容如下:
                                                    # rax: 0x00000000:00003000 rcx: 0x00000000:00000007
                                                    # rdx: 0x00000000:00000180 rbx: 0x00000000:00007c00
                                                    # rsp: 0x00000000:00007bfe rbp: 0x00000000:00000000
                                                    # rsi: 0x00000000:ffff07be rdi: 0x00000000:00087c00
                                                    # r8 : 0x00000000:00000000 r9 : 0x00000000:00000000
                                                    # r10: 0x00000000:00000000 r11: 0x00000000:00000000
                                                    # r12: 0x00000000:00000000 r13: 0x00000000:00000000
                                                    # r14: 0x00000000:00000000 r15: 0x00000000:00000000
                                                    # rip: 0x00000000:00000673
                                                    # eflags 0x00000002
        pushl $0x0 # Set the LBA
        pushl 0x8(%si) # address
        pushw %es # Set the address of
        pushw %bx # the transfer buffer
        pushw $0x1 # Read 1 sector
        pushw $0x10 # Packet length # 準備使用0x13中斷的0x42功能以擴展方式從磁盤讀入扇區(qū),
                                            # 這一組壓棧指令就是在棧上構造磁盤地址包(Disk Address Packet)。
                                            # 壓棧完成之后,cpu主要寄存器的內容如下:
                                            # rax: 0x00000000:00004200 rcx: 0x00000000:00000007
                                            # rdx: 0x00000000:00000180 rbx: 0x00000000:00007c00
                                            # rsp: 0x00000000:00007bee rbp: 0x00000000:00000000
                                            # rsi: 0x00000000:ffff7bee rdi: 0x00000000:00087c00
                                            # r8 : 0x00000000:00000000 r9 : 0x00000000:00000000
                                            # r10: 0x00000000:00000000 r11: 0x00000000:00000000
                                            # r12: 0x00000000:00000000 r13: 0x00000000:00000000
                                            # r14: 0x00000000:00000000 r15: 0x00000000:00000000
                                            # rip: 0x00000000:00000685
                                            # eflags 0x00000002
                                            # sp寄存器指向0x7bee,此時棧頂附近16字節(jié)的內容如下:
                                            # 0x0000000000007bee : 0x10 0x00 0x01 0x00 0x00 0x7c 0x00 0x00
                                            # 0x0000000000007bf6 : 0x3f 0x00 0x00 0x00 0x00 0x00 0x00 0x00
                                            # 第0字節(jié)表示DAP的大小,此處為0x10,即16字節(jié),第1字節(jié)未使用,應填0,
                                            # 這兩個字節(jié)是由"pushw $0x10"指令壓入的。第2字節(jié)表示需要讀入的扇區(qū)數目,
                                            # 此處為0x01,只讀入1個扇區(qū),第3字節(jié)未使用,應填0,這兩個字節(jié)是由
                                            # "pushw $0x1"指令壓入的。第4到7字節(jié)是以"segment: offset"的形式給出的
                                            # 用于存放讀入的扇區(qū)數據的緩沖區(qū)的地址,此處是0x0000:7c00,這實際上
                                            # 就是bios初始加載主引導記錄的地址,即本段代碼被搬移到0x600區(qū)域之前
                                            # 所在的位置,這4個字節(jié)是由"pushw %es"和"pushw %bx"指令壓入的。
                                            # 第8到15字節(jié)表示的是讀入操作的起始扇區(qū)號(從0開始計算),此處是
                                            # 0x000000000000003f,本次讀入的是第63扇區(qū),這8個字節(jié)是由
                                            # "pushl $0x0"和"pushl 0x8(%si)"指令壓入的,si指向的是之前在分區(qū)表中
                                            # 找到的活動分區(qū)條目,它的第8到11字節(jié)存放的就是該分區(qū)的起始扇區(qū)號:
                                            # 0x00000000000007be : 0x80 0x01 0x01 0x00 0xa5 0x0f 0xff 0xff
                                            # 0x00000000000007c6 : 0x3f 0x00 0x00 0x00 0xa1 0xff 0x7f 0x00
        movw %sp,%si # Packer pointer # 在棧上完成DAP的構造之后,將其起始地址賦給si
        movw $0x4200,%ax # BIOS: LBA Read from disk # 寫入功能號0x42
        jmp main.8 # Skip the CHS setup # 跳轉到"main.8:"調用0x13中斷
main.6: popw %bx # Restore %bx # 若不支持EDD功能,則與此恢復之前壓棧的bx和cx,壓棧之前cx
                                                    # 存放的是柱面號和扇區(qū)號,bx存放的是用于存放讀入的扇區(qū)數據的
                                                    # 緩沖區(qū)地址,都是0x13中斷的0x02功能所需的入參。
        popw %cx # Restore %cx
main.7: movw $0x201,%ax # BIOS: Read from disk # 填寫0x13中斷的0x02功能所需的最后一點入參。al存放需要讀入的
                                                    # 扇區(qū)數目,此處為1,只讀入一個扇區(qū)。ah存放功能號0x02。
main.8: int $0x13 # Call the BIOS # 不管是使用0x02功能讀入,還是使用0x42功能讀入,至此已完成各自
                                                    # 入參的設置,統(tǒng)一運行至此執(zhí)行0x13中斷。
        movw %di,%sp # Restore stack # 將sp恢復至扇區(qū)拷貝之前的位置,即在"main.5:"處保存在di中的內容
        jc err_rd # If error # CF為1表示讀入過程出錯
#
# Now that we've loaded the bootstrap, check for the 0xaa55 signature. If it
# is present, execute the bootstrap we just loaded.
#
                                                    # 至此已完成扇區(qū)的讀入,cpu主要寄存器的內容如下:
                                                    # rax: 0x00000000:00000000 rcx: 0x00000000:00000007
                                                    # rdx: 0x00000000:00000180 rbx: 0x00000000:00007c00
                                                    # rsp: 0x00000000:00007c00 rbp: 0x00000000:00000000
                                                    # rsi: 0x00000000:ffff7bee rdi: 0x00000000:00087c00
                                                    # r8 : 0x00000000:00000000 r9 : 0x00000000:00000000
                                                    # r10: 0x00000000:00000000 r11: 0x00000000:00000000
                                                    # r12: 0x00000000:00000000 r13: 0x00000000:00000000
                                                    # r14: 0x00000000:00000000 r15: 0x00000000:00000000
                                                    # rip: 0x00000000:00000692
                                                    # eflags 0x00000002
        cmpw $MAGIC,0x1fe(%bx) # Bootable? # 前面已經通過0x13中斷從磁盤讀入了一個512字節(jié)的扇區(qū)到
                                                    # 0x7c00區(qū)域,此處判斷該扇區(qū)的最后兩個字節(jié)是否為0xaa55,
                                                    # 以確定該扇區(qū)是否可引導。
        jne err_os # No # 讀入扇區(qū)不可引導則報錯
        jmp *%bx # Invoke bootstrap # 跳轉至0x7c00執(zhí)行剛讀入的bootstrap代碼
#
# Various error message entry points.
#
err_pt: movw $msg_pt,%si # "Invalid partition
        jmp putstr # table"
err_rd: movw $msg_rd,%si # "Error loading
        jmp putstr # operating system"
err_os: movw $msg_os,%si # "Missing operating
        jmp putstr # system"
#
# Output an ASCIZ string to the console via the BIOS.
#
putstr.0: movw $0x7,%bx # Page:attribute
        movb $0xe,%ah # BIOS: Display
        int $0x10 # character
putstr: lodsb # Get character
        testb %al,%al # End of string?
        jnz putstr.0 # No
putstr.1: jmp putstr.1 # Await reset
msg_pt: .asciz "Invalid partition table"
msg_rd: .asciz "Error loading operating system"
msg_os: .asciz "Missing operating system"
        .org PT_OFF-1,0x90
flags: .byte FLAGS # Flags
partbl: .fill 0x10,0x4,0x0 # Partition table
        .word MAGIC # Magic number


本文來自ChinaUnix博客,如果查看原文請點:http://blog.chinaunix.net/u/9831/showart_1018347.html
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復

  

北京盛拓優(yōu)訊信息技術有限公司. 版權所有 京ICP備16024965號-6 北京市公安局海淀分局網監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯網協會會員  聯系我們:huangweiwei@itpub.net
感謝所有關心和支持過ChinaUnix的朋友們 轉載本站內容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP