应用层和内核层数据传输-7

Posted 杨斌并

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了应用层和内核层数据传输-7相关的知识,希望对你有一定的参考价值。

应用层和内核层数据传输

Linux—切皆文件!

  • 文件对应的操作有打开,关闭,读写
  • 设备节点对应的操作有打开,关闭,读写

1.如果我在应用层使用系统IO对设备节点进行打开,关闭,读写等操作会发生什么呢?

  • linux/fs.h

  • 当我们在应用层read设备节点的时候,就会触发我们驱动里面read 这个函数。

ssize_t(*read)(struct file *, char_user*,size_t, loff_t *); 

当我们在应用层 write设备节点的时候,就会触发我们驱动里面write这个函数。

ssize_t(*write)(struct file*,const char__user*, size_t, loff_t*);
  • 当我们在应用层poll/select的时候,就会触发我们驱动里面poll这个函数。
unsigned int(*poll) (struct file *,struct poll_table_struct*);
  • 当我们在应用层ioctl的时候,就会触发我们驱动里面ioctl这个函数。
long (*unlocked_ioctl)(struct file *, unsigned int, unsigned long); 
  • 当我们在应用层open的时候,就会触发我们驱动里面open这个函数。
int (*open) (struct inode *, struct file *);
  • 当我们在应用层close的时候,就会触发我们驱动里面close这个函数。
int (*release) (struct inode *, struct file *);

2假如我们的file_operations里面没有read,我们在应用层read设备节点的时候会发 生什么?

  • 什么也不会发生,也不会报错!

3我们的应用层和内核层是不能直接进行数据传输的。

  • #include <asm/uaccess.h>
  • 用这个也行 为了同意一个包用这个 #include <linux/uaccess.h> 这个头文件包含了那个
static inline long copy_from_user(void *to, const void__user *from, unsigned long n)
  • 对应客户端的write函数,该函数在io.h中 一般为了统一使用#include
    <unistd.h> 这个头文件包含了那个
int __cdecl write(int _Filehandle,const void *_Buf,unsigned int _MaxCharCount)
  • to 拷贝到哪里去
  • from 数据从哪里来
  • n 数据大小
static inline long copy_to_user(void _user *to, const void *from, unsigned long n)

  • 对应客户端的read函数 #include <unistd.h>
read (int __fd, void *__buf, size_t __nbytes)
  • 设备节点是 连接上层应用和底层驱动的桥梁
  • 上层应用 》 设备节点 》 底层驱动

驱动代码的例子

Android 下的

  • misc.c文件
#include <linux/init.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/uaccess.h>


int misc_open(struct inode * inode, struct file * file){
    printk("hello misc_open \\n");
    return 0;  
}

int misc_release(struct inode * inode, struct file * file){
    printk("hello misc_release bye bye \\n");
    return 0;
}

int misc_read(struct file* file, char __user * ubuf, size_t size, loff_t * loff_t){

    char kbuf[64] = "heheh_read";

    printk("hello misc_read \\n");

    if(copy_to_user(ubuf, kbuf, strlen(kbuf)) != 0 ){
        printk("copy_to_user error \\n");
        return -1;
    }
    
    return 0;

}

int misc_write(struct file * file, const char __user * ubuf, size_t size, loff_t * loff_t){
    printk("hello misc_write \\n");
    char kbuf[64] = {0};

    if (copy_from_user(kbuf, ubuf, size) != 0)
    {

        printk("copy_from_to_user error \\n");
        return -1;
    
    }

    printk("kbuf is %s \\n", kbuf);
    return 0;

}

struct file_operations misc_fops =
{
    .owner = THIS_MODULE,
    .open = misc_open,
    .release = misc_release,
    .read = misc_read,
    .write = misc_write
};


struct miscdevice misc_dev = 
{
    .minor = MISC_DYNAMIC_MINOR,
    .name = "hello_misc",
    .fops = &misc_fops
};

static int misc_init(void){

    int ret;
    ret = misc_register(&misc_dev);

    if (ret <0)
    {
        printk("misc_registe is error \\n");
    }

    printk("misc registe is succeed \\n");
    return 0;
}

static int misc_exit(void){
    misc_deregister(&misc_dev);
    printk(KERN_EMERG "misc byb byb \\n");
    return 0;
}

module_init(misc_init);
module_exit(misc_exit);
MODULE_LICENSE("DUAL BAD/GPL");
MODULE_AUTHOR("LIYU");

  • app 可执行文件
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

void main(){
    int fd;
    char buf[64] = {0};
    char buf_write[64] = "write aaaaaaaaa";
    fd = open("/dev/hello_misc",O_RDWR);
    if (fd < 0)
    {
        printf("open error \\n");
    }
    printf("open success \\n");
    read(fd,buf,sizeof(buf));
    write(fd,buf_write,sizeof(buf_write));
    printf("buf is %s\\n",buf);
    close(fd);
}

  • Makefile文件
obj-m +=misc.o
KOIR:=/home/topeet/ybb/android/itop-3399_8.1/kernel
PWD?=$(shell pwd)
all:
        make -C $(KOIR) M=${PWD} modules
clean:
        rm -rf *.o
        rm -rf *.ko
        rm -rf *.mod.c
        rm -rf *.symvers
        rm -rf *.order

以上是关于应用层和内核层数据传输-7的主要内容,如果未能解决你的问题,请参考以下文章

wince6.0启动异砦新手求助

007-大数据-高并发网络基础1

关于UNIX网络编程的的OSI,1.7章的总结

操作系统内核和网络协议栈在哪里重叠?

linux内核源码分析之网络数据收发流程

浅谈 Linux 内核开发之网络设备驱动