史萊姆論壇

返回   史萊姆論壇 > 專業主討論區 > 網路疑難應用技術研討區
忘記密碼?
論壇說明

歡迎您來到『史萊姆論壇』 ^___^

您目前正以訪客的身份瀏覽本論壇,訪客所擁有的權限將受到限制,您可以瀏覽本論壇大部份的版區與文章,但您將無法參與任何討論或是使用私人訊息與其他會員交流。若您希望擁有完整的使用權限,請註冊成為我們的一份子,註冊的程序十分簡單、快速,而且最重要的是--註冊是完全免費的!

請點擊這裡:『註冊成為我們的一份子!』

Google 提供的廣告


發文 回覆
 
主題工具 顯示模式
舊 2004-06-06, 05:49 AM   #1
psac
榮譽會員
 
psac 的頭像
榮譽勳章
UID - 3662
在線等級: 級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時
註冊日期: 2002-12-07
住址: 木柵市立動物園
文章: 17381
現金: 5253 金幣
資產: 33853 金幣
預設 Linux開機程序的分析

這篇文章的目的,在將linuxkernel的boot部份做一個介紹,因為筆者覺得很少有這樣的
文章介紹一個作業系統最最開始的一步--把kernel本身載入至記憶體中,同時進行一些機
器相關(machinedependent)的啟始化工作,由於linux剛好使用的是大家最熟悉的386,
486系列PC,所以在說明其程序流程時,也剛好可以對其相關的PC硬體架構做探討,可以
說是一舉兩得,不過,我必須假設讀者對於組合語言及PC最基礎的架構,如暫存器,分
段,分頁,中斷服務等有大概的認識。
  讀者可在linuxsourcecode的/boot子目錄下找到幾個以.S作為副檔名的組合語言檔
,本文要說明的即是其中的bootsect.S及setup.S兩個檔案,及盡量簡單的說明其所牽涉
的相關硬體部份。


bootsect.S
  這個程序是linuxkernel的第一個程序,包括了linux自己的bootstrap程序,但是在
說明這個程序前,必須先說明一般IBMPC開機時的動作(此處的開機是指"開啟PC的電源"
):
  一般PC在電源一開時,是由記憶體中位址FFFF:0000開始執行(這個位址一定在ROMBIO
S中,ROMBIOS一般是在FEOOOh到FFFFFh中),而此處的內容則是一個jump指令,jump到另
一個位於ROMBIOS中的位置,開始執行一系列的動作,包括了檢查RAM,keyboard,顯示
器,軟硬磁牒等等,這些動作是由系統測試碼(systemtestcode)來執行的,隨著製作BI
OS廠商的不同而會有些許差異,但都是大同小異,讀者可自行觀察自家機器開機時,螢
幕上所顯示的檢查訊息。
  緊接著系統測試碼之後,控制權會轉移給ROM中的啟動程序(ROMbootstraproutine)
,這個程序會將磁牒上的零道零扇區讀入記憶體中(這就是一般所謂的bootsector,如果你
曾接觸過電腦病毒,就大概聽過它的大名),至於被讀到記憶體的哪裡呢?--絕對位置07C0
:0000(即07C00h處),這是IBM系列PC的特性。而位在linux開機磁牒的bootsector上的正
是linux的bootsect程序,也就是說,bootsect是第一個被讀入記憶體中並執行的程序。現
在,我們可以開始來看看到底bootsect做了什麼。
第一步
  首先,bootsect將它"自己"從被ROMBIOS載入的絕對位址0x7C00處搬到0x90000處,
然後利用一個jmpi(jumpindirectly)的指令,跳到新位置的jmpi的下一行去執行,關鍵
的assemblycode如下:
.
(搬移bootsect本身)
.
.
jmpigo,INITSEC
go:
.
.
.
  表示將跳到CS為0x9000,IP為offset"go"的位置(CS:IP=0x9000ffsetgo),其中I
NITSEC=0x9000定義於程序開頭的部份,而go這個label則恰好是下一行指令所在的位置

第二步
  接著,將其它segmentregisters包括DS,ES,SS都指向0x9000這個位置,與CS看齊
