You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux用户空间读取SMMUv2寄存器时返回全0的问题排查

问题

系统中存在ARM SMMUv2,尝试在Linux用户空间读取其内存映射寄存器时遇到以下问题:

  1. 打开并mmap了/dev/mem,偏移量为从DTS获取的SMMU_BASE物理地址(例如0x8000000),但映射区域读取内容全为0;
  2. 执行命令dd if=/dev/mem of=test bs=4096 skip=32768 count=4时,报错Bad Address;
  3. 在内核空间使用ioremap(0x8000000, 0x1000)尝试读取,结果同样全为0。

用户空间读取代码如下:

static int smmuread(int fd, unsigned long address, unsigned int length, off_t offset,
    unsigned long data, unsigned int data_size)
{
    volatile uint8_t *mptr = 0;
    volatile uint8_t *wptr = NULL;
    unsigned int range_len = (length - offset);

    mptr = mmap(0, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, address);
    if (mptr == (void *) -1) {
        printf("Failed to do mmap\n");
        return 1;
    }

    wptr = mptr + offset;
        switch (data_size) {
            case 1:
                printf("%02x\n", *wptr);;
                break;
            case 2:
                printf("%04x\n", *(uint16_t *)wptr);;
                break;
            case 4:
                printf("%08x\n", *(uint32_t *)wptr);;
                break;
            case 8:
                printf("%lx\n", *(uint64_t *)wptr);;
                break;
            default:
                range_len = (length - offset);
                if (data_size)
                    range_len = MIN(range_len, data_size);
                dump_range(wptr, range_len);
                break;
        }

    munmap(mptr, length);
    return 0;
}
解决思路与方案
  • 检查SMMU硬件使能状态
    ARM SMMUv2默认可能处于复位关闭状态,未初始化的寄存器读值会全为0。先确认内核是否开启了SMMU驱动配置CONFIG_ARM_SMMU_V2,未开启则需开启后重新编译内核;若已开启,查看内核日志确认SMMU驱动是否成功探测并初始化设备。如果是自定义内核模块访问,需手动配置SMMU控制寄存器(如SMMU_CR)完成硬件使能。

  • 验证设备树与地址映射权限

    1. 检查DTS中SMMU节点的status属性是否为"okay",若为"disabled",内核不会映射该硬件区域,需修改DTS后重新烧录;
    2. 内核配置CONFIG_STRICT_DEVMEM会限制用户空间通过/dev/mem访问非RAM/PCIe区域,可添加启动参数devmem=1临时关闭限制,或修改内核配置关闭CONFIG_STRICT_DEVMEM后重新编译。
  • 确认地址对齐与访问范围
    mmap的偏移参数必须是页大小(通常4KB)的整数倍,确保传入的SMMU_BASE物理地址已对齐;同时确认映射长度覆盖了你要访问的寄存器范围,避免越界或部分映射导致的无效访问。

  • 内核空间访问的注意事项
    内核中使用ioremap后,需确保SMMU对应的时钟、电源域已被正确开启(多数SoC中外设需先开启时钟才能访问寄存器)。可参考内核原生SMMU驱动的初始化流程,先完成时钟、电源配置,再进行寄存器读写操作。

内容的提问来源于stack exchange,提问作者wangt13

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 03:05:33