Back to home page

LXR

 
 

    


0001 /*
0002  *  linux/arch/arm/boot/bootp/init.S
0003  *
0004  *  Copyright (C) 2000-2003 Russell King.
0005  *
0006  * This program is free software; you can redistribute it and/or modify
0007  * it under the terms of the GNU General Public License version 2 as
0008  * published by the Free Software Foundation.
0009  *
0010  *  "Header" file for splitting kernel + initrd.  Note that we pass
0011  *  r0 through to r3 straight through.
0012  *
0013  *  This demonstrates how to append code to the start of the kernel
0014  *  zImage, and boot the kernel without copying it around.  This
0015  *  example would be simpler; if we didn't have an object of unknown
0016  *  size immediately following the kernel, we could build this into
0017  *  a binary blob, and concatenate the zImage using the cat command.
0018  */
0019         .section .start,#alloc,#execinstr
0020         .type   _start, #function
0021         .globl  _start
0022 
0023 _start:     add lr, pc, #-0x8       @ lr = current load addr
0024         adr r13, data
0025         ldmia   r13!, {r4-r6}       @ r5 = dest, r6 = length
0026         add r4, r4, lr      @ r4 = initrd_start + load addr
0027         bl  move            @ move the initrd
0028 
0029 /*
0030  * Setup the initrd parameters to pass to the kernel.  This can only be
0031  * passed in via the tagged list.
0032  */
0033         ldmia   r13, {r5-r9}        @ get size and addr of initrd
0034                         @ r5 = ATAG_CORE
0035                         @ r6 = ATAG_INITRD2
0036                         @ r7 = initrd start
0037                         @ r8 = initrd end
0038                         @ r9 = param_struct address
0039 
0040         ldr r10, [r9, #4]       @ get first tag
0041         teq r10, r5         @ is it ATAG_CORE?
0042 /*
0043  * If we didn't find a valid tag list, create a dummy ATAG_CORE entry.
0044  */
0045         movne   r10, #0         @ terminator
0046         movne   r4, #2          @ Size of this entry (2 words)
0047         stmneia r9, {r4, r5, r10}   @ Size, ATAG_CORE, terminator
0048 
0049 /*
0050  * find the end of the tag list, and then add an INITRD tag on the end.
0051  * If there is already an INITRD tag, then we ignore it; the last INITRD
0052  * tag takes precedence.
0053  */
0054 taglist:    ldr r10, [r9, #0]       @ tag length
0055         teq r10, #0         @ last tag (zero length)?
0056         addne   r9, r9, r10, lsl #2
0057         bne taglist
0058 
0059         mov r5, #4          @ Size of initrd tag (4 words)
0060         stmia   r9, {r5, r6, r7, r8, r10}
0061         b   kernel_start        @ call kernel
0062 
0063 /*
0064  * Move the block of memory length r6 from address r4 to address r5
0065  */
0066 move:       ldmia   r4!, {r7 - r10}     @ move 32-bytes at a time
0067         stmia   r5!, {r7 - r10}
0068         ldmia   r4!, {r7 - r10}
0069         stmia   r5!, {r7 - r10}
0070         subs    r6, r6, #8 * 4
0071         bcs move
0072         mov pc, lr
0073 
0074         .size   _start, . - _start
0075 
0076         .align
0077 
0078         .type   data,#object
0079 data:       .word   initrd_start        @ source initrd address
0080         .word   initrd_phys     @ destination initrd address
0081         .word   initrd_size     @ initrd size
0082 
0083         .word   0x54410001      @ r5 = ATAG_CORE
0084         .word   0x54420005      @ r6 = ATAG_INITRD2
0085         .word   initrd_phys     @ r7
0086         .word   initrd_size     @ r8
0087         .word   params_phys     @ r9
0088         .size   data, . - data