祝各位道友念头通达
GitHub Gitee 语雀 打赏

内核态到用户态数据传输的几种方式

内核态-用户态数据传输方式

参考: https://blog.csdn.net/bingqingsuimeng/article/details/7924756

1. 数据拷贝(copy_to_user, copy_from_user)

这个就是一个简单的数据拷贝, 跟用户态的 拷贝函数 memcpy 差不多, 其性能也是相差不多, 不过速率较低

示例代码: https://gitee.com/han_gx/my_notes/tree/master/linux_C/driver_test

2. 内存映像(mmap)

首先这里内存映射包含两个方面

  1. 内核态到硬件上的内存映射
    内核态和硬件之间数据大量的传输,需要映射到虚拟内存上,以PCIE设备为例(目前就接触PCIE这块),内核态会申请一块用于DMA的虚拟内存, 然后将物理地址传输给fpga, fpga给定的物理地址写入固定大小数据即可.物理地址由内核固定的接口提供,经过验证,直接对物理地址不能进行偏移,读写等操作.(验证方法,将要偏移的大小传至fpga,fpga将起始物理地址进行一定的偏移,和内核态对起始物理地址进行偏移,偏移过后的地址不一致)
  2. 用户态到内核态的内存映射
    用户态直接使用mmap接口, 在内核态需要对mmap函数进行重载,负责会调用失败.

示例代码, 这里是一个PCIE驱动,其中包含了对用户态到内核态的mmap,并在驱动程序中重写了 mmap:
驱动代码: https://gitee.com/han_gx/linux_cpu/tree/48T/xbmd_drv
用户调用: https://gitee.com/han_gx/linux_cpu/tree/48T/xbmd_test
/dev/mem
介绍: 在liunx和嵌入式linux当中,基本上都有 dev/mem 设备, 该设备是内核所有物理地址空间的全映像,这些地址包括: 物理内存(RAM)空间、物理存储(ROM)空间、CPU总线地址、CPU寄存器地址、外设寄存器地址、GPIO、定时器、ADC、DMA地址空间等. 缺点: 非法访问导致系统不稳定,甚至内核崩溃
对/dev/mem源码解读
通过源码修改解除/dev/mem的某些限制
使用方法: dev/memmmap 结合

int fd = 0;
char *mmap_addr = NULL;
unsigned char *mmap_addr = 0x12345678;  //这里代表内存的物理地址, 可以是其内核申请获得的物理地址,也可以是用户态申请获得的物理地址
fd = open("/dev/mem", O_RDWR | O_NDELAY);   /* 读写权限,非阻塞 */
mmap_addr=(char *)mmap(NULL, MMAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, mmap_addr);

扩展:

  1. hexdump -n 32 -s 2 /dev/mem, 可以通过偏移量和长度查看/dev/mem物理地址的值
  2. /dev/kmem(不是必然存在的) 可以查看内核虚拟内存的全镜像,查看对应地址的变量等

3. proc 文件系统

4. 虚拟文件系统

5. 信号量

6.由内核主动发起的信息交互

posted @ 2022-07-29 11:33  韩若明瞳  阅读(1561)  评论(0编辑  收藏  举报