write、read

内核接口

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 (*read) (struct file *filp, char __user *buf, size_t count, loff_t *f_pos);
ssize_t (*write) (struct file *filp, const char __user *buf, size_t count, loff_t *f_pos);

filp:待操作的设备文件file结构体指针;
buf:待写入所读取数据的用户空间缓冲区指针;
count:待读取数据字节数;
f_pos:待读取数据文件位置,读取完成后根据实际读取自救书重新定位;
__usr:是一个空的宏,主要用来显示的告诉程序员它修饰的指针变量存放的是用户空间地址。

在这里插入图片描述
在这里插入图片描述

struct file {
    // ...
    struct path                     f_path;
    struct inode                    *f_inode;
    const struct file_operations    *f_op;

    atomic_long_t                    f_count;
    unsigned int                     f_flags;
    fmode_t                          f_mode;
    struct mutex                     f_pos_lock;
    loff_t                           f_pos;
    struct fown_struct               f_owner;
    // ...
}

hello_drv.c

static char kernel_buf[1024];

static ssize_t hello_drv_read (struct file *file, char __user *buf, size_t size, loff_t *offset)
{
	int err;
	printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
	err = copy_to_user(buf, kernel_buf, MIN(1024, size));
	if(err < 0)
	{
		err = -EFAULT;
		return err;
	} 
	return MIN(1024, size);
}

static ssize_t hello_drv_write (struct file *file, const char __user *buf, size_t size, loff_t *offset)
{
	int err;
	printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
	err = copy_from_user(kernel_buf, buf, MIN(1024, size));
	if(err < 0)
	{
		err = -EFAULT;
		return err;
	} 
	return MIN(1024, size);
}

test.c

char buf[1024];

fd = open("/dev/hello", O_RDWR);

len = read(fd, buf, 1024);
write(fd, argv[2], len);

1、kernel_buf是定义在内核中,buf是定义在用户空间的,两者不相通;
2、参数struct file *file是用于管理进程打开的文件,当open时会被创建;
打开的设备节点时/dev/hello这个需要和驱动里注册的设备名一致。
在用户层中:
当open设备节点时返回一个fd,是结构体files_struct中数组的下标,而数组成员的类型就是file,因此可以得到驱动程序hello_drv_read(…)中第一个参数;
3、注意,始终需要判断需要写入写出数据的大小和缓冲区大小的,防止数据大于缓冲区大小;
4、FILE,为打印相应的文件名,
  LINE,为打印语句在源代码中相应的行,
  FUNCTION,为打印语句在源代码中相应的函数名。
5、虽然用户层的buf和内核层的buf是同一个用户层地址,但是两者是隔离的;所以从程序里看到的都一样都是虚地址。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值