Goal
Implement a kernel module that can passing parameter when insert module, and add an entry to /proc that can write/read data. In embedded linux often using similar facility to help debug.
Code:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <linux/module.h> | |
#include <linux/moduleparam.h> | |
#include <linux/init.h> | |
#include <linux/kernel.h> | |
#include <linux/proc_fs.h> | |
#include <linux/uaccess.h> | |
#define BUFSIZE 100 | |
MODULE_LICENSE("GPL"); | |
MODULE_AUTHOR("Ray Tsai"); | |
static int mode=0; | |
module_param(mode,int,0660); | |
static char *entry="Default"; | |
module_param(entry,charp,0660); | |
// Proc related structure | |
static struct proc_dir_entry *ent; | |
static int private_test_data = 123; | |
// Write handler | |
static ssize_t test_write(struct file *file, const char __user *ubuf,size_t count, loff_t *ppos) | |
{ | |
char buf[BUFSIZE]; | |
int temp = 0; | |
int num =0; | |
pr_info( KERN_DEBUG "write handler\n"); | |
if(copy_from_user(buf, ubuf, count)) | |
{ | |
pr_info( KERN_DEBUG "Error copy from user \n"); | |
return -EFAULT; | |
} | |
num = sscanf(buf,"%d",&temp); | |
private_test_data = temp; | |
return count; | |
} | |
// Read handler | |
static ssize_t test_read(struct file *file, char __user *ubuf,size_t count, loff_t *ppos) | |
{ | |
char buf[BUFSIZE]; | |
int len=0; | |
pr_info( KERN_DEBUG "read handler\n"); | |
if(*ppos > 0 || count < BUFSIZE) | |
return 0; | |
len += sprintf(buf,"private_test_data = %d\n",private_test_data); | |
if(copy_to_user(ubuf,buf,len)) | |
return -EFAULT; | |
*ppos = len; | |
return len; | |
} | |
static struct file_operations myops = | |
{ | |
.owner = THIS_MODULE, | |
.read = test_read, | |
.write = test_write, | |
}; | |
static int __init test_module_init(void) | |
{ | |
pr_info("Init Ray test module!\n"); | |
pr_info("Test module: %d!\n", mode); | |
pr_info("Create %s \n", entry); | |
ent = proc_create(entry,0660,NULL,&myops); | |
return 0; | |
} | |
static void __exit test_module_exit(void) | |
{ | |
proc_remove(ent); | |
pr_info("Exit Ray test module!\n"); | |
} | |
module_init(test_module_init); | |
module_exit(test_module_exit); |
Makefile:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
obj-m := test_module.o | |
KERNELDIR ?= /lib/modules/$(shell uname -r)/build | |
all default: modules | |
install: modules_install | |
modules modules_install help clean: | |
$(MAKE) -C $(KERNELDIR) M=$(shell pwd) $@ |
Usage:
1. Insert module and make /proc/Ray entry#>sudo insmod test_module.ko entry="Ray" mode=1238
2. Write data#>echo 123 > /proc/Ray3. Read data#>cat /proc/Ray
沒有留言:
張貼留言