Skip to content

Commit 1fad25c

Browse files
committed
protos/linux: Add optional support for 64-bit boot protocol
1 parent 91f64df commit 1fad25c

4 files changed

Lines changed: 123 additions & 10 deletions

File tree

common/lib/uri.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,10 @@ static struct file_handle *uri_boot_dispatch(char *s_part, char *path) {
206206
return fopen(volume, path);
207207
}
208208

209+
#if defined (UEFI) && defined (__x86_64__)
210+
bool uri_open_allow_high = false;
211+
#endif
212+
209213
struct file_handle *uri_open(char *uri) {
210214
struct file_handle *ret;
211215

@@ -238,7 +242,12 @@ struct file_handle *uri_open(char *uri) {
238242

239243
if (hash != NULL && ret != NULL) {
240244
uint8_t out_buf[BLAKE2B_OUT_BYTES];
245+
#if defined (UEFI) && defined (__x86_64__)
246+
void *file_buf = freadall_mode(ret, MEMMAP_BOOTLOADER_RECLAIMABLE, uri_open_allow_high);
247+
uri_open_allow_high = false;
248+
#else
241249
void *file_buf = freadall(ret, MEMMAP_BOOTLOADER_RECLAIMABLE);
250+
#endif
242251
blake2b(out_buf, file_buf, ret->size);
243252
uint8_t hash_buf[BLAKE2B_OUT_BYTES];
244253

common/lib/uri.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
#include <stdbool.h>
55
#include <fs/file.h>
66

7+
#if defined (UEFI) && defined (__x86_64__)
8+
extern bool uri_open_allow_high;
9+
#endif
10+
711
bool uri_resolve(char *uri, char **resource, char **root, char **path, char **hash);
812
struct file_handle *uri_open(char *uri);
913

common/protos/linux.c

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
#include <drivers/gop.h>
2222

2323
noreturn void linux_spinup(void *entry, void *boot_params);
24+
#if defined (UEFI) && defined (__x86_64__)
25+
noreturn void linux_spinup64(void *entry, void *boot_params);
26+
#endif
2427

2528
// The following definitions and struct were copied and adapted from Linux
2629
// kernel headers released under GPL-2.0 WITH Linux-syscall-note
@@ -382,14 +385,6 @@ noreturn void linux_load(char *config, char *cmdline) {
382385
///////////////////////////////////////
383386
// Modules
384387
///////////////////////////////////////
385-
386-
uint32_t modules_mem_base;
387-
if (setup_header->version <= 0x202 || setup_header->initrd_addr_max == 0) {
388-
modules_mem_base = 0x38000000;
389-
} else {
390-
modules_mem_base = setup_header->initrd_addr_max + 1;
391-
}
392-
393388
size_t size_of_all_modules = 0;
394389

395390
for (size_t i = 0; ; i++) {
@@ -398,6 +393,9 @@ noreturn void linux_load(char *config, char *cmdline) {
398393
break;
399394

400395
struct file_handle *module;
396+
#if defined (UEFI) && defined (__x86_64__)
397+
uri_open_allow_high = true;
398+
#endif
401399
if ((module = uri_open(module_path)) == NULL)
402400
panic(true, "linux: Failed to open module with path `%s`. Is the path correct?", module_path);
403401

@@ -406,6 +404,24 @@ noreturn void linux_load(char *config, char *cmdline) {
406404
fclose(module);
407405
}
408406

407+
uintptr_t modules_mem_base;
408+
409+
#if defined (UEFI) && defined (__x86_64__)
410+
if ((setup_header->xloadflags & 3) == 3) {
411+
modules_mem_base = (uintptr_t)ext_mem_alloc_type_aligned_mode(
412+
size_of_all_modules,
413+
MEMMAP_BOOTLOADER_RECLAIMABLE,
414+
0x100000,
415+
true
416+
);
417+
} else {
418+
#endif
419+
if (setup_header->version <= 0x202 || setup_header->initrd_addr_max == 0) {
420+
modules_mem_base = 0x38000000;
421+
} else {
422+
modules_mem_base = setup_header->initrd_addr_max + 1;
423+
}
424+
409425
modules_mem_base -= size_of_all_modules;
410426
modules_mem_base = ALIGN_DOWN(modules_mem_base, 0x100000);
411427

@@ -420,8 +436,11 @@ noreturn void linux_load(char *config, char *cmdline) {
420436

421437
modules_mem_base -= 0x100000;
422438
}
439+
#if defined (UEFI) && defined (__x86_64__)
440+
}
441+
#endif
423442

424-
size_t _modules_mem_base = modules_mem_base;
443+
uintptr_t _modules_mem_base = modules_mem_base;
425444
for (size_t i = 0; ; i++) {
426445
char *module_path = config_get_value(config, i, "MODULE_PATH");
427446
if (module_path == NULL)
@@ -430,17 +449,29 @@ noreturn void linux_load(char *config, char *cmdline) {
430449
print("linux: Loading module `%#`...\n", module_path);
431450

432451
struct file_handle *module;
452+
453+
#if defined (UEFI) && defined (__x86_64__)
454+
uri_open_allow_high = true;
455+
#endif
433456
if ((module = uri_open(module_path)) == NULL)
434457
panic(true, "linux: Could not open `%#`", module_path);
435458

436459
fread(module, (void *)_modules_mem_base, 0, module->size);
437460

438461
_modules_mem_base += module->size;
462+
463+
fclose(module);
439464
}
440465

441466
if (size_of_all_modules != 0) {
442467
setup_header->ramdisk_image = (uint32_t)modules_mem_base;
443-
setup_header->ramdisk_size = (uint32_t)size_of_all_modules;
468+
#if defined (UEFI) && defined (__x86_64__)
469+
boot_params->ext_ramdisk_image = (uint32_t)(modules_mem_base >> 32);
470+
#endif
471+
setup_header->ramdisk_size = (uint32_t)size_of_all_modules;
472+
#if defined (UEFI) && defined (__x86_64__)
473+
boot_params->ext_ramdisk_size = (uint32_t)(size_of_all_modules >> 32);
474+
#endif
444475
}
445476

446477
///////////////////////////////////////
@@ -572,6 +603,13 @@ no_fb:;
572603

573604
irq_flush_type = IRQ_PIC_ONLY_FLUSH;
574605

606+
#if defined (UEFI) && defined (__x86_64__)
607+
if ((setup_header->xloadflags & 3) == 3) {
608+
flush_irqs();
609+
linux_spinup64((void *)kernel_load_addr + 0x200, boot_params);
610+
}
611+
#endif
612+
575613
common_spinup(linux_spinup, 2, (uint32_t)kernel_load_addr,
576614
(uint32_t)(uintptr_t)boot_params);
577615
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
section .data
2+
3+
align 16
4+
linux_gdt64:
5+
dq 0
6+
7+
dq 0
8+
9+
dw 0xffff
10+
dw 0x0000
11+
db 0x00
12+
db 10011011b
13+
db 10101111b
14+
db 0x00
15+
16+
dw 0xffff
17+
dw 0x0000
18+
db 0x00
19+
db 10010011b
20+
db 10001111b
21+
db 0x00
22+
23+
.end:
24+
25+
align 16
26+
linux_gdt64_ptr:
27+
dw (linux_gdt64.end - linux_gdt64) - 1
28+
dq linux_gdt64
29+
30+
section .text
31+
32+
bits 64
33+
34+
global linux_spinup64
35+
linux_spinup64:
36+
cli
37+
cld
38+
39+
lgdt [rel linux_gdt64_ptr]
40+
41+
lea rbx, [rel .fj]
42+
push 0x10
43+
push rbx
44+
retfq
45+
46+
.fj:
47+
mov eax, 0x18
48+
mov ds, eax
49+
mov es, eax
50+
mov fs, eax
51+
mov gs, eax
52+
mov ss, eax
53+
54+
mov rax, rdi
55+
56+
xor ebp, ebp
57+
xor edi, edi
58+
xor ebx, ebx
59+
60+
jmp rax
61+
62+
section .note.GNU-stack noalloc noexec nowrite progbits

0 commit comments

Comments
 (0)