mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 08:24:32 -08:00
Allow larger initrd images
This commit is contained in:
@@ -9,31 +9,73 @@
|
|||||||
static wchar_t kernel_name[] = KERNEL_FILENAME;
|
static wchar_t kernel_name[] = KERNEL_FILENAME;
|
||||||
static wchar_t initrd_name[] = INITRD_FILENAME;
|
static wchar_t initrd_name[] = INITRD_FILENAME;
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
loader_alloc_aligned(
|
||||||
|
EFI_BOOT_SERVICES *bootsvc,
|
||||||
|
EFI_MEMORY_TYPE mem_type,
|
||||||
|
size_t *length,
|
||||||
|
void **pages)
|
||||||
|
{
|
||||||
|
EFI_STATUS status;
|
||||||
|
EFI_PHYSICAL_ADDRESS addr;
|
||||||
|
|
||||||
|
size_t alignment = PAGE_SIZE;
|
||||||
|
while (alignment < *length)
|
||||||
|
alignment *= 2;
|
||||||
|
|
||||||
|
size_t page_count = alignment / PAGE_SIZE;
|
||||||
|
*length = alignment;
|
||||||
|
|
||||||
|
con_debug(L"Trying to find %d aligned pages for %x\n", page_count, mem_type);
|
||||||
|
|
||||||
|
status = bootsvc->AllocatePages(AllocateAnyPages, mem_type, page_count * 2, &addr);
|
||||||
|
CHECK_EFI_STATUS_OR_RETURN(status, L"Allocating %d pages for alignment", page_count * 2);
|
||||||
|
con_debug(L" Found %d pages at %lx\n", page_count * 2, addr);
|
||||||
|
|
||||||
|
EFI_PHYSICAL_ADDRESS aligned = addr;
|
||||||
|
aligned = ((aligned - 1) & ~(alignment - 1)) + alignment;
|
||||||
|
con_debug(L" Aligning %lx to %lx\n", addr, aligned);
|
||||||
|
|
||||||
|
size_t before =
|
||||||
|
(reinterpret_cast<uint64_t>(aligned) -
|
||||||
|
reinterpret_cast<uint64_t>(addr)) /
|
||||||
|
PAGE_SIZE;
|
||||||
|
|
||||||
|
if (before) {
|
||||||
|
con_debug(L" Freeing %d initial pages\n", before);
|
||||||
|
bootsvc->FreePages(addr, before);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t after = page_count - before;
|
||||||
|
if (after) {
|
||||||
|
EFI_PHYSICAL_ADDRESS end =
|
||||||
|
reinterpret_cast<EFI_PHYSICAL_ADDRESS>(
|
||||||
|
reinterpret_cast<uint64_t>(aligned) +
|
||||||
|
page_count * PAGE_SIZE);
|
||||||
|
con_debug(L" Freeing %d remaining pages\n", after);
|
||||||
|
bootsvc->FreePages(end, after);
|
||||||
|
}
|
||||||
|
|
||||||
|
*pages = (void *)aligned;
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
loader_alloc_pages(
|
loader_alloc_pages(
|
||||||
EFI_BOOT_SERVICES *bootsvc,
|
EFI_BOOT_SERVICES *bootsvc,
|
||||||
EFI_MEMORY_TYPE mem_type,
|
EFI_MEMORY_TYPE mem_type,
|
||||||
size_t *length,
|
size_t *length,
|
||||||
void **pages,
|
void **pages)
|
||||||
bool align)
|
|
||||||
{
|
{
|
||||||
EFI_STATUS status;
|
EFI_STATUS status;
|
||||||
|
|
||||||
size_t page_count = ((*length - 1) / PAGE_SIZE) + 1;
|
size_t page_count = ((*length - 1) / PAGE_SIZE) + 1;
|
||||||
EFI_PHYSICAL_ADDRESS addr = (EFI_PHYSICAL_ADDRESS)*pages;
|
EFI_PHYSICAL_ADDRESS addr = (EFI_PHYSICAL_ADDRESS)*pages;
|
||||||
|
|
||||||
if (align) {
|
con_debug(L"Trying to find %d non-aligned pages for %x at %lx\n",
|
||||||
// Align addr to the next multiple of N pages
|
page_count, mem_type, addr);
|
||||||
size_t align_size = page_count * PAGE_SIZE;
|
|
||||||
addr = ((addr - 1) & ~(align_size - 1)) + align_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = bootsvc->AllocatePages(AllocateAddress, mem_type, page_count, &addr);
|
status = bootsvc->AllocatePages(AllocateAddress, mem_type, page_count, &addr);
|
||||||
if (status == EFI_NOT_FOUND || status == EFI_OUT_OF_RESOURCES) {
|
|
||||||
// couldn't get the address we wanted, try loading the kernel anywhere
|
|
||||||
status =
|
|
||||||
bootsvc->AllocatePages(AllocateAnyPages, mem_type, page_count, &addr);
|
|
||||||
}
|
|
||||||
CHECK_EFI_STATUS_OR_RETURN(status,
|
CHECK_EFI_STATUS_OR_RETURN(status,
|
||||||
L"Allocating %d kernel pages type %x",
|
L"Allocating %d kernel pages type %x",
|
||||||
page_count, mem_type);
|
page_count, mem_type);
|
||||||
@@ -69,12 +111,11 @@ loader_load_initrd(
|
|||||||
|
|
||||||
data->initrd_length = ((EFI_FILE_INFO *)info)->FileSize;
|
data->initrd_length = ((EFI_FILE_INFO *)info)->FileSize;
|
||||||
|
|
||||||
status = loader_alloc_pages(
|
status = loader_alloc_aligned(
|
||||||
bootsvc,
|
bootsvc,
|
||||||
memtype_initrd,
|
memtype_initrd,
|
||||||
&data->initrd_length,
|
&data->initrd_length,
|
||||||
&data->initrd,
|
&data->initrd);
|
||||||
true);
|
|
||||||
CHECK_EFI_STATUS_OR_RETURN(status, L"Allocating pages");
|
CHECK_EFI_STATUS_OR_RETURN(status, L"Allocating pages");
|
||||||
|
|
||||||
status = file->Read(file, &data->initrd_length, data->initrd);
|
status = file->Read(file, &data->initrd_length, data->initrd);
|
||||||
@@ -161,7 +202,7 @@ loader_load_elf(
|
|||||||
|
|
||||||
length = prog_header.mem_size;
|
length = prog_header.mem_size;
|
||||||
void *addr = (void *)(prog_header.vaddr - KERNEL_VIRT_ADDRESS);
|
void *addr = (void *)(prog_header.vaddr - KERNEL_VIRT_ADDRESS);
|
||||||
status = loader_alloc_pages(bootsvc, memtype_kernel, &length, &addr, false);
|
status = loader_alloc_pages(bootsvc, memtype_kernel, &length, &addr);
|
||||||
CHECK_EFI_STATUS_OR_RETURN(status, L"Allocating kernel pages");
|
CHECK_EFI_STATUS_OR_RETURN(status, L"Allocating kernel pages");
|
||||||
|
|
||||||
if (data->kernel == 0)
|
if (data->kernel == 0)
|
||||||
@@ -236,20 +277,19 @@ loader_load_kernel(
|
|||||||
|
|
||||||
CHECK_EFI_STATUS_OR_RETURN(status, L"loader_load_elf: %s", kernel_name);
|
CHECK_EFI_STATUS_OR_RETURN(status, L"loader_load_elf: %s", kernel_name);
|
||||||
|
|
||||||
data->initrd = (void *)((uint64_t)data->kernel + data->kernel_length);
|
data->data = (void *)((uint64_t)data->kernel + data->kernel_length);
|
||||||
status = loader_load_initrd(bootsvc, root, data);
|
|
||||||
|
|
||||||
CHECK_EFI_STATUS_OR_RETURN(status, L"loader_load_file: %s", initrd_name);
|
|
||||||
|
|
||||||
data->data = (void *)((uint64_t)data->initrd + data->initrd_length);
|
|
||||||
data->data_length += PAGE_SIZE; // extra page for map growth
|
data->data_length += PAGE_SIZE; // extra page for map growth
|
||||||
status = loader_alloc_pages(
|
|
||||||
|
status = loader_alloc_aligned(
|
||||||
bootsvc,
|
bootsvc,
|
||||||
memtype_data,
|
memtype_data,
|
||||||
&data->data_length,
|
&data->data_length,
|
||||||
&data->data,
|
&data->data);
|
||||||
true);
|
CHECK_EFI_STATUS_OR_RETURN(status, L"loader_alloc_aligned: kernel data");
|
||||||
CHECK_EFI_STATUS_OR_RETURN(status, L"loader_alloc_pages: kernel data");
|
|
||||||
|
data->initrd = (void *)((uint64_t)data->data + data->data_length);
|
||||||
|
status = loader_load_initrd(bootsvc, root, data);
|
||||||
|
CHECK_EFI_STATUS_OR_RETURN(status, L"loader_load_file: %s", initrd_name);
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,9 +133,9 @@ efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table)
|
|||||||
status = loader_load_kernel(bootsvc, &load);
|
status = loader_load_kernel(bootsvc, &load);
|
||||||
CHECK_EFI_STATUS_OR_FAIL(status);
|
CHECK_EFI_STATUS_OR_FAIL(status);
|
||||||
|
|
||||||
console::print(L" %u image bytes at 0x%x\r\n", load.kernel_length, load.kernel);
|
console::print(L" %x image bytes at 0x%x\r\n", load.kernel_length, load.kernel);
|
||||||
console::print(L" %u initrd bytes at 0x%x\r\n", load.initrd_length, load.initrd);
|
console::print(L" %x data bytes at 0x%x\r\n", load.data_length, load.data);
|
||||||
console::print(L" %u data bytes at 0x%x\r\n", load.data_length, load.data);
|
console::print(L" %x initrd bytes at 0x%x\r\n", load.initrd_length, load.initrd);
|
||||||
|
|
||||||
struct kernel_header *version = (struct kernel_header *)load.kernel;
|
struct kernel_header *version = (struct kernel_header *)load.kernel;
|
||||||
if (version->magic != KERNEL_HEADER_MAGIC) {
|
if (version->magic != KERNEL_HEADER_MAGIC) {
|
||||||
@@ -145,7 +145,7 @@ efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table)
|
|||||||
|
|
||||||
console::print(L" Kernel version %d.%d.%d %x%s\r\n",
|
console::print(L" Kernel version %d.%d.%d %x%s\r\n",
|
||||||
version->major, version->minor, version->patch, version->gitsha & 0x0fffffff,
|
version->major, version->minor, version->patch, version->gitsha & 0x0fffffff,
|
||||||
version->gitsha & 0xf0000000 ? "*" : "");
|
version->gitsha & 0xf0000000 ? L"*" : L"");
|
||||||
console::print(L" Entrypoint 0x%x\r\n", load.kernel_entry);
|
console::print(L" Entrypoint 0x%x\r\n", load.kernel_entry);
|
||||||
|
|
||||||
kernel_entry kernel_main =
|
kernel_entry kernel_main =
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ mymessage:
|
|||||||
resq 1024
|
resq 1024
|
||||||
|
|
||||||
extern main
|
extern main
|
||||||
|
extern exit
|
||||||
|
|
||||||
section .text
|
section .text
|
||||||
global getpid
|
global getpid
|
||||||
@@ -38,16 +39,6 @@ sleep:
|
|||||||
pop rbp
|
pop rbp
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
__localexit:
|
|
||||||
push rbp
|
|
||||||
mov rbp, rsp
|
|
||||||
|
|
||||||
mov rax, 9 ; exit syscall
|
|
||||||
syscall
|
|
||||||
jmp __localexit ; shouldn't get here
|
|
||||||
|
|
||||||
|
|
||||||
global _start
|
global _start
|
||||||
_start:
|
_start:
|
||||||
xor rbp, rbp ; Sentinel rbp
|
xor rbp, rbp ; Sentinel rbp
|
||||||
@@ -60,4 +51,4 @@ _start:
|
|||||||
call main
|
call main
|
||||||
|
|
||||||
mov rdi, rax
|
mov rdi, rax
|
||||||
call __localexit
|
call exit
|
||||||
|
|||||||
Reference in New Issue
Block a user