设备与模块


设备与模块

设备类型:unix系统为了统一常见设备,设定的类型

模块

内核对象

sysfs:表示设备树的文件系统

设备类型

块设备blkdevs

字符设备cdevs

网络设备

也称以太网设备,提供对网络的访问

物理适配器+特定的协议

打破了unix 一切皆文件的设计原则

通过socket api访问

杂项设备miscdevs

简化的字符设备:牺牲通用性,换取使用的方便

虚拟设备

对内核的功能扩展,伪设备pseudo devices

如随机数发生器/dev/random,空设备/dev/null,零设备/dev/zero

模块

hello, world

static int hello_init(void) 
{
printk(KERN_ALERT “I bear a charmed life.\n”); 
return 0;
}
/*
* hello_exit – the exit function, called when the module is removed.
*/ 
static void hello_exit(void) 
{
printk(KERN_ALERT “Out, out, brief candle!\n”); 
}

module_init(hello_init); 
module_exit(hello_exit);

MODULE_LICENSE(“GPL”); 
MODULE_AUTHOR(“Shakespeare”); 
MODULE_DESCRIPTION(“A Hello, World Module”);

module_init()和module_exit()都是宏,唯一参数为初始化函数,类型为int my_init(void);

如果载入非GPL模块,不能被调试,不能调用GPL_only符号

剩下两个没啥用

构建模块

2.6内核采用kbuild,构建模块更容易,第一步选择哪里管理源码:

  1. 模块源码加入内核源码树
  2. 内核代码树外构建模块源码

安装模块

模块依赖性

必须事先生成依赖关系

depmod

生成依赖关系信息

依赖信息存放在/lib/modules/version/modules.dep

载入模块

root权限 insmod

modprobe提供了依赖性分析

modprobe module [ module paras ]

管理配置选项

对于薪资目录建立kconfig,要在存在的kconfig文件中引入

source “driver/char/fishing/Kconfig”

添加一个配置选项

config FISHING_POLE 
tristate “Fish Master 3000 support” 
default n 
help
If you say Y here...

添加依赖型:

depends on FISH_TANK

配置系统元选项

CONFIG_BROKEN_ON_SMP:驱动非多处理器安全,用于告知风险

CONFIG——EXPERIMENTAL:告知风险

参数模块

module_param(name, type, perm);

定义的全局变量,同时出现在sysfs文件系统

perm制定了sysfs下的权限

例子

static int allow_live_bait = 1; /* default to on */ 
module_param(allow_live_bait, bool, 0644); /* a Boolean type */

外部参数名与内部不同:

static unsigned int max_test = DEFAULT_MAX_LINE_TEST; 
module_param_named(maximum_line_test, max_test, int, 0);

导出符号表

导出内核函数,才能被模块直接使用

需要指令EXPORT_SYMBOL()和EXPORT_SYMBOL_GPL()

int get_pirate_beard_color(struct pirate *p) 
{
return p->beard.color; 
} 
EXPORT_SYMBOL(get_pirate_beard_color);

然后get_pirate_beard_color可以被所有模块访问

确保自己的模块使用的所有接口,都被导出

设备模型

独立机制表示设备

  • 重复代码最小化
  • 引用计数这样的统一机制
  • 所有设备以树的形式出现
  • 方便关闭电源

kobject

设备模型的核心,类似对象

struct kobject {
    const char            *name;
    struct list_head    entry;
    struct kobject         *parent;    /*构建设备树,即为sysfs*/
    struct kset         *kset; 
    struct kobj_type     *ktype;
    struct sysfs_dirent *sd;        /*sysfs文件系统中,表示kobject的inode*/
    struct kref            kref;        /*提供引用计数*/
    ...
}

通常嵌入别的结构体,如struct cdev

kobject嵌入其它机构时,该结构拥有kobject提供的标准功能

并成为层次架构的一部分

ktype

kobject type, <linux/kobject.h>中

struct kobj_type &#123; 
    void (*release)(struct kobject *);                /*析构函数*/ 
    const struct sysfs_ops         *sysfs_ops;         //描述sysfs读写时的特性
    struct attribute             **default_attrs;    //描述了kobject的默认属性
&#125;;

kset

kobject对象的集合体.把所有相关的kobject放到同一位置

少数的ktype,多个kset

struct kset &#123; 
    struct list_head         list;            //链接所有kobject
    spinlock_t                 list_lock;         //保护这个链表中元素的自旋锁
    struct kobject             kobj;             //集合元素的基类
    struct kset_uevent_ops     *uevent_ops;    //处理集合中kobject的热插拔操作
    // uevent:用户事件的缩写
&#125;;

相互关系

相同kset的kobject以独立的目录出现在文件系统

操作管理kobject

引用计数

类似inode

sysfs

虚拟文件系统,提供了kobject对象层次的视图

挂载在sys目录下

将kobject与目录项紧密联系,通过kobject中的dentry实现

目录devices

在sysfs添加删除kobject

向sysfs添加文件

1.默认属性

ktype中包含attribute结构体,定义在<linux/sysfs.h>

struct attribute{
    const char         *name;        //属性名称,出现在sysfs中的文件名
    struct module    *owner;
    mode_t            mode;        //sysfs中该文件的权限
}

sysfs_ops描述了如何使用属性

show()读属性,store()写属性

2.创建新属性

/*添加新属性,最终出现在sysfs中的文件名*/
int syss_create_file(struct kobject *kobj, const struct attribute *attr);
/*创建符号链接*/
int sysfs_create_link(struct kobject *kobj, struct kobject *target, char *name);
/*删除新属性*/
void sysfs_remove_file(struct kobject *kobj, const struct attribute *attr);

sysfs约定:

保证每个文件导出一个值,文本形式,映射为简单C类型

sysfs树形的实际用途得看源代码

17.4.3 内核事件层

内核到用户的消息通知系统

通过kobject和sysfs,能很好标识时间的源(一个sysfs路径)

int kobject_uevent(struct kobject *kobj, enum kobject_action action);

第一个参数为发送信号的kobject

第二个为描述信号的动作或动词,枚举类型,映射相应的字符串


文章作者: N1co5in3
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 N1co5in3 !
  目录