2121#include <drivers/gop.h>
2222
2323noreturn 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}
0 commit comments