乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      【轉(zhuǎn)】Linux那些事兒之我是Sysfs(4)舉例一lddbus - wilson的日志 ...

       蝸牛an 2010-12-10

      【轉(zhuǎn)】Linux那些事兒之我是Sysfs(4)舉例一lddbus

      linux kernel 2009-07-14 16:26:04 閱讀146 評論0   字號: 訂閱

      對了,你得把ldd3的examples代碼下下來。不然沒法繼續(xù)了。

      接下來我們從例子著手,
      localhost:/home/XX/examples/lddbus#insmod lddbus.ko
      此時再看/sys/bus/ 這時就多了一個文件夾ldd。里面的文件構(gòu)成是這樣的
      /sys/bus/ldd/
      |--device
      |--driver
      `--version
      localhost:/sys/bus/ldd#cat version
      $Revision: 1.9$

      這表示系統(tǒng)中多了一種名叫l(wèi)dd的總線類型。同時再看/sys/device/,也多出來一個ldd0的文件夾。這表示系統(tǒng)中多了一個名叫l(wèi)dd0的硬件。
      在lddbus.c中, 定義了一個總線和硬件類型 
      struct bus_type ldd_bus_type = {
              .name = "ldd",
              .match = ldd_match,
              .hotplug  = ldd_hotplug,
      };

      struct device ldd_bus = {
              .bus_id   = "ldd0",
              .release  = ldd_bus_release
      };

      lddbus模塊初始化時調(diào)用這個函數(shù)

      static int __init ldd_bus_init(void)
      {
              int ret;

              ret = bus_register(&ldd_bus_type);
              if (ret)
                      return ret;
              if (bus_create_file(&ldd_bus_type, &bus_attr_version))
                      printk(KERN_NOTICE "Unable to create version attribute\n");
              ret = device_register(&ldd_bus);
              if (ret)
                      printk(KERN_NOTICE "Unable to register ldd0\n");
              return ret;
      }

      其實就是調(diào)用了兩個注冊函數(shù),bus_register(), device_register()。bus_create_file()是在sysfs下創(chuàng)建一個文件夾。

      bus_register(),向系統(tǒng)注冊ldd_bus_type這個總線類型。bus_create_file()這個就是向sysfs中創(chuàng)建一個文件。device_register()系統(tǒng)注冊ldd_bus這個硬件類型。
      注冊好了之后,我們就可以在sysfs下看到相應(yīng)的信息。

      我們深入下去,仔細看看bus_register的代碼。
          688 int bus_register(struct bus_type * bus)
          689 {
          690         int retval;
          691
          692         retval = kobject_set_name(&bus->subsys.kset.kobj, "%s", bus->name);
          693         if (retval)
          694                 goto out;
          695
          696         subsys_set_kset(bus, bus_subsys);
          697         retval = subsystem_register(&bus->subsys);
          698         if (retval)
          699                 goto out;
          700
          701         kobject_set_name(&bus->devices.kobj, "devices");
          702         bus->devices.subsys = &bus->subsys;
          703         retval = kset_register(&bus->devices);
          704         if (retval)
          705                 goto bus_devices_fail;
          706
          707         kobject_set_name(&bus->drivers.kobj, "drivers");
          708         bus->drivers.subsys = &bus->subsys;
          709         bus->drivers.ktype = &ktype_driver;
          710         retval = kset_register(&bus->drivers);
          711         if (retval)
          712                 goto bus_drivers_fail;
          713         bus_add_attrs(bus);
          714
          715         pr_debug("bus type '%s' registered\n", bus->name);
          716         return 0;
          717
          718 bus_drivers_fail:
          719         kset_unregister(&bus->devices);
          720 bus_devices_fail:
          721         subsystem_unregister(&bus->subsys);
          722 out:
          723         return retval;
          724 }
      692-700是對bus->subsys的操作。701-705是操作bus->devices。706-710是操作bus->drivers。
      692 kobject_set_name()設(shè)置bus->subsys.kset.kobj的名字。此函數(shù)很簡單,就是調(diào)用vsnprintf()。此不列出。

      696 subsys_set_kset(bus, bus subsys)

      #define subsys_set_kset(obj,_subsys)  (obj)->subsys.kset.kobj.kset = &(_subsys).kset

      我們先看看bus_subsys的定義,它是一個subsystem類型的全局變量。在driver/base/bus.c中,decl subsys(bus, &ktype bus, NULL); 在/include/linux/kobject.h中有,decl subsys的原型,
      #define decl_subsys(_name,_type,_hotplug_ops) \
      struct subsystem _name##_subsys = { \
      .kset = { \
      .kobj = { .name = __stringify(_name) }, \
      .ktype = _type, \
      .hotplug_ops =_hotplug_ops, \
      } \
      }
      就相當于
      struct subsystem bus_subsys = { \
      .kset = { \
      .kobj = { .name = “bus” }, \
      .ktype = ktype_bus, \
      .hotplug_ops =NULL, \
      } \
      }
      其中ktype bus定義如下,
      static struct kobj_type ktype_bus = {
      .sysfs_ops = &bus_sysfs_ops,
      };

      697 subsystem_register(&bus->subsys)作用是向全局的bus_subsys”登記”, 把自己加入到bus_subsys的鏈表中去。
      subsystem_register() -> kset_add() -> kobject_add()
          155 int kobject_add(struct kobject * kobj)
          156 {
          157         int error = 0;
          158         struct kobject * parent;
          159
          160         if (!(kobj = kobject_get(kobj)))
          161                 return -ENOENT;
          162         if (!kobj->k_name)
          163                 kobj->k_name = kobj->name;
          164         parent = kobject_get(kobj->parent);
          165
          166         pr_debug("kobject %s: registering. parent: %s, set: %s\n",
          167                  kobject_name(kobj), parent ? kobject_name(parent) : "<NULL>",
          168                  kobj->kset ? kobj->kset->kobj.name : "<NULL>" );
          169
          170         if (kobj->kset) {
          171                 down_write(&kobj->kset->subsys->rwsem);
          172
          173                 if (!parent)
          174                         parent = kobject_get(&kobj->kset->kobj);
          175
          176                 list_add_tail(&kobj->entry,&kobj->kset->list);
          177                 up_write(&kobj->kset->subsys->rwsem);
          178         }
          179         kobj->parent = parent;
          180
          181         error = create_dir(kobj);
          182         if (error) {
          183                 /* unlink does the kobject_put() for us */
          184                 unlink(kobj);
          185                 if (parent)
          186                         kobject_put(parent);
          187         } else {
          188                 kobject_hotplug(kobj, KOBJ_ADD);
          189         }
          190
          191         return error;
          192 }

      代碼的170-178就是把自己連入到父輩上級kset中。我們注意到在kobject_add()函數(shù)中181行調(diào)用了create_dir(kobj),這個函數(shù)作用是在sysfs下創(chuàng)建一個文件夾??梢妅object和sysfs是同時更新的。

      kset_register(&bus->devices) 和kset_register(&bus->drivers)作用類似,把bus->devices這個kset加入到bus- >subsys這個subsystem中去。最后形成圖1的層次結(jié)構(gòu)。

      圖1:lddbus kobject層次結(jié)構(gòu)

      同理,我們可以看看device_register()的代碼,它也是向devices_subsys這個subsystem注冊,最后形成這樣的結(jié)構(gòu)與圖1類似。

      目前為止,我們知道了所謂的xx_register函數(shù),就是通過其內(nèi)嵌的kobject鏈入對應(yīng)的subsystem,或是kset的層次結(jié)構(gòu)中去。這樣就可以通過一些全局的變量找到它們了。

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多