。另外將SP及DX指向一任意位移位址(offset),這個位址等一下會用來存放磁牒參數表
(diskpara-metertable)
  提到磁牒參數表,就必須提到BIOS中斷1Eh。先簡單的介紹一下BIOS的中斷服務:80
x86將記憶體最低的256*4byte保留給256個中斷向量(每個interruptvector大小為4byte,
所以一共有256*4=1024byte),而其中的第1Eh個向量指向"磁牒參數表",這個表會告訴
電腦如何去讀取磁牒機,而我們所要做的事是搬移磁牒參數表到剛才所設定的任意位址

  接著,改變搬移來的參數表的參數,以符合我們的需要。再將中斷向量1Eh指向我們
所修改過的磁牒參數表,然後呼叫BIOSinterrupt的int13h(function0,即AH=0)重置磁
盤控制卡及磁牒驅動器,之後磁牒機就會照我們的意思動作了。如果你曾trace過DOS的
kernel,你會發現,上述的動作在DOS中也有類似的對應流程。
現在讓我們來看看關鍵的程序碼:.
.
.
push#0
popfs
movbx,#0x78
.
(使GS:SI=FS:BX,指向磁牒參數表,
再將GS:SI所指位址的內容搬移6個
word至ESI所指的位址)
.
.
  此段程序是將FS:BX調整成0000:0078,接著再將GS:SI的內容設成與FS:BX相同,此
處0x78h即為int1Eh的起始位置(7*16+8=120,(1*16+14)*4=120)。調整ESI為剛才所設
定的任意位址,從GS:SI搬移6個word(即12byte)到ESI所指的位置,顯然磁牒參數表的
長度就是6個word,(不過事實上,磁牒參數表的確實長度是11個byte)。關於磁牒參數表
,有興趣的讀者可自行參閱講述BIOSinterruptservices的技術手冊,會有詳細的說明。
 
  讀者可以用debug自行觀察自家電腦上DOS的磁牒參數表的起始位置(即int1Eh的內容
)。以下是筆者機器的情形(筆者使用的作業系統是MSDOS6.2):
C:>debug
-d0000:0000
0000:00008A101601F4067000-1600CB04F4067000......p.......p.
0000:0010F40670000301790E-43EB00F0EBEA00F0..p...y.C.......
0000:002004108E340C118E34-5700CB046F00CB04...4...4W...o...
0000:00308700CB0408079433-B700CB04F4067000.......3......p.
0000:00400C01790E4DF800F0-41F800F0BA165F06..y.M...A....._.
0000:005039E700F01B01790E-70118E341201790E9.....y.p..4..y.
0000:006000E000F085175F06-6EFE00F0EE067000......_.n.....p.
0000:007053FF00F0A4F000F0-220500003E4600C0S......."...>F..
^^^^^^^^
由上圖中可知,在DOS中磁牒參數表的起始位置(int1Eh的內容)為0000:0522。接著觀察
DOS中位置0000:0522開始的11個byte,也就是磁牒參數表的內容
C:>debug
-d0000:0520l10
0000:05204D53DF022502121B-FF54F60F08000000MS..%....T......
^^^^^^^^^^^^^^^^^^^^^^
此11byte即為磁牒參數表的內容(分別是byte00h到0Ah)
  在程序中我們所更動的是第五個byte(byte04h),改為18h(在上圖例子中為12h),這
個byte的功能是定義磁軌上一個磁區的資料筆數。關鍵的程序碼如下:
.
movb4(di),*18
.
 
第三步
  接著利用BIOS中斷服務int13h的第0號功能,重置磁牒控制器,使得剛才的設定發揮
功能。
.
.
xorah,ah
xordl,dl
int0x13
.
.
第四步
  完成重置磁牒控制器之後,bootsect就從磁牒上讀入緊鄰著bootsect的setup程序,
也就是以後將會介紹的setup.S,此讀入動作是利用BIOS中斷服務int13h的第2號功能。
setup的image將會讀入至程序所指定的記憶體絕對位址0x90200處,也就是在記憶體中緊鄰著
bootsect所在的位置。待setup的image讀入記憶體後,利用BIOS中斷服務int13h的第8號功
能讀取目前磁牒機的參數。
第五步
  再來,就要讀入真正linux的kernel了,也就是你可以在linux的根目錄下看到的"v
