東北大學(xué)MINIXMBRbootblock分析_第1頁
東北大學(xué)MINIXMBRbootblock分析_第2頁
東北大學(xué)MINIXMBRbootblock分析_第3頁
已閱讀5頁,還剩4頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、Minix代碼分析之一:引導(dǎo)扇區(qū)代碼作者:聰聰( )本文本可以任意發(fā)布,在發(fā)布時注意請保持原作者的姓名。email: luoc on gszptt .n et.c n1.1計算機加電當(dāng)我們打開計算機電源時, 計算機嘰嘰嘎嘎進行設(shè)備和內(nèi)存檢測過后就讀取硬盤或者軟盤的 引導(dǎo)扇區(qū),這個扇區(qū)只有 512字節(jié)(每個扇區(qū)都一樣大),顯然這512字節(jié)不能夠有多大作 用,操作系統(tǒng)需要通過這個引導(dǎo)扇區(qū)代碼再裝載操作系統(tǒng)的其他部分。這512字節(jié)的代碼被BIOS放在地址從 0x0000:0x7c00開始處。然后直接跳轉(zhuǎn)到 0x0000:0x7c00處去執(zhí)行。以上工 作是BIOS干的,你什么也不用作在還沒有跳轉(zhuǎn)到這段

2、代碼之前,也就是 BIOS把磁盤的引導(dǎo)扇區(qū)讀入到內(nèi)存之后,其DL和ES、SI寄存器的內(nèi)容如下:DL:表示啟動設(shè)備,例如,如果計算機是從軟盤啟動的則DL=0,若是從IDE的C、D盤啟動的則DL分別為0x80和0x81。如果是從硬盤啟動的話,ES:SI是 指向BIOS中的硬盤分區(qū)表存放的地址。1.2執(zhí)行引導(dǎo)扇區(qū)代碼好了,我們現(xiàn)在已經(jīng)知道,計算機的BIOS已經(jīng)把引導(dǎo)扇區(qū)的512字節(jié)的內(nèi)容讀入到了 0:0x7c00處,然后就跳轉(zhuǎn)到0:0x7C00處去執(zhí)行,也就是執(zhí)行引導(dǎo)扇區(qū) 代碼,其引導(dǎo)扇區(qū)代碼見后面。下面對引導(dǎo)扇區(qū)代碼進行解釋。引導(dǎo)扇區(qū)代碼的執(zhí)行過程如下:1.2.1 BIOS在把引導(dǎo)扇區(qū)裝載到地址

3、0:0x7C00處后,引導(dǎo)扇區(qū)代碼首先設(shè)置正確的堆棧。其堆棧內(nèi)容如下圖所示:堆棧說明sies如果是硬盤的話ES:SI為指向BIOS的硬盤分區(qū)表 地址dx<-0:0x7c04,其中,dl是啟動設(shè)備號碼(0=軟盤A, 仁軟盤b,0x80=硬盤C, 0x8仁硬盤D等)bp也指 向此處的地址00'00H<-0:0x7c02 (本程序會在此處填入boot分區(qū)的偏移)00'00H<-0:0x7c00 (本程序會在此處填入每個柱面的扇區(qū) 數(shù))以下為引導(dǎo)扇區(qū)代碼(即此程序代碼)1.2.2調(diào)用BIOS中斷:ah=0x08,int 0x13得到磁盤驅(qū)動器參數(shù)其BIOS中斷調(diào)用ah

4、=0x08,int 0x13說明如下:中斷調(diào)用ah=0x08,int 0x13返回后,在以下寄存器返回以下信息:DL:本機軟盤驅(qū)動器的數(shù)目DH:最大磁頭號(或說磁面數(shù)目)。0表示有1個磁面,1表示有2個磁面CH:存放10位磁道柱面數(shù)的低 8位(高2位在CL的D7、D6中)。1表示有1個柱 面,2表示有2個柱面,依次類推。CL:05位存放每磁道的扇區(qū)數(shù)目。6和7位表示10位磁道柱面數(shù)的高 2位。AX=0BH=0BL表示驅(qū)動器類型:1=360K 5.252=1.2M 5.253=720K 3.54=1.44M 3.5ES:SI指向軟盤參數(shù)表錯誤信息:若產(chǎn)生錯誤,進位標志CF=1,AH存放錯誤信息碼

