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

设备树reserved-memory的no-map属性疑问:为何可通过虚拟地址访问

问题:reserved-memory的no-map属性为何未阻止驱动创建虚拟映射?

设备树配置

reserved-memory {
    #address-cells = <2>;
    #size-cells = <2>;
    ranges;

    axpu_reserved_mem: axpursvd@90000000 {
        no-map;
        reg = <0x0 0x90000000 0x0 0x30000000>;
    };
};

axpu@50000000 {
    compatible = "ab21-axpu";
    reg = <0 0x50000000 0 0x10000000>;
     ...
    memory-region = <&axpu_reserved_mem>;
};

驱动关键代码

probe函数(简化版)

struct axpu_dev {
    struct device *dev;
    void __iomem *base;
    u64 paddr;
    u64 vaddr;
};

static int axpu_probe(struct platform_device *pdev)
{
    struct device *dev = &pdev->dev;
    struct resource *res;
    struct axpu_dev *axpu;
    struct device_node *np;
    int rc;
    int ret;

    res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    axpu = devm_kzalloc(dev, sizeof(*axpu), GFP_KERNEL);
    axpu->dev = dev;
    axpu->base = devm_ioremap(dev, res->start, resource_size(res));
    res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
    devm_request_irq(dev, res->start, axpu_irq_handler, IRQF_TRIGGER_HIGH, "axpu_irq", axpu);
    np = of_parse_phandle(dev->of_node, "memory-region", 0);
    rc = of_address_to_resource(np, 0, res);
    axpu->paddr = res->start;
    axpu->vaddr = memremap(res->start, resource_size(res), MEMREMAP_WB);
    platform_set_drvdata(pdev, axpu);
    axpu_init(axpu);
    return sysfs_create_group(&dev->kobj, &axpu_attr_group);
}

axpu_init函数

static void axpu_init(struct axpu_dev *axpu)
{
    printk("testing reserved memory ..\n");
    writel_relaxed(0x12345678, axpu->vaddr + 0);
    writel_relaxed(0x23456789, axpu->vaddr + 8);
    printk("read-back data = %llx, %llx\n", readl_relaxed(axpu->vaddr + 0), readl_relaxed(axpu->vaddr + 8));
}

运行现象

正常访问日志

/ # insmod axpu.ko
axpu_probe called!
 MEM : res->start = 50000000, res->end = 5fffffff, res->name = axpu@50000000
axpu->base = ffffffc010000000
 IRQ : res->start = 15, res->end = 15, res->name = axpu@50000000
axpu_dev 50000000.axpu: Allocated reserved memory, vaddr: 0xFFFFFFC080000000, paddr: 0x90000000
writing 0x12345678 at non-mapped reserved memory 0x90000000, 0x90000008 ..
read-back data = 12345678, 23456789

直接访问物理地址崩溃日志

------------[ cut here ]------------
Ignoring spurious kernel translation fault at virtual address 0000000090000000
WARNING: CPU: 0 PID: 27 at arch/arm64/mm/fault.c:311 __do_kernel_fault+0x108/0x150
odules linked in: axpu(+)
CPU: 0 PID: 27 Comm: insmod Not tainted 5.10.0-rc5 #548
Hardware name: ETRI ab21m (DT)
pstate: 60400009 (nZCv daif +PAN -UAO -TCO BTYPE=--)
pc : __do_kernel_fault+0x108/0x150
lr : __do_kernel_fault+0x108/0x150

问题分析与解答

你的设备树配置没有问题,no-map的行为完全符合设计预期:

  1. no-map的核心作用是禁止内核为该预留内存创建全局线性映射(即内核虚拟地址空间中直接映射物理地址的默认区域),而非禁止驱动通过手动映射函数创建映射。
  2. 直接访问物理地址0x90000000崩溃,恰恰证明这段内存没有被加入内核的全局线性映射,完全符合no-map的要求。
  3. 驱动中通过memremap()手动创建虚拟映射是被允许的,这正是no-map设计的初衷——将内存映射的控制权完全交给驱动,而非由内核自动管理。

如果需要让这段内存完全无法被任何方式映射(极端场景),需要额外的硬件或内核配置,但常规场景下,你的当前配置和行为都是正常的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 06:05:21