一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

linux啟動過程全接觸--點滴的力量

 accesine 2005-08-23
Linux啟動過程全接觸
handong 發(fā)表于 2004-12-8 10:27:00
作者:秋水 本文選自:開放系統(tǒng)世界——賽迪網(wǎng) 2002年10月10日

關(guān)于Windows啟動過程介紹的文章可謂多如牛毛,而對于Linux的介紹卻是鳳毛麟角。凡是曾經(jīng)使用過Linux的用戶可能都會注意到,當(dāng)計算機啟動時,屏幕上會出現(xiàn)很多信息。一般情況下,這些信息我們可以通過以下的命令看到:

cat /var/log/dmesg | more


這些信息究竟有什么含義?這個問題看起來似乎很容易回答,因為只要在Linux參考書里查找一下,就會找出一個類似于這樣的答案:“這是一些內(nèi)核啟動信息……”。但是“內(nèi)核啟動信息”到底是什么意思呢?

要想對Linux內(nèi)部工作有所了解,就必須要對Linux內(nèi)核的體系結(jié)構(gòu)有一個全面的了解。下面我們就去揭開它的秘密。在此,我不想解釋Linux內(nèi)核的體系結(jié)構(gòu),只想解釋(或者說是試圖去解釋)計算機系統(tǒng)啟動進程中一些最基本的概念。這里所說的啟動過程是指從按下開關(guān)到提示符出現(xiàn)的整個過程。

啟動指的是什么


在操作系統(tǒng)的詞匯里,啟動是指通過處理器執(zhí)行一些指令,把操作系統(tǒng)的一部分放入到主存中。在啟動過程中,Linux內(nèi)部的數(shù)據(jù)結(jié)構(gòu)會被初始化,會被賦給一些初始值,并且某些進程會被創(chuàng)建。因為當(dāng)計算機電源打開時,所有的硬件設(shè)備都處于一種不可預(yù)知的狀態(tài),內(nèi)存也處于一種不活動的隨機狀態(tài),所以,計算機的啟動過程可以說是一個長且復(fù)雜的任務(wù)。因此,我們必須知道,之所以叫“啟動”主要是因為計算機體系結(jié)構(gòu)的原因。

在此提請讀者注意:

1.對計算機內(nèi)部的工作和內(nèi)核的操作有一個基本的了解,對自己非常有益。

2.這篇文章中提到的所有文件,指的都是Linux內(nèi)核2.4.2-2版本里的文件。這些文件對于所有的Linux內(nèi)核來說都是相同的,并且可以在任何一個Linux系統(tǒng)里找到它們,此處我使用的是Red Hat 7.1。

3.在本文里,討論范圍限于IBM PC體系結(jié)構(gòu)。

BIOS及其功能


當(dāng)計算機打開電源時,內(nèi)存里包含的是一些隨機的數(shù)據(jù),所有的東西都沒有被初始化,操作系統(tǒng)也沒有被加載。開始整個啟動過程的是一個特殊的硬件電路,它觸發(fā)CPU的Reset腳的邏輯值。然后,一些CPU的寄存器比如CS(一個分段寄存器:代碼段寄存器,它指向含有程序指令的段),eip(在執(zhí)行指令過程中,當(dāng)CPU檢測到一個意外事故發(fā)生時,它會做出三種類型的判斷:錯誤、陷阱、中止,這取決于eip寄存器的值,它存儲在內(nèi)核模塊棧里)就會被給定一個值。接著,物理地址為0xfffffff0的代碼將被執(zhí)行。這個地址被存儲在一個只讀存儲器(ROM)里。BIOS(基本輸入/輸出系統(tǒng))實際上是一段存儲在ROM里的程序。它包含了一系列可以被某些操作系統(tǒng)調(diào)用,用于處理計算機各種硬件設(shè)備的中斷驅(qū)動和低級程序。其中微軟的DOS就是這樣的一種操作系統(tǒng)。

