diff --git a/ChangeLog b/ChangeLog index 489088db0..bb06a93f5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-05-16 Vladimir Serbinenko + + * grub-core/kern/arm/uboot/startup.S: Move stack before modules. + 2013-05-16 Vladimir Serbinenko * grub-core/lib/dtc/libfdt-grub.diff: Remove extraneous uintptr_t diff --git a/grub-core/kern/arm/uboot/startup.S b/grub-core/kern/arm/uboot/startup.S index 80dd15361..3e3869867 100644 --- a/grub-core/kern/arm/uboot/startup.S +++ b/grub-core/kern/arm/uboot/startup.S @@ -39,11 +39,9 @@ * Also where global/static variables are located. * _end: * End of bss region (but not necessarily module blob). - * : - * Any part of the module blob that extends beyond _end. + * : * : * Loadable modules, post relocation. - * : * : */ @@ -71,8 +69,7 @@ FUNCTION(codestart) 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. + @ they need to be manually relocated to _end ldr r0, =EXT_C(__bss_start) @ src add r0, r0, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1) mvn r1, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1) @@ -80,22 +77,24 @@ FUNCTION(codestart) 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 + + add r1, r1, #GRUB_KERNEL_MACHINE_STACK_SIZE + and r1, r1, #~0x7 @ Ensure 8-byte alignment + sub sp, r1, #8 + add r1, r1, #1024 ldr r12, =EXT_C(grub_modbase) str r1, [r12] -1: ldr r3, [r0], #4 @ r3 = *src++ - str r3, [r1], #4 @ *dst++ = r3 + add r1, r1, r2 + add r0, r0, r2 + sub r1, r1, #4 + sub r0, r0, #4 + +1: ldr r3, [r0], #-4 @ r3 = *src-- + str r3, [r1], #-4 @ *dst-- = r3 subs r2, #4 @ remaining -= 4 bne 1b @ while remaining != 0 - - @ Set up a new stack, beyond the end of copied modules. - ldr r3, =GRUB_KERNEL_MACHINE_STACK_SIZE - add r3, r1, r3 @ Place stack beyond end of modules - and sp, r3, #~0x7 @ Ensure 8-byte alignment @ Since we _are_ the C run-time, we need to manually zero the BSS @ region before continuing diff --git a/grub-core/kern/uboot/hw.c b/grub-core/kern/uboot/hw.c index 9cacb4ad2..272b83bd7 100644 --- a/grub-core/kern/uboot/hw.c +++ b/grub-core/kern/uboot/hw.c @@ -40,8 +40,7 @@ grub_uboot_mm_init (void) { struct sys_info *si = grub_uboot_get_sys_info (); - grub_mm_init_region ((void *) (grub_modules_get_end () - + GRUB_KERNEL_MACHINE_STACK_SIZE), + grub_mm_init_region ((void *) grub_modules_get_end (), GRUB_KERNEL_MACHINE_HEAP_SIZE); if (si && (si->mr_no != 0))