linux设备:初始化
生活随笔
收集整理的這篇文章主要介紹了
linux设备:初始化
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
本文轉載自 http://blog.china unix.net/uid-24631445-id-3419097.html
不過本人在此將源碼修改為3.14.3的源碼了
當按下開機鍵后,電腦經過自檢,執行引導程序,內核初始化,然后創建了內核線程init線程,init線程調用do_basic_setup()來初始化外部設備,加載驅動程序.... ? (這一段實在其他地方看來的,并不表示我看過內核初始化的代碼)
文件/init/main.c static void __init do_basic_setup(void) { ? ?? ?? ?? ?cpuset_init_smp(); ? ?? ?? ?? ? usermodehelper_init(); ? ?? ?? ?? ? shmem_init(); ? ?? ?? ?? ? driver_init(); ? ?? ?? ?? ? init_irq_proc(); ? ?? ?? ?? ? do_ctors(); ? ?? ?? ?? ? usermodehelper_enable(); ? ?? ?? ?? ? do_initcalls(); ? ?? ?? ?? ? random_int_secret_init(); }
下面是driver_init()函數 文件/drivers/base/init.c void __init driver_init(void) { ? ?? ?? ?? ? ? ?? ?? ?? ? devtmpfs_init(); ? ?? ?? ?? ? devices_init(); ? ?? ?? ?? ? buses_init(); ? ?? ?? ?? ? classes_init(); ? ?? ?? ?? ? firmware_init(); ? ?? ?? ?? ? hypervisor_init();
? ?? ?? ?? ? ? ?? ?? ?? ? platform_bus_init(); ? ?? ?? ?? ? cpu_dev_init(); ? ?? ?? ?? ? memory_dev_init(); ? ?? ?? ?? ? container_dev_init(); }
它又調用了devices_init()、buses_init()、chasses_init();
下面是devices_init() 文件/drivers/base/core.c int __init devices_init(void) { ? ?? ?? ?? ? devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL); ? ?? ?? ?? ? if (!devices_kset) ? ?? ?? ?? ? ? ?? ?? ?? ? return -ENOMEM; ? ?? ?? ?? ? dev_kobj = kobject_create_and_add("dev", NULL); ? ?? ?? ?? ? if (!dev_kobj) ? ?? ?? ?? ? ? ?? ?? ?? ? goto dev_kobj_err; ? ?? ?? ?? ? sysfs_dev_block_kobj = kobject_create_and_add("block", dev_kobj); ? ?? ?? ?? ? if (!sysfs_dev_block_kobj) ? ?? ?? ?? ? ? ?? ?? ?? ? goto block_kobj_err; ? ?? ?? ?? ? sysfs_dev_char_kobj = kobject_create_and_add("char", dev_kobj); ? ?? ?? ?? ? if (!sysfs_dev_char_kobj) ? ?? ?? ?? ? ? ?? ?? ?? ? goto char_kobj_err;
? ?? ?? ?? ? return 0;
? char_kobj_err: ? ?? ?? ?? ? kobject_put(sysfs_dev_block_kobj); ? block_kobj_err: ? ?? ?? ?? ? kobject_put(dev_kobj); ? dev_kobj_err: ? ?? ?? ?? ? kset_unregister(devices_kset); ? ?? ?? ?? ? return -ENOMEM; }
因此devices_init()就是調用kset_create_and_add和kobject_create_and_add函數來創建kset和kobject對象。 devices_kset? =? kset_create_and_add("devices",? &device_uevent_ops,? NULL);
dev_kobj? =? kobject_create_and_add("dev",? NULL);
sysfs_dev_block_kobj? =? kobject_create_and_add("block",? dev_kobj);
sysfs_dev_char_kobj? =? kobject_create_and_add("char",? dev_kobj);
下面的buses_init,classes_init,firmware_init,hypervisor_init與此類似,下面列出這些函數創建的kset和kobject對象。在創建這些對象的時候也會在/sys目錄下創建相應的目錄。
接著是函數:platform_bus_init(),
文件/drivers/base/platform.c
接著是:cpu_dev_init(); 文件/drivers/base/cpu.c void __init cpu_dev_init(void) { ? ?? ?? ?? ? if (subsys_system_register(&cpu_subsys, cpu_root_attr_groups)) ? ?? ?? ?? ? ? ?? ?? ?? ? panic("Failed to register CPU subsystem");
? ?? ?? ?? ? cpu_dev_register_generic(); }
struct bus_type cpu_subsys = { ? ?? ?? ?? ? .name = "cpu", ? ?? ?? ?? ? .dev_name = "cpu", ? ?? ?? ?? ? .match = cpu_subsys_match, #ifdef CONFIG_HOTPLUG_CPU ? ?? ?? ?? ? .online = cpu_subsys_online, ? ?? ?? ?? ? .offline = cpu_subsys_offline, #endif };
下面是subsys_system_register()函數 文件/drivers/base/bus.c int subsys_system_register(struct bus_type *subsys, ? ?const struct attribute_group **groups) { ? ?? ?? ?? ? return subsys_register(subsys, groups, &system_kset->kobj); } 因此在/sys/devices/system目錄下創建了cpu目錄
最后是memory_dev_init函數 文件/drivers/base/memory.c int __init memory_dev_init(void) { ? ?? ?? ?? ? unsigned int i; ? ?? ?? ?? ? int ret; ? ?? ?? ?? ? int err; ? ?? ?? ?? ? unsigned long block_sz;
? ?? ?? ?? ? ret = subsys_system_register(&memory_subsys, memory_root_attr_groups); ? ?? ?? ?? ? if (ret) ? ?? ?? ?? ? ? ?? ?? ?? ? goto out;
? ?? ?? ?? ? block_sz = get_memory_block_size(); ? ?? ?? ?? ? sections_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE;
? ?? ?? ?? ? mutex_lock(&mem_sysfs_mutex); ? ?? ?? ?? ? for (i = 0; i < NR_MEM_SECTIONS; i += sections_per_block) { ? ?? ?? ?? ? ? ?? ?? ?? ? err = add_memory_block(i); ? ?? ?? ?? ? ? ?? ?? ?? ? if (!ret) ? ?? ?? ?? ? ? ?? ?? ?? ? ? ?? ?? ?? ? ret = err; ? ?? ?? ?? ? } ? ?? ?? ?? ? mutex_unlock(&mem_sysfs_mutex);
out: ? ?? ?? ?? ? if (ret) ? ?? ?? ?? ? ? ?? ?? ?? ? printk(KERN_ERR "%s() failed: %d\n", __func__, ret); ? ?? ?? ?? ? return ret; }
可以看出整個driver_init()只是在/sys下創建了一系列的kset和kobject對象和相應的目錄,但沒有創建任何真正的設備,或者虛擬的設備。比如/sys/devices/system/cpu目錄下的cpu0目錄的創建,這些可能是在do_initcalls中處理的,我得先搞清楚這個函數是怎么起作用的
當按下開機鍵后,電腦經過自檢,執行引導程序,內核初始化,然后創建了內核線程init線程,init線程調用do_basic_setup()來初始化外部設備,加載驅動程序.... ?
文件/init/main.c static void __init do_basic_setup(void) { ?
下面是driver_init()函數 文件/drivers/base/init.c void __init driver_init(void) { ?
?
它又調用了devices_init()、buses_init()、chasses_init();
下面是devices_init() 文件/drivers/base/core.c int __init devices_init(void) { ?
?
?
因此devices_init()就是調用kset_create_and_add和kobject_create_and_add函數來創建kset和kobject對象。 devices_kset?
下面的buses_init,classes_init,firmware_init,hypervisor_init與此類似,下面列出這些函數創建的kset和kobject對象。在創建這些對象的時候也會在/sys目錄下創建相應的目錄。
- buses_init:
- ?
? ? ? ? bus_kset? =? kset_create_and_add("bus",? &bus_uevent_ops,? NULL);
- ?
?? ?? ?? ?? system_kset = kset_create_and_add("system", NULL, &devices_kset->kobj); -
- classes_init:
- ?
? ? ? ? class_kset? =? kset_create_and_add("class",? NULL,? NULL);
-
- firmware_init:
- ?
? ? ? ? firmware_kobj? =? kobject_create_and_add("firmware",? NULL);
-
- hypervisor_init:
- ?
? ? ? ? hypervisor_kobj? =? kobject_create_and_add("hypervisor",? NULL);
接著是函數:platform_bus_init(),
文件/drivers/base/platform.c
- 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;
- }
- ?
- struct device platform_bus = {
- ?
?? ?.init_name = "platform", - };
-
- struct bus_type platform_bus_type = {
- ?
?? ?.name ? ?? ?? = "platform", - ?
?? ?.dev_groups ? ?? ?= platform_dev_groups, - ?
?? ?.match ? ?? ?= platform_match, - ?
?? ?.uevent ? ?? = platform_uevent, - ?
?? ?.pm ? ?? ?? ?? = &platform_dev_pm_ops - };
接著是:cpu_dev_init(); 文件/drivers/base/cpu.c void __init cpu_dev_init(void) { ?
?
struct bus_type cpu_subsys = { ?
下面是subsys_system_register()函數 文件/drivers/base/bus.c int subsys_system_register(struct bus_type *subsys, ?
最后是memory_dev_init函數 文件/drivers/base/memory.c int __init memory_dev_init(void) { ?
?
?
?
out: ?
可以看出整個driver_init()只是在/sys下創建了一系列的kset和kobject對象和相應的目錄,但沒有創建任何真正的設備,或者虛擬的設備。比如/sys/devices/system/cpu目錄下的cpu0目錄的創建,這些可能是在do_initcalls中處理的,我得先搞清楚這個函數是怎么起作用的
總結
以上是生活随笔為你收集整理的linux设备:初始化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Corner Proposal Netw
- 下一篇: kset_create_and_add