Linux是否使用附于計算機系統(tǒng)的BIOS來初始化硬件設(shè)備?或者說,是否有其它的東西來完成同樣的任務(wù)?不過這個問題沒有那么簡單,必須要了解一些知識。我們從80386模式開始。Intel微處理器實現(xiàn)地址翻譯(從邏輯地址->線性地址->物理地址)有兩種不同的途徑,分別稱作實模式和保護模式。實模式存在主要是為了使得處理器可以和較老的處理相兼容。事實上,所有的BIOS程序都是在實模式下運行的。但是,Linux內(nèi)核是在保護模式下運行,而不是在實模式下。因此,一旦初始化完成后,Linux就不再使用BIOS,而是完全由自己來為計算機上的所有硬件提供驅(qū)動程序(這點和DOS是不一樣的)。

那么什么時候Linux使用保護模式?為什么BIOS不能使用相同的模式?BIOS使用實模式是因為其在操作過程中使用的是實模式地址,并且在計算機剛打開電源時,只有實模式地址可用。一個實模式地址由段地址和偏移地址組成,因此,相應(yīng)的物理地址就為段地址×(2×8)+偏移。

那么,這是不是意味著在整個啟動過程中,Linux就從來不使用BIOS了呢?答案是否定的。在啟動階段,Linux從硬盤或者其它外部設(shè)備加載內(nèi)核時,需要使用BIOS。

讓我們來看一下啟動時BIOS主要做了哪些操作:

1.BIOS要對硬件進行一系列徹底的檢測。這個步驟主要是檢查系統(tǒng)安裝有哪些設(shè)備,以及它們工作是否正常。通常把這個步驟叫做自檢(Power-On Self-Test,POST),這時會顯示版本及其它很多相關(guān)的硬件信息。

2.BIOS要對硬件進行初始化。這一步非常重要,因為它要保證所有的硬件設(shè)備在IRQ(中斷請求)和I/O端口操作時都沒有沖突。等這步完成以后,它會顯示一個已經(jīng)安裝的PCI設(shè)備表。

3.接著到了操作系統(tǒng),BIOS將查找一個可以引導(dǎo)的操作系統(tǒng)。這取決于BIOS的設(shè)置,它可以從軟盤、硬盤或者光盤啟動。

4.一旦發(fā)現(xiàn)一個合法的設(shè)備,BIOS就會把其第一扇區(qū)的內(nèi)容復(fù)制到物理地址,即從0x00007c00開始的內(nèi)存中,然后跳至剛加載的地址并執(zhí)行之。

到此為止,BIOS所要做的工作就全部完成了。

自舉程序及其功用


BIOS調(diào)用一個專門的程序,這個程序的任務(wù)就是把操作系統(tǒng)的內(nèi)核調(diào)入內(nèi)存。這個程序就叫做自舉程序(Boot Loader)。在我們繼續(xù)下面內(nèi)容之前,先來看一下啟動系統(tǒng)的不同途徑。

1.從軟盤啟動Linux

從軟盤啟動時,存儲在軟盤第一扇區(qū)的指令將被加載并執(zhí)行。這個指令然后就會把其余的內(nèi)核復(fù)制到內(nèi)存中。

Linux內(nèi)核可以裝在1.44MB的軟盤里,不過為了減少磁盤占用量,它們都進行了壓縮。這個壓縮過程是在編譯時完成的,而解壓縮的過程則由自舉程序完成。

從軟盤啟動Linux時,自舉程序要做的工作非常簡單。它是一個位于/usr/src/linux-2.4.2/arch/i386/boot/bootsect.S的匯編語言文件。當(dāng)我們編譯Linux內(nèi)核源代碼,或者獲取一個新的內(nèi)核時,這個可執(zhí)行的匯編代碼就會被放在內(nèi)核程序的前端。由此可見,要制作一個可啟動的Linux軟盤其實很簡單。我們只要從磁盤的第一個扇區(qū)拷貝Linux內(nèi)核,就可以創(chuàng)建一個可啟動軟盤。當(dāng)BIOS加載軟盤的第一個扇區(qū)時,它實際上拷貝的是自舉程序。自舉程序由BIOS調(diào)用(跳到物理地址為0x00007c00的位置),然后執(zhí)行以下的操作:

