用uio正确映射读写内存mmap

news/2024/11/8 9:08:56/

在 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.ppmy.cn/news/1545313.html

相关文章

【NOIP提高组】合唱队形

【NOIP提高组】合唱队形 C语言Java &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; N位同学站成一排&#xff0c;音乐老师要请其中的(N-K)位同学出列&#xff0c;使得剩下的K位同学排成合唱队形。 合唱队形是指这样的一种队形&#xff1a;设…

React中类组件和函数组件的理解和区别

react代码模块分为类组件和函数组件。 从语法和定义、内部状态管理、生命周期、性能、可读性和维护性、上下文、集成状态管理库等角度对比React中类组件和函数组件。 1、语法和定义 类组件&#xff1a; 使用 ES6 的类&#xff08;class&#xff09;语法定义的 React 组件。…

网页版五子棋——用户模块(服务器开发)

前一篇文章&#xff1a;网页版五子棋—— WebSocket 协议-CSDN博客 目录 前言 一、编写数据库代码 1.数据库设计 2.配置 MyBatis 3.创建实体类 4.创建 UserMapper 二、前后端交互接口 1.登录接口 2.注册接口 3.获取用户信息 三、服务器开发 1.代码编写 2.测试后端…

2024年网鼎杯青龙组|MISC全解

转载或摘抄时请标明出处 MISC01 wdbflag{22226aba1d98c4302a6f508cad7da5d8} MISC02 一把梭工具没有任何结果&#xff0c;估计缺少符号表&#xff0c;直接strings flag > out.txt导出后慢慢找线索 在桌面上发现了png和txt文件&#xff0c;用文件名做一次筛选 第一行发现bas…

【机器学习】机器学习回归模型全解析:线性回归、多项式回归、过拟合与泛化、向量相关性与岭回归的理论与实践

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

HarmonyOS-消息推送

一. 服务简述 Push Kit&#xff08;推送服务&#xff09;是华为提供的消息推送平台&#xff0c;建立了从云端到终端的消息推送通道。所有HarmonyOS 应用可通过集成 Push Kit&#xff0c;实现向应用实时推送消息&#xff0c;使消息易见&#xff0c;构筑良好的用户关系&#xff0…

数据结构 —— 红黑树

目录 1. 初识红黑树 1.1 红黑树的概念 1.2 红⿊树的规则 1.3 红黑树如何确保最长路径不超过最短路径的2倍 1.4 红黑树的效率:O(logN) 2. 红黑树的实现 2.1 红黑树的基础结构框架 2.2 红黑树的插⼊ 2.2.1 情况1&#xff1a;变色 2.2.2 情况2&#xff1a;单旋变色 2.2…

法语nous sommes

法语短语 “nous sommes” 的词源可以追溯到拉丁语&#xff0c;具体分析如下&#xff1a; 1. “Nous” 的词源&#xff1a; “Nous” 是法语中表示 “我们” 的人称代词&#xff0c;源自拉丁语的 “nos”&#xff0c;它表示 “我们” 的意思。 拉丁语 “nos” 是第一人称复数…