日本免费全黄少妇一区二区三区-高清无码一区二区三区四区-欧美中文字幕日韩在线观看-国产福利诱惑在线网站-国产中文字幕一区在线-亚洲欧美精品日韩一区-久久国产精品国产精品国产-国产精久久久久久一区二区三区-欧美亚洲国产精品久久久久

FreeBSD的Loader和內(nèi)核初始化( 二 )


初始化內(nèi)核的可調(diào)整參數(shù),這些參數(shù)由引導(dǎo)程序傳來準(zhǔn)備GDT(全局描述符表)
準(zhǔn)備IDT(中斷描述符表)初始化系統(tǒng)控制臺初始化DDB(內(nèi)核的點(diǎn)調(diào)試器),如果它被編譯進(jìn)內(nèi)核的話初始化TSS(任務(wù)狀態(tài)段)準(zhǔn)備LDT(局部描述符表)建立proc0(0號進(jìn)程,即內(nèi)核的進(jìn)程)的pcb(進(jìn)程控制塊)init386()首先初始化內(nèi)核的可調(diào)整參數(shù),這些參數(shù)由引導(dǎo)程序傳來 。先設(shè)置環(huán)境指針(environment pointer, envp)調(diào)用,再調(diào)用init_param1() 。
envp指針已由loader存放在結(jié)構(gòu)bootinfo中:sys/i386/i386/machdep.c:
kern_envp = (CADdr_t)bootinfo.bi_envpKERNBASE;
/* 初始化基本可調(diào)整項,如hz等 */
init_param1();
init_param1()定義在sys/kern/subr_param.c之中 。這個文件里有一些sysctl項,兩個函數(shù),init_param1()和init_param2() 。這兩個函數(shù)從init386()中調(diào)用:sys/kern/subr_param.c
hz = HZ;
TUNABLE_INT_FETCH("kern.hz", &hz);
TUNABLE__FETCH用來獲取環(huán)境變量的值:/usr/src/sys/sys/kernel.h
#define TUNABLE_INT_FETCH(path, var)getenv_int((path), (var))
Sysctlkern.hz是系統(tǒng)時鐘頻率 。同時,這些sysctl項被init_param1()設(shè)定:
kern.maxswzone, kern.maxbcache, kern.maxtsiz, kern.dfldsiz, kern.dflssiz,
kern.maxssiz, kern.sgrowsiz 。然后init386() 準(zhǔn)備全局描述符表(Global Descriptors Table, GDT) 。
在x86上每個任務(wù)都運(yùn)行在自己的虛擬地址空間里,這個空間由"段址:偏移量"的數(shù)對指定 。
舉個例子,當(dāng)前將要由處理器執(zhí)行的指令在 CS:EIP,那么這條指令的線性虛擬地址就是“代碼段虛擬段地址CSEIP 。為了簡便,段起始于虛擬地址0,終止于界限4G字節(jié) 。所以,在這個例子中,指令的線性虛擬地址正是EIP的值 。段寄存器,如CS、DS等是選擇符,即全局描述符表中的索引(更精確的說,索引并非選擇符的全部,而是選擇符中的INDEX部分) 。譯者注: 對于80386,選擇符有16位,INDEX部分是其中的高13位 。
FreeBSD的全局描述符表為每個CPU保存著15個選擇符:sys/i386/i386/Machdep.c:
union descriptor gdt[NGDT * MAXCPU];/* 全局描述符表 */
sys/i386/include/segments.h:
/*
* 全局描述符表(GDT)中的入口
*/
#define GNULL_SEL0/* 空描述符 */
#define GCODE_SEL1/* 內(nèi)核代碼描述符 */
#define GDATA_SEL2/* 內(nèi)核數(shù)據(jù)描述符 */
#define GPRIV_SEL3/* 對稱多處理(SMP)每處理器專有數(shù)據(jù) */
#define GPROC0_SEL 4/* Task state process slot zero and up, 任務(wù)狀態(tài)進(jìn)程 */
#define GLDT_SEL5/* 每個進(jìn)程的局部描述符表 */
#define GUSERLDT_SEL6/* 用戶自定義的局部描述符表 */
#define GTGATE_SEL 7/* 進(jìn)程任務(wù)切換關(guān)口 */
#define GBIOSLOWMEM_SEL 8/* BIOS低端內(nèi)存訪問(必須是這第8個入口) */
#define GPANIC_SEL 9/* 會導(dǎo)致全系統(tǒng)異常中止工作的任務(wù)狀態(tài) */
#define GBIOSCODE32_SEL 10 /* BIOS接口(32位代碼) */
#define GBIOSCODE16_SEL 11 /* BIOS接口(16位代碼) */
#define GBIOSDATA_SEL12 /* BIOS接口(數(shù)據(jù)) */
#define GBIOSUTIL_SEL13 /* BIOS接口(工具) */
#define GBIOSARGS_SEL14 /* BIOS接口(自變量,參數(shù)) */
請注意,這些#defines并非選擇符本身,而只是選擇符中的INDEX域,因此它們正是全局描述符表中的索引 。例如,內(nèi)核代碼的選擇符(GCODE_SEL)的值為0x08 。
下一步是初始化中斷描述符表(Interrupt Descriptor Table, IDT) 。
這張表在發(fā)生軟件或硬件中斷時會被處理器引用 。例如,執(zhí)行系統(tǒng)調(diào)用時,用戶應(yīng)用程序提交INT 0x80 指令 。這是一個軟件中斷,處理器用索引值0x80在中斷描述符表中查找記錄 。這個記錄指向處理這個中斷的例程 。在這個特定情形中,這是內(nèi)核的系統(tǒng)調(diào)用關(guān)口 。
譯者注: Intel 80386支持“調(diào)用門,可以使得用戶程序只通過一條call指令就調(diào)用內(nèi)核中的例程 。可是FreeBSD并未采用這種機(jī)制,也許是因為使用軟中斷接口可免去動態(tài)鏈接的麻煩吧 。

推薦閱讀