diff --git a/grub-core/kern/arm/uboot/startup.S b/grub-core/kern/arm/uboot/startup.S index 0ed33cc42..9585bf959 100644 --- a/grub-core/kern/arm/uboot/startup.S +++ b/grub-core/kern/arm/uboot/startup.S @@ -65,20 +65,28 @@ FUNCTION(codestart) ldr sp, =entry_state push {r4-r12,lr} @ store U-Boot context (sp in r12) - @ Put kernel parameters aside until we can store them (further down) - mov r4, r1 @ machine type - mov r5, r2 @ boot data + ldr r12, =EXT_C(uboot_machine_type) + str r1, [r12] + ldr r12, =EXT_C(uboot_boot_data) + str r2, [r12] @ Modules have been stored as a blob in BSS, @ they need to be manually relocated to _end or @ (__bss_start + grub_total_module_size), whichever greater. - bl uboot_get_real_bss_start @ r0 = src + ldr r0, =EXT_C(__bss_start) @ src + add r0, r0, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1) + mvn r1, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1) + and r0, r0, r1 + ldr r1, =EXT_C(_end) @ dst = End of BSS ldr r2, grub_total_module_size @ blob size add r3, r0, r2 @ blob end cmp r1, r3 @ _end < blob end? movlt r1, r3 @ dst = blob end + blob size - + + ldr r12, =EXT_C(grub_modbase) + str r1, [r12] + 1: ldr r3, [r0], #4 @ r3 = *src++ str r3, [r1], #4 @ *dst++ = r3 subs r2, #4 @ remaining -= 4 @@ -91,34 +99,15 @@ FUNCTION(codestart) @ Since we _are_ the C run-time, we need to manually zero the BSS @ region before continuing - bl uboot_get_real_bss_start @ zero from here + ldr r0, =EXT_C(__bss_start) @ zero from here ldr r1, =EXT_C(_end) @ to here mov r2, #0 1: str r2, [r0], #4 cmp r0, r1 bne 1b - - @ Global variables now accessible - store kernel parameters in memory - ldr r12, =EXT_C(uboot_machine_type) - str r4, [r12] - ldr r12, =EXT_C(uboot_boot_data) - str r5, [r12] b EXT_C(grub_main) - /* - * __bss_start does not actually point to the start of the runtime - * BSS, but rather to the next byte following the preceding data. - */ -FUNCTION (uboot_get_real_bss_start) - ldr r0, =EXT_C(__bss_start) @ src - tst r0, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1) - beq 1f - mvn r1, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1) - and r0, r0, r1 - add r0, r0, #(GRUB_KERNEL_MACHINE_MOD_ALIGN) -1: bx lr - /* * uboot_syscall(): * This function is effectively a veneer, so it cannot diff --git a/grub-core/kern/uboot/init.c b/grub-core/kern/uboot/init.c index b9944a452..431bd7b36 100644 --- a/grub-core/kern/uboot/init.c +++ b/grub-core/kern/uboot/init.c @@ -35,10 +35,10 @@ extern char _end[]; extern grub_size_t grub_total_module_size; extern int (*uboot_syscall_ptr) (int, int *, ...); -grub_addr_t grub_modbase; - -grub_uint32_t uboot_machine_type; -grub_addr_t uboot_boot_data; +/* Set to anything other than zero so it lands in .data and not .bss. */ +grub_addr_t grub_modbase = 0x55aa55aa; +grub_uint32_t uboot_machine_type = 0x55aa55aa; +grub_addr_t uboot_boot_data = 0x55aa55aa; static unsigned long timer_start; @@ -69,7 +69,6 @@ uboot_timer_ms (void) void grub_machine_init (void) { - grub_addr_t end, real_bss_start; int ver; /* First of all - establish connection with U-Boot */ @@ -85,26 +84,14 @@ grub_machine_init (void) uboot_puts ("invalid U-Boot API version\n"); } - /* - * Modules were relocated to _end, or __bss_start + grub_total_module_size, - * whichever greater. (And __bss_start may not point to actual BSS start...) - */ - real_bss_start = uboot_get_real_bss_start (); - end = real_bss_start + grub_total_module_size; - if (end < (grub_addr_t) _end) - end = (grub_addr_t) _end; - grub_modbase = end; - /* Initialize the console so that GRUB can display messages. */ grub_console_init_early (); /* Enumerate memory and initialize the memory management system. */ grub_uboot_mm_init (); - grub_dprintf ("init", "__bss_start: 0x%08x, real_bss_start: 0x%08x\n", - (grub_addr_t) __bss_start, real_bss_start); - grub_dprintf ("init", "end: 0x%08x, _end: 0x%08x\n", - (grub_addr_t) end, (grub_addr_t) _end); + grub_dprintf ("init", "__bss_start: %p\n", __bss_start); + grub_dprintf ("init", "_end: %p\n", _end); grub_dprintf ("init", "grub_modbase: %p\n", (void *) grub_modbase); grub_dprintf ("init", "grub_modules_get_end(): %p\n", (void *) grub_modules_get_end ());