物理地址是处理器在系统总线上看到的地址。使用精简指令集(Reduced Instruction Set Computer,RISC)的处理器通常只实现一个物理地址空间,外围设备和物理内存使用统一的物理地址空间。
程序只能通过虚拟地址访问外设寄存器,内核提供了以下函数来把外设寄存器的物理地址映射到虚拟地址空间:
- 函数ioremap()把外设寄存器的物理地址映射到内核虚拟地址空间
void *__ioremap(phys_addr_t offset, size_t size, unsigned long flags);
- 函数io_remap_pfn_range()把外设寄存器的物理地址映射到进程的用户虚拟地址空间
int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn,
unsigned long size, pgprot_t prot);
- 函数remap_pfn_range()用于把内存的物理页映射到进程的用户虚拟地址空间
int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn,
unsigned long size, pgprot_t prot);
内核提供了函数iounmap()来删除函数ioremap()创建的映射。
void iounmap(void *addr);
ARM64架构的实现
ARM64架构定义了两种内存类型:
- 正常内存(Normal Memory):包括物理内存和只读存储器(ROM)。
- 设备内存(Device Memory):指分配给外围设备寄存器的物理地址区域。
对于正常内存,可以设置共享属性和缓存属性。共享属性用来定义一个位置是否可以被多个核共享,分为不可共享、内部共享核外部共享。缓存属性用来定义访问时是否通过处理器的缓存。
设备内存的共享属性总是外部共享,缓存属性总是不可缓存(即必须绕过处理器的缓存)。
物理地址宽度
目前ARM64处理器支持的最大物理地址宽度是48位。
寄存器TCR_EL1(Translation Control Register for Exception Level 1,异常级别1的转换控制寄存器)的字段IPS(Intermediate Physical Address Size,中间物理地址长度)控制物理地址的宽度,IPS字段的长度是3位,IPS字段的值和物理地址宽度的对应关系如下:
IPS字段 | 物理地址宽度 |
---|---|
000 | 32位 |
001 | 36位 |
010 | 40位 |
011 | 42位 |
100 | 44位 |
101 | 48位 |
110 | 52位 |