(1)把自已從地址0x00007c00移動到0x00090000;

(2)使用地址0x00003ff4,創(chuàng)建“實模式”棧;

(3)設(shè)置磁盤參數(shù)表,這里使用的是BIOS提供的軟盤驅(qū)動程序;

(4)通過調(diào)用BIOS程序顯示“Loading”信息;

(5)自舉程序調(diào)用BIOS程序來加載軟盤上內(nèi)核的setup()函數(shù),并把它放在起始地址為0x00090200的內(nèi)存中;

(6)接下來自舉程序調(diào)用一個BIOS程序,這個程序從軟盤加載剩余的內(nèi)核程序,并將其放入起始地址為0x00010000(所謂的低地址)或者0x00100000(所謂的高地址);

(7)然后,跳轉(zhuǎn)到setup()函數(shù)。

2.從硬盤啟動Linux

當(dāng)系統(tǒng)從硬盤啟動時,啟動過程又有所不同。硬盤的第一個扇區(qū)叫做MBR(Master Boot Record),其上存儲著分區(qū)表和一個小程序。這個程序加載存儲由操作系統(tǒng)的第一扇區(qū)來開始啟動。Linux是一個高度靈活且非常優(yōu)秀的軟件,所以在MBR里,它使用一個叫做LILO的程序來代替上述的那個程序。LILO允許用戶選擇所要啟動的操作系統(tǒng)。

一般來說,Linux是從硬盤啟動的。這就需要不同的自舉程序。在Intel系統(tǒng)里,用得最多的自舉程序就是LILO。對于其它的體系結(jié)構(gòu),還存在著別的自舉程序。LILO可以安裝在MBR上(請注意:在安裝Red Hat Linux時,有一個步驟會讓用戶選擇把LILO安裝到MBR或者引導(dǎo)扇區(qū))或一個活動分區(qū)的引導(dǎo)扇區(qū)上。

由于LILO太大,MBR無法容納,所以它被分成兩部分。MBR(或者磁盤分區(qū)的引導(dǎo)扇區(qū))包含有一個小的自舉程序,它被BIOS載入到起始地址為0x00007c00的內(nèi)存中。然后,這個小程序再把自己移到0x0009a000地址處,接著設(shè)置實模式棧,最后加載第二部分的LILO自舉程序(請注意:實模式棧地址范圍是0x0009b000 到 0x0009a200)。

第二部分的LILO會從磁盤讀取所有可用的操作系統(tǒng),并且給用戶列出,以選擇所要啟動的系統(tǒng)。一旦用戶選擇完成,自舉程序就會加載相應(yīng)的扇區(qū)內(nèi)容到內(nèi)存中并且執(zhí)行之。

自舉程序被BIOS調(diào)用時(跳到物理地址為0x00007c00處),要執(zhí)行以下操作:

(1)把自已從地址0x00007c00移動到0x00090000;

(2)使用地址0x00003ff4,創(chuàng)建“實模式”棧;

(3)設(shè)置磁盤參數(shù)表。這里使用的是BIOS提供的軟盤驅(qū)動程序;

(4)通過調(diào)用BIOS程序顯示“Loading Linux”信息;

(5)自舉程序調(diào)用BIOS程序來加載軟盤上內(nèi)核的setup()函數(shù),并把它放在起始地址為0x00090200的內(nèi)存中;

(6)接下來自舉程序調(diào)用一個BIOS程序,這個程序從軟盤加載剩余的內(nèi)核程序,并將其放入起始地址為0x00010000或者0x00100000;

(7)然后,跳轉(zhuǎn)到setup()函數(shù)。

Setup()函數(shù)的功用


現(xiàn)在我們就可以深入研究一下自舉過程中不可缺少的匯編語言函數(shù)了。

Setup()函數(shù)可以在/usr/src/linux-2.4.2/arch/i386/boot/setup.S文件中找到。

Setup()函數(shù)代碼是在完整的內(nèi)核自舉程序加載以后,才會跳到相應(yīng)的函數(shù)代碼處。在內(nèi)核文件中,其偏移地址是0x200。這使得自舉程序很容易找到這段代碼,并將其拷貝到起始物理地址為0x00090200的內(nèi)存中。

