《Linux内核设计与实现》读书笔记——设备与模块

设备驱动和管理相关的四种内核成分

设备类型:在所有Unix系统中为了统一普通设备的操作所采用的分类。

模块:Linux内核中用于按需加载和卸载目标码的机制。

内核对象:内核数据结构体中支持面向对象的简单操作,还支持维护对象之间的父子关系。

sysfs:表示系统中设备树的一个文件系统。

 

设备类型

Linux中设备被分为三种类型:

块设备(blkdev);

字符设备(cdev);

网路设备:打破了Unix的“所有东西都是文件”的设计原则,它不是通过设备节点来访问,而是通过套接字来访问;

并不是所有设备都表示物理设备,比如/dev/random是随机数发生器,/dev/null是空设备。

 

模块

将模块入口点注册到系统中:

/* Each module must use one module_init(). */
#define module_init(initfn)                 \
    static inline initcall_t __inittest(void)       \
    { return initfn; }                  \
    int init_module(void) __attribute__((alias(#initfn)));

将模块出口点注册到系统中:

/* This is only required if you want to be unloadable. */
#define module_exit(exitfn)                 \
    static inline exitcall_t __exittest(void)       \
    { return exitfn; }                  \
    void cleanup_module(void) __attribute__((alias(#exitfn)));

指定模块的版权:

#define MODULE_LICENSE(_license) MODULE_INFO(license, _license)

为驱动程序声明参数:

#define module_param_named(name, value, type, perm)            \
    param_check_##type(name, &(value));                \
    module_param_call(name, param_set_##type, param_get_##type, &value, perm); \
    __MODULE_PARM_TYPE(name, #type)
#define module_param(name, type, perm)              \
    module_param_named(name, name, type, perm)

name:用户可见的参数名;

type:存放参数的类型;

perm:指定模块在sysfs文件系统中下对应的文件的权限;

以上只是声明,必须在使用该宏前定义相关的变量。

模块描述:

#define MODULE_PARM_DESC(_parm, desc) \
    __MODULE_INFO(parm, _parm, #_parm ":" desc)

导出符号表:

#define EXPORT_SYMBOL(sym)                  \
    __EXPORT_SYMBOL(sym, "")
#define EXPORT_SYMBOL_GPL(sym)                  \
    __EXPORT_SYMBOL(sym, "_gpl")

只有被显式导出后的内核函数才可以被模块调用。

安装模块使用命令:

make modules_install

载入模块:

insmod

卸载模块:

rmmod

模块探测:

modprobe

 

设备模型

设备模型的核心部分是看kobject,对应结构体(include\linux\kobject.h):

struct kobject {
    const char      *name;
    struct list_head    entry;
    struct kobject      *parent;
    struct kset     *kset;
    struct kobj_type    *ktype;
    struct sysfs_dirent *sd;
    struct kref     kref;
    unsigned int state_initialized:1;
    unsigned int state_in_sysfs:1;
    unsigned int state_add_uevent_sent:1;
    unsigned int state_remove_uevent_sent:1;
    unsigned int uevent_suppress:1;
};

kobject通常是嵌入其它结构体中的,其单独存在的意义不大。比如(include\linux\cdev.h):

struct cdev {
    struct kobject kobj;
    struct module *owner;
    const struct file_operations *ops;
    struct list_head list;
    dev_t dev;
    unsigned int count;
};

 

sysfs

sysfs文件系统是一个处于内存中的虚拟文件系统,它为我们提供了kobject对象层次结构的视图。

sysfs代替了先前处于/proc下的设备相关文件。

sysfs挂载在sys目录下:

 

猜你喜欢

转载自blog.csdn.net/jiangwei0512/article/details/106153199