Uefi application hangs up when trying to load the kernel
Uefi application hangs up when trying to load the kernel
Hello everyone,
I am currently in the process of writing a new uefi bootloader, as my old projects somehow became more and more chaotic and I didn't know where anything was anymore. I have psf1 font support so far, can display 32bit bitmaps and am currently loading a 64bit kernel. however, the bootloader then hangs in loader.c under utils/loader.c where I call uefi_call_wrapper. Maybe you can help me to fix this problem?
Best regards
Source: https://github.com/rxbin1201/littleBootV1
I am currently in the process of writing a new uefi bootloader, as my old projects somehow became more and more chaotic and I didn't know where anything was anymore. I have psf1 font support so far, can display 32bit bitmaps and am currently loading a 64bit kernel. however, the bootloader then hangs in loader.c under utils/loader.c where I call uefi_call_wrapper. Maybe you can help me to fix this problem?
Best regards
Source: https://github.com/rxbin1201/littleBootV1
Re: Uefi application hangs up when trying to load the kernel
Hello!
You call Kernel->GetInfo twice here
Removing the duplicate fixed the issue.
I would also recommend adding --serial file:./Out.log to uefi-run's Qemu arguments so you can see the exceptions UEFI prints out.
You can also print to this file using the gnuefi print function like so:
Your duplicate code causes a #UD. Maybe someone more experienced with UEFI and #UD exceptions can explain why that is.
You can read more about exceptions and interrupts here (The AMD64 docs have a lot of helpful information you can reference in the future!)
https://www.amd.com/system/files/TechDo ... G14.887970
Hope this helps and have fun!
You call Kernel->GetInfo twice here
Code: Select all
<...>
Status = uefi_call_wrapper(
Kernel->GetInfo,
4,
Kernel,
&gEfiFileInfoGuid,
&FileInfoSize,
NULL
);
if(EFI_ERROR(Status)) {
return Status;
}
Status = uefi_call_wrapper(
BS->AllocatePool,
3,
EfiLoaderData,
FileInfoSize,
(VOID **)&FileInfo
);
if(EFI_ERROR(Status)) {
return Status;
}
Status = uefi_call_wrapper(
Kernel->GetInfo,
4,
Kernel,
&gEfiFileInfoGuid,
&FileInfoSize,
(VOID **)&FileInfo
);
if(EFI_ERROR(Status)) {
return Status;
}
<...>
I would also recommend adding --serial file:./Out.log to uefi-run's Qemu arguments so you can see the exceptions UEFI prints out.
You can also print to this file using the gnuefi print function like so:
Code: Select all
Print(L"Test print to serial\n");
You can read more about exceptions and interrupts here (The AMD64 docs have a lot of helpful information you can reference in the future!)
https://www.amd.com/system/files/TechDo ... G14.887970
Hope this helps and have fun!
Re: Uefi application hangs up when trying to load the kernel
Thanks for you help! I removed the duplicate and now in my switch argument it tells me as Status "Error Kernel! Reason: Not Found"Rover wrote:Hello!
You call Kernel->GetInfo twice hereRemoving the duplicate fixed the issue.Code: Select all
<...> Status = uefi_call_wrapper( Kernel->GetInfo, 4, Kernel, &gEfiFileInfoGuid, &FileInfoSize, NULL ); if(EFI_ERROR(Status)) { return Status; } Status = uefi_call_wrapper( BS->AllocatePool, 3, EfiLoaderData, FileInfoSize, (VOID **)&FileInfo ); if(EFI_ERROR(Status)) { return Status; } Status = uefi_call_wrapper( Kernel->GetInfo, 4, Kernel, &gEfiFileInfoGuid, &FileInfoSize, (VOID **)&FileInfo ); if(EFI_ERROR(Status)) { return Status; } <...>
I would also recommend adding --serial file:./Out.log to uefi-run's Qemu arguments so you can see the exceptions UEFI prints out.
You can also print to this file using the gnuefi print function like so:Your duplicate code causes a #UD. Maybe someone more experienced with UEFI and #UD exceptions can explain why that is.Code: Select all
Print(L"Test print to serial\n");
You can read more about exceptions and interrupts here (The AMD64 docs have a lot of helpful information you can reference in the future!)
https://www.amd.com/system/files/TechDo ... G14.887970
Hope this helps and have fun!
Code: Select all
int pages = (phdr->p_memsz + 0x1000 - 1) / 0x1000;
Elf64_Addr segment = phdr->p_paddr;
Status = uefi_call_wrapper(
BS->AllocatePages,
4,
AllocateAddress,
EfiLoaderData,
pages,
&segment
);
if(EFI_ERROR(Status)) {
return Status;
}
Re: Uefi application hangs up when trying to load the kernel
Hello!
It seems like your kernel64.elf is being opened.
I also noticed a bug with your Log(); function that causes text to move back to the top of the screen. (Unless that is what you wanted)
Adding Print() statements to your error conditions can help pinpoint the error easier for you and make debugging less guesswork.
For example:
This can tell you exactly which call failed.
It seems like AllocatePages is returning an error in your for loop.
Have you tried using gnuefi's AllocatePool(); function? I have found that it works better (and easier) than calling AllocatePages and it doesn't need a uefi_call_wrapper.
Also, imo, it is easier to loop through the ELF and add up the section sizes you need so you only have to call AllocatePool/AllocatePages once for each section and then you can load your kernel code/data to it.
You can see how I do this here. (No guarantee it is bug free)
You don't have to worry about where the kernel is in physical memory (just don't overwrite it) since you can map it anywhere in virtual memory.
P.S
I would recommend changing theseInto
It is more readable imo.
It seems like your kernel64.elf is being opened.
I also noticed a bug with your Log(); function that causes text to move back to the top of the screen. (Unless that is what you wanted)
Adding Print() statements to your error conditions can help pinpoint the error easier for you and make debugging less guesswork.
For example:
Code: Select all
Status = uefi_call_wrapper(
Kernel->GetInfo,
4,
Kernel,
&gEfiFileInfoGuid,
&FileInfoSize,
NULL
);
if(EFI_ERROR(Status)) {
Print(L"Failed to GetInfo\n");
return Status;
}
It seems like AllocatePages is returning an error in your for loop.
Have you tried using gnuefi's AllocatePool(); function? I have found that it works better (and easier) than calling AllocatePages and it doesn't need a uefi_call_wrapper.
Also, imo, it is easier to loop through the ELF and add up the section sizes you need so you only have to call AllocatePool/AllocatePages once for each section and then you can load your kernel code/data to it.
You can see how I do this here. (No guarantee it is bug free)
You don't have to worry about where the kernel is in physical memory (just don't overwrite it) since you can map it anywhere in virtual memory.
P.S
I would recommend changing these
Code: Select all
static const uint16_t ET_NONE = 0;
Code: Select all
#define ET_NONE 0
Re: Uefi application hangs up when trying to load the kernel
Thank you very much. I will try it soon. And with the log function I have also noticed it but I have not found the solution for it yet.Rover wrote:Hello!
It seems like your kernel64.elf is being opened.
I also noticed a bug with your Log(); function that causes text to move back to the top of the screen. (Unless that is what you wanted)
Adding Print() statements to your error conditions can help pinpoint the error easier for you and make debugging less guesswork.
For example:This can tell you exactly which call failed.Code: Select all
Status = uefi_call_wrapper( Kernel->GetInfo, 4, Kernel, &gEfiFileInfoGuid, &FileInfoSize, NULL ); if(EFI_ERROR(Status)) { Print(L"Failed to GetInfo\n"); return Status; }
It seems like AllocatePages is returning an error in your for loop.
Have you tried using gnuefi's AllocatePool(); function? I have found that it works better (and easier) than calling AllocatePages and it doesn't need a uefi_call_wrapper.
Also, imo, it is easier to loop through the ELF and add up the section sizes you need so you only have to call AllocatePool/AllocatePages once for each section and then you can load your kernel code/data to it.
You can see how I do this here. (No guarantee it is bug free)
You don't have to worry about where the kernel is in physical memory (just don't overwrite it) since you can map it anywhere in virtual memory.
P.S
I would recommend changing theseIntoCode: Select all
static const uint16_t ET_NONE = 0;
It is more readable imo.Code: Select all
#define ET_NONE 0
-
- Member
- Posts: 5560
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Uefi application hangs up when trying to load the kernel
The first call to GetInfo() is supposed to fail. It needs to fail with the error code EFI_BUFFER_TOO_SMALL so you can allocate the correct buffer to hold whatever info you're requesting. Since the first call doesn't fail, one of the parameters you pass to it must be incorrect, and it's corrupting memory somewhere.
Re: Uefi application hangs up when trying to load the kernel
Oops. I didn’t know that.Octocontrabass wrote:The first call to GetInfo() is supposed to fail. It needs to fail with the error code EFI_BUFFER_TOO_SMALL so you can allocate the correct buffer to hold whatever info you're requesting. Since the first call doesn't fail, one of the parameters you pass to it must be incorrect, and it's corrupting memory somewhere.
I thought I used that uefi call in my code without issues but I actually use LibFileInfo.
They should probably use LibFileInfo() instead of a call wrapper since they use gnuefi. Unless there is something else I am overlooking.