解壓縮Linux內(nèi)核的工作由另外一個(gè)startup_32( )函數(shù)來完成。該函數(shù)位于/usr/src/linux-2.4.2/arch/i386/kernel/head.S文件中。
這時(shí)你可能會(huì)說兩個(gè)不同的函數(shù)用同一個(gè)名字不會(huì)出錯(cuò)嗎?答案是不會(huì)的。因?yàn)閮蓚€(gè)函數(shù)都是到自己初始地址去執(zhí)行,并且都有自己的執(zhí)行環(huán)境,所以不會(huì)出錯(cuò)。
下面我們來看一下第二個(gè)startup_32( )函數(shù)的功能。當(dāng)執(zhí)行這個(gè)函數(shù)時(shí),實(shí)際上是為第一個(gè)Linux進(jìn)程(process 0)設(shè)置環(huán)境。這個(gè)函數(shù)將執(zhí)行下面的操作:
(1)段寄存器將以最后的值進(jìn)行初始化;
(2)為process 0設(shè)置內(nèi)核模式棧;
(3)調(diào)用并且執(zhí)行setup_idt( )函數(shù),該函數(shù)將把所有的IDT填充空值;
(4)把從BIOS中獲得的參數(shù)放在第一頁的框架中;
(5)識(shí)別處理器的模式;
(6)使用GDT和IDT表加載gdtr和idtr寄存器;
(7)最后跳到start_kernel( )函數(shù)。
start_kernel( )函數(shù)功能
start_kernel( )函數(shù)完成Linux內(nèi)核的初始化工作。這個(gè)函數(shù)執(zhí)行后,所有的基本內(nèi)核組件都將被初始化。這也是整個(gè)啟動(dòng)過程的最后一步。
該函數(shù)將完成以下的功能:
(1)執(zhí)行paging_init( )函數(shù)初始化頁表(Page Tables);
(2)執(zhí)行mem_init( )函數(shù)初始化頁描述符(Page Descriptors);
(3)執(zhí)行trap_init( ) 和 init_IRQ( )函數(shù),最后一次對(duì)IDT進(jìn)行初始化;
(4)執(zhí)行kmem_cache_init( )和kmem_cache_sizes_init ( )函數(shù),對(duì)Slab Allocator進(jìn)行初始化;
(5)執(zhí)行time_init( )函數(shù),初始化系統(tǒng)日期和時(shí)間;
(6)內(nèi)核的線程process 1是通過調(diào)用kernel_thread( )來完成的。接著就建立其它的內(nèi)核線程并且執(zhí)行/sbin/init程序。
到此屏幕上就會(huì)顯示“Linux version 2.4.2 ……”信息。此外,還會(huì)顯示很多其它信息。最后,就會(huì)出現(xiàn)用戶的登錄提示符。這是在告訴用戶Linux內(nèi)核已經(jīng)加載完成,用戶已經(jīng)可以使用。
總結(jié)
到現(xiàn)在為止,整個(gè)啟動(dòng)過程都已經(jīng)描述完畢。其中提到的許多詞匯我都沒有解釋,只簡要說了一下IDT、GDT、eip寄存器和cs寄存器等。


