I'm writing a UEFI bootloader for a hobby kernel.
I'm getting an 'EFI_NOT_FOUND' error when using the 'AllocatePages' UEFI function to allocate pages at a specific physical address. I'm able to successfully load and parse the kernel ELF file. I'm able to allocate pages using the 'AllocateAnyPages' allocation type, then copy the kernel image into memory without any problems.
If I use the 'AllocateAddress' allocation type to allocate pages at a specific address, I get an 'EFI_NOT_FOUND' error. The spec states that this indicates "The requested pages could not be found".
The UEFI spec states:
However if I use 'AllocateAnyPages', and pass in the same `p_paddr` value from the ELF file's program header, the pages are actually allocated at the physical address specified. This confusing behavior occurs in both QEMU (using OVMF) and on real hardware. Due to UEFI identity mapping the address space, I can actually load the kernel into memory using 'AllocateAnyPages', exit boot services, jump to the kernel entry point, and successfully load the kernel.Allocation requests of Type AllocateAnyPages allocate any available range of pages that satisfies the
request. On input, the address pointed to by Memory is ignored.
Does anyone know why this is happening? Am I overlooking something critical in my design?
I'm also confused about where to place the kernel in physical memory. The linker script for my test kernel specifies that the kernel starts at physical address 1MB. I know that UEFI doesn't guarantee any physical address is free, however no test value I've used has yielded a valid value when using the 'AllocateAddress' allocation type. Should I perform all of the virtual memory mapping before jumping to the kernel, and not worry about the kernel's physical address at all?