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.    
  6.     error = device_register(&platform_bus);
  7.     if(error) return error;
  8.    
  9.     error = bus_register(&platform_bus_type);
  10.     if(error)
  11.     device_unregister(&platform_bus);
  12.     return error;
  13. }
  14.  
  15. struct device platform_bus = {
  16.     .init_name = "platform",
  17. };

  18. struct bus_type platform_bus_type = {
  19.     .name      = "platform",
  20.     .dev_groups     = platform_dev_groups,
  21.     .match     = platform_match,
  22.     .uevent    = platform_uevent,
  23.     .pm        = &platform_dev_pm_ops
  24. };

接着是: 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中处理的,我得先搞清楚这个函数是怎么起作用的
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值