当前位置: 首页 > news >正文

用uio正确映射读写内存mmap

在 OpenLunar 系统中,要通过 UIO 映射出可读写的内存,可以按照以下步骤确保正确配置和使用 `UIO`,以便映射后的内存具有读写权限。

### 1. 配置设备树 (DTS) 文件
在 OpenLunar 系统中,通常通过设备树(DTS)文件为 `UIO` 设备定义内存区域和访问权限。需要确保在 DTS 中定义的 `reg` 属性范围内的内存是可读写的。

#### DTS 配置示例
假设要创建一个 `UIO` 设备节点,以下是一个示例设备树片段:

```dts
uio_device@0 {
    compatible = "generic-uio";
    reg = <0x40000000 0x1000>; // 假设内存起始地址和大小
    interrupts = <0 32 4>;     // 设备中断配置,视需要而定
};
```

确保该 `reg` 地址范围内的内存支持读写。如果硬件设计将这部分内存设置为只读,那么需要调整硬件配置。

### 2. 加载 UIO 驱动
确保内核已启用 `UIO` 支持,或者使用 `uio_pdrv_genirq` 驱动绑定设备。可以通过以下命令来绑定驱动:

```bash
modprobe uio
modprobe uio_pdrv_genirq
```

然后,将设备节点与 `uio_pdrv_genirq` 绑定:

```bash
echo "generic-uio" > /sys/bus/platform/devices/uio_device@0/driver_override
echo "uio_pdrv_genirq" > /sys/bus/platform/drivers/uio_pdrv_genirq/bind
```

### 3. 使用 `mmap` 映射内存
在应用程序中,通过 `/dev/uioX` 设备文件访问 `UIO` 内存,并使用 `mmap` 映射为用户空间内存。

确保 `mmap` 使用了 `PROT_READ | PROT_WRITE` 权限,并且映射模式为 `MAP_SHARED`。以下是一个 `mmap` 映射的示例代码:

```c
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>

#define UIO_DEV "/dev/uio0"    // 假设设备文件为 /dev/uio0
#define MEM_SIZE 0x1000        // 映射内存大小,与 DTS 配置保持一致

int main() {
    int uio_fd;
    void *mapped_mem;

    // 打开 UIO 设备文件
    uio_fd = open(UIO_DEV, O_RDWR);
    if (uio_fd < 0) {
        perror("Failed to open UIO device");
        return -1;
    }

    // 使用 mmap 映射内存
    mapped_mem = mmap(NULL, MEM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, uio_fd, 0);
    if (mapped_mem == MAP_FAILED) {
        perror("mmap failed");
        close(uio_fd);
        return -1;
    }

    // 写操作示例
    *((volatile int *)mapped_mem) = 0x12345678;

    // 读操作示例
    int read_value = *((volatile int *)mapped_mem);
    printf("Read value: 0x%x\n", read_value);

    // 解除映射并关闭文件
    munmap(mapped_mem, MEM_SIZE);
    close(uio_fd);

    return 0;
}
```

#### 代码说明
1. **打开 UIO 设备文件**:通过 `/dev/uioX`(如 `/dev/uio0`)访问设备。
2. **mmap 映射**:`PROT_READ | PROT_WRITE` 和 `MAP_SHARED` 确保内存映射支持读写且可以被多个进程共享。
3. **读写操作**:通过指针直接访问映射内存区域,进行读写操作。
4. **清理资源**:使用 `munmap` 解除映射,并关闭设备文件。

### 4. 检查内存权限
如果在上述步骤完成后仍无法写入,可能是硬件或系统设置中限制了内存写入权限。可以通过以下步骤检查内存是否可写:

- 使用 `devmem` 工具在物理地址上直接写入,验证是否能正常写入。
- 确保映射区域不受内存保护机制影响,避免写保护设置。

### 5. 确保内存一致性
对于某些内存映射,可能需要调用 `msync` 以确保缓存一致性:

```c
msync(mapped_mem, MEM_SIZE, MS_SYNC);
```

### 总结
1. **正确配置 DTS** 以确保 `UIO` 设备支持可读写内存区域。
2. **加载 UIO 驱动** 并使用 `uio_pdrv_genirq` 驱动绑定设备。
3. **使用 mmap** 时设置 `PROT_READ | PROT_WRITE` 权限。
4. **验证内存权限**,确保硬件和系统不限制写操作。
5. **保持缓存一致性**,确保写入立即生效。


http://www.mrgr.cn/news/68108.html

相关文章:

  • 带你搞懂红黑树的插入和删除
  • 计算机基础学习(非常详细)零基础入门到精通,收藏这篇就够了
  • JVM 由多个模块组成,每个模块负责特定的功能
  • element plus el-form自定义验证输入框为纯数字函数
  • Nacos 关于Nacos的随意添加用户
  • python实现RSA算法
  • 如何在 Java 中使用 Canal 同步 MySQL 数据到 Redis
  • 数据结构——快速排序
  • 带你用Go实现二维码小游戏(下)
  • 一文了解git TAG
  • 基于Python+Vue开发的蛋糕商城管理系统
  • C++ 判断是不是平衡二叉树
  • 【fiddler】用fiddler实现手机抓包
  • 华为OD机试 - 学生排名(Java 2024 E卷 100分)
  • LLMs之PDF:zeroX(一款PDF到Markdown 的视觉模型转换工具)的简介、安装和使用方法、案例应用之详细攻略
  • move_base
  • D365 无法在数据被选择或插入到另一个事务作用域中的缓冲区上调用 NEXT、update() 或 delete()
  • Visual Studio Code从安装到正常使用
  • 在鱼皮的模拟面试里面学习有感
  • 代码中的设计模式-策略模式
  • LLMs之RAG:《LightRAG: Simple and Fast Retrieval-Augmented Generation》翻译与解读
  • MDC(重要)
  • 06 网络编程基础
  • STM32Cube高效开发教程<高级篇><FreeRTOS>(十二)-----互斥量使用例程
  • YoloV10改进策略:上采样改进|CARAFE,轻量级上采样|即插即用|附改进方法+代码
  • OpenResty 1.27.1.1 已经正式发布