1. 程式人生 > >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目錄下建立相應的目錄。
  1. buses_init:
  2.      bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL);
  3.          system_kset = kset_create_and_add("system", NULL, &devices_kset->kobj);
  4. classes_init:
  5.      class_kset = kset_create_and_add("class", NULL, NULL);
  6. firmware_init:
  7.      firmware_kobj = kobject_create_and_add("firmware", NULL);
  8. hypervisor_init:
  9.      hypervisor_kobj = kobject_create_and_add("hypervisor", NULL);

接著是函式:platform_bus_init(), 檔案/drivers/base/platform.c
  1. int __init platform_bus_init(void)
  2. {
  3.     int error;
  4.     early_platform_cleanup();
  5.     error = device_register(&platform_bus);
  6.     if(error) return error;
  7.     error = bus_register(&platform_bus_type);
  8.     if(error)
  9.     device_unregister(&platform_bus);
  10.     return error;
  11. }
  12. struct device platform_bus = {
  13.     .init_name = "platform",
  14. };
  15. struct bus_type platform_bus_type = {
  16.     .name      = "platform",
  17.     .dev_groups     = platform_dev_groups,
  18.     .match     = platform_match,
  19.     .uevent    = platform_uevent,
  20.     .pm        = &platform_dev_pm_ops
  21. };
接著是: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中處理的,我得先搞清楚這個函式是怎麼起作用的