Commit 1500d1a2 authored by Russell King's avatar Russell King

[ARM] Update bootp kernel+initrd loader.

Drop support for old param struct method, and clean up code.
parent 7e0b6a45
/*
* linux/arch/arm/boot/bootp/init.S
*
* Copyright (C) 2000-2002 Russell King
* Copyright (C) 2000-2003 Russell King.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Header file for splitting kernel + initrd. Note that we pass
* "Header" file for splitting kernel + initrd. Note that we pass
* r0 through to r3 straight through.
*
* This demonstrates how to append code to the start of the kernel
* zImage, and boot the kernel without copying it around. This
* example would be simpler; if we didn't have an object of unknown
* size immediately following the kernel, we could build this into
* a binary blob, and concatenate the zImage using the cat command.
*/
.section .start,#alloc,#execinstr
.type _start, #function
.globl _start
_start: adr r10, initdata
ldr r11, initdata
sub r11, r10, r11 @ work out exec offset
b splitify
.size _entry,. - _entry
.type initdata, #object
initdata: .word initdata @ compiled address of this
.size initdata,. - initdata
splitify: adr r13, data
ldmia r13!, {r4-r6} @ move the initrd
add r4, r4, r11 @ correction
bl move
_start: adr r12, kernel_start @ offset of kernel zImage
ldr r4, [r12, #0x2c] @ length of zImage
adr r13, data
add r4, r4, r12 @ end of zImage, start of initrd
ldmia r13!, {r5-r6} @ r5 = dest, r6 = length
bl move @ move the initrd
/*
* Setup the initrd parameters to pass to the kernel. This can either be
* passed in via a param_struct or a tag list. We spot the param_struct
* method by looking at the first word; this should either indicate a page
* size of 4K, 16K or 32K.
* Setup the initrd parameters to pass to the kernel. This can only be
* passed in via the tagged list.
*/
ldmia r13, {r4-r8} @ get size and addr of initrd
@ r5 = ATAG_INITRD
@ r6 = initrd start
@ r7 = initrd end
@ r8 = param_struct address
ldr r9, [r8, #0] @ no param struct?
teq r9, #0x1000 @ 4K?
teqne r9, #0x4000 @ 16K?
teqne r9, #0x8000 @ 32K?
beq param_struct
ldr r9, [r8, #4] @ get first tag
teq r9, r4
bne taglist @ ok, we have a tag list
ldmia r13, {r5-r9} @ get size and addr of initrd
@ r5 = ATAG_CORE
@ r6 = ATAG_INITRD2
@ r7 = initrd start
@ r8 = initrd end
@ r9 = param_struct address
ldr r10, [r9, #4] @ get first tag
teq r10, r5 @ is it ATAG_CORE?
/*
* We didn't find a valid tag list - create one.
* If we didn't find a valid tag list, create a dummy ATAG_CORE entry.
*/
str r4, [r8, #4]
mov r4, #8
str r4, [r8, #0]
mov r4, #0
str r4, [r8, #8]
movne r10, #0 @ terminator
movne r4, #2 @ Size of this entry (2 words)
stmneia r8, {r4, r5, r10} @ Size, ATAG_CORE, terminator
/*
* find the end of the tag list, and then add an INITRD tag on the end.
* If there is already an INITRD tag, then we ignore it; the last INITRD
* tag takes precidence.
*/
taglist: ldr r9, [r8, #0] @ tag length
teq r9, #0 @ last tag?
addne r8, r8, r9
taglist: ldr r10, [r9, #0] @ tag length
teq r10, #0 @ last tag (zero length)?
addne r9, r9, r10, lsl #2
bne taglist
mov r4, #16 @ length of initrd tag
mov r9, #0 @ end of tag list terminator
stmia r8, {r4, r5, r6, r7, r9}
adr r12, kernel_start
mov r5, #4 @ Size of initrd tag (4 words)
stmia r9, {r5, r6, r7, r8, r10}
mov pc, r12 @ call kernel
/*
* We found a param struct. Modify the param struct for the initrd
* Move the block of memory length r6 from address r4 to address r5
*/
param_struct: add r8, r8, #16*4
stmia r8, {r6,r7} @ save in param_struct
mov pc, r12 @ call kernel
move: ldmia r4!, {r7 - r10} @ move 32-bytes at a time
stmia r5!, {r7 - r10}
ldmia r4!, {r7 - r10}
......@@ -89,15 +72,18 @@ move: ldmia r4!, {r7 - r10} @ move 32-bytes at a time
bcs move
mov pc, lr
data: .word initrd_start
.word initrd_addr
.word initrd_len
.size _start, . - _start
.type data,#object
data: .word initrd_addr @ destination initrd address
.word initrd_len @ initrd size
.word 0x54410001 @ r4 = ATAG_CORE
.word 0x54420005 @ r5 = ATAG_INITRD
.word 0x54420005 @ r5 = ATAG_INITRD2
.word initrd_addr @ r6
.word initrd_len @ r7
.word params @ r8
.size data, . - _data
.type initrd_start,#object
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment