Refactor arm-uboot code to make it genereic.
arm-coreboot startup code can be very similar to arm-uboot but current code has U-Boot specific references. So split U-Boot part from generic part.
This commit is contained in:
parent
a35ac85430
commit
d08c968514
7 changed files with 170 additions and 108 deletions
173
grub-core/kern/arm/startup.S
Normal file
173
grub-core/kern/arm/startup.S
Normal file
|
@ -0,0 +1,173 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/offsets.h>
|
||||
#include <grub/symbol.h>
|
||||
#include <grub/machine/kernel.h>
|
||||
|
||||
/*
|
||||
* GRUB is called from U-Boot as a Linux Kernel type image, which
|
||||
* means among other things that it always enters in ARM state.
|
||||
*
|
||||
*
|
||||
* Overview of GRUB image layout:
|
||||
*
|
||||
* _start:
|
||||
* Entry point (1 ARM branch instruction, to "codestart")
|
||||
* grub_total_module_size:
|
||||
* Data field: Size of included module blob
|
||||
* (when generated by grub-mkimage)
|
||||
* codestart:
|
||||
* Remainder of statically-linked executable code and data.
|
||||
* __bss_start:
|
||||
* Start of included module blob.
|
||||
* Also where global/static variables are located.
|
||||
* _end:
|
||||
* End of bss region (but not necessarily module blob).
|
||||
* <stack>:
|
||||
* <modules>:
|
||||
* Loadable modules, post relocation.
|
||||
* <heap>:
|
||||
*/
|
||||
|
||||
.text
|
||||
.arm
|
||||
FUNCTION(_start)
|
||||
b codestart
|
||||
|
||||
@ Size of final image integrated module blob - set by grub-mkimage
|
||||
.org _start + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE
|
||||
VARIABLE(grub_total_module_size)
|
||||
.long 0
|
||||
|
||||
VARIABLE(grub_modbase)
|
||||
.long 0
|
||||
bss_start_ptr:
|
||||
.long EXT_C(__bss_start)
|
||||
end_ptr:
|
||||
.long EXT_C(_end)
|
||||
|
||||
@ Memory map at start:
|
||||
@ * text+data
|
||||
@ * list relocations
|
||||
@ * modules
|
||||
@ Before we enter C, we need to apply the relocations
|
||||
@ and get following map:
|
||||
@ * text+data
|
||||
@ * BSS (cleared)
|
||||
@ * stack
|
||||
@ * modules
|
||||
@
|
||||
@ To make things easier we ensure
|
||||
@ that BSS+stack is larger than list of relocations
|
||||
@ by increasing stack if necessarry.
|
||||
@ This allows us to always unconditionally copy backwards
|
||||
@ Currently list of relocations is ~5K and stack is set
|
||||
@ to be at least 256K
|
||||
|
||||
FUNCTION(codestart)
|
||||
@ Store context: Machine ID, atags/dtb, ...
|
||||
@ U-Boot API signature is stored on the U-Boot heap
|
||||
@ Stack pointer used as start address for signature probing
|
||||
mov r12, sp
|
||||
adr sp, entry_state
|
||||
push {r0-r12,lr} @ store U-Boot context (sp in r12)
|
||||
|
||||
adr r1, _start
|
||||
ldr r0, bss_start_ptr @ src
|
||||
add r0, r0, r1
|
||||
|
||||
add r0, r0, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1)
|
||||
mvn r2, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1)
|
||||
and r0, r0, r2
|
||||
1:
|
||||
ldr r3, [r0], #4 @load next offset
|
||||
@ both -2 and -1 are treated the same as we have only one type of relocs
|
||||
@ -2 means "end of this type of relocs" and -1 means "end of all relocs"
|
||||
add r2, r3, #2
|
||||
cmp r2, #1
|
||||
bls reloc_done
|
||||
@ Adjust next offset
|
||||
ldr r2, [r3, r1]
|
||||
add r2, r2, r1
|
||||
str r2, [r3, r1]
|
||||
b 1b
|
||||
|
||||
reloc_done:
|
||||
|
||||
@ Modules have been stored as a blob
|
||||
@ they need to be manually relocated to _end
|
||||
add r0, r0, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1)
|
||||
mvn r1, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1)
|
||||
and r0, r0, r1 @ src = aligned end of relocations
|
||||
|
||||
ldr r1, end_ptr @ dst = End of BSS
|
||||
ldr r2, grub_total_module_size @ 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
|
||||
|
||||
str r1, EXT_C(grub_modbase)
|
||||
|
||||
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
|
||||
|
||||
@ Since we _are_ the C run-time, we need to manually zero the BSS
|
||||
@ region before continuing
|
||||
ldr r0, bss_start_ptr @ zero from here
|
||||
@ If unaligned, bytewise zero until base address aligned.
|
||||
mov r2, #0
|
||||
1: tst r0, #3
|
||||
beq 2f
|
||||
strb r2, [r0], #1
|
||||
b 1b
|
||||
2: ldr r1, end_ptr @ to here
|
||||
1: str r2, [r0], #4
|
||||
cmp r0, r1
|
||||
bne 1b
|
||||
|
||||
b EXT_C(grub_main)
|
||||
|
||||
.align 3
|
||||
@ U-boot/coreboot context stack space
|
||||
VARIABLE(grub_arm_saved_registers)
|
||||
.long 0 @ r0
|
||||
.long 0 @ r1
|
||||
.long 0 @ r2
|
||||
.long 0 @ r3
|
||||
.long 0 @ r4
|
||||
.long 0 @ r5
|
||||
.long 0 @ r6
|
||||
.long 0 @ r7
|
||||
.long 0 @ r8
|
||||
.long 0 @ r9
|
||||
.long 0 @ r10
|
||||
.long 0 @ r11
|
||||
.long 0 @ sp
|
||||
.long 0 @ lr
|
||||
entry_state:
|
Loading…
Add table
Add a link
Reference in a new issue