📄 chrdev.c
字号:
#include <linux/module.h>#include <linux/kernel.h>#include <linux/fs.h>#include <asm/uaccess.h>#include <linux/ioctl.h>#include "chrdev_stanley.h"#define DEVICE_NAME "chrdev"#ifdef CONFIG_DEVFS_FS#include <linux/devfs_fs_kernel.h>#endif#ifdef HELLO_DEBUG#include <linux/proc_fs.h>#endifint pointer;char *string;char *msg1="This is an kernel module example string1-----------------\n";char *msg2="This is an kernel module example string2-----------------\n";char *msg3="This is an kernel module example string3-----------------\n";int hello_open(struct inode *node, struct file *filp){// printk("major and minor device number=%x\n", node->i_rdev);// printk("Major number=%d\n", MAJOR(node->i_rdev)); printk("Device is open\n"); pointer=0; return 0;}int hello_close(struct inode *node, struct file *filp){ printk("Device is closed\n"); return 0;}ssize_t hello_read(struct file *filp, char *buffer, size_t length, loff_t *offset){ printk("Read data from kernelspace to userspace\n"); if(pointer==0) { copy_to_user(buffer, string, 40); pointer=40; return 40; }else return 0;}ssize_t hello_write(struct file *filp, const char *buffer, size_t length, loff_t *offset){ printk("Write data from userspace to kernelspace\n"); copy_from_user(string, buffer, length); return length;}int hello_ioctl(struct inode *node, struct file *filp, unsigned int cmd, unsigned long arg){ switch(cmd) { case IOCTL_SET_MSG: if (arg==1) string=msg1; if (arg==2) string=msg2; if (arg==3) string=msg3; break; case IOCTL_GET_MSG: if (string==msg1) *(long *)arg=1; if (string==msg2) *(long *)arg=2; if (string==msg3) *(long *)arg=3; default: break; } return 0;}int major;struct file_operations fops={ open : hello_open, release : hello_close, read : hello_read, write: hello_write, ioctl: hello_ioctl};#ifdef HELLO_DEBUGint hello_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *data){ sprintf(buf, "Test Device proc mechanism.\n"); *eof=1; return strlen(buf);}static void hello_create_proc(){ create_proc_read_entry("hello_char", 0 /* default mode */, NULL /* parent dir */, hello_read_proc, NULL /* client data */);}static void hello_remove_proc(){ /* no problem if it was not registered */ remove_proc_entry("hello_char", NULL /* parent dir */);}#endifint init_module(){ string=msg1; major=register_chrdev(MAJOR_NUM, DEVICE_NAME, &fops); if ( major>0 ) printk("\n\nMajor=%d\n", major); else if ( major < 0) { printk ("Can't register this module\n"); unregister_chrdev(MAJOR_NUM, DEVICE_NAME); return 1; }#ifdef CONFIG_DEVFS_FS devfs_hello_dir = devfs_mk_dir (NULL, "hello", NULL); devfs_helloraw = devfs_register (devfs_hello_dir, "hello", DEVFS_FL_DEFAULT, MAJOR_NUM, MINOR_NUM, S_IFCHR | S_IRUSR | S_IWUSR, &fops, NULL );#endif#ifdef HELLO_DEBUG /* only when debugging */ hello_create_proc();#endif return 0;}void cleanup_module(){ string=msg1;#ifdef CONFIG_DEVFS_FS unregister (devfs_helloraw);#endif#ifdef HELLO_DEBUG /* only when debugging */// hello_remove_proc();#endif unregister_chrdev(MAJOR_NUM, DEVICE_NAME);}MODULE_LICENSE("GPL");MODULE_AUTHOR("Stanley Peng");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -