OSDev.org
https://forum.osdev.org/

uefi seems to load image incorrectly
https://forum.osdev.org/viewtopic.php?f=1&t=37448
Page 1 of 1

Author:  rizxt [ Sun Nov 08, 2020 6:43 pm ]
Post subject:  uefi seems to load image incorrectly

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 [i]scasd[i] instructions...

Exception:
Code:
/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) !!!!

Attachment:
2020-11-08_19-41.png
2020-11-08_19-41.png [ 50.68 KiB | Viewed 635 times ]

Attachment:
2020-11-08_19-43.png
2020-11-08_19-43.png [ 13.89 KiB | Viewed 635 times ]

Author:  nexos [ Sun Nov 08, 2020 8:06 pm ]
Post subject:  Re: uefi seems to load image incorrectly

Where is the source to your EFI application?

Author:  rizxt [ Sun Nov 08, 2020 8:09 pm ]
Post subject:  Re: uefi seems to load image incorrectly

nexos wrote:
Where is the source to your EFI application?

https://github.com/microNET-OS/microCOR ... bootloader

Author:  bzt [ Mon Nov 09, 2020 9:00 am ]
Post subject:  Re: uefi seems to load image incorrectly

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

Author:  rizxt [ Mon Nov 09, 2020 9:50 am ]
Post subject:  Re: uefi seems to load image incorrectly

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 :roll:
Any help?

Author:  rizxt [ Mon Nov 09, 2020 10:44 am ]
Post subject:  Re: uefi seems to load image incorrectly

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...

Author:  nexos [ Mon Nov 09, 2020 10:55 am ]
Post subject:  Re: uefi seems to load image incorrectly

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.

Author:  bzt [ Mon Nov 09, 2020 11:47 am ]
Post subject:  Re: uefi seems to load image incorrectly

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

Author:  rizxt [ Mon Nov 09, 2020 12:54 pm ]
Post subject:  Re: uefi seems to load image incorrectly

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!

Author:  bzt [ Mon Nov 09, 2020 1:27 pm ]
Post subject:  Re: uefi seems to load image incorrectly

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 :roll:
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

Author:  rizxt [ Tue Nov 10, 2020 6:34 am ]
Post subject:  Re: uefi seems to load image incorrectly

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...

Author:  zaval [ Tue Nov 10, 2020 4:42 pm ]
Post subject:  Re: uefi seems to load image incorrectly

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?

Page 1 of 1 All times are UTC - 6 hours
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/