zaval wrote:not that, this one:
Code: Select all
EFI_PHYSICAL_ADDRESS RdosMemBase = RDOS_MEM;
MemMapCount = 0;
MemMapArr = (struct MemMapEntry *)RdosMemBase;
In the function ConvertMemoryMap(), you assign to global pointer MemMapArr the hardcoded address (above). then you use it in other functions and in that function as well. this is wrong. you need to use UEFI memory allocation services for initializing that pointer (see my example above).
PS. I looked at the file you posted, and unlike two other bases:
Code: Select all
#define RDOS_LOADER 0x110000
#define RDOS_MEM 0x400
#define RDOS_BASE 0x121000
where you do use AllocatePages() with the AllocateAddress allocation type, this RDOS_MEM value is just assigned to the global pointer MemMapArr and used straight (as your internal memory map array) as if you are sure you aren't messing up FW structures.
further, before converting from UEFI memory map to your own memory map, you do this:
which means, you count this range as always free memory. why?
The short answer why I assume that "DOS" memory has a certain layout is a bit of legacy. It's also because the startup memory allocation in the kernel is designed to start using memory from the second page and up. Thus, it's more or less a requirement that FW doesn't use "DOS" memory for the firmware. I think I picked 0x400 for the memory map based on the assumption that the legacy BIOS & DOS data areas would not be relevant for EFI FW. This might be faulty for some systems, but then I simply cannot support those.
There is also a requirement for a fixed below 4G area where the processor can switch between long mode and protected mode. I decided to put this just above the DOS high memory area, and then I also placed the transient loader at this position. Since the 64-bit loader needs to switch back to protected mode, by disabling paging, it must reside at a fixed address below 4G.
The OS image itself can reside at any position below 4G since it is remapped with paging, but it is easier if it has a fixed position. So, if the area is just allocated then it might be mapped above 4G if the computer has more than 4G of memory.
Things would be much easier & less fixed if EFI supported allocating memory below 4G, but it doesn't as far as I know.
An alternative to using fixed memory in the EFI interface would be to let the 64-bit loader find free areas below 4G and then copy the RDOS image to those and fix up the memory map. However, since no EFI BIOS this far has denied the fixed allocations, I've not had reason to do this.
Still, I don't think the placement of the memory structure at 0x400 is causing the GetMemoryMap to fail since it's used after the call to GetMemoryMap to reformat the information, and it is the MemDescrSize that contains 0 after the call to GetMemoryMap. A possible issue might be that EFI expects it to contain the size on entry, but it is not initialized before passing it as a parameter (so should be 0).