Page 1 of 1
uefi seems to load image incorrectly
Posted: Sun Nov 08, 2020 6:43 pm
by austanss
I've been getting General Protection faults when running my EFI image. It doesn't make much sense. However, I investigated a bit.
When the machine throws an exception, I pause it and dump the memory. I disassembled the memory dump and looked for where the instruction pointer was located, a
scasd instruction. In fact, the area is covered with
scasd instructions...
Exception:
Code: Select all
/usr/bin/qemu-system-x86_64 -bios res/OVMF.fd -cdrom microNET.iso -m 512M -net none -serial stdio
BdsDxe: loading Boot0001 "UEFI QEMU DVD-ROM QM00003 " from PciRoot(0x0)/Pci(0x1,0x1)/Ata(Secondary,Master,0x0)
BdsDxe: starting Boot0001 "UEFI QEMU DVD-ROM QM00003 " from PciRoot(0x0)/Pci(0x1,0x1)/Ata(Secondary,Master,0x0)
!!!! X64 Exception Type - 0D(#GP - General Protection) CPU Apic ID - 00000000 !!!!
ExceptionData - 0000000000000000
RIP - 000000001EA372D9, CS - 0000000000000038, RFLAGS - 0000000000000202
RAX - AFAFAFAFAFAFAFAF, RCX - 000000001F16ADE0, RDX - 0000000000000000
RBX - 000000001EB47018, RSP - 000000001FF078C0, RBP - 000000001FF07990
RSI - 000000001F9EE018, RDI - 000000001EC32B18
R8 - 0000000000000001, R9 - 0000000000000001, R10 - 000000000000001F
R11 - 0000000000000010, R12 - 0000000000000000, R13 - 0000000000000001
R14 - 0000000000000004, R15 - 000000001F084F44
DS - 0000000000000030, ES - 0000000000000030, FS - 0000000000000030
GS - 0000000000000030, SS - 0000000000000030
CR0 - 0000000080010033, CR2 - 0000000000000000, CR3 - 000000001FC01000
CR4 - 0000000000000668, CR8 - 0000000000000000
DR0 - 0000000000000000, DR1 - 0000000000000000, DR2 - 0000000000000000
DR3 - 0000000000000000, DR6 - 00000000FFFF0FF0, DR7 - 0000000000000400
GDTR - 000000001F9EEA98 0000000000000047, LDTR - 0000000000000000
IDTR - 000000001F175018 0000000000000FFF, TR - 0000000000000000
FXSAVE_STATE - 000000001FF07520
!!!! Find image based on IP(0x1EA372D9) (No PDB) (ImageBase=000000001EA34000, EntryPoint=000000001EA39530) !!!!
Re: uefi seems to load image incorrectly
Posted: Sun Nov 08, 2020 8:06 pm
by nexos
Where is the source to your EFI application?
Re: uefi seems to load image incorrectly
Posted: Sun Nov 08, 2020 8:09 pm
by austanss
nexos wrote:Where is the source to your EFI application?
https://github.com/microNET-OS/microCOR ... bootloader
Re: uefi seems to load image incorrectly
Posted: Mon Nov 09, 2020 9:00 am
by bzt
You probably have an incorrect EFI call (which does not comply with the EFI ABI), that's why you end up executing code outside of the text segment.
I haven't found that yet, but I've found another error in your code:
main.c.
In line 110 you get the size of the memory map. That's fine. But in line 126 you allocate more memory, which could increase the size of the memory map that you don't take into account. Therefore in line 135 the get memory map will return EFI_BUFFER_TOO_SMALL.
There are the following options:
1. you allocate exactly as many bytes as there are in a free slot. Then the memory map size doesn't change, only one entry gets "efi loader memory" type instead of "free" type (unlikely)
2. you allocate fewer bytes than the smallest free slots where it fits. Then the memory map size will grow, it's going to keep the free slot (but smaller in size), and there will be an additional "efi loader memory" entry (most likely)
3. in a very unusual circumstances your allocation could split a free slot into two. Then there'll be the original free entry (but with smaller size), an "efi loader memory" entry, and a new "free" entry (unlikely, but probable)
The solution is to allocate more memory for the map than reported, as suggested on the
wiki (there's also an example code).
Cheers,
bzt
Re: uefi seems to load image incorrectly
Posted: Mon Nov 09, 2020 9:50 am
by austanss
bzt wrote:You probably have an incorrect EFI call (which does not comply with the EFI ABI), that's why you end up executing code outside of the text segment.
I haven't found that yet, but I've found another error in your code:
main.c.
In line 110 you get the size of the memory map. That's fine. But in line 126 you allocate more memory, which could increase the size of the memory map that you don't take into account. Therefore in line 135 the get memory map will return EFI_BUFFER_TOO_SMALL.
There are the following options:
1. you allocate exactly as many bytes as there are in a free slot. Then the memory map size doesn't change, only one entry gets "efi loader memory" type instead of "free" type (unlikely)
2. you allocate fewer bytes than the smallest free slots where it fits. Then the memory map size will grow, it's going to keep the free slot (but smaller in size), and there will be an additional "efi loader memory" entry (most likely)
3. in a very unusual circumstances your allocation could split a free slot into two. Then there'll be the original free entry (but with smaller size), an "efi loader memory" entry, and a new "free" entry (unlikely, but probable)
The solution is to allocate more memory for the map than reported, as suggested on the
wiki (there's also an example code).
Cheers,
bzt
Alas, once I fixed that (I allocated memory_map_size + 2048, hope thats enough) the
RIP was now located at
0x1EA372E0 when the exception was thrown. So it seems I have a few bad EFI calls... goodie
Any help?
Re: uefi seems to load image incorrectly
Posted: Mon Nov 09, 2020 10:44 am
by austanss
So I was doing a good ole' debuggin' trick of moving around an infinite loop. The code seems to break when making any kind of EFI call. It'll call InitializeLib alright, but when using any EFI function, using uefi_call_wrapper or directly, or any form otherwise, it throws a general protection exception. Very confused... anyone know why? I'm thinking it could be improperly loaded/linked efi stuff, therefore causing the machine to jump to garbage...
Re: uefi seems to load image incorrectly
Posted: Mon Nov 09, 2020 10:55 am
by nexos
The problem may be in how you are building. My EFI app skips GNU EFI. Basically, what I do is follow the build instructions at
https://wiki.osdev.org/UEFI_App_Bare_Bones, and then I use the EFI header file from GNU EFI. You can find those headers at
https://github.com/Nexware-Project/EfiHeaders. Simply copy those to your source directory, update you include path to include those files, and your good! Note that you will not have any functions to do things like copy memory, you will have to write those. Also, don't use uefi_call_wrapper when doing it this way, as you are actually using the MS ABI. My EFI bootloader's full source is at
https://github.com/Nexware-Project/NexBoot, inside the Loader directory.
Re: uefi seems to load image incorrectly
Posted: Mon Nov 09, 2020 11:47 am
by bzt
If you want to keep GNU EFI, then compile with your native toolchain (not with mingw32), then as the last step convert the ELF into PE. This is the recommended way with GNU-EFI.
Mando wrote:This is the way
This can be found on the
wiki, and
here's a working real-life example that I use and that's known to work under Linux. As you can see, I have an "objcopy" line in the Makefile's %.efi rule, that's responsible for creating the PE executable from the ELF shared object, otherwise I'm using the native compiler on x86_64.
Cheers,
bzt
Re: uefi seems to load image incorrectly
Posted: Mon Nov 09, 2020 12:54 pm
by austanss
bzt wrote:If you want to keep GNU EFI, then compile with your native toolchain (not with mingw32), then as the last step convert the ELF into PE. This is the recommended way with GNU-EFI.
Mando wrote:This is the way
This can be found on the
wiki, and
here's a working real-life example that I use and that's known to work under Linux. As you can see, I have an "objcopy" line in the Makefile's %.efi rule, that's responsible for creating the PE executable from the ELF shared object, otherwise I'm using the native compiler on x86_64.
Cheers,
bzt
I had completely overhauled my code using nexos's method...
but this one is better. However I get exceptions when using ST->ConOut->OutputString
specifically, not any other function. Don't know why, but I don't care anyway. The only thing I need to fix now is the kernel loading. Thanks everyone!
Re: uefi seems to load image incorrectly
Posted: Mon Nov 09, 2020 1:27 pm
by bzt
rizxt wrote:Alas, once I fixed that (I allocated memory_map_size + 2048, hope thats enough)
More than likely that's enough. But the first get memory map returned the exact descriptor entry size (usually 20 or 24 bytes), so you could add "+ 2*DescriptorSize".
rizxt wrote:the
RIP was now located at
0x1EA372E0 when the exception was thrown. So it seems I have a few bad EFI calls... goodie
Any help?
Or a stack corruption (that's also possible). Try single-steping instructions from the point where your code gets control. Somewhere, something messes up the control flow.
Cheers,
bzt
Re: uefi seems to load image incorrectly
Posted: Tue Nov 10, 2020 6:34 am
by austanss
My bootloader works! I can verify this via checking my serial line for GLOBAL CONSTRUCTORS CALLED, The only problem I have now is that I can't get my GOP framebuffer to work after I enter the kernel...
Re: uefi seems to load image incorrectly
Posted: Tue Nov 10, 2020 4:42 pm
by zaval
rizxt wrote:My bootloader works! I can verify this via checking my serial line for GLOBAL CONSTRUCTORS CALLED, The only problem I have now is that I can't get my GOP framebuffer to work after I enter the kernel...
did you try to OutputString() inside your OSL? does it work? regarding GOP, I hope, you know, that you cannot use GOP functions outside Boot Services context (after ExitBootServices() call), only address of the framebuffer and its parameters handed over to you through the GOP instance are valid?