5、。1.2.3把以上得到的磁盤參數(shù)分別放到 parameters處相應(yīng)的位置,磁盤參數(shù)占 11字節(jié)的空間。1.2.4根據(jù)上面得到的磁盤參數(shù)調(diào)用 BIOS中斷ah=0x02H,int 13H 來讀取第1 扇區(qū),且把它存放在地址 0:0x1000處。1.2.5跳轉(zhuǎn)到0:0x1000處執(zhí)行裝載kernel、mm、fs、net等代碼。1.3引導(dǎo)扇區(qū)代碼以下為引導(dǎo)扇區(qū)代碼:(其中,洋文我一字未動,中文是我添加的,以后同)! Bootblock 1.2 - Mi nix boot block. Author: Kees J. Bot! Floppy sensing code: Guy Helmer! Whe

6、n the PC is powered on, it will try to read the first sector of floppy! disk 0 into address 0x7C00. If this fails due to the abse nee of flexible! magn etic media, it will read the master boot record from the first sector! of the hard disk. This sector not only contains executable code, but also! th

7、e partition table of the hard disk. When executed, it will select the! active partition and load the first sector of that into address 0x7C00.! This file contains the code that is eventually read from either the floppy! disk, or the hard disk partition. It is just smart enough to load the! secondary

8、 boot code from the boot device into memory at address 0x10000 and! execute that. The disk addresses for this secondary boot code are patched! into this code by installboot as 24-bit sector numbers and 8-bit sector! counts above enddata upwards. The secondary boot code is in turn smart! enough to lo

9、ad the different parts of the Minix kernel into memory and! execute them to finally get Minix started.! Kees J. Bot - 91/12/21:! Adapted Guy Helmers code and added hard disk support for my boot monitor! package.!LOADOFF = 0x7C00 ! 0x0000:LOADOFF is where this code is loaded !對了,以上的宏定義是指本代碼存放的位置了BOOT

10、SEG = 0x1000 ! Secondary boot code segment.! 以上的宏定義表示第二個 BOOT 代碼的位置。BOOTOFF = 0x0030 ! Offset into secondary boot above header BUFFER = 0x0600 ! First free memoryDSKBASE = 0x1E ! Floppy disk parameter vector DSKPARSIZE = 11 ! 11 bytes of floppy parametersSECTORS = 4 ! Offset into parameters to secto

11、rs per track LOWSEC = 8 ! Offset of logical first sector in partition ! table! Variables addressed using bp registerdevice = 0 ! The boot devicelowsec = 2 ! Offset of boot partition within drive secpcyl = 6 ! Sectors per cylinder = heads * sectors.define begtext, begdata, begbss, endtext, enddata, e

12、ndbss, _main .databegdata:.bssbegbss:.text begtext: _main:! Start boot procedure.!此處被放在 0:0x7c00 處,這是 Minix 執(zhí)行的第一個語句。由于上面已經(jīng)講得很清楚了 !而且有洋文注釋,以下不再祥述。boot:!設(shè)置正確的數(shù)據(jù)段xor ax, ax ! ax = 0x0000, the vector segmentmov ds, axcli ! Ignore interrupts while setting stackmov ss, ax ! ss = ds = vector segment!棧底為 0

13、:0x7c00 mov sp, #LOADOFF ! Usual place for a bootstrap stacksti!上面已經(jīng)解釋過了,在棧底留下兩個字的空間以供傳遞參數(shù)給加載代碼( Minix 代碼分析( 2)馬上就會講到)push axpush ax ! Push a zero lowsec(bp)!臨時在堆棧中保存啟動設(shè)備( dl)push dx ! Boot device in dl will be device(bp)!bp 指向此處,以后用 bp 指針改變本棧的內(nèi)容mov bp, sp ! Using var(bp) is one byte cheaper then va

