Back to home page

OSCL-LXR

 
 

    


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