前言:
平时的驱动调试中,有时候想读取某个内存,看看内存的值或者变化情况。自制一个用来读取内存的工具,可以方便驱动的开发测试。工具分为驱动程序和应用程序,具体的编写步骤和源代码如下:
1. 编写 字符设备 驱动程序
- 先copy需要的 头文件,这里可以从之前的驱动程序里copy过来,也可借鉴网上相关资源
- 再写 入口函数(_init),出口函数(_exit),file_operations结构体
入口函数:注册字符设备驱动 和 fileoperations 结构体,以及创建一个类和类的设备(方便加载时系统自动创建设备节点)
出口函数:取消注册字符设备驱动 和 取消注册类 与 destroy类设备
file_operations结构体: 拿 THIS_MODULE 或者 方法 进行 填充
入口函数和出口函数是对称的,入口函数注册了字符设备驱动出口函数要取消掉,入口函数注册了类和类的设备则在出口函数应取消注册和destroy。 - 注册好了需要声明一下 告诉内核,下面的几行代码需要加入到驱动程序的末尾
module_init(drvFun_init);
module_exit(drvFun_exit);
MODULE_LICENSE("GPL");
- 这样一个字符设备的驱动框架就完成了。字符设备驱动的 file_operations 结构体非常重要,结构体内部都是指针,这样方便结构体的初始化和调用操作。
其实驱动程序有相当一部分工作是对 file_operations 结构体的填充,结构体的内容很全面,涵盖了所有对文件的操作方法(linux一切皆文件)。本设备驱动仅用到(填充)了 ioctl 方法,具体linux中 ioctl 这个系统调用的介绍在文末有一个连接可以参考。
struct file_operations {
struct module *owner;
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
int (*readdir) (struct file *, void *, filldir_t);
unsigned int (*poll) (struct file *, struct poll_table_struct *);
int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *);
int (*open) (struct inode *, struct file *);
int (*flush) (struct file *, fl_owner_t id);
int (*release) (struct inode *, struct file *);
int (*fsync) (struct file *, struct dentry *, int datasync);
int (*aio_fsync) (struct kiocb *, int datasync)