標籤:style http color 使用 os 檔案 資料 ar
SYSINIT是一個通用的調用排序與分別執行機制的架構。FreeBSD目前使用它來進行核心的動態初始化。SYSINIT使得FreeBSD的核心各子系統可以在核心或模組動態載入連結時被重整、添加、刪除、替換,這樣,核心和模組載入時就不必去修改一個靜態有序初始化安排表甚至重新編譯核心。這個體系也使得核心模組(現在稱為KLD可以與核心不同時編譯、連結、在引導系統時載入,甚至在系統運行時載入。這些操作是通過"核心連結器"(kernel linker)和"連結器集合"(linker set)完成的。連結器集合(Linker Set)是一種連結方法。這種方法將整個程式源檔案中靜態申明的資料收集到一個可鄰近定址的資料單元中。 SYSINIT要依靠連結器擷取遍布整個程式原始碼多處申明的待用資料並把它們組成一個彼此相鄰的資料區塊。這種連結方法被稱為"連結器集合"(linker set)。SYSINIT使用兩個連結器集合以維護兩個資料集合,包含每個資料條目的調用順序、函數、一個會被提交給該函數的資料指標。?
SYSINIT按照兩類優先順序標識對函數排序以便執行。第一類優先順序的標識是子系統的標識,給出SYSINIT分別執行子系統的函數的全域順序,定義在中的枚舉sysinit_sub_id內。第二類優先順序標識在子系統中的元素的順序,定義在中的枚舉sysinit_elem_order內。 有兩種時刻需要使用SYSINIT:系統啟動或核心模組載入時,系統析構或核心模組卸載時。核心子系統通常在系統啟動時使用SYSINIT的定義項以初始化資料結構。例如,進程調度子系統使用一個SYSINIT定義項來初始化運行隊列資料結構。裝置驅動程式應避免直接使用SYSINIT(),對於匯流排結構上的物理真實裝置應使用DRIVER_MODULE()調用的函數先偵測裝置的存在,如果存在,再進行裝置的初始化。這一系統過程中,會做一些專門針對裝置的事情,然後調用SYSINIT()本身。對於非匯流排結構一部分的虛裝置,應改用DEV_MODULE()。
使用SYSINIT
介面
標頭檔
<sys/kernel.h>
?
宏
SYSINIT(uniquifier, subsystem, order, func, ident)
SYSUNINIT(uniquifier, subsystem, order, func, ident)
啟動
宏SYSINIT()在SYSINIT啟動資料集合中建立一個SYSINIT資料項目,以便SYSINIT在系統啟動或模組載入時排序並執行其中的函數。SYSINIT()有一個參數uniquifier,SYSINIT用它來標識資料項目,隨後是子系統順序號、子系統元素順序號、待調用函數、傳遞給函數的資料。所有的函數必須有一個恒量指標參數。
SYSINIT()的例子
#include <sys/kernel.h>
?
void foo_null(void *unused)
{
foo_doo();
}
SYSINIT(foo, SI_SUB_FOO, SI_ORDER_FOO, foo_null, NULL);
?
struct foo foo_voodoo = {
FOO_VOODOO;
}
?
void foo_arg(void *vdata)
{
struct foo *foo = (struct foo *)vdata;
foo_data(foo);
}
SYSINIT(bar, SI_SUB_FOO, SI_ORDER_FOO, foo_arg, &foo_voodoo);
?
注意,SI_SUB_FOO和SI_ORDER_FOO應當分別在上面提到的枚舉sysinit_sub_id和sysinit_elem_order之中。既可以使用已有的枚舉項,也可以將自己的枚舉項添加到這兩個枚舉的定義之中。你可以使用數學運算式微調SYSINIT的執行順序。以下的例子樣本了一個需要剛好要在核心參數調整的SYSINIT之前執行的SYSINIT。
調整SYSINIT()順序的例子
static void
mptable_register(void *dummy __unused)
{
?
apic_register_enumerator(&mptable_enumerator);
}
?
SYSINIT(mptable_register, SI_SUB_TUNABLES - 1, SI_ORDER_FIRST,
mptable_register, NULL);
析構
宏SYSUNINIT()的行為與SYSINIT()的相當,只是它將資料項目填加至SYSINIT的析構資料集合。?
SYSUNINIT()的例子
#include <sys/kernel.h>
?
void foo_cleanup(void *unused)
{
foo_kill();
}
SYSUNINIT(foobar, SI_SUB_FOO, SI_ORDER_FOO, foo_cleanup, NULL);
?
struct foo_stack foo_stack = {
FOO_STACK_VOODOO;
}
?
void foo_flush(void *vdata)
{
}
SYSUNINIT(barfoo, SI_SUB_FOO, SI_ORDER_FOO, foo_flush, &foo_stack);
SRC=http://os.51cto.com/art/200511/11446.htm