這個Setup()文函數(shù)到底是做什么用的?在計算機時里,內(nèi)核要正確地操作所有硬件就必需首先要檢測到它們,并且以一種有序的方式進行初始化。Setup()函數(shù)初始化所有的硬件設(shè)備,從而為內(nèi)核操作它創(chuàng)造了一個環(huán)境。

但是,前面我們不是已經(jīng)提到過BIOS會檢測所有的硬件嗎?雖然BIOS初始化了所有的硬件,但是Linux內(nèi)核并不放心,它還要以自己的方式對所有的硬件進行初始化。Linux內(nèi)核之所以要設(shè)計成這樣,是為了增強可移植性和穩(wěn)定性。這也是Linux內(nèi)核要優(yōu)于很多目前可用的Unix和類Unix內(nèi)核的原因之一,并且也使得它在很多方面表現(xiàn)的非常出眾。

Setup()函數(shù)主要完成以下任務(wù):

(1)首先是檢測系統(tǒng)可用內(nèi)存的總量,它是通過BIOS程序來完成檢測的;

(2)設(shè)置鍵盤重復(fù)延遲時間和重復(fù)速度;

(3)檢測視頻卡;

(4)重新初始化硬盤控制器和硬盤參數(shù);

(5)檢測一個MCA;

(6)檢測一個PS/2定點設(shè)備(鼠標(biāo)總線);

(7)檢測高級電源管理器(APM)BIOS支持;

(8)檢測內(nèi)核在內(nèi)存中的位置,如果在低地址0x00010000,就將其移到高地址0x00001000,如在高地址則不做任何移動;

(9)設(shè)置設(shè)備中斷描述表(IDT)和全局描述表(GDT);

(10)如已經(jīng)有了浮點單位(FPU),則重置之;

(11)重新調(diào)用程序中斷控制器;

(12)通過設(shè)置cr0狀態(tài)寄存器的PE位,把CPU從“實模式”切換到“保護模式”;

(13)跳轉(zhuǎn)到stratup_32( )匯編語言函數(shù)。

第一個stratup_32( )函數(shù)做什么


在啟動過程中要用到兩個stratup_32( )函數(shù),雖然它們都是匯編語言函數(shù),但是卻是兩個完全不同的函數(shù)。我們這里所說的函數(shù)包含在/usr/src/linux-2.4.2/arch/i386/boot/compressed/head.S文件里。

Setup()文件執(zhí)行后,這個函數(shù)就被加載到物理地址為0x00100000或者物理地址為0x00001000的內(nèi)存中(取決于內(nèi)核是載入高或者低內(nèi)存)。

當(dāng)執(zhí)行這個函數(shù)時,會執(zhí)行以下的操作:

(1)初始化段寄存器和一個臨時棧。

(2)內(nèi)核中沒有初始化的數(shù)據(jù)都用0填充。它是通過symbols _edata和 _end來識別的。

(3)執(zhí)行decompress_kernel( )函數(shù)。這個函數(shù)用于對Linux內(nèi)核解壓縮。這個時候,屏幕上將顯示“Uncompressing Linux……”信息。解壓縮完成后,就會顯示“OK, booting the kernel”信息?,F(xiàn)在有一個問題,就是解完壓縮的內(nèi)核被放置在什么位置?答案是如果Linux內(nèi)核被加載低地址,那么解壓縮的內(nèi)核將被置于物理地址為0x00100000的地方。如果在高地址,則內(nèi)核會被先解壓到一個臨時緩沖區(qū)中,待完成后再將其加載到物理地址為0x00100000的地方。

(4)最后,跳轉(zhuǎn)到物理地址為0x00100000的地方執(zhí)行。

到此為止,代碼執(zhí)行操作就由另外一個startup_32( )函數(shù)來接管。也就是說,第二個startup_32( )函數(shù)接管了啟動過程。

第二個startup_32( )函數(shù)完成的功能


