亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

FreeBSD 內(nèi)核中的SYSINIT分析

系統(tǒng) 2324 0

FreeBSD?kernel 是一個膨大的系統(tǒng) ,? 對于這樣一個大系統(tǒng) ,? 里面往往包含了大量的子系統(tǒng)和 ??
模塊 , 當(dāng)系統(tǒng)初始化時這些模塊就需要初始化 ,? 按照通常的思路 , 這些初始化過程必須在某處 ??
被顯式地調(diào)用 , 這樣一來 , 當(dāng)你新增某個模塊 , 你必須再修改那個系統(tǒng)初始化的地方來調(diào)用這 ??
個新增模塊的初始化過程 ,? 而且由于 ANSI?C 語言的限制 , 調(diào)用某個函數(shù)最好先聲明 , 這樣當(dāng)系 ??
統(tǒng)的初始化過程開始增加時 ,? 那個調(diào)用初始化過程的文件開始大量包含那些本來不相關(guān)的頭 ??
文件 ,? 偶合度就增加了 ,? 這是一種不好的設(shè)計 .??

FreeBSD
為了應(yīng)付這種情況 ,? 使用一種叫做 SYSINIT 的機制 .? 我們知道 FreeBSD 使用一種叫做 ??
ELF
的二進(jìn)制目標(biāo)執(zhí)行文件格式 .? 這種文件格式允許文件內(nèi)部組織成結(jié)構(gòu)化的方式 ,? 文件內(nèi) ??
部可以由不同的組成部分 (section),?FreeBSD 正是利用了這種機制 .???

FreeBSD
使用 GNU?GCC 作為其 C 語言編譯器 ,? 這種編譯器允許在 C 源程序中嵌入?yún)R編語言代碼 ,??
FreeBSD
通過在 C 源程序中加入?yún)R編指令來在目標(biāo)文件中增加額外的 section,? 在文件 ??
/sys/sys/linker_set.h
中定義如下 :??