14、r.!把 BIOS 的硬磁盤參數(shù)表指針( es:si )保存在棧中。push espush si ! es:si = partition table entry if hard disk!為了以后適當(dāng)改變 parameter 處的磁盤參數(shù)表,現(xiàn)在則正確的設(shè)置 di mov di, #LOADOFF+parameters ! char (*di)DSKPARSIZE = parameters;!判斷啟動設(shè)備是硬盤還是軟盤testb dl, dl ! Winchester disks if dl >= 0x80jge floppywinchester:!啟動設(shè)備是硬盤。! Get the o

15、ffset of the first sector of the boot partition from the partition! table. The table is found at es:si, the lowsec parameter at offset LOWSEC.! 對了,我們已經(jīng)說過, es:si 已經(jīng)指向了硬盤的磁盤參數(shù)表,以下 ax 里面存放的就 會是分區(qū)表中!活動分區(qū)的第一個邏輯扇區(qū)的偏移esegles ax, LOWSEC(si) ! es:ax = LOWSEC+2(si):LOWSEC(si)! 把引導(dǎo)盤的邏輯第一個扇區(qū)的偏移放到棧中,也就是說改變棧的內(nèi)容,(

16、注意上面講到過的 BP 的值) mov lowsec+0(bp), ax ! Low 16 bits of partition's first sector mov lowsec+2(bp), es ! High 16 bits of partition's first sector! Get the drive parameters, the number of sectors is bluntly written into the! floppy disk parameters. !對了,上面已經(jīng)說過的,取得磁盤參數(shù) movb ah, #0x08 ! Code for dr

17、ive parameters int 0x13 ! dl still contains drive!取得每扇區(qū)的扇區(qū)數(shù)目andb cl, #0x3F ! cl = max sector number (1-origin) movb SECTORS(di), cl ! Number of sectors per track!bh 是最大的磁頭數(shù)目(或者說磁面數(shù)目),因為我們已經(jīng)說過,! “表0示有 1 個磁面, 1 表示有 2 個磁面” incb dh ! dh = 1 + max head number (0-origin)!跳轉(zhuǎn)去裝載啟動( BOOT )代碼。jmp loadboot! Fl

18、oppy:! Execute three read tests to determine the drive type. Test for each floppy! type by reading the last sector on the first track. If it fails, try a type! that has less sectors. Therefore we start with 1.44M (18 sectors) then 1.2M! (15 sectors) ending with 720K/360K (both 9 sectors). (The flopp

19、y parameters! of the last two are equal, apart from the motor start time. This saves us! the rather painful "try to read track 41" test.) !如果啟動設(shè)備是軟盤,則從 floppy 處開始執(zhí)行。以下一句是在!di 上加上一部分偏移以指向下一組參數(shù)。 !為了得到正確的磁盤容量,只有一組一組參數(shù)試,首先判斷軟 !盤是不是 1.44M 的,再判斷是不是 1.2M 的以此類推 next: add di, #DSKPARSIZE ! Next set

20、 of parameters!我們知道,中斷矢量 0x1e(DSKBASE=0x1e )處的地址所指的是軟盤 !參數(shù)表,而中斷矢量 n 的位置是 0:4*n 處,所以要!乘以 4,例如中斷矢量 int 10h 入口是在地址 0:40h 處。以下改變軟磁!盤參數(shù)表指向我們定義的位置處 floppy: mov DSKBASE*4+0, di ! Load offset of disk parametersmov DSKBASE*4+2, ds ! Load segment of disk parameters !得到參數(shù)后復(fù)位驅(qū)動器。xorb ah, ah ! Reset drive int 0x

