日本免费全黄少妇一区二区三区-高清无码一区二区三区四区-欧美中文字幕日韩在线观看-国产福利诱惑在线网站-国产中文字幕一区在线-亚洲欧美精品日韩一区-久久国产精品国产精品国产-国产精久久久久久一区二区三区-欧美亚洲国产精品久久久久

FreeBSD啟動(dòng)扇區(qū)代碼分析( 二 )


movw $LOAD,%sp # stack 以上代碼:1)首先使用“cld指令清除方向標(biāo)志,使得以下的進(jìn)行“rep操作時(shí)SI和DI的值遞增 。2)使ax清零,并使除代碼段cs外的另外兩個(gè)數(shù)據(jù)段寄存器es、ds和堆棧段ss清零 。當(dāng)然,此時(shí)cs由于reset或初始上電已經(jīng)為零了 。3)BIOS已經(jīng)把引導(dǎo)扇區(qū)的512字節(jié)的內(nèi)容讀入到了0:0x7c00處,movw $LOAD,%sp 使得堆棧指針指向扇區(qū)代碼(或曰本段代碼 0:0x7c00)的頂部 。雖然堆棧向下生長可能會(huì)影響代碼的內(nèi)容,但下面我們馬上就把位于0:7c00處代碼移到其他地方去執(zhí)行 。#
# 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處 。注意,此時(shí)由于代碼連接的重定向,$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通過以上一段代碼的執(zhí)行,本代碼已被搬移到0:0x600處,此時(shí)si=di=0x600 0x100,以上代碼把di的值保存到bp,bp此時(shí)指向本程序搬移后的未用的空間的首部,且把此bp所指的16字節(jié)空間清零 。以上過程如下圖所示:┏>0:0x600 ┏━━━━━┓┃ ┃ ┃┃ ┃搬┃┃ ┃移┃┃ ┃之┃┃ ┃后┃┃ ┃的┃┃ ┃代┃┃ ┃碼┃┃ ┃ ┃┃ 0:0x7ff ┣━━━━━┫┃ ┃0 ┃<-bp指向這里(0:0x800),以此開始的16字節(jié)被清零 。┃ ┣━━━━━┫以下所稱的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字節(jié)的第二個(gè)字節(jié)置為1,表示我們已經(jīng)讀取了一個(gè)分區(qū) 。然后跳轉(zhuǎn)到搬移之后的新代碼的main處執(zhí)行 。#
# 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把磁盤的引導(dǎo)扇區(qū)讀入到內(nèi)存之后,其dl的內(nèi)容表示啟動(dòng)設(shè)備,但我們安裝好FreeBSD之后,我們可以改變此引導(dǎo)扇區(qū)的內(nèi)容,其中的一個(gè)改變就是可以使我們可以“手動(dòng)指定我們實(shí)際安裝FreeBSD的分區(qū),如果我們希望指定FreeBSD所在的boot分區(qū),那么我們?cè)赽p-0x45處的位置(即_FLAGS(%bp)處)的bit 0x20置1,那么上面的“movb _SETDRV(%bp),%dl一句中movb_SETDRV(%bp),%dl(即bp-0x46)即指向我們“手動(dòng)指定FreeBSD所在分區(qū)代碼,例如,IDE的C、D盤(嚴(yán)格來說是第一個(gè)物理磁盤的第一個(gè)和第二個(gè)分區(qū))的代碼分別為 0x80和0x81 。如果沒有“手動(dòng)指定啟動(dòng)分區(qū),那么,我們?nèi)笔∈褂脵C(jī)器當(dāng)前啟動(dòng)的分區(qū),上面說過,機(jī)器當(dāng)前啟動(dòng)的分區(qū)代碼放在dl中 。因?yàn)镕reeBSD Boot Manager 不可能安裝到軟盤(如果從軟盤啟動(dòng)則dl為0),所以,使用testb %dl,%dl來判斷驅(qū)動(dòng)器代碼是否合法(volid) 。有關(guān)_FLAGS(%bp)中其他bit位表示的意義,在隨后的代碼分析中慢慢給你道來 。#

推薦閱讀