#ifdef?__alpha__??
#define?MAKE_SET(set,?sym)??????????????????????????????????????????????\??
????????static?void?const?*?const?__set_##set##_sym_##sym?=?&sym;???????\??
????????__asm(".align?3");??????????????????????????????????????????????\??
????????__asm(".section?.set."?#set?",\"aw\"");?????????????????????????\??
????????__asm(".quad?"?#sym);???????????????????????????????????????????\??
????????__asm(".previous")??
#else??
#define?MAKE_SET(set,?sym)?????
#define?MAKE_SET(set,?sym)??????????????????????????????????????????????\??
????????static?void?const?*?const?__set_##set##_sym_##sym?=?&sym;???????\??
????????__asm(".section?.set."?#set?",\"aw\"");?????????????????????????\??
????????__asm(".long?"?#sym);???????????????????????????????????????????\??
????????__asm(".previous")??
#endif??
#define?TEXT_SET(set,?sym)?MAKE_SET(set,?sym)??
#define?DATA_SET(set,?sym)?MAKE_SET(set,?sym)??

程序一旦在某處調(diào)用 DATA_SET 宏指令 ,? 就會將相應(yīng)的匯編符號加入到目標(biāo)文件 .? 例如 :??
int?myint;??
DATA_SET(myset,?myint);??
這兩句話將導(dǎo)致在目標(biāo)文件中創(chuàng)建一個 myset?section,? 并且 myint 的地址將被放入這個 ??
section
.??

系統(tǒng)的初始化必須按嚴(yán)格的順序進(jìn)行 ,? 為此 FreeBSD 定義了很多子系統(tǒng)的順序號 ,? 這些順序 ??
連同 SYSINIT 的許多相關(guān)定義在 /sys/sys/kernel.h 頭文件中 :??

enum?sysinit_sub_id?{??
????????SI_SUB_DUMMY????????????=?0x0000000,????/*?not?executed;?for?linker*/??
????????SI_SUB_DONE?????????????=?0x0000001,????/*?processed*/??
????????SI_SUB_CONSOLE??????????=?0x0800000,????/*?console*/??
????????SI_SUB_COPYRIGHT????????=?0x0800001,????/*?first?use?of?console*/??
????????SI_SUB_TUNABLES?????????=?0x0700000,????/*?establish?tunable?values?*/??
????????SI_SUB_VM???????????????=?0x1000000,????/*?virtual?memory?system?init*/??
????????SI_SUB_KMEM?????????????=?0x1800000,????/*?kernel?memory*/??
????????SI_SUB_KVM_RSRC?????????=?0x1A00000,????/*?kvm?operational?limits*/??
????????SI_SUB_CPU??????????????=?0x1e00000,????/*?CPU?resource(s)*/??
????????SI_SUB_KLD??????????????=?0x1f00000,????/*?KLD?and?module?setup?*/??
????????SI_SUB_INTRINSIC????????=?0x2000000,????/*?proc?0*/??
????????SI_SUB_VM_CONF??????????=?0x2100000,????/*?config?VM,?set?limits*/??
????????SI_SUB_RUN_QUEUE????????=?0x2200000,????/*?the?run?queue*/??
????????SI_SUB_CREATE_INIT??????=?0x2300000,????/*?create?the?init?process?*/??
????????SI_SUB_DRIVERS??????????=?0x2400000,????/*?Let?Drivers?initialize?*/??
????????SI_SUB_CONFIGURE????????=?0x3800000,????/*?Configure?devices?*/??
????????SI_SUB_VFS??????????????=?0x4000000,????/*?virtual?file?system*/??
????????SI_SUB_CLOCKS???????????=?0x4800000,????/*?real?time?and?stat?clocks*/??
????????SI_SUB_MBUF?????????????=?0x5000000,????/*?mbufs*/??
????????SI_SUB_CLIST????????????=?0x5800000,????/*?clists*/??
????????SI_SUB_SYSV_SHM?????????=?0x6400000,????/*?System?V?shared?memory*/??
????????SI_SUB_SYSV_SEM?????????=?0x6800000,????/*?System?V?semaphores*/??
????????SI_SUB_SYSV_MSG?????????=?0x6C00000,????/*?System?V?message?queues*/??
????????SI_SUB_P1003_1B?????????=?0x6E00000,????/*?P1003.1B?realtime?*/??
????????SI_SUB_PSEUDO???????????=?0x7000000,????/*?pseudo?devices*/??
????????SI_SUB_EXEC?????????????=?0x7400000,????/*?execve()?handlers?*/??
????????SI_SUB_PROTO_BEGIN??????=?0x8000000,????/*?XXX:?set?splimp?(kludge)*/??
????????...??
};??

子系統(tǒng)內(nèi)還有順序號 :??
enum?sysinit_elem_order?{??
????????SI_ORDER_FIRST??????????=?0x0000000,????/*?first*/??
????????SI_ORDER_SECOND?????????=?0x0000001,????/*?second*/??
????????SI_ORDER_THIRD??????????=?0x0000002,????/*?third*/??
????????SI_ORDER_MIDDLE?????????=?0x1000000,????/*?somewhere?in?the?middle?*/??
????????SI_ORDER_ANY????????????=?0xfffffff?????/*?last*/??
};??

FreeBSD
為每個想要在系統(tǒng)初始化時被調(diào)用的函數(shù) ,? 定義兩個函數(shù)類型 :??
typedef?void?(*sysinit_nfunc_t)?__P((void?*));??
typedef?void?(*sysinit_cfunc_t)?__P((const?void?*));??
它們是系統(tǒng)初始化被調(diào)用時使用的函數(shù)原型 .??
兩個重要的宏使得初始化函數(shù)能夠在系統(tǒng)開始時被執(zhí)行 :??

#define?C_SYSINIT(uniquifier,?subsystem,?order,?func,?ident)????\??
????????static?struct?sysinit?uniquifier?##?_sys_init?=?{???????\??
????????????????subsystem,??????????????????????????????????????\??
????????????????order,??????????????????????????????????????????\??
????????????????func,???????????????????????????????????????????\??
????????????????ident???????????????????????????????????????????\??
????????};??????????????????????????????????????????????????????\??
????????DATA_SET(sysinit_set,uniquifier?##?_sys_init);??

#define?SYSINIT(uniquifier,?subsystem,?order,?func,?ident)??????\??
????????C_SYSINIT(uniquifier,?subsystem,?order,?????????????????\??
????????(sysinit_cfunc_t)(sysinit_nfunc_t)func,?(void?*)ident)??

其中每個初始化函數(shù)被存儲成這樣一個結(jié)構(gòu) :??
????????struct?sysinit?{??
???????????unsigned?int????subsystem;??????????????/*?subsystem?identifier*/??
???????????unsigned?int????order;??????????????????/*?init?order?within?subsystem*/??
???????????sysinit_cfunc_t?func;???????????????????/*?function?????????????*/??
???????????const?void??????*udata;?????????????????/*?multiplexer/argument?*/??
????????};??
這個結(jié)構(gòu)包含了子系統(tǒng)編號 ,? 子系統(tǒng)中的順序號 ,? 初始化函數(shù)的地址 ,? 以及這個函數(shù) ??
使用的參數(shù) .??

現(xiàn)在如果有個函數(shù)想要在系統(tǒng)啟動時自動被調(diào)用 ,? 并且知道這個函數(shù)是為 VM 子系統(tǒng)做準(zhǔn)備工 ??
,? 可以這樣申明 :??

long?myvar;??
void?init_myvar(void?*p)??
{??
?????*(long?*)p?=?2;??
}??
SYSINIT(init_myvar,?SI_SUB_VM,?1000,?init_myvar,?&myvar)??

這樣聲明的初始化過程分布在很多目標(biāo)文件中 ,? 當(dāng) gcc 的連接編輯器 ld 運行時就會把屬于同 ??
一個 section 的數(shù)據(jù)合并到一個連續(xù)的地址塊中 .??
由于在這個 section 中包含的只能是指向 sysinit 結(jié)構(gòu)的指針 , 這樣 FreeBSD 就可以把這個地址 ??
當(dāng)成一個 sysinit*? 的數(shù)組 ,?FreeBSD 找出這個 sysinit_set 地址 ,? 邊歷這個數(shù)組并調(diào)用其中 ??
的初始化函數(shù) .? 為了確切知道這個 section 的大小 ( 直接讀 ELF 是可能的 , 但是那樣太復(fù)雜 , ??
知道 kernel 調(diào)用初始化過程時文件系統(tǒng)可能還沒有初始化呢 ),? 系統(tǒng)中包含一個工具 ??
gensetdefs,?
這個工具能掃描給出的一組 .o 目標(biāo)文件 ,? 并找到任何名字是由 .set. 開頭的 ??
section,?
它統(tǒng)計有多少個這樣的的初始化函數(shù) ,? 并在 sysinit_set 的開頭生成一個長整形 ??
計數(shù)器 .?gensetdefs 生成三個文件 :??
setdef0.c?setdef1.c?setdefs.h??

文件 setdef0.c 的內(nèi)容 :??

--------------------------------------------------------??
/*?THIS?FILE?IS?GENERATED,?DO?NOT?EDIT.?*/??

#define?DEFINE_SET(set,?count)??????????????????\??
__asm__(".section?.set."?#set?",\"aw\"");???????\??
__asm__(".globl?"?#set);????????????????????????\??
__asm__(".type?"?#set?",@object");??????????????\??
__asm__(".p2align?2");??????????????????????????\??
__asm__(#set?":");??????????????????????????????\??
__asm__(".long?"?#count);???????????????????????\??
__asm__(".previous")??

#include?"setdefs.h"????????????/*?Contains?a?`DEFINE_SET'?for?each?set?*/??
--------------------------------------------------------??

這里的 DEFINE_SET 效果就是申明一 C 結(jié)構(gòu) :??
struct?linker_set?{??
????????int?????ls_length;??
????????void????*ls_items[1];???????????/*?really?ls_length?of?them,??
????????????????????????????????????????????????*?trailing?NULL?*/??
};??

文件 setdef1.c 的內(nèi)容 :??

--------------------------------------------------------??
/*?THIS?FILE?IS?GENERATED,?DO?NOT?EDIT.?*/??

#define?DEFINE_SET(set,?count)??????????????????????????\??
__asm__(".section?.set."?#set?",\"aw\"");???????\??
__asm__(".long?0");?????????????????????\??
__asm__(".previous")??

#include?"setdefs.h"????????????/*?Contains?a?`DEFINE_SET'?for?each?set?*/??

這個 DEFINE_SET 在某個 section 中放入一個 ?long?0.??
--------------------------------------------------------??

文件 setdefs.h 的內(nèi)容 :??

DEFINE_SET(cons_set,?3);??
DEFINE_SET(kbddriver_set,?2);??
DEFINE_SET(periphdriver_set,?5);??
DEFINE_SET(scrndr_set,?9);??
DEFINE_SET(scterm_set,?1);??
DEFINE_SET(sysctl_set,?552);??
DEFINE_SET(sysinit_set,?323);??
DEFINE_SET(sysuninit_set,?155);??
DEFINE_SET(vga_set,?9);??
DEFINE_SET(videodriver_set,?4);??

當(dāng) kernel 被連接時 ,? Makefile setdef0.o 被安排最前面 ,? 這樣 ld 就把這個初始化函數(shù)的 ??
計數(shù)器安排在這個 section 的最前面 .?FreeBSD?kernel 就能從這個 section 的開頭讀到這個計 ??
數(shù)器 ,? 也就知道了有多少個初始化函數(shù) .? Makefile 中被安排在中間的的是 FreeBSD 的其他 ??
.o
文件 ,? 最后由 setdef1.o 壓陣 .?setdef1.c 定義了一個空指針 , 用以表示這個 section 的結(jié)束 ??
,
這種安排 ,? 我把它叫做夾三明治 .??

初始化過程的調(diào)用被安排在內(nèi)核 ?/sys/kern/init_main.c mi_startup 函數(shù)中 ,?mi_startup??
是系統(tǒng)啟動過程中 ,? 第一個被執(zhí)行的 C 語言函數(shù) ,?? 它做的第一件事情就是調(diào)用這些初始化函 ??
數(shù) ,? 開始時對所有的初始化過程做優(yōu)先級排序 ,? 然后順序調(diào)用它們 .??

void??????????????????????
mi_startup(void)??
{?????????????????
??????????????????????????
????????register?struct?sysinit?**sipp;?????????/*?system?initialization*/??
????????register?struct?sysinit?**xipp;?????????/*?interior?loop?of?sort*/??
????????register?struct?sysinit?*save;??????????/*?bubble*/??

restart:??????????
??????????
????????
這是優(yōu)先級別排序 ,? 這里沒有使用那個在 setdef0.c 中定義的計數(shù)器 ,? 而是使用 ??
????????
setdef1.c 中定義的空指針作為結(jié)束標(biāo)志 .??
??????????
????????/*????????
?????????*?Perform?a?bubble?sort?of?the?system?initialization?objects?by??
?????????*?their?subsystem?(primary?key)?and?order?(secondary?key).??
?????????*/???????
????????for?(sipp?=?sysinit;?*sipp;?sipp++)?{??
????????????????for?(xipp?=?sipp?+?1;?*xipp;?xipp++)?{??
????????????????????????if?((*sipp)->subsystem?< (*xipp)->subsystem?||??
?????????????????????????????((*sipp)->subsystem?==?(*xipp)->subsystem?&&??
??????????????????????????????(*sipp)->order?<= (*xipp)->order))??
????????????????????????????????continue;???????/*?skip*/??
????????????????????????save?=?*sipp;??
????????????????????????*sipp?=?*xipp;??
????????????????????????*xipp?=?save;??
????????????????}??
????????}??

????????/*??
?????????*?Traverse?the?(now)?ordered?list?of?system?initialization?tasks.??
?????????*?Perform?each?task,?and?continue?on?to?the?next?task.??
?????????*??
?????????*?The?last?item?on?the?list?is?expected?to?be?the?scheduler,??
?????????*?which?will?not?return.??
?????????*/??
????????for?(sipp?=?sysinit;?*sipp;?sipp++)?{??

????????????????if?((*sipp)->subsystem?==?SI_SUB_DUMMY)??
????????????????????????continue;???????/*?skip?dummy?task(s)*/??


這是按順序調(diào)用 :??
/*??
?????????*?Traverse?the?(now)?ordered?list?of?system?initialization?tasks.??
?????????*?Perform?each?task,?and?continue?on?to?the?next?task.??
?????????*??
?????????*?The?last?item?on?the?list?is?expected?to?be?the?scheduler,??
?????????*?which?will?not?return.??
?????????*/??
????????for?(sipp?=?sysinit;?*sipp;?sipp++)?{??

????????????????if?((*sipp)->subsystem?==?SI_SUB_DUMMY)??
????????????????????????continue;???????/*?skip?dummy?task(s)*/??

????????????????if?((*sipp)->subsystem?==?SI_SUB_DONE)??
????????????????????????continue;??

????????????????/*?Call?function?*/??
????????????????(*((*sipp)->func))((*sipp)->udata);??

????????????????/*?Check?off?the?one?we're?just?done?*/??
????????????????(*sipp)->subsystem?=?SI_SUB_DONE;??

????????????????/*?Check?if?we've?installed?more?sysinit?items?via?KLD?*/??
????????????????if?(newsysinit?!=?NULL)?{??
????????????????????????if?(sysinit?!=?(struct?sysinit?**)sysinit_set.ls_items)??
????????????????????????????????free(sysinit,?M_TEMP);??
????????????????????????sysinit?=?newsysinit;??
????????????????????????newsysinit?=?NULL;??
????????????????????????goto?restart;??
????????????????}??
????????}??

????????panic("Shouldn't?get?here!");??
}??
??????

SRC= http://www.moon-soft.com/program/bbs/readelite432617.htm

FreeBSD 內(nèi)核中的SYSINIT分析


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 日本欧美一区二区三区 | 6一10周岁毛片在线 717影院理论午夜伦八戒 | 欧美午夜激情影院 | 欧美日韩国产人成在线观看 | 99热成人精品国产免男男 | 久久这里只精品国产99热8 | 欧美精品国产一区二区三区 | 久久精品视频观看 | 国模无水印一区二区三区 | 久久美女| 亚洲成a人片在线观看www | 久久久精品日本一区二区三区 | 成人日韩精品 | 欧美午夜在线观看理论片 | 久久免费国产精品一区二区 | 国产伦久视频免费观看 视频 | 特黄级| 成人免费性视频 | 国产一区二区不卡 | 国内精品视频九九九九 | 亚洲性图第一页 | 久久成年人 | 日本一区二区在线 | 久久久久久穴 | 久久精品亚洲一区二区 | 91精品久久久久亚洲国产 | 国产精品亚洲一区二区在线观看 | 欧美jlzz18性欧美 | 天天射日| 成人亚洲国产精品久久 | 久草最新在线 | 久久久精品视频免费观看 | 日韩 欧美 亚洲 国产 | 午夜91理论片| 国产成人cao在线 | 久久精品国产精品亚洲20 | 小明看看成人免费 | 国产大片91精品免费观看不卡 | 国产精品久久国产三级国不卡顿 | 99精品观看 | 亚洲欧美精品天堂久久综合一区 |