编译过程:
将写好的模块放到Linux内核的任意目录下
修改相应的Kconfig和Makefile文件
执行make语句
生成.ko文件
lsmod 列举当前的模块
insmod XXX.ko 插入模块
rmmod XXX 移除模块
驱动的open/read/write函数实际上是由一个叫
file_operations的结构体统一管理的。
Ø 这是字符驱动最重要的一个结构体(之一),里面包含
了一组函数指针。这组函数指针指向驱动
精华版的file_operations(简约而不简单)
struct file_operations {
struct module *owner;
int (*open) (struct inode *, struct file *);
int (*release) (struct inode *, struct file *);
ssize_t (*read)(struct file *, char __user *, size_t, loff_t *);
ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *);
…
}
字符驱动注册的过程:
1.在初始化函数中根据需要申请资源申请和初始化
2.通过rigester_chrdev()把驱动注册进内核。
手动建立设备:
mknod /dev/文件名 c 主设备号 从设备号
2.自动创建:
udev机制,使用insmod时自动创建设备节点,使用rmmod时自动删除设备节点。
udev是设备管理器,主要用于管理/dev下的设备节点。
创建过程:
首先定义和创建设备类:
struct class *my_class;
ma_class=class_create(THIS_MODULE,name);
根据类创建设备节点:
struct device *my_device;
my_device=device_create(my_class,NULL,MKDEV(major_nr,minor_nr),NULL,name);
卸载过程:
首先删除设备节点;
device_destory(my_class,MKDEV(major_nr,minor_nr));
销毁创建好的设备类:
class_destory(my_class);
用户态与内核态数据的传输
从内核空间拷贝n字节数据到用户空间
copy_to_user(user_buffer,kernel_buffer,n)
从用户空间拷贝n字节数据到内核空间
copy_from_user(kernel_buffer,user_buffer,n)
从内核空间拷贝一数据到用户空间
put_user(kernel_value,user_buffer)
从用户空间拷贝一数据(任意类型)变量到用户空间
get_user(kernel_value,user_buffer)