83 return EFI_INVALID_PARAMETER;
97 Print(L
"section header table extends beyond file bounds!\n");
98 return EFI_INVALID_PARAMETER;
101 kernel->
shdrs = AllocatePool(shdrTableSize);
104 Print(L
"failed to allocate %llu bytes for section headers!\n", shdrTableSize);
105 return EFI_OUT_OF_RESOURCES;
109 if (EFI_ERROR(status))
111 Print(L
"failed to seek to section header table (0x%x)!\n", status);
115 status = uefi_call_wrapper(
file->Read, 3,
file, &shdrTableSize, kernel->
shdrs);
116 if (EFI_ERROR(status))
118 Print(L
"failed to read section header table (0x%x)!\n", status);
149 return EFI_INVALID_PARAMETER;
153 if (symtabSection ==
NULL)
156 if (symtabSection ==
NULL)
168 Print(L
"invalid symbol table section!\n");
169 return EFI_INVALID_PARAMETER;
174 Print(L
"invalid symbol table entry size (%llu)!\n", symtabSection->
entrySize);
175 return EFI_INVALID_PARAMETER;
179 if (symbolCount == 0)
188 kernel->
symbols = AllocatePool(symtabSection->
size);
191 Print(L
"failed to allocate %llu bytes for symbol table!\n", symtabSection->
size);
192 return EFI_OUT_OF_RESOURCES;
195 EFI_STATUS status = uefi_call_wrapper(
file->SetPosition, 2,
file, symtabSection->
offset);
196 if (EFI_ERROR(status))
198 Print(L
"failed to seek to symbol table (0x%x)!\n", status);
203 if (EFI_ERROR(status))
205 Print(L
"failed to read symbol table (0x%x)!\n", status);
221 Print(L
"failed to allocate %llu bytes for string table!\n", strtabSection->
size);
222 return EFI_OUT_OF_RESOURCES;
225 status = uefi_call_wrapper(
file->SetPosition, 2,
file, strtabSection->
offset);
226 if (EFI_ERROR(status))
228 Print(L
"failed to seek to string table (0x%x)!\n", status);
233 if (EFI_ERROR(status))
235 Print(L
"failed to read string table (0x%x)!\n", status);
302 return EFI_INVALID_PARAMETER;
307 Print(L
"Loading kernel... ");
309 EFI_FILE* kernelDir =
NULL;
311 EFI_STATUS status = EFI_SUCCESS;
314 status = uefi_call_wrapper(rootHandle->Open, 5, rootHandle, &kernelDir, L
"kernel", EFI_FILE_MODE_READ, 0);
315 if (EFI_ERROR(status))
317 Print(L
"failed to open boot directory (0x%x)!\n", status);
321 status = uefi_call_wrapper(kernelDir->Open, 5, kernelDir, &
file, L
"kernel", EFI_FILE_MODE_READ, 0);
322 if (EFI_ERROR(status))
324 Print(L
"failed to open kernel file (0x%x)!\n", status);
328 EFI_FILE_INFO* fileInfo = LibFileInfo(
file);
329 if (fileInfo ==
NULL)
331 Print(L
"failed to get kernel file info (0x%x)!\n", status);
332 status = EFI_LOAD_ERROR;
335 uint64_t fileSize = fileInfo->FileSize;
340 Print(L
"kernel file too small (%llu bytes)!\n", fileSize);
341 status = EFI_INVALID_PARAMETER;
346 status = uefi_call_wrapper(
file->Read, 3,
file, &elfHdrSize, &kernel->
header);
347 if (EFI_ERROR(status))
349 Print(L
"failed to read ELF header (0x%x)!\n", status);
355 Print(L
"invalid ELF header in kernel file!\n");
356 status = EFI_INVALID_PARAMETER;
362 Print(L
"no program headers in kernel ELF!\n");
363 status = EFI_INVALID_PARAMETER;
369 Print(L
"invalid program header size (%u)!\n", kernel->
header.
phdrSize);
370 status = EFI_INVALID_PARAMETER;
378 Print(L
"program header table extends beyond file bounds!\n");
379 status = EFI_INVALID_PARAMETER;
383 kernel->
phdrs = AllocatePool(phdrTableSize);
386 Print(L
"failed to allocate %llu bytes for program headers!\n", phdrTableSize);
387 status = EFI_OUT_OF_RESOURCES;
392 if (EFI_ERROR(status))
394 Print(L
"failed to seek to program header table (0x%x)!\n", status);
398 status = uefi_call_wrapper(
file->Read, 3,
file, &phdrTableSize, kernel->
phdrs);
399 if (EFI_ERROR(status))
401 Print(L
"failed to read program header table (0x%x)!\n", status);
405 Print(L
"sections... ");
407 if (EFI_ERROR(status))
409 Print(L
"failed to load section headers (0x%x)!\n", status);
413 Print(L
"symbols... ");
415 if (EFI_ERROR(status))
417 Print(L
"failed to load symbol table (0x%x)!\n", status);
424 if (EFI_ERROR(status))
426 Print(L
"failed to determine kernel bounds (0x%x)!\n", status);
430 uint64_t kernelSize = virtEnd - virtStart;
435 uefi_call_wrapper(BS->AllocatePages, 4, AllocateAnyPages, EfiReservedMemoryType, kernelPageAmount, &physStart);
436 if (EFI_ERROR(status))
438 Print(L
"failed to allocate %llu pages for kernel (0x%x)!\n", kernelPageAmount, status);
445 kernel->
size = kernelPageAmount * EFI_PAGE_SIZE;
447 Print(L
"phys=0x%llx virt=0x%llx size=%llu KB... ", kernel->
physStart, kernel->
virtStart, kernel->
size / 1024);
451 if (EFI_ERROR(status))
453 Print(L
"failed to load kernel segments (0x%x)!\n", status);
459 Print(L
"loaded %u symbols... ", kernel->
symbolCount);
463 status = EFI_SUCCESS;
466 if (status != EFI_SUCCESS)
470 FreePool(kernel->
phdrs);
475 FreePool(kernel->
shdrs);
490 if (kernel->
physStart != 0 && EFI_ERROR(status))
492 uefi_call_wrapper(BS->FreePages, 3, kernel->
physStart, kernelPageAmount);
497 uefi_call_wrapper(
file->Close, 1,
file);
499 if (kernelDir !=
NULL)
501 uefi_call_wrapper(kernelDir->Close, 1, kernelDir);
static EFI_STATUS determine_kernel_bounds(const elf_phdr_t *phdrs, const elf_hdr_t *header, uint64_t phdrTableSize, uintptr_t *virtStart, uintptr_t *virtEnd)
static EFI_STATUS load_kernel_segments(EFI_FILE *file, uintptr_t physStart, uintptr_t virtStart, uint64_t kernelPageAmount, const elf_phdr_t *phdrs, const elf_hdr_t *header, uint64_t fileSize)