字符设备
1 2 3 4
| 1.模块框架 2.设备号 3.字符设备驱动注册 4.file_operation结构体
|
内核模块框架
1 2 3 4 5 6 7 8 9 10
| 1.头文件 #include <linux/init.h> #include <linux/module.h> 2.模块加载函数----static int hello_init(); 3.模块卸载函数----static int hello_exit(); 4.模块许可声明 module_exit(); module_init(); MODULE_LICENSE("GPL") GPL:开源协议
|
用户程序、库————————————用户空间
系统调用、系统调用、字符驱动程序、内核—————————内核空间
字符型硬件——————————————-Linux系统中IO设备
设备号
1 2 3 4
| 设备号 32位:主设备号前12位【1~254】,次设备号后12位【0~255】 设备号:主设备,次设备号《==》设备号 设备号申请注册 =》向linux申请占用某设备号 设备号释放注销 将设备号归还给系统
|
函数
1 2 3 4 5 6 7 8
| 静态申请:register_chrdev_region(设备号,数量,设备名) 动态申请:alloc_chrdev_region(设备号,次设备号,数量) 注销:unresgister_chrdev_region(设备号,数量)
命令 make insmod *.ko 查看设备:cat /proc/device
|
字符设备结构体
1 2 3 4 5 6 7 8
| struct cdev{ struct kobject kobjs; struct module *owner; struct file_operations *ops; struct list_head list; dev_t dev; unsigned int count; }
|
1 2 3 4 5 6 7 8 9 10 11
| static file_operations xx_fops ={
};
int (*open)(struct inode *inode,struct file *file); int (*release)(struct inode*,struct file*); ssize_t (*read)(struct file*,char __user*,ssize_,loff_t*); ssize_t (*write)(struct file *,const char __user*,size_t,loff_t *); loff_t (*llseek)(struct file*,loff_t ,int ); int (*ioctl)(struct inode *,struct file *,unsigned int,unsigned long);
|
file_operations:文件操作
file:文件对象
inode:节点对象
Linux模块
1.模块参数
模块加载到内核的过程中,通过命令行。传递给该模块的值
模块对应于模块中定义的全局变量
引入模块参数:对于不同的硬件,驱动程序需要参数也许会发生变换。包括,硬件的通信参数,手机屏幕大小,驱动访问的IO内存地址,为了满足这些要求内核允许在装载 模块时,指定模块的参数
宏定义声明
1 2 3 4
| 内核变量类型 type:变量的类型 Bool(invbool反布尔型)、charp(字符指针)、int、long、short、uint、ulong、ushort。 注意,这里面没有浮点型,因为内核不支持浮点型数据
|
2.模块及操作函数
3.模块之间的通信