目录
一.模块参数
二.驱动代码
三.模块加载
四.查看
字符设备驱动代码:
// hello.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("A simple character device driver");
#define HELLO_SIZE 256
static char hello_buffer[HELLO_SIZE];
static int hello_open(struct inode *inode, struct file *filp);
static ssize_t hello_read(struct file *filp, char *buf, size_t count, loff_t *f_pos);
static ssize_t hello_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos);
static int hello_release(struct inode *inode, struct file *filp);
static int my_param = 0;
static struct file_operations hello_fops = {
.open = hello_open,
.read = hello_read,
.write = hello_write,
.release = hello_release,
};
static int hello_major = 0;
static int __init hello_init(void) {
int result;
result = register_chrdev(hello_major, "hello", &hello_fops);
if (result < 0) {
printk(KERN_ALERT "hello: cannot obtain major number %d\n", hello_major);
return result;
}
if (hello_major == 0) {
hello_major = result;
}
printk(KERN_INFO "Hello, character device driver loaded\n");
return 0;
}
static void __exit hello_exit(void) {
unregister_chrdev(hello_major, "hello");
printk(KERN_INFO "Goodbye, character device driver unloaded\n");
}
static int hello_open(struct inode *inode, struct file *filp) {
// Open logic, if needed
return 0;
}
static ssize_t hello_read(struct file *filp, char *buf, size_t count, loff_t *f_pos) {
// Read logic, if needed
return 0;
}
static ssize_t hello_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos) {
ssize_t retval = 0;
if (copy_from_user(hello_buffer, buf, count)) {
return -EFAULT;
}
// Write logic here using data in hello_buffer
return retval;
}
static int hello_release(struct inode *inode, struct file *filp) {
// Release logic, if needed
return 0;
}
module_init(hello_init);
module_exit(hello_exit);
module_param(my_param,int ,S_IRUGO);
MODULE_PARM_DESC(my_param,"get an value from user...\n");
- 模块参数
宏:
module_param(name, type, perm);
module_param_array(name, type, num_point, perm);
module_param_named(name_out, name_in, type, perm);
module_param_string(name, string, len, perm);
MODULE_PARM_DESC(name, describe);
访问权限:perm
S_IRUGO:任何人均可读取但不能修改
S_IRUGO|S_IWUSR:允许root修改
整数类型:
module_param(name, type, perm);
参数 | 描述 |
name | 用来接受参数的变量名 |
type | 参数的数据类型 |
perm | 访问权限 |
Char类型:
module_param_named(name_out, name_in, type, perm);
参数 | 描述 |
name_out | 记载模块时,参数的名字 |
name_in | 模块内部变量的名字 |
type | 参数类型 |
perm | 访问权限 |
字符串类型:
module_param_string(name, string, len, perm);
参数 | 描述 |
name | 在加载模块时,参数的名字 |
string | 模块内部的字符数组的名字 |
len | 模块内部的字符数组的大小 |
perm | 访问权限 |
数组类型:
module_param_array(name, type, num_point, perm);
参数 | 描述 |
name | 在加载模块时,数组名 |
type | 模块数组的类型 |
num_point | 用来获取用户在加载模块时传递的参数个数,为NULL时,表示不关心用户传递的参数个数 |
perm | 访问权限 |
指定描述信息:
MODULE_PARM_DESC(name, describe);
参数 | 描述 |
name | 参数变量名 |
describe | 描述信息的字符串 |
- 驱动代码
以整形为例
在简单的字符设备驱动中添加代码:
static int my_param = 0;
module_param(my_param,int ,S_IRUGO);
MODULE_PARM_DESC(my_param,"get an value from user...\n");
- 模块编译
insmod your_driver.ko your_param=42
- 查看
dmesg查看日志
modinfo -p param.ko查看参数