/proc/iomem这个文件记录的是物理地址的分配情况,内存只占用4G(32位CPU)物理地址的一部分,一般从地址0开始,每一行都代表一个资源(地址范围和资源名), 可用物理内存的资源名为“System RAM”,如
01000000-35aeffff : System RAM
这个是由e820表中的 E820_RAM类型的表项通过insert_resource这个API注册到iomem_resource这颗资源树上的,
if (e820.map[i].type != E820_RESERVED || res->start < (1ULL<<20)) {
res->flags |= IORESOURCE_BUSY;
insert_resource(&iomem_resource, res);
}
其它类型:
01200000-0188b446 : Kernel code
0188b447-01bae6ff : Kernel data
01c33000-01dbbfff : Kernel bss
这些地址范围都是基于物理地址的
@ arch/x86/kernel/setup.c
code_resource.start = virt_to_phys(_text);
code_resource.end = virt_to_phys(_etext)-1;
data_resource.start = virt_to_phys(_etext);
data_resource.end = virt_to_phys(_edata)-1;
bss_resource.start = virt_to_phys(&__bss_start);
bss_resource.end = virt_to_phys(&__bss_stop)-1;
insert_resource(&iomem_resource, &code_resource);
insert_resource(&iomem_resource, &data_resource);
insert_resource(&iomem_resource, &bss_resource);
一般平台设备的定义中会定义该设备所拥有的资源(MMIO)来申请该设备所占用的物理地址范围,然后在平台驱动的注册函数内部会调用insert_resource函数将设备的物理地址资源注册到资源树中。
API: page_is_ram(pfn)
这个函数会判定给定的页框号是否属于物理内存,其实现主要是在iomem_resource 这颗资源树上查找名为"System Ram" 的资源,如果包含在其中的话,就说明该页框号属于物理内存而不是通过MMIO映射的设备寄存器。