解壓縮Linux內(nèi)核的工作由另外一個startup_32( )函數(shù)來完成。該函數(shù)位于/usr/src/linux-2.4.2/arch/i386/kernel/head.S文件中。

這時你可能會說兩個不同的函數(shù)用同一個名字不會出錯嗎?答案是不會的。因為兩個函數(shù)都是到自己初始地址去執(zhí)行,并且都有自己的執(zhí)行環(huán)境,所以不會出錯。

下面我們來看一下第二個startup_32( )函數(shù)的功能。當(dāng)執(zhí)行這個函數(shù)時,實際上是為第一個Linux進程(process 0)設(shè)置環(huán)境。這個函數(shù)將執(zhí)行下面的操作:

(1)段寄存器將以最后的值進行初始化;

(2)為process 0設(shè)置內(nèi)核模式棧;

(3)調(diào)用并且執(zhí)行setup_idt( )函數(shù),該函數(shù)將把所有的IDT填充空值;

(4)把從BIOS中獲得的參數(shù)放在第一頁的框架中;

(5)識別處理器的模式;

(6)使用GDT和IDT表加載gdtr和idtr寄存器;

(7)最后跳到start_kernel( )函數(shù)。

start_kernel( )函數(shù)功能


start_kernel( )函數(shù)完成Linux內(nèi)核的初始化工作。這個函數(shù)執(zhí)行后,所有的基本內(nèi)核組件都將被初始化。這也是整個啟動過程的最后一步。

該函數(shù)將完成以下的功能:

(1)執(zhí)行paging_init( )函數(shù)初始化頁表(Page Tables);

(2)執(zhí)行mem_init( )函數(shù)初始化頁描述符(Page Descriptors);

(3)執(zhí)行trap_init( ) 和 init_IRQ( )函數(shù),最后一次對IDT進行初始化;

(4)執(zhí)行kmem_cache_init( )和kmem_cache_sizes_init ( )函數(shù),對Slab Allocator進行初始化;

(5)執(zhí)行time_init( )函數(shù),初始化系統(tǒng)日期和時間;

(6)內(nèi)核的線程process 1是通過調(diào)用kernel_thread( )來完成的。接著就建立其它的內(nèi)核線程并且執(zhí)行/sbin/init程序。

到此屏幕上就會顯示“Linux version 2.4.2 ……”信息。此外,還會顯示很多其它信息。最后,就會出現(xiàn)用戶的登錄提示符。這是在告訴用戶Linux內(nèi)核已經(jīng)加載完成,用戶已經(jīng)可以使用。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    人妻巨大乳一二三区麻豆| 免费特黄欧美亚洲黄片| 玩弄人妻少妇一区二区桃花| 午夜成年人黄片免费观看| 国产精品亚洲综合天堂夜夜| 91欧美日韩一区人妻少妇| 九九久久精品久久久精品| 色一情一伦一区二区三| 国产精品亚洲精品亚洲| 国产老熟女超碰一区二区三区| 欧洲一级片一区二区三区| 欧美日韩乱一区二区三区| 中字幕一区二区三区久久蜜桃| 欧洲精品一区二区三区四区| 亚洲第一区二区三区女厕偷拍 | 毛片在线观看免费日韩| 国产日韩综合一区在线观看| 亚洲国产欧美精品久久| 婷婷色网视频在线播放| 色婷婷成人精品综合一区| 欧美日韩国产黑人一区| 亚洲一区二区欧美激情| 亚洲高清一区二区高清| 中文字幕日韩精品人一妻| 精品日韩视频在线观看| 久久国产精品亚州精品毛片| 操白丝女孩在线观看免费高清| 亚洲熟女精品一区二区成人| 欧美日韩国产午夜福利| 国产不卡的视频在线观看| 欧美大胆女人的大胆人体| 日韩人妻精品免费一区二区三区 | 黄色日韩欧美在线观看| 成人精品一级特黄大片| 国内九一激情白浆发布| 太香蕉久久国产精品视频| 夫妻性生活一级黄色录像| 成年午夜在线免费视频| 在线视频免费看你懂的| 日韩中文字幕免费在线视频| 欧美黑人在线精品极品|