字符设备

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.模块之间的通信