引導代碼

分析linux0.11版本的引導程序


BIOS程序從0XFFFF0處開始執行,BIOS程序的入口地址就在0XFFFF0,第一條指令就放在這個位置;

CS(code segment register)代碼段寄存器,存在於CPU中,指向CPU當前執行代碼在內存中所在的區域;

IP/EIP(Instruction Pointer)指令指針寄存器,存在於CPU中,記錄將要執行的指令在代碼段內的偏移地址,


1,BIOS在內存中加載中斷向量表和中斷服務程序;

BIOS程序固化在計算機主板上一塊很小的ROM芯片裏面,通常不同的主板所用的BIOS也有所不同,就啓動部分而言,各種類型的BIOS原理大致相似,

該例程所示的BIOS只有8K,所佔用地址段爲0XFE000~0XFFFFF,


BIOS程序在內存的最開始位置(即0X00000)用1kb的內存空間(0x00000 ~ 0x003ff)構建中斷向量表,並在緊挨着的位置用256字節的內存空間構建BIOS數據區(0x00400~0x004ff),在大約56KB以後的位置(0X0E05B)加載了8KB左右的中斷向量表相應的若干中斷服務程序,

中斷向量表中有256箇中斷向量,每個中斷向量佔4個字節,其中2個字節是CS的值,兩個字節是IP的值,每個中斷向量都指向一個具體的中斷服務程序;


2,加載操作系統內核程序併爲保護模式做準備;

從現在開始要執行真正的boot操作了,即把軟盤中的操作系統程序加載至內存,對於0.11版本而言,計算機將分3批次逐次加載操作系統的內核代碼,第一批由BIOS中斷0x19h把第一扇區bootsect的內容加載到內存,第二批和第三批在bootsect的指揮下,分別把其後的4個扇區和隨後的240個扇區的內容加載到內存;

    a) 加載第一部分代碼-引導程序(bootsect)

    CPU接收到一個int 19h的中斷,然後立即在中斷向量表中找到19h中斷向量,接下來中斷向量把CPU指向0x0E6F2,這個位置就是19h相對應的中斷服務程序的入口地址,這個中斷服務程序的作用就是把BIOS事先設計好的,代碼是固定的,與linux操作系統無關,這個中斷服務程序將軟驅0號磁頭對應的盤面的0磁道1扇區的內容拷貝到內存0X07C00處,這個扇區的內容就是0.11操作系統的引導程序,就是bootsect,其作用就是陸續把軟盤中的操作系統程序載入到內存,這樣製作的第一扇區就稱爲啓動扇區,

第一扇區的程序是由bootsect.s中的彙編程序彙編而成,

   b)加載第二批和第三批代碼到內存

      bootsect的作用就是把第二批和第三批程序陸續加載到內存,爲此,bootsect首要工作就是規劃內存,

     爲了規劃內存,bootsect首先設計瞭如下的代碼:

     SETUPLEN = 4 //將要加載的setup程序的扇區數

    BOOTSEG = 0X07C0//啓動扇區被BIOS加載的位置

    INITSEG = 0X9000 //將要移動的新位置

    SETUPSEG = 0X9020 //被加載到的位置

    SYSSEG = 0X1000 // 內核被加載的位置

   ENDSEG = SYSSEG+SYSSIZE    //停止加載的位置

 複製bootsect從0X07C00到0X90000處,

    接着bootsect執行第二步,將setup程序加載到內存中,這個將要借住中斷向量0x13h所指向的中斷服務程序來完成;

    這個中斷服務程序的執行過程與0x19h中斷向量所指向啓動加載服務程序不同;

    0x19h中斷向量所指向的啓動加載服務是BIOS指向的,而0x13h的中斷服務程序是linux操作系統自身的啓動代碼bootsect執行的;

   0x19h的中斷服務程序只負責把軟盤的第一扇區的代碼加載到0X07C00位置,int 0x13h的中斷服務程序則可以根據設計者的意圖把指定扇區的代碼加載到內存的指定位置;

  接着加載第三部分代碼-system模塊:將系統模塊載入內存;

     與int 0x13h一樣,只是這次加載的扇區數爲240,是之前的4個扇區的60倍,所需時間是之前的幾十倍;爲此,在加載期間顯示一行屏幕消息"Loading system",以提升用戶,計算機此時正在加載系統;加載工作主要由bootsect調用read_it子程序完成的;

linux0.11使用Minix操作系統的文件系統管理方式,要求系統必須存在一個根文件系統,其他文件系統掛接其上,而不是同等地位;系統的啓動必須兩部分數據:系統內核鏡像和根文件系統;


   

3,setup程序將位於0X10000的內核程序拷貝到內存地址起始位置0X00000處;而0X00000這個位置原來存放着由BIOS建立的中斷向量表以及BIOS數據區,這個複製動作將BIOS中斷向量表和BIOS數據區完全覆蓋,使它們不復存在,直到新的中斷服務體系構建完畢之前,操作系統不再具備響應並處理中斷的能力,

這樣做的意義有三個:a)廢除BIOS的中斷向量表,等價於廢除了BIOS提供的實模式下的中斷服務程序;

                                        b)收回使用壽命剛剛結束的程序所佔的內存空間;

                                        c)讓內核代碼佔據內存物理地址最開始的最天然的最有利的位置;

廢除了BIOS提供的實模式下的中斷服務程序,但是操作系統不能沒有中斷,所以必須建立新的中斷機制;

  

4,設置中斷描述符表和全局描述符表

     通過setup程序自身提供的數據信息對中斷描述符表寄存器IDTR和全局描述符表寄存器GDTR進行初始化設置;


GDT表是保護模式下管理段描述符的數據結構;


在執行main函數之前,先要執行三個彙編代碼生成的程序,即bootsect,setup和head之後,才執行由main函數開始的用C語言編寫的操作系統內核程序;

第一步,加載bootsect到0X07C00,然後複製到0X90000,

第二步,加載setup到0X90200;這兩段程序是分別加載和執行的;

head.s的加載與執行稍有不同,先將head.s彙編成目標代碼,將用C語言編寫的內核程序編譯成目標代碼,然後鏈接成system模塊,也就是說system模塊裏面,既有內核程序也有head程序,兩者是緊挨着的,要點是,head程序在前,內核程序在後,所以head程序名字叫"head"head程序在內存中佔有25kb+184B的空間,





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章