Chinaunix首页 | 论坛 | 博客
  • 博客访问: 837017
  • 博文数量: 489
  • 博客积分: 475
  • 博客等级: 下士
  • 技术积分: 3087
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-08 16:28
文章分类

全部博文(489)

文章存档

2013年(7)

2012年(301)

2011年(181)

分类:

2011-12-10 20:35:25

在新版本的内核中struct device 已经没有bus_id成员,取而代之的是通过dev_name和dev_set_name对设备的名字进行操作。
dev_name和dev_set_name在2.6.35.6内核中的源代码如下:
static inline const char *dev_name(const struct device *dev)
{
        /* Use the init name until the kobject becomes available */
        if (dev->init_name)
                return dev->init_name;

        return kobject_name(&dev->kobj);
}

extern int dev_set_name(struct device *dev, const char *name, ...)
        __attribute__((format(printf, 2, 3)));
kernel 邮件列表
中讲了:struct device - replace bus_id with dev_name(),以后只要使用dev->bus_id的时候,改成dev_name(dev)就可以了。

第四章:linux内核模块:
4.5,模块被加载后,在/sys/module/目录下将出现以此模块名命名的目录。当“参数读/写权限”为 0 时,表示此参数不存在 sysfs 文件系统下对应的文件节点,如果此模块存在“参数读/写权限”不为 0的命令行参数,在此模块的目录下还将出现 parameters目录,包含一系列以参数名命名的文件节点,这些文件的权限值就是传入module_param()的“参数读/写权限” ,而文件的内容为参数的值。
4.6,导出符号:
模块可以使用如下宏导出符号到内核符号表:
EXPORT_SYMBOL(符号名); 
EXPORT_SYMBOL_GPL(符号名); 
导 出的 符号 将可 以 被 其 他 模块 使用 , 使用 前 声明 一 下 即 可 。
4.8,模块的使用计数 
Linux  2.6 内核提供了模块计数管理接口 try_module_get(&module)和 module_put(&module),
int try_module_get(struct module *module); 
该函数用于增加模块使用计数;若返回为 0,表示调用失败,希望使用的模块没有被加载或正在被卸载中。 
void module_put(struct module *module); 
该函数用于减少模块使用计数。 

第 5 章  Linux文件系统与设备文件系统 
1.file结构体 
文件结构体代表一个打开的文件(设备对应于设备文件) ,系统中每个打开的文件在内核空间都有一个关联的  struct file。它由内核在打开文件时创建,并传递给在文件上进行操作的任何函数。在文件的所有实例都关闭后,内核释放这个数据结构。在内核和驱动源代码中,struct file的指针通常被命名为  file 或 filp(即 file pointer)。代码清单 5.3给出了文件结构体的定义。 
2.inode结构体 
VFS  inode 包含文件访问权限、属主、组、大小、生成时间、访问时间、最后修改时间等信息。它是Linux 管理文件系统的最基本单位,也是文件系统连接任何子目录、文件的桥梁,inode结构体的定义如代码清单5.4所示。 
5.4.1    udev与devfs的区别
取代 devfs的几点原因: 
1.devfs所做的工作被确信可以在用户态来完成。 
2.一些bug相当长的时间内未被修复。 
3.devfs的维护者和作者停止了对代码的维护工作。 
udev 完全在用户态工作,利用设备加入或移除时内核所发送的热插拔事件(hotplug event)来工作。在热插拔时,设备的详细信息会由内核输出到位于/sys的sysfs文件系统。udev的设备命名策略、权限控制和事件处理都是在用户态下完成的,它利用sysfs中的信息来进行创建设备文件节点等工作。 
5.4.2   sysfs文件系统与Linux设备模型 
1.sysfs 文件系统
sysfs把连接在系统上的设备和总线组织成为一个分级的文件, 它们可以由用户空间存取,向用户空间导出内核数据结构以及它们的属性。sysfs的一个目的就是展示设备驱动模型中各组件的层次关系,其顶级目录包括block、device、bus、drivers、class、power 和 firmware。 

2.kobject内核对象 
kobject是Linux 2.6 引入的设备管理机制,在内核中由kobject结构体表示,这个数据结构使所有设备在底层都具有统一的接口。kobject提供了基本的对象管理能力,是构成 Linux  2.6 设备模型的核心结构,每个在内核中注册的 kobject 对象都对应于sysfs文件系统中的一个目录。   
kobject结构体的定义如代码清单 5.6所示。 
1  struct kobject 
2  { 
3    char *k_name;  
4    char name[KOBJ_NAME_LEN]; //对象名称 
5    struct kref kref; //对象引用计数 
6    struct list_head entry; //用于挂接该kobject对象到kset链表 
7    struct kobject *parent; //指向父对象的指针 
8    struct kset *kset; //所属kset的指针 
9    struct kobj_type *ktype; //指向对象类型描述符的指针 
10   struct dentry *dentry; //sysfs文件系统中与该对象对应的文件节点入口 
11 }; 
内核通过 kobject 的 kref 成员实现对象引用计数管理,且提供两个函数kobject_get()、kobject_put()分别用于增加和减少引用计数;
kobj_type 数据结构包含 3 个成员:用于释放 kobject 占用的资源的release()函数、指向sysfs操作的 sysfs_ops指针和sysfs文件系统默认属性列表。 
1  struct kobj_type  
2  { 
3   void (*release)(struct kobject *);//release函数 
4   struct sysfs_ops  * sysfs_ops;//属性操作 
5   struct attribute  ** default_attrs;//默认属性 
6  }; 
kobj_type 结构体种的 sysfs_ops 包括 store()和 show()两个成员函数,用于实现属性的读写;

Linux内核中提供一系列操作kobject的函数: 
void kobject_init(struct kobject * kobj); 
该函数用于初始化 kobject,它设置kobject引用计数为1,entry域指向自身,其所属 kset引用计数加1。 
int kobject_set_name(struct kobject *kobj, const char *format, ...); 
该函数用于设置指定kobject的名称。 
void  kobject_cleanup(struct  kobject  *  kobj) 和 void kobject_release(struct kref *kref); 
该函数用于清除kobject,当其引用计数为0时,释放对象占用的资源。 
struct kobject *kobject_get(struct kobject *kobj); 
该函数用于将kobj  对象的引用计数加1,同时返回该对象的指针。 
void kobject_put(struct kobject * kobj); 
该函数用于将 kobj 对象的引用计数减 1,如果引用计数降为 0,则调用
kobject_release()释放该 kobject对象。 
int kobject_add(struct kobject * kobj); 
该函数用于将 kobject 对象加入 Linux 设备层次,它会挂接该 kobject 对象到 kset的 list链中,增加父目录各级kobject的引用计数,在其parent指向的目录下创建文件节点,并启动该类型内核对象的hotplug函数。 
int kobject_register(struct kobject * kobj); 
该函数用于注册kobject, 它会先调用kobject_init()初始化kobj, 再调用kobject_add()完成该内核对象的添加。 
void kobject_del(struct kobject * kobj); 
这个函数是kobject_add()的反函数, 它从Linux设备层次(hierarchy)中删除 kobject对象。 
void kobject_unregister(struct kobject * kobj); 
这个函数是 kobject_register()的反函数,用于注销 kobject。与 kobject_register()相反,它首先调用kobject_del()从设备层次中删除该对象,再调用 kobject_put()减少该对象的引用计数,如果引用计数降为0,则释放该kobject对象。 




阅读(377) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~