mlinuz"。在讀入前,將會先呼叫BIOS中斷服務int10h的第3號功能,讀取游標位置,之
後再呼叫BIOS中斷服務int10h的第13h號功能,在螢幕上輸出字串串"Loading",這個字
符串在bootlinux時都會首先被看到,相信大家應該覺得很眼熟吧。
  linux的kernel將會被讀入至記憶體絕對位址0x10000處,鍵關的程序碼如下:
.
.
movax,#SYSSEG
moves,ax
callread_it
callkill_motor
.
.
  其中SYSSEG於程序開頭時定義為0x1000,先將ES內容設為0x1000,接著在read_it這
個子程序便以ES為目的地的節位址,將kernel讀入記憶體中,至於read_it子程序的詳細內
容筆者並不想一一介紹,不過聰明的讀者們應該已經猜到,read_it一定又利用了BIOSi
nt13h與磁牒有關的I/O中斷服務了。
  至於kill_motor子程序,它的功能在於停止軟碟機的馬達(各位聰明的讀者會不會覺
得這個子程序的名稱取得頗為傳神呢?),其程序碼如下:
.
.
kill_motor:
pushdx
movdx,#0x3f2
xoral,al
outb
popdx
ret
.
.
  首先利用DX指定要輸出的port,而03f2這個port則是代表了軟碟控制器(floppydis
kcontroller)的所在,再利用outb將資料送出,而我們送出的資料,當然就是歸零過的
AL了。如此一來,軟碟的馬達就停止了。
第六步
  接下來做的事是檢查rootdevice,之後就仿照一開始的方法,利用indirectjump跳

至剛剛已讀入的setup部份,程序碼如下:
.
.
jmpi0,SETYPSEG
  其中SETUPSEG已在先前定義為0x9020,所以CS:IP會設定為9020:0000,即跳到絕對
位址為0x90200,也就是setup的起點。而bootsect也大功告成了。
到此為止,記憶體的內容應該如下圖所顯示:
比較
  把大家所熟知的MSDOS與linux的開機部份做個粗淺的比較,MSDOS由位於磁牒上boo
tsector的boot程序負責把IO.SYS載入記憶體中,而IO.SYS則負有把DOS的kernel--MSDOS.
SYS載入記憶體的重責大任。而linux則是由位於bootsector的bootsect程序負責把setup及
linux的kernel載入記憶體中,再將控制權交給setup。
  至於setup.S,就留到下一次再來討論了。
 
psac 目前離線  
送花文章: 3, 收花文章: 1631 篇, 收花: 3205 次
回覆時引用此帖
舊 2004-07-02, 05:11 AM   #2 (permalink)
管理版主
榮譽勳章
UID - 42425
在線等級: 級別:14 | 在線時長:273小時 | 升級還需:12小時級別:14 | 在線時長:273小時 | 升級還需:12小時級別:14 | 在線時長:273小時 | 升級還需:12小時級別:14 | 在線時長:273小時 | 升級還需:12小時
註冊日期: 2003-02-25
住址: 巫拉星球
文章: 1045
精華: 0
現金: 106 金幣
資產: 23113941 金幣
預設

基本上這也是一張圖打死的,
看文字會發瘋吧我想....
同理,考完一併告訴你完整流程,
而且是一張圖打死喔^^
看了保證你也可以去考RHEL的第一階段^^||
至少有30分吧...
巫拉 目前離線  
送花文章: 90, 收花文章: 110 篇, 收花: 222 次
回覆時引用此帖
舊 2004-07-02, 10:22 AM   #3 (permalink)
協調管理員
 
飛鳥 的頭像
榮譽勳章
UID - 23073
在線等級: 級別:72 | 在線時長:5513小時 | 升級還需:108小時級別:72 | 在線時長:5513小時 | 升級還需:108小時
註冊日期: 2003-01-07
VIP期限: 無限期
住址: 史萊姆團隊
文章: 7199
精華: 11
現金: 837 金幣
資產: 260029 金幣
預設

考試的開機流量會很重要,懂了會有30分到50分左右
__________________
http://flybird017.googlepages.com/quok.gif http://flybird020.googlepages.com/new321.gif
寶貝你我的地球
, 請 少開電器,減少溫室氣體排放外,多種植植物,減少列印, 多用背面,丟棄時做垃圾分類。