21、13!cl 里面為每磁道的扇區(qū)數(shù)目。movb cl, SECTORS(di) ! cl = number of last sector on track !不用對 720K/360K 磁盤進行測試了。cmp di, #LOADOFF+dsdd3 ! No need to do the last 720K/360K test jz success! Try to read the last sector on track 0!以下試讀取磁道 0 的最后一個扇區(qū),如果成功說明所選的參數(shù)是對的。 mov es, lowsec(bp) ! es = vector segment (lowsec = 0

22、) mov bx, #BUFFER ! es:bx buffer = 0x0000:0x0600 mov ax, #0x0201 ! Read sector, #sectors = 1 xorb ch, ch ! Track 0, last sector xorb dh, dh ! Drive dl, head 0 int 0x13jb next ! Error, try the next floppy type !得到正確的磁盤參數(shù) success:movb dh, #2 ! Load number of heads for multiply! Number of sectors is st

23、ill in cl loadboot:! Load the secondary boot code from the boot device! 從啟動設(shè)備中裝載第二個啟動代碼! al=cl= 每磁道多少扇區(qū)movb al, cl ! al = cl = sectors per trackmulb dh ! dh = heads, ax = heads * sectors! ax 里面保存的是每柱面多少扇區(qū)數(shù),然后放入到棧底 mov secpcyl(bp), ax ! Sectors per cylinder = heads * sectors !裝載第二個啟動代碼于 0x10000 :0 處(

24、第二個 boot 代碼下一篇文檔中 馬上就要講到)!即裝載第一扇區(qū)于 es:bx = 10000 :0 處 mov ax, #BOOTSEG ! Segment to load secondary boot code into mov es, axxor bx, bx ! Load first sector at es:bx = BOOTSEG:0x0000! 啟動代碼的開始地址放入 si ,供以后跳轉(zhuǎn)用mov si, #LOADOFF+addresses ! Start of the boot code addresses!int 13h,ah = 2( 讀扇區(qū))說明:! 用這個功能將從磁盤

25、上把一個或更多個扇區(qū)讀進存儲器. 因為這是一個低級功能 ,! 在一個操作中讀取的全部扇區(qū)必須在同一磁道上 (就是說 , 要有相同的磁 頭號和磁道! 柱面號或磁道號 ).BIOS 不能自動地從一條磁道末尾切換到另一磁道開 始,因此,用! 戶必須把把跨多條磁道的讀操作分為若干條單磁道讀操作。!入口參數(shù):! ah = 02H 指出讀扇區(qū)功能調(diào)用號。! AL 置要讀的扇區(qū)數(shù)目,不允許讀磁道末端以外的數(shù)值,也不允許使該 寄存器為 0! DL 驅(qū)動器代碼, 0 和 1 表示軟盤, 80 和 81 識別硬盤! DH 所讀磁盤的磁頭號, 0 和 1 是軟盤磁頭, 0 到 15H 代表 XT 或 AT 機的硬盤

26、,其他的! 磁盤也可能有不同的磁頭號! CH 識別 10 位開始磁道柱面號(或軟盤的磁道號)的低 8 位。 CL 寄存 器的 6-7 為存放其高! 2位。對于 320K/360K 軟盤,磁道號的范圍是 0-39,;于 1.2M 軟盤, 磁道號是 0-79 ;! 對于硬盤,其值是 0-1023! CL 其 6-7 位識別 10 位開始磁道柱面號(或軟盤的磁道號)的高 2 位。 0-5 位放入所讀的起始!扇區(qū)號。對于320K/360K軟盤,取值范圍是1-8或1-9;于1.2M軟盤, 取值是 1-15 ;對于! 硬盤,其值是 1-17 ,需注意,扇區(qū)號是從 1 而不是 0 開始。! ES:BX 置存

27、放從磁盤上讀出數(shù)據(jù)的存儲器容量。 這個存儲器容量應(yīng)該是 能容納 02H 功能調(diào)用讀! 的所有扇區(qū)數(shù)據(jù)。因此,用戶在調(diào)用這個功能之前必須了解所讀扇區(qū)的 大小和數(shù)量。!出口參數(shù):! ES:BX 所讀的數(shù)據(jù)的存儲區(qū)域的指針。 如果讀入若干扇區(qū), 這些扇區(qū)的 數(shù)據(jù)會依次排列!錯誤信息:! 如果產(chǎn)生錯誤,進位標志 CF = 1 ,錯誤信息放在 AH 中! AH 存放錯誤代碼。load:! 取得下一個扇區(qū)數(shù):低 16 位,在 addresses 處到底存放的是什么內(nèi)容,目前倘不 清楚,只知道它! 是由程序 installboot 在此處賦了一些值,等我分析完 installboot 程序后再補以下這 段內(nèi)

28、容。! 但是有一點是很清楚的,就是以下程序裝載boot 的第二部分,本代碼裝載完 boot的第二部分代碼!后就跳轉(zhuǎn)到那里去執(zhí)行。mov ax, 1(si) ! Get next sector number: low 16 bits movb dl, 3(si) ! Bits 16-23 for your 8GB disk xorb dh, dh ! dx:ax = sector within partition add ax, lowsec+0(bp)adc dx, lowsec+2(bp)! dx:ax = sector within drivediv secpcyl(bp) ! ax =

29、cylinder, dx = sector within cylinder xchg ax, dx ! ax = sector within cylinder, dx = cylinder movb ch, dl ! ch = low 8 bits of cylinder divb SECTORS(di) ! al = head, ah = sector (0-origin) xorb dl, dl ! About to shift bits 8-9 of cylinder into dl shr dx, #1 shr dx, #1 ! dl6.7 = high cylinder orb dl

30、, ah ! dl0.5 = sector (0-origin) movb cl, dl ! cl0.5 = sector, cl6.7 = high cyl incb cl ! cl0.5 = sector (1-origin) movb dh, al ! dh = al = head movb dl, device(bp) ! dl = device to read movb al, SECTORS(di) ! Sectors per track - Sector number (0-origin) subb al, ah ! = Sectors left on this track cm

31、pb al, (si) ! Compare with # sectors to read jbe read ! Can't read past the end of a cylinder? movb al, (si) ! (si) < sectors left on this trackread: push ax ! Save al = sectors to readmovb ah, #2 ! Code for disk read (all registers in use now!)int 0x13 ! Call the BIOS for a readpop cx ! Rest

32、ore al in cljb error ! Jump on disk read error movb al, cl ! Restore al = sectors read addb bh, al ! bx += 2 * al * 256 (add bytes read) addb bh, al ! es:bx = where next sector must be read add 1(si), ax ! Update address by sectors read adcb 3(si), ah ! Don't forget bits 16-23 (add ah = 0) subb

33、(si), al ! Decrement sector count by sectors read jnz load ! Not all sectors have been readadd si, #4 ! Next (address, count) paircmpb ah, (si) ! Done when no sectors to readjnz load ! Read next chunk of secondary boot codedone:! Call secondary boot, assuming a long a.out header (48 bytes). The a.ou

34、t! header is usually short (32 bytes), but secondary boot has two entry points:! One at offset 0 for the long, and one at offset 16 for the short header.! Parameters passed in registers are:! dl = Boot-device.! es:si = Partition table entry if hard disk.!pop si ! Restore es:si = partition table entr

35、ypop es ! dl is still loadedjmpf BOOTOFF, BOOTSEG ! jmp to sec. boot (skipping header).! Read error: print message, hang forevererror:! mov si, #LOADOFF+errno+1 ! Uncomment this at disaster time!prnum: movb al, ah ! Error number in ah! andb al, #0x0F ! Low 4 bits! cmpb al, #10 ! A-F?! jb digit ! 0-9! addb al, #7 ! 'A' - ':'!digit: addb (si), al ! Modify '0' in string! dec si! movb cl, #4 ! Next 4 bits! shrb ah, cl! jnz prnum ! Again if digit > 0mov si, #LOADOFF+rderr ! String to

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論