ioremap和iounmap -- 内核态地址映射

本文深入探讨了内核态下ioremap和iounmap的使用方法,包括物理地址到虚拟地址的映射过程及映射后的访问与释放操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

ioremap和iounmap -- 内核态地址映射

#include <linux/module.h> 
#include <linux/kernel.h>
#include <asm/io.h>  /* for ioremap and iounmap */


static int __init hello_init(void)
{
    void        * v_addr = NULL;
    unsigned long p_addr = 0xfe000000;
    unsigned long size   = 0x1000;

    /* 将物理地址映射为虚拟地址 */
    v_addr = ioremap(p_addr, size);
    if (NULL == v_addr)
    {
        printk("ioremap 0x%lx error\n", p_addr);
    }
    else
    {
        /* 使用虚拟地址访问物理空间,访问结束后,释放本次映射 */
        printk("*(unsigned int *)v_addr = 0x%x\n",
                *(unsigned int *)v_addr);
        iounmap(v_addr);
    }

    return 0;
}

static void __exit hello_exit(void)
{
    printk(KERN_ALERT "Goodbye world 1.\n");
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("zengxiaolong ");
MODULE_DESCRIPTION("A sample driver");
MODULE_SUPPORTED_DEVICE("testdevice");
 

### Linux ive驱动中 `ioremap` 用户态 `mmap` 的交互问题 在Linux内核驱动开发过程中,当使用 `ioremap` 将设备的物理地址映射到内核虚拟地址后,如果希望该内存区域能够被用户空间通过 `mmap` 访问,则需要特别注意一些配置细节。以下是可能导致 `mmap` 失败的原因以及解决方案。 #### 1. 内核驱动中的 `mmap` 实现 为了使用户空间可以成功调用 `mmap` 并访问由 `ioremap` 映射的内存区域,驱动程序必须实现 `file_operations` 结构体中的 `mmap` 函数指针[^1]。通常情况下,这涉及以下几个方面: - **设置页表属性** 使用 `remap_pfn_range` 或者更现代的方式(如 `vm_insert_page`),将内核映射的页面重新映射给用户空间。需要注意的是,这些方法会依赖于具体的硬件架构内存管理单元(MMU)的支持。 - **权限控制** 确保分配给用户的虚拟地址具有正确的读/写权限。例如,某些硬件寄存器可能只允许读取而不支持写入操作,因此需要调整 `vma->vm_flags` 中的相关标志位。 ```c static int my_mmap(struct file *filp, struct vm_area_struct *vma) { unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; void __iomem *addr; addr = ioremap(offset, vma->vm_end - vma->vm_start); if (!addr) return -ENOMEM; if (remap_pfn_range(vma, vma->vm_start, virt_to_phys(addr) >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)) { iounmap(addr); return -EAGAIN; } return 0; } ``` 上述代码片段展示了如何利用 `remap_pfn_range` 来成从内核空间向用户空间的映射过程[^2]。 #### 2. 设备树节点配置 对于基于ARM或其他RISC处理器平台上的嵌入式系统而言,还需要检查设备树(Device Tree)定义是否正确设置了可共享缓冲区的信息。具体来说就是确认是否有如下字段存在并合理赋值: - compatible 字符串匹配; - reg 属性指定基址及其长度; - interrupts 描述中断源位置等等。 另外值得注意的一点是,部分SoC厂商可能会提供额外的DTB扩展选项用于优化性能或者兼容特定外设接口标准[^3]。 #### 3. 编译选项与模块加载参数 最后别忘了核查当前运行环境下的编译开关状态(`CONFIG_*`)以及动态载入时传递过来的关键字参数列表里有没有遗漏任何必要的条目项。比如开启DMA一致性缓存刷新功能也许会对解决跨域数据同步难题有所帮助。 --- ### 总结 综上所述,针对Kernel Driver Ioremap 用户态 MMAP Failed 这一现象可以从多个角度入手排查原因并采取相应措施加以修复善。包括但不限于补充整的File Operations结构成员函数定义;依据实际需求定制化修改Page Table Entry Flags组合模式;审慎评估DTS描述语法准确性等方面的工作都需要逐一落实到位才能最终达成预期目标效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值