http://netgames123.googlepages.com/tobikeways.jpg

飛鳥 目前離線  
送花文章: 11706, 收花文章: 3363 篇, 收花: 16453 次
回覆時引用此帖
舊 2004-07-04, 05:27 AM   #4 (permalink)
長老會員
 
NiGHTsC 的頭像
榮譽勳章
UID - 913
在線等級: 級別:287 | 在線時長:83518小時 | 升級還需:578小時級別:287 | 在線時長:83518小時 | 升級還需:578小時級別:287 | 在線時長:83518小時 | 升級還需:578小時級別:287 | 在線時長:83518小時 | 升級還需:578小時級別:287 | 在線時長:83518小時 | 升級還需:578小時級別:287 | 在線時長:83518小時 | 升級還需:578小時級別:287 | 在線時長:83518小時 | 升級還需:578小時級別:287 | 在線時長:83518小時 | 升級還需:578小時級別:287 | 在線時長:83518小時 | 升級還需:578小時級別:287 | 在線時長:83518小時 | 升級還需:578小時級別:287 | 在線時長:83518小時 | 升級還需:578小時級別:287 | 在線時長:83518小時 | 升級還需:578小時
註冊日期: 2002-12-06
住址: 加拿大-魁北克(Canada-Quebec) -- 故鄉-高雄
文章: 5587
現金: 5951 金幣
資產: 193833733 金幣
預設

@_@..大大們,看不懂的話,怎麼辦????????
__________________
貴在中和,不爭之爭
http://i.imgur.com/QnVA4.jpg
2011-中華民國建國百年跨年慶典(精研完整版)
臺灣 我們的母親
臺灣 我們居住的家園
臺灣 我們心目中永遠的第一
相聚在這塊土地上,珍惜這裡的一切
NiGHTsC 目前離線  
送花文章: 13209, 收花文章: 1782 篇, 收花: 4045 次
回覆時引用此帖
舊 2004-07-04, 06:17 AM   #5 (permalink)
管理版主
榮譽勳章
UID - 42425
在線等級: 級別:14 | 在線時長:273小時 | 升級還需:12小時級別:14 | 在線時長:273小時 | 升級還需:12小時級別:14 | 在線時長:273小時 | 升級還需:12小時級別:14 | 在線時長:273小時 | 升級還需:12小時
註冊日期: 2003-02-25
住址: 巫拉星球
文章: 1045
精華: 0
現金: 106 金幣
資產: 23113941 金幣
預設

吾....好吧.....馬上寫....
不過我不太會貼圖....
我在請飛鳥幫我貼出來> <a
麻煩等一等ㄟ...
巫拉 目前離線  
送花文章: 90, 收花文章: 110 篇, 收花: 222 次
回覆時引用此帖
舊 2004-07-04, 04:35 PM   #6 (permalink)
Han
註冊會員
榮譽勳章

勳章總數
UID - 5141
在線等級: 級別:1 | 在線時長:7小時 | 升級還需:5小時
註冊日期: 2002-12-07
VIP期限: 2006-06
文章: 329
精華: 0
現金: 425 金幣
資產: 425 金幣
預設

引用:
原文由 wisley 所發表
基本上這也是一張圖打死的,
看文字會發瘋吧我想....
同理,考完一併告訴你完整流程,
而且是一張圖打死喔^^
看了保證你也可以去考RHEL的第一階段^^||
至少有30分吧...
光看文字果然 有要發瘋的感覺 = =||
Han 目前離線  
送花文章: 0, 收花文章: 1 篇, 收花: 1 次
回覆時引用此帖
發文 回覆



發表規則
不可以發文
不可以回覆主題
不可以上傳附加檔案
不可以編輯您的文章

論壇啟用 BB 語法
論壇啟用 表情符號
論壇啟用 [IMG] 語法
論壇禁用 HTML 語法
Trackbacks are 禁用
Pingbacks are 禁用
Refbacks are 禁用


所有時間均為台北時間。現在的時間是 02:26 AM


Powered by vBulletin® 版本 3.6.8
版權所有 ©2000 - 2025, Jelsoft Enterprises Ltd.


SEO by vBSEO 3.6.1