版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領
文檔簡介
Linux系統(tǒng)的啟動
2.1操作系統(tǒng)的啟動
一般來說,操作系統(tǒng)的引導過程分兩個步驟。首先,電腦硬體經(jīng)過開機自檢(PowerOnSelf-Test,POST)之後,從軟碟或硬碟的固定位置裝載一小段代碼,這段代碼一般稱為“引導裝載器”。然後,由引導裝載器負責裝入並運行操作系統(tǒng)。引導裝載器非常小,一般只有幾百個位元組,而操作系統(tǒng)龐大而複雜。上述分成兩階段的引導過程,可將電腦中的固化軟體保持得足夠小,同時也便於實現(xiàn)對不同操作系統(tǒng)的引導。2.1.1系統(tǒng)引導過程簡介
系統(tǒng)啟動過程主要由以下幾個步驟組成(以硬碟啟動為例):(1)開機(2)BIOS加電自檢(PowerOnSelfTest,POST),記憶體地址為0ffff:0000(3)將硬碟第一個扇區(qū)(0頭0道1扇區(qū),也就是BootSector)讀入記憶體地址0000:7c00處。(4)檢查(WORD)0000:7dfe是否等於0xaa55,若不等於則轉(zhuǎn)去嘗試其他啟動介質(zhì),如果沒有其他啟動介質(zhì)則顯示"NoROMBASIC"然後死機。(5)跳轉(zhuǎn)到0000:7c00處執(zhí)行MBR中的程式。(6)MBR首先將自己複製到0000:0600處,然後繼續(xù)執(zhí)行。(7)在主分區(qū)表中搜索標誌為活動的分區(qū)。如果發(fā)現(xiàn)沒有活動分區(qū)或有不止一個活動分區(qū),則停止。(8)將活動分區(qū)的第一個扇區(qū)讀入記憶體地址0000:7c00處。(9)檢查(WORD)0000:7dfe是否等於0xaa55,若不等於則顯示"MissingOperatingSystem"然後停止,或嘗試軟碟啟動。(10)跳轉(zhuǎn)到0000:7c00處繼續(xù)執(zhí)行特定系統(tǒng)的啟動程式。(11)啟動系統(tǒng)。以上步驟中2,3,4,5步是由BIOS的引導程式完成。6,7,8,9,10步由MBR中的引導程式完成。一般多系統(tǒng)引導程式(如SmartBootManager、BootStar、PQBoot
等)都是將標準主引導記錄替換成自己的引導程式,在運行系統(tǒng)啟動程式之前讓用戶選擇要啟動的分區(qū)。而某些系統(tǒng)自帶的多系統(tǒng)引導程式(如LILO,NTLoader等)則可以將自己的引導程式放在系統(tǒng)所處分區(qū)的第一個扇區(qū)中,在Linux中即為是兩個扇區(qū)的SuperBlock。注:以上各步驟中使用的是標準MBR,其他多系統(tǒng)引導程式的引導過程與此不同。2.1.2硬碟結(jié)構(gòu)
1.硬碟參數(shù)當硬碟的容量還非常小的時候,人們採用與軟碟類似的結(jié)構(gòu)生產(chǎn)硬碟。硬碟盤片的每一條磁軌都具有相同的扇區(qū)數(shù)。由此產(chǎn)生了所謂的3D參數(shù)(DiskGeometry)以及相應的尋址方式。到目前為止,通常還是沿用這種CHS(Cylinder/Head/Sector)來表示硬碟參數(shù)。其中:磁頭數(shù)(Heads)表示硬碟總共有幾個磁頭,也就是有幾面盤片,最大為256(用8個二進位位存儲);柱面數(shù)(Cylinders)表示硬碟每一面盤片上有幾條磁軌,最大為1024(用10個二進位位存儲);扇區(qū)數(shù)(Sectorspertrack)表示每一條磁軌上有幾個扇區(qū),最大為63(用6個二進位位存儲)。每個扇區(qū)一般是512個位元組。2.基本INT13H調(diào)用簡介
BIOSint13H調(diào)用是BIOS提供的磁片基本輸入輸出中斷調(diào)用,它可以完成磁片(包括硬碟和軟碟)的複位、讀寫、校驗、定位、診斷和格式化等功能。它使用的是CHS尋址方式,因此最大只能訪問8GB左右的硬碟(本文中如不作特殊說明,均以1M=1048576位元組為單位)。3.現(xiàn)代硬碟結(jié)構(gòu)簡介在老式硬碟中,由於每個磁軌的扇區(qū)數(shù)相等,所以外道的記錄密度要遠低於內(nèi)道,因此會浪費很多磁片空間。為了進一步提高硬碟容量,人們改用等密度結(jié)構(gòu)生產(chǎn)硬碟。也就是說,外圈磁軌的扇區(qū)比內(nèi)圈磁軌多。採用這種結(jié)構(gòu)後,硬碟不再具有實際的3D參數(shù),尋址方式也改為線性尋址,即以扇區(qū)為單位進行尋址。為了與使用3D尋址的老軟體相容(如使用BIOSINT13H介面的軟體),在硬碟控制器內(nèi)部安裝了一個地址翻譯器,由它負責將老式3D參數(shù)翻譯成新的線性參數(shù)。不同的工作模式(如LBA、LARGE、NORMAL)對應不同的3D參數(shù)。4.擴展INT13H
雖然現(xiàn)代硬碟都已經(jīng)採用了線性尋址,但是由於基本INT13H的制約,使用BIOS的INT13H介面的程式(如DOS等)還只能訪問8G以內(nèi)的硬碟空間。為了打破這一限制,Microsoft等幾家公司制定了擴展INT13H標準(ExtendedINT13H),採用線性尋址方式存取硬碟,突破了8G的限制,並還加入了對可拆卸介質(zhì)(如活動硬碟)的支持。2.1.3引導扇區(qū)
1.BootSector的組成
BootSector也就是硬碟的第一個扇區(qū),它由MBR(MasterBootRecord),DPT(DiskPartitionTable)和BootRecordID三部分組成。MBR又稱作主引導記錄,佔用BootSector的前446個位元組(0to0x1BD),存放系統(tǒng)主引導程式(它負責從活動分區(qū)中裝載並運行系統(tǒng)引導程式)。DPT即主分區(qū)表佔用64個位元組(0x1BEto0x1FD),記錄了磁片的基本分區(qū)資訊。主分區(qū)表分為四個分區(qū)項,每項16位元組,分別記錄了每個主分區(qū)的資訊(因此最多可以有四個主分區(qū))。BootRecordID即引導區(qū)標記佔用兩個位元組(0x1FEand0x1FF),對於合法引導區(qū),它等於0xAA55,這是判別引導區(qū)是否合法的標誌。BootSector的具體結(jié)構(gòu)如下圖所示:2.分區(qū)表結(jié)構(gòu)簡介分區(qū)表由四個分區(qū)項構(gòu)成,每一項的結(jié)構(gòu)如下:BYTEState:分區(qū)狀態(tài),0=未啟動,0x80=啟動(注意此項)BYTEStartHead:分區(qū)起始磁頭號WORDStartSC:分區(qū)起始扇區(qū)和柱面號,底位元組的低6位為扇區(qū)號,高2位為柱面號的第9,10位,高位元組為柱面號的低8位BYTEType:分區(qū)類型,如0x0B=FAT32,0x83=Linux等,00表示此項未用BYTEEndHead:分區(qū)結(jié)束磁頭號WORDEndSC:分區(qū)結(jié)束扇區(qū)和柱面號,定義同前DWORDRelative:線上性尋址方式下的分區(qū)相對扇區(qū)地址(對於基本分區(qū)即為絕對地址)DWORDSectors:分區(qū)大小(總扇區(qū)數(shù))
在DOS/Windows系統(tǒng)下,基本分區(qū)必須以柱面為單位劃分(Sectors*Heads個扇區(qū)),如對於CHS為764/256/63的硬碟,分區(qū)的最小尺寸為256*63*512/1048576=7.875MB。由於硬碟的第一個扇區(qū)已經(jīng)被引導扇區(qū)佔用,所以一般來說,硬碟第一個磁軌(0頭0道)的其餘62個扇區(qū)是不會被分區(qū)佔用的。某些分區(qū)軟體甚至將第一個柱面全部空出來。3.擴展分區(qū)由於主分區(qū)表中只能分四個分區(qū),無法滿足需求,因此設計了一種擴展分區(qū)格式。基本上說,擴展分區(qū)的資訊是以鏈表形式存放的,但也有一些特別的地方。
首先,主分區(qū)表中要有一個基本擴展分區(qū)項,所有擴展分區(qū)都隸屬於它,也就是說其他所有擴展分區(qū)的空間都必須包括在這個基本擴展分區(qū)中。對於DOS/Windows來說,擴展分區(qū)的類型為0x05或0x0F(LBA模式)。除基本擴展分區(qū)以外的其他所有擴展分區(qū)則以鏈表的形式級聯(lián)存放,後一個擴展分區(qū)的資料項目記錄在前一個擴展分區(qū)的分區(qū)表中,但兩個擴展分區(qū)的空間並不重疊。
擴展分區(qū)類似於一個完整的硬碟,必須進一步分區(qū)才能使用。但每個擴展分區(qū)中只能存在一個其他分區(qū)。此分區(qū)在DOS/Windows環(huán)境中即為邏輯盤。因此每一個擴展分區(qū)的分區(qū)表(同樣存儲在擴展分區(qū)的第一個扇區(qū)中)中最多只能有兩個分區(qū)資料項目(包括下一個擴展分區(qū)的資料項目)。以上所有擴展分區(qū)表中的第二個分區(qū)項(指向下一個擴展分區(qū))的相對扇區(qū)地址均相對於主擴展分區(qū),而不是前一個擴展分區(qū)。
2.2Linux的引導過程
不同電腦平臺引導過程的區(qū)別主要在於第一階段的引導過程。對PC機上的Linux系統(tǒng)而言,電腦(即BIOS)負責從軟碟或硬碟的第一個扇區(qū)(即引導扇區(qū))中讀取引導裝載器,然後,由引導裝載器從磁片或其他位置裝入操作系統(tǒng)。從軟碟引導時,BIOS讀取並運行引導扇區(qū)中的代碼。引導扇區(qū)中的代碼讀取軟碟前幾百個塊(依賴於實際的內(nèi)核大?。?,然後將這些代碼放置在預先定義好的記憶體位置。利用軟碟引導Linux時,沒有檔系統(tǒng),內(nèi)核處於連續(xù)的扇區(qū)中,這樣安排可簡化引導過程。但是,如果利用LILO(LInux
LOader)也可從包含檔系統(tǒng)的軟碟上引導Linux。
從硬碟引導時,由於硬碟是可分區(qū)的,因此引導過程比軟碟複雜一些。BIOS首先讀取並運行硬碟主引導記錄中的代碼,這些代碼首先檢驗主引導記錄中的分區(qū)表,尋找到活動分區(qū)(即標誌為可引導分區(qū)的分區(qū)),然後讀取並運行活動分區(qū)之引導扇區(qū)中的代碼?;顒臃謪^(qū)引導扇區(qū)的作用和軟碟引導扇區(qū)的作用一樣:從分區(qū)中讀取內(nèi)核映象並啟動內(nèi)核。和軟碟引導不同的是,內(nèi)核映象保存在硬碟分區(qū)檔系統(tǒng)中,而不象軟碟那樣保存在後續(xù)的連續(xù)扇區(qū)中,因此,硬碟引導扇區(qū)中的代碼還需要定位內(nèi)核映象在檔系統(tǒng)中的位置,然後裝載內(nèi)核並啟動內(nèi)核。Linux系統(tǒng)的常見引導方式有兩種:LILO引導和Loadin引導;其中LILO可實現(xiàn)多重引導,Loadin可在DOS下引導Linux。此外,Linux內(nèi)核也自帶了一個bootsect-loader。由於bootsect-loader只能實現(xiàn)Linux的引導,不像前兩個那樣具有很大的靈活性,所以在普通應用場合實際上很少使用。但由於bootsect-loader短小、沒有多餘的代碼、並且是內(nèi)核源碼的有機組成部分。下麵將主要對bootsect-loader檔進行分析。bootsect-loader在內(nèi)和源碼中對應的程式是/arch/i386/boot/bootsect.s。幾個相關檔是:(1)/arch/i386/boot/bootsect.s(2)/include/linux/config.h(3)/include/asm/boot.h(4)/include/linux/autoconf.h2.2.1Linux系統(tǒng)引導過程分析
開啟Intelx86PC的電源後,機器就會開始執(zhí)行ROMBIOS的一系列系統(tǒng)測試動作,包括檢查RAM、鍵盤、顯示器和軟硬磁片等。接著控制權(quán)轉(zhuǎn)移給ROM中的啟動程式(ROMbootstraproutine);該程式會將磁片上的第0軌第0扇區(qū)(稱為bootsector或MasterBootRecord,MBR,系統(tǒng)的引導程式就放在此處)讀入記憶體,放入自0x07C0:0x0000開始的512個位元組處;然後處理機跳轉(zhuǎn)到該處開始執(zhí)行(位於該處的)MBR引導程式,CS:IP=0x07C0:0x0000。加電後處理機運行在與8086相相容的實模式下。如果要用bootsect-loader進行系統(tǒng)引導,則必須把bootsect.s編譯連接後對應的二進位代碼置於MBR;當ROMBIOS把bootsect.s編譯連接後對應的二進位代碼裝入記憶體後,機器的控制權(quán)就完全轉(zhuǎn)交給bootsect;也就是說,bootsect將是第一個被讀入記憶體中並執(zhí)行的程式。Bootsect接管機器控制權(quán)後,將依次進行以下一些動作:(1)首先,bootsect將它“自己”(自位置0x07C0:0x0000開始的512個位元組)從被ROMBIOS載入的地址0x07C0:0x0000處搬到0x9000:0000處;這一任務由bootsect.s的前十條指令完成;第十一條指令“jmpigo,INITSEG”則把機器跳轉(zhuǎn)到“新”的bootsect的“jmpigo,INITSEG”後的那條指令“go:mov
di,#0x4000-12”;之後,繼續(xù)執(zhí)行bootsect的剩下的代碼;在bootsect.s中定義了幾個常量:BOOTSEG=0x07C0bios載入MBR的約定位置的段址;INITSEG=0x9000bootsect.s的前十條指令將自己搬到此處(段址)SETUPSEG=0x9020裝入Setup.s的段址SYSSEG=0x1000系統(tǒng)區(qū)段址這些常量的定義可參見/include/asm/boot.h;在下面的分析中這些常量會經(jīng)常用到。(2)以0x9000:0x4000-12為棧底,建立自己的棧區(qū);其中0x9000:0x4000-12到0x9000:0x4000的一十二個位元組預留作磁片參數(shù)表區(qū);(3)在0x9000:0x4000-12到0x9000:0x4000的一十二個預留位元組中建立新的磁片參數(shù)表。由於設計者考慮到有些老的bios不能準確地識別磁片每個磁軌的扇區(qū)數(shù),使得bios建立的磁片參數(shù)表妨礙磁片的最高性能發(fā)揮,所以設計者在bios建立的磁片參數(shù)表的基礎上使用枚舉法測試,試圖建立準確的“新”的磁片參數(shù)表(這是在後繼步驟中完成的);並把參數(shù)表的位置由原來的0x0000:0x0078搬到0x9000:0x4000-12;且修改老的磁片參數(shù)表區(qū)使之指向新的磁片參數(shù)表;(4)接下來是load_setup子過程;它調(diào)用0x13中斷的第2號服務;把第0道第2扇區(qū)開始的連續(xù)的setup_sects(為常量4)個扇區(qū)讀到緊鄰bootsect的記憶體區(qū);,即0x9000:0x0200開始的2048個位元組;而這四個扇區(qū)的內(nèi)容就是/arch/i386/boot/setup.s編譯連接後對應的二進位代碼。換句話說,如果要用bootsect-loader進行系統(tǒng)引導,不僅必須把bootsect.s編譯連接後對應的二進位代碼置於MBR,而且還要將\把setup.s編譯連接後對應的二進位代碼置於緊跟MBR後的連續(xù)的四個扇區(qū)中。由於setup.s對應的可執(zhí)行碼是由bootsect裝載的,所以可以根據(jù)需要修改bootsect來設置setup.s對應的可執(zhí)行碼;(5)load_setup子過程的惟一出口是probe_loop子過程;該過程通過枚舉法測試磁片“每個磁軌的扇區(qū)數(shù)”;(6)接下來幾個子過程比較清晰:顯示“Loading”;讀入系統(tǒng)到0x1000:0x0000;關掉軟驅(qū)馬達;根據(jù)的5步測出的“每個磁軌的扇區(qū)數(shù)”確定磁片類型;最後跳轉(zhuǎn)到0x9000:0x0200,即setup.s對應的可執(zhí)行碼的入口,將機器控制權(quán)轉(zhuǎn)交setup.s;整個bootsect代碼運行完畢。引導過程執(zhí)行完後的記憶體映像圖如圖2.3所示。完成了系統(tǒng)的引導後,系統(tǒng)將進入到初始化處理階段。系統(tǒng)的初始化分為實模式和保護模式兩部分。為了簡單起見,在上面的分析中,忽略了對大內(nèi)核的處理的分析。因為對大內(nèi)核的處理,只是此引導過程中的一個很小的部分,並不影響對整體的把握。2.2.2實模式下的初始化
實模式下的初始化,主要是指從內(nèi)核引導成功後,到進入保護模式之前系統(tǒng)所做的一些處理。在內(nèi)核源碼中對應的程式是/arch/i386/boot/setup.s;以下部分主要對該檔進行分析。這部分的分析要弄懂它的處理流程和INITSEG(9000:0000)段參數(shù)表的建立的過程。該參數(shù)表包含了很多硬體參數(shù),這些都是以後進行保護模式下初始化以及核心建立的基礎。相關檔有:
/arch/i386/boot/bootsect.s/include/linux/config.h
/include/asm/boot.h
/include/asm/segment.h
/include/linux/version.h
/include/linux/compile.h
setup.s完成在實模式下版本檢查,並將硬碟、滑鼠及記憶體的參數(shù)寫入到INITSEG中,並負責進入保護模式。實模式下的初始化過程如圖2.4及圖2.5所示:
圖2.4實模式下的初始化過程1圖2.5實模式下的初始化過程2表2.1INITSEG(9000:0000)段參數(shù)表:(參見include/linux/tty.h)參數(shù)名偏移量(段址均為0x9000)長度Byte參考檔PARAM_CURSOR_POS0x00002arch/i386/boot/video.sextendedmemSize0x00022arch/i386/boot/setup.sPARAM_VIDEO_PAGE0x00042arch/i386/boot/video.sPARAM_VIDEO_MODE0x00061arch/i386/boot/video.sPARAM_VIDEO_COLS0x00071arch/i386/boot/video.s未用0x00082include/linux/tty.hPARAM_VIDEO_EGA_BX0x000a2arch/i386/boot/video.s未用0x000c2include/linux/tty.hPARAM_VIDEO_LINES0x000e1arch/i386/boot/video.sPARAM_HAVE_VGA0x000f1arch/i386/boot/video.sPARAM_FONT_POINTS0x00102arch/i386/boot/video.sPARAM_LFB_WIDTH0x00122arch/i386/boot/video.sPARAM_LFB_HEIGHT0x00142arch/i386/boot/video.sPARAM_LFB_DEPTH0x00162arch/i386/boot/video.sPARAM_LFB_BASE0x00184arch/i386/boot/video.sPARAM_LFB_SIZE0x001c4arch/i386/boot/video.s暫未用①0x00204include/linux/tty.hPARAM_LFB_LINELENGTH0x00242arch/i386/boot/video.sPARAM_LFB_COLORS0x00266arch/i386/boot/video.s暫未用②0x002c2arch/i386/boot/video.sPARAM_VESAPM_SEG0x002e2arch/i386/boot/video.sPARAM_VESAPM_OFF0x00302arch/i386/boot/video.sPARAM_LFB_PAGES0x00322arch/i386/boot/video.s保留0x0034--0x003f
include/linux/tty.hAPMBIOSVersion③0x00402arch/i386/boot/setup.sBIOScodesegment0x00422arch/i386/boot/setup.sBIOSentryoffset0x00444arch/i386/boot/setup.sBIOS16bitcodeseg0x00482arch/i386/boot/setup.sBIOSdatasegment0x004a2arch/i386/boot/setup.s支持32位標誌④0x004c2arch/i386/boot/setup.sBIOScodeseglength0x004e4arch/i386/boot/setup.sBIOSdataseglength0x00522arch/i386/boot/setup.shd0參數(shù)0x008016arch/i386/boot/setup.shd0參數(shù)0x009016arch/i386/boot/setup.sPS/2device標誌⑤0x01ff1arch/i386/boot/setup.s
注:①include/linux/tty.h:CL_MAGICandCL_OFFSEThere②include/linux/tty.h:unsignedcharrsvd_size;//0x2cunsignedcharrsvd_pos;//0x2d③0表示沒有電源管理(APM)BIOS④0x0002置位表示支持32位模式⑤0表示沒有,0x0aa表示有滑鼠器2.2.3保護模式下的初始化
保護模式下的初始化,是指處理機進入保護模式後到運行系統(tǒng)第一個內(nèi)核程式過程中,系統(tǒng)所做的一些處理。保護模式下的初始化在內(nèi)核源碼中對應的程式是/arch/i386/boot/compressed/head.s和/arch/i386/kernel/head.s;以下部分主要是針對這兩個檔進行的分析。在i386體系結(jié)構(gòu)中,因為i386本身的問題,在"arch/alpha/kernel/head.s"中需要更多的設置,最終是通過callSYMBOL_NAME(start_kernel)轉(zhuǎn)到start_kernel()這個體系結(jié)構(gòu)無關的函數(shù)中去執(zhí)行了。
在i386系統(tǒng)中,當內(nèi)核以bzImage的形式壓縮,即大內(nèi)核方式(BIG_KERNEL)壓縮時就需要預先處理bootsect.s和setup.s,按照大核模式使用$(CPP)處理生成bbootsect.s和bsetup.s,然後再編譯生成相應的.o檔,並使用"arch/i386/boot/compressed/build.c"生成的build工具,將實際的內(nèi)核(未壓縮的,含kernel中的head.s代碼)與"arch/i386/boot/compressed"下的head.s和misc.c合成到一起,其中的head.s代替了"arch/i386/kernel/head.s"的位置,由Bootloader引導執(zhí)行(startup_32入口),然後它調(diào)用misc.c中定義的decompress_kernel()函數(shù),使用"lib/inflate.c"中定義的gunzip()將內(nèi)核解壓到0x100000,再轉(zhuǎn)到其上執(zhí)行"arch/i386/kernel/head.s"中的startup_32代碼。幾個有關檔是:/arch/i386/boot/compressed/head.s/arch/i386/kernel/head.s//arch/i386/boot/compressed/MISC.c/arch/i386/boot/setup.s/include/asm/segment.h/arch/i386/kernel/traps.c/include/i386/desc.h/include/asm-i386/processor.h保護模式下的初始化過程大致如下:1./arch/i386/kernel/head.s流程因為在setup.s最後的是一條轉(zhuǎn)跳指令,跳到內(nèi)核第一條指令並開始執(zhí)行。指令中指向的是記憶體中的絕對地址,無法依此判斷轉(zhuǎn)跳到了head.s。但是可以通過Makefile簡單的確定head.s位於內(nèi)核的前端。在arch/i386的Makefile
中定義了HEAD:=arch/i386/kernel/head.o
在Linux總的Makefile中的語句includearch/$(ARCH)/Makefile說明HEAD定義在該檔中有效。由如下語句:vmlinux:$(CONFIGURATION)init/main.oinit/version.o
linuxsubdirs$(LD)$(LINKFLAGS)$(HEAD)init/main.oinit/version.o\$(ARCHIVES)\$(FILESYSTEMS)\$(DRIVERS)\$(LIBS)-ovmlinux$(NM)vmlinux|grep-v'\(compiled\)\|\(\.o$$\)\|\(a\)'|sort>System.map從這個依賴關係可以獲得大量的資訊:(1)$(HEAD)即head.o的確第一個被連接到核心中;(2)內(nèi)核支持的所有檔系統(tǒng)全部編譯到$(FILESYSTEMS)即fs/filesystems.a中;(3)內(nèi)核中支持的所有網(wǎng)路協(xié)議全部編譯到net.a中;(4)內(nèi)核中支持的所有SCSI驅(qū)動全部編譯到scsi.a中;
這樣看來,內(nèi)核就是一堆庫檔和目標檔的集合。如果要對內(nèi)核減肥的話,可以好好比較一下,看究竟是那個部分佔用了空間。在System.map中包含了所有的內(nèi)核輸出的函數(shù),這些是在編寫內(nèi)核模組的時候可以調(diào)用的系統(tǒng)函數(shù)。2.head.s的分析(1)首先將ds、es、fs和gs指向系統(tǒng)數(shù)據(jù)段KERNEL_DS(KERNEL_DS在asm/segment.h中定義,表示全局描述符表中中的第三項)。
注意:該此時生效的全局描述符表並不是在head.s中定義的,而仍然是在setup.s中定義的。(2)數(shù)據(jù)段全部清空。(3)setup_idt為一段子程式,將中斷向量表全部指向ignore_int函數(shù)。該函數(shù)列印出“unknowninterrupt”,當然這樣的中斷處理函數(shù)什麼也幹不了。(4)查看數(shù)據(jù)線A20是否有效,否則迴圈等待。地址線A20是x86的歷史遺留問題,決定是否能訪問1M以上記憶體。(5)拷貝啟動參數(shù)到0x5000頁的前半頁,而將setup.s取出的bios參數(shù)放到後半頁。(6)檢查CPU類型。(7)初始化頁表,只初始化最初幾頁。①將swapper_pg_dir(0x2000)和pg0(0x3000)清空,swapper_pg_dir作為整個系統(tǒng)的頁目錄。②將pg0作為第一個頁表,將其地址賦到swapper_pg_dir的第一個32位字中。③同時將該頁表項也賦給swapper_pg_dir的第3072個入口,表示虛擬地址0xc0000000也指向pg0。④將pg0這個頁表填滿指向記憶體前4M。⑤進入分頁方式。(8)裝入新的GDT和ldt表。(9)刷新段寄存器ds、es、fs和gs。(10)使用系統(tǒng)堆疊,即預留的0x6000頁面。(11)執(zhí)行start_kernel函數(shù),這是第一個C編制的函數(shù),內(nèi)核又有了一個新的開始。圖2.6/arch/i386/kernel/head.s流程圖一圖2.7/arch/i386/kernel/head.s流程圖二3./arch/i386/boot/compressed/head.s流程圖2.8是/arch/i386/boot/compressed/head.s的流程圖。從圖中可看到,保護模式下的初始化主要做了幾件事:解壓內(nèi)核到0x100000處、建立頁目錄和pg0頁表並啟動分頁功能(即虛存管理功能)、保存實模式下測到的硬體資訊到empty_zero_page、初始化命令緩存區(qū)、檢測cpu類型、檢查協(xié)處理器、重新建立GDT全局描述符表和中斷描述附表IDT。
圖2.8/arch/i386/boot/compressed/head.s流程
從頁目錄和pg0頁表可以看出,0;4M物理記憶體被用作系統(tǒng)區(qū),它被映射到系統(tǒng)段線性空間的0;4M和3G;3G+4M;即系統(tǒng)可以通過訪問這兩個段來訪問實際的0;4M物理記憶體,也就是系統(tǒng)所在的區(qū)域;本來在實模式下初始化時已經(jīng)建立了全局描述符表GDT,而此處重新建立全局描述符表GDT則主要是出於兩個原因:一個就是若內(nèi)核是大內(nèi)核bzimag,則以前建立的GDT,可能在解壓時已經(jīng)被覆蓋了。所以在這個源碼檔中均只採用相對轉(zhuǎn)移指令jxx
nf或jxx
nb;二是以前建立的GDT是建立在實地址方式下的,而現(xiàn)在則是在啟用保護虛擬地址方式之後建立的,也即現(xiàn)在的GDT是建立在邏輯地址(即線性地址)上的;每次建立新的GDT後和啟用保護虛擬地址方式後都必須重新裝載系統(tǒng)棧和重新初始化各段寄存器:cs,ds,es,fs,gs;
從實模式下的初始化和保護模式下的初始化過程可以看出,Linux系統(tǒng)由實模式進入到保護模式的過程大致如圖2.9所示。由於分頁機制只能在保護模式下啟動,不能在實模式下啟動,所以第一步是必要的;又因為在386保護模式下GDT和IDT是建立在邏輯地址(線性地址)上的,所以第三步也是必要的;位置系統(tǒng)數(shù)據(jù)大小0x101000頁目錄swapper_pg_dir4K0x102000頁表pg04K0x103000empty_bad_page4K0x104000empty_bad_page_table4K0x105000empty_zero_page4K0x105000系統(tǒng)硬體參數(shù)2K0x105800命令緩衝區(qū)2K0x106000全局描述附表gdt_table4192B經(jīng)過實模式和保護模式下的初始化後,主要系統(tǒng)數(shù)據(jù)的分佈如表2.2所示。
從上面對Linux系統(tǒng)的初始化過程的分析可以看出,以程式執(zhí)行流程為線索,即按照程式的執(zhí)行先後順序,弄懂程式執(zhí)行的各個階段所進行的處理,及其各階段之間的相互聯(lián)繫。而流程圖應該是這種分析方法最合適的表達工具。事實上,以程式執(zhí)行流程為線索,是分析任何源代碼都首選的方法。用這種方法來分析系統(tǒng)的初始化過程或用戶進程的執(zhí)行流程應該說是很有效的。當然由於操作系統(tǒng)的特殊性,光用這種方法是遠遠不夠的。2.2.4系統(tǒng)初始化
Linux內(nèi)核裝入之後,Linux內(nèi)核進行硬體和設備驅(qū)動程式的初始化,然後運行init。init是Linux內(nèi)核啟動的第一個用戶級進程,其進程標識號始終為1,該進程在系統(tǒng)引導和關機過程中扮演重要角色。Linux內(nèi)核進行的初始化工作可大體描述如下:(1)Linux內(nèi)核一般是壓縮保存的,因此,它首先要進行自身的解壓縮。內(nèi)核映象前面的一些代碼完成解壓縮。(2)如果系統(tǒng)中安裝有可支持特殊文本模式的、且Linux可識別的SVGA卡,Linux會提示用戶選擇適當?shù)奈谋撅@示模式。但是,如果在內(nèi)核的編譯過程中預先設置了文本模式,則不會提示選擇顯示模式。該顯示模式也可通過LILO或rdev
設置。(3)內(nèi)核接下來檢測其他的硬體設備,例如硬碟、軟碟和網(wǎng)卡等,並對相應的設備驅(qū)動程式進行配置。這時,內(nèi)核會輸出一些硬體資訊,類似下麵的輸出:LILOboot:
LoadingLinux.
Memory:sizedbyint13088h
Console:16pointfont,400scans
Console:colourVGA+80x25,1virtualconsole(max63)
pcibios_init:BIOS32ServiceDirectorystructureat0x000f7510
pcibios_init:BIOS32ServiceDirectoryentryat0xfd7d2
pcibios_init:PCIBIOSrevision2.10entryat0xfd9e6
ProbingPCIhardware.
Calibratingdelayloop..ok-231.83BogoMIPS
Memory:30760k/32704kavailable(748kkernelcode,384kreserved,812kdata)
SwanseaUniversityComputerSocietyNET3.035forLinux2.0
NET3:UNIXdomainsockets0.13forLinuxNET3.035.
SwanseaUniversityComputerSocietyTCP/IPforNET3.034
IPProtocols:IGMP,ICMP,UDP,TCP
LinuxIPmulticastrouter0.07.
VFS:Diskquotasversiondquot_5.6.0initialized
Checking386/387coupling...Ok
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度裝修工程節(jié)能認證保修合同
- 2025年度酒業(yè)知識產(chǎn)權(quán)保護合伙人合同
- 二零二五年度經(jīng)典實習合同(建筑行業(yè)實習)
- 二零二五年度藥品研發(fā)過程中的數(shù)據(jù)保密與共享合同
- 2025年度運輸公司司機的二零二五年度勞動合同執(zhí)行與評估協(xié)議
- 2025年度私人車輛抵押借款合同(含車輛貸款合規(guī)審查)
- 2024-2025學年新教材高中化學專題2研究物質(zhì)的基本方法3人類對原子結(jié)構(gòu)的認識課時作業(yè)含解析蘇教版必修第一冊
- 高科技企業(yè)產(chǎn)品中的冷鏈運輸安全保障策略
- 探索小微企業(yè)如何運用創(chuàng)新設計提升機械設備效能
- 教育培訓在提升川菜館員工素質(zhì)中的作用
- 子宮畸形的超聲診斷
- 2024年1月高考適應性測試“九省聯(lián)考”數(shù)學 試題(學生版+解析版)
- JT-T-1004.1-2015城市軌道交通行車調(diào)度員技能和素質(zhì)要求第1部分:地鐵輕軌和單軌
- (高清版)WST 408-2024 定量檢驗程序分析性能驗證指南
- (正式版)JBT 11270-2024 立體倉庫組合式鋼結(jié)構(gòu)貨架技術規(guī)范
- DB11∕T 2035-2022 供暖民用建筑室溫無線采集系統(tǒng)技術要求
- 《復旦大學》課件
- 針灸與按摩綜合療法
- Photoshop 2022從入門到精通
- T-GDWJ 013-2022 廣東省健康醫(yī)療數(shù)據(jù)安全分類分級管理技術規(guī)范
- DB43-T 2775-2023 花櫚木播種育苗技術規(guī)程
評論
0/150
提交評論