作为我的OS课程的一部分,我需要编写自己的微型OS内核,该内核在带有UEFI(OSVF)的QEMU下运行。 UEFI规范似乎非常复杂,并且有一点与我无关,那就是是否有可能具有静态的(编译时定义的)物理内存布局,从而使我的内核具有适量的可用物理内存,而还保留了UEFI使用的区域。
让我以xv6为例进行说明。它具有一个由旧版BIOS运行的简单的手工引导程序。根据{{3}},此操作系统按以下方式分配物理内存:
+------------------+
| Free Space |
+------------------+ 0x00500000
| Kernel |
+------------------+ 0x00100000
| BIOS and I/O | <------------ Bootloader code is loaded here
+------------------+ 0x00000000
之所以如此简单的布局,是因为设备和BIOS使用的所有“魔术”内存都位于物理[0x00000000; 0x000FFFFF]
范围内。特别是,引导加载程序会在此范围内加载,然后可以自由选择任何要加载内核的内存区域。从0x00500000
开始的可用空间可以分配给用户空间程序。
我想在UEFI引导的内核中有一个类似的简单内存布局;但是,这似乎并不是一件容易的事。问题是:
解决这些问题的方法之一是通过GetMemoryMap()
使用UEFI提供的内存映射。该图描述了固件使用的所有内存区域。但是,在运行时找出内存布局会使事情变得复杂,而不是像xv6所采用的静态内存布局那样。为了简单起见,我愿意牺牲一些RAM空间。
那么在UEFI引导的内核中有没有办法实现静态物理内存布局?
答案 0 :(得分:1)
那么在UEFI引导的内核中有没有办法实现静态物理内存布局?
不。您可以尝试静态分配一台计算机可以正常工作的物理内存区域(UEFI内置的内存管理器确实具有“在此特定物理地址处分配页面”的功能),但是不能保证UEFI不会在任何其他计算机上保留物理地址;并没有区别,它是哪个物理地址范围。
相反,在启动代码启用分页之前,它可以愉快地使用从UEFI的内存管理器分配的页面和/或在引导加载程序的“ .bss”部分中预先分配的内存,而无需关心物理地址是什么;并且在启动代码启用分页之后,物理地址几乎对所有事物都变得无关紧要(并且您可以根据需要使用虚拟地址空间,如果您不喜欢安全性/ KASLR,可以在内核空间中静态分配虚拟地址范围)。>
对于UEFI,大多数情况下,如果可能/受支持,则静态分配的物理地址不会有任何好处,也不会使任何事情变得简单。