1. 程式人生 > >Linux核心初始化步驟(五)

Linux核心初始化步驟(五)


/*
 * 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裝置和驅動都會掛載到這個總線上;