⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 copy_xx_user.c

📁 内核空间地址向用户空间地址的映射实例
💻 C
字号:
  /* 马上练习 copy_to_user/copy_from_user()的用法,毕竟put_user()/get_user()的效率有点低, 而且老加上while()循环,不好看  */    //#define KERNEL_DEBUG#include <linux/kernel.h>#include <linux/module.h>#include <linux/fs.h>#include <asm/uaccess.h>	/* for put_user */#include <linux/init.h>#define KERNEL_DEBUG#include "mod_head.h"/**  Prototypes - this would normally go in a .h file*/static __init int chardev_init(void);static __exit void chardev_exit(void);static int device_open(struct inode *, struct file *);static int device_release(struct inode *, struct file *);static ssize_t device_read(struct file *, char *, size_t, loff_t *);static ssize_t device_write(struct file *, const char *, size_t, loff_t *);#define SUCCESS 0#define DEVICE_NAME "chardev_bob_test"	/* Dev name as it appears in /proc/devices   */#define BUF_LEN 6		/* Max length of the message from the device *//** Global variables are declared as static, so are global within the file.*/static int Major;		/* Major number assigned to our device driver */static char msg[BUF_LEN] = {'\0'};	/* The msg the device will give when asked */static char *msg_Ptr;static volatile unsigned long chardev_users = 0UL;  //防止互斥, 这里用更严格的test_and_set_bit() 函数static int device_open(struct inode *inode, struct file *file){	//	if (Device_Open)	//		return -EBUSY;	//	Device_Open++;	//	上面的办法太不可靠了。用原子操作或者bit操作才是最可靠的。	if(test_and_set_bit(0,&chardev_users))		return -EBUSY;	msg_Ptr = msg;	try_module_get(THIS_MODULE); 	return SUCCESS;}static int device_release(struct inode *inode, struct file *file){	if( !test_and_clear_bit(0,&chardev_users)) {  //如果value还为1,就错了		dbg("It looks that the bit operation is wrong \n");		return -1;	}			module_put(THIS_MODULE);	return 0;}static ssize_t device_read(struct file *filp,	/* see include/linux/fs.h   */			char *buffer,	/* buffer to fill with data */			size_t length,	/* length of the buffer     */			loff_t * offset)	/* loff_t  ==   long long */{	//	Number of bytes actually written to the buffer	int bytes_read = 0;		if (*msg_Ptr == 0)		return 0;//	while (length && *msg_Ptr) {////		//	   kernel  ----> user//		put_user(*(msg_Ptr++), buffer++);////		length--;//		bytes_read++;//	}		/* copy_to_user() 的用法很简单 */	dbg("msg_Ptr length=%d\n",strlen(msg_Ptr));	if(copy_to_user(buffer,msg_Ptr,			min(strlen(msg_Ptr),length)))	{		dbg("copy_to_user() error \n");		return -EFAULT;	}	bytes_read = min(strlen(msg_Ptr),length);		return bytes_read;	}static ssize_tdevice_write(struct file *filp, 		const char *buffer, 		size_t len, 		loff_t * off){	int bytes_write = 0;	int max_bytes = sizeof(msg) -1;	memset(msg,'\0',sizeof(msg));//	while( *buffer && bytes_write < len && bytes_write < max_bytes )//	{			//		//	   kernel <---user//		get_user(*(msg_Ptr++),buffer++);//msg_Ptr[i] is same//		bytes_write++;//	}	copy_from_user(msg_Ptr,buffer,			min( min(strlen(buffer),len), sizeof(msg)-1));	bytes_write = min( min(strlen(buffer),len), sizeof(msg)-1 );		dbg("write %d bytes \n",bytes_write);	return bytes_write;}static struct file_operations fops = {	.owner	= THIS_MODULE,	.read 	= device_read,	.write 	= device_write,	.open 	= device_open,//	.ioctl  = device_ioctl,	//bob add to get pid of some process	.release= device_release	//others are NULL;};/** Functions*/static __init int chardev_init(void){	Major = register_chrdev(0, DEVICE_NAME, &fops);	if (Major < 0) {		dbg("Registering the character device failed with %d\n", Major);		return Major;	}	dbg("I was assigned major number %d.  To talk to\n", Major);	dbg("the driver, create a dev file with\n");	dbg("'mknod /dev/hello c %d 0'.\n", Major);	dbg("Try various minor numbers.  Try to cat and echo to\n");	dbg("the device file.\n");	dbg("Remove the device file and module when done.\n");	return 0;}static __exit void chardev_exit(void){	int ret = unregister_chrdev(Major, DEVICE_NAME);	if (ret < 0)		dbg("Error in unregister_chrdev: %d\n", ret);}module_init(chardev_init);module_exit(chardev_exit);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -