MMU的相关概念可参考:https://www.cnblogs.com/lethe1203/p/18064515 Linux驱动开发在某些情况也会直接操作寄存器 MMU主要完成的功能: 1、完成虚拟空间到物理空间的映射 2、内存保护,设置存储器的访问权限,设置虚拟存储空间的缓冲特性 对于32位的处理器来说,虚拟地址范围为:2^32 = 4GB,假设开发板上有512MB的DDR,这个512M就是物理内存,经过MMU就可以将512M映射到4GB的虚拟空间。 涉及到内存管理单元(MMU)以及虚拟内存系统的设计。解决地址冲突的问题可以通过以下几种方式:
- 分页机制
- 地址空间布局随机化
- 内存映射和区域分配
实现物理内存和虚拟内存转换:
1、ioremap函数
ioremap 函 数 用 于 获 取 指 定 物 理 地 址 空 间 对 应 的 虚 拟 地 址 空 间 , 定 义 在arch/arm/include/asm/io.h 文件中,定义如下:#define ioremap(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE) void __iomem * __arm_ioremap(phys_addr_t phys_addr, size_t size, unsigned int mtype) { return arch_ioremap_caller(phys_addr, size, mtype, __builtin_return_address(0)); } EXPORT_SYMBOL(__arm_ioremap); // 参数说明 phys_addr:要映射给的物理起始地址 size:要映射的内存空间大小 mtype:ioremap 的类型,可以选择 MT_DEVICE、MT_DEVICE_NONSHARED、MT_DEVICE_CACHED 和 MT_DEVICE_WC,ioremap 函数选择 MT_DEVICE。 返回值:__iomem 类型的指针,指向映射后的虚拟空间首地址。
2、iounmap函数
卸载驱动的时候需要使用 iounmap 函数释放掉 ioremap 函数所做的映射,iounmap 函数原型如下:void iounmap (volatile void __iomem *addr)iounmap 只有一个参数 addr,此参数就是要取消映射的虚拟地址空间首地址
I/O内存访问函数:
I/O 端口和 I/O 内存。当外部寄存器或内存映射到 IO 空间时,称为 I/O 端口。当外部寄存器或内存映射到内存空间时,称为 I/O 内存。但是对于 ARM 来说没有 I/O 空间这个概念,因此 ARM 体系下只有 I/O 内存(可以直接理解为内存)。使用 ioremap 函数将寄存器的物理地址映射到虚拟地址以后,我们就可以直接通过指针访问这些地址,但是 Linux 内核不建议这么做,而是推荐使用一组操作函数来对映射后的内存进行读写操作。1、读操作函数
u8 readb(const volatile void __iomem *addr) // 8bit操作函数 u16 readw(const volatile void __iomem *addr) // 16bit操作函数 u32 readl(const volatile void __iomem *addr) // 32bit操作函数
2、写操作函数
void writeb(u8 value, volatile void __iomem *addr) void writew(u16 value, volatile void __iomem *addr) void writel(u32 value, volatile void __iomem *addr)writeb、writew 和 writel 这三个函数分别对应 8bit、16bit 和 32bit 写操作,参数 value 是要写入的数值,addr 是要写入的地址。 标签:__,addr,映射,void,虚拟地址,地址映射,内存 From: https://www.cnblogs.com/lethe1203/p/18091326