Linux核心初始化步驟(五)
阿新 • • 發佈:2018-12-01
/* * Ok, the machine is now initialized. None of the devices * have been touched yet, but the CPU subsystem is up and * running, and memory and process management works. * * Now we can finally start doing some real work.. */ static void __init do_basic_setup(void) { /*針對SMP系統,初始化核心control group 的cpuset子系統,如果非SMP,此函式為空*/ cpuset_init_smp(); /*建立一個單執行緒工作佇列khelper.執行的系統中只有一個,主要作用是指定使用者空間的程式 路徑和環境變數,最終執行指定的user space的程式,屬於關鍵執行緒,不能關閉*/ usermodehelper_init(); shmem_init(); /*初始化驅動模型中的各子系統,可見的現象是在/sys中出現的目錄和檔案*/ driver_init(); /*在proc檔案系統中建立irq目錄,並在其中初始化系統中所有中斷對應的目錄*/ init_irq_proc(); /*呼叫連結到核心中的所有建構函式,也就是連結進.ctor段中的所有函式 do_ctors(); usermodehelper_enable(); /*呼叫所有編譯核心的驅動模組中的初始化函式*/ do_initcalls(); }
下面對driver_init()作進一步的分析
/** * driver_init - initialize driver model. * * Call the driver model init functions to initialize their * subsystems. Called early from init/main.c. */ void __init driver_init(void) { /* These are the core pieces */ /*devtmpfs主要完成了對裝置檔案建立的管理工作*/ devtmpfs_init(); /*devices_init()就是呼叫kset_create_and_add和kobject_create_and_add函式 來建立kset和kobject物件。 devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL); 建立/sys/devices頂級容器節點 dev_kobj = kobject_create_and_add("dev", NULL); 建立/sys/dev頂級容器節點 sysfs_dev_block_kobj = kobject_create_and_add("block", dev_kobj); 建立/sys/dev/block二級節點 sysfs_dev_char_kobj = kobject_create_and_add("char", dev_kobj); 建立/sys/dev/char二級節點 */ devices_init(); //建立devices相關的裝置模型 /*buses_init()就是呼叫kset_create_and_add和kobject_create_and_add函式 來建立kset和kobject物件。 bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL); 建立/sys/bus這個頂級容器節點,該節點是Linux核心中所有匯流排型別的父節點 system_kset = kset_create_and_add("system", NULL, &devices_kset->kobj); */ buses_init();// 建立Linux裝置模型匯流排部分的頂級節點 /*class_kset = kset_create_and_add("class", NULL, NULL); 建立了/sys/class這個頂級容器節點,該節點是Linux核心中所有class型別的父節點 */ classes_init(); //建立linux裝置模型類部分的頂級容器節點 /*firmware_kobj = kobject_create_and_add("firmware", NULL); 建立了/sys/firmware這個頂級kobj節點 */ firmware_init();//建立Linux裝置模型中firmware部分的頂級節點 /*hypervisor_kobj = kobject_create_and_add("hypervisor", NULL); 建立了/sys/hypervisor這個頂級節點 */ hypervisor_init();//建立hypervisor_kobj的頂級容器節點 /* These are also core pieces, but must come after the * core core pieces. */ /* 初始化Linux平臺匯流排,平臺匯流排是一種虛擬匯流排,主要用來管理CPU的片上資源,具有 較好的可移植效能,現在有很多驅動已經用platform改寫了,主要生成了以下幾個節點 /sys/bus/platform /sys/bus/platform/devices /sys/bus/platform/drivers */ platform_bus_init(); /*在/sys/devices/system/節點下建立一個名為“cpu”的子節點/sys/devices/system/cpu/ 該節點包含cpu的相關屬性 */ cpu_dev_init();//建立一個名為“cpu”的類 /*在/sys/devices/system/節點下建立一個名為“memory"的子節點/sys/devices/system/memory/ 該節點包含了記憶體相關的屬性 */ memory_dev_init();//建立memory裝置在sysfs中的介面 }
int __init platform_bus_init(void)
{
int error;
early_platform_cleanup();
error = device_register(&platform_bus);
if (error)
return error;
error = bus_register(&platform_bus_type);
if (error)
device_unregister(&platform_bus);
return error;
}
platform_bus_init函式中引入兩個變數,platform_bus,platform_bus_type,這兩個變數
定義如下:
struct device platform_bus = {
.init_name = "platform",
};
struct bus_type platform_bus_type = {
.name = "platform",
.dev_attrs = platform_dev_attrs,
.match = platform_match,
.uevent = platform_uevent,
.pm = &platform_dev_pm_ops,
};
該函式先呼叫device_register函式註冊platform_bus這個裝置,這會在/sys/devices/節點下建立platform節點/sys/devices/platform,此裝置節點是所有platform裝置的父節點,即所有platform_device裝置都會在/sys/devices/platform下建立子節點。然後呼叫bus_register函式註冊platform_bus_type這個匯流排型別,這會在/sys/bus目錄下建立一個platform節點,這個節點是所有platform裝置和驅動的匯流排型別,即所有的platform裝置和驅動都會掛載到這個總線上;