11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * linux/arch/arm/boot/bootp/init.S 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2000-2003 Russell King. 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is free software; you can redistribute it and/or modify 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * it under the terms of the GNU General Public License version 2 as 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * published by the Free Software Foundation. 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * "Header" file for splitting kernel + initrd. Note that we pass 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * r0 through to r3 straight through. 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This demonstrates how to append code to the start of the kernel 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * zImage, and boot the kernel without copying it around. This 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * example would be simpler; if we didn't have an object of unknown 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * size immediately following the kernel, we could build this into 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * a binary blob, and concatenate the zImage using the cat command. 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .section .start,#alloc,#execinstr 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .type _start, #function 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .globl _start 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds_start: add lr, pc, #-0x8 @ lr = current load addr 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adr r13, data 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ldmia r13!, {r4-r6} @ r5 = dest, r6 = length 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds add r4, r4, lr @ r4 = initrd_start + load addr 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bl move @ move the initrd 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Setup the initrd parameters to pass to the kernel. This can only be 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * passed in via the tagged list. 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ldmia r13, {r5-r9} @ get size and addr of initrd 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds @ r5 = ATAG_CORE 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds @ r6 = ATAG_INITRD2 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds @ r7 = initrd start 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds @ r8 = initrd end 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds @ r9 = param_struct address 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ldr r10, [r9, #4] @ get first tag 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds teq r10, r5 @ is it ATAG_CORE? 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If we didn't find a valid tag list, create a dummy ATAG_CORE entry. 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds movne r10, #0 @ terminator 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds movne r4, #2 @ Size of this entry (2 words) 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stmneia r9, {r4, r5, r10} @ Size, ATAG_CORE, terminator 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * find the end of the tag list, and then add an INITRD tag on the end. 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If there is already an INITRD tag, then we ignore it; the last INITRD 52659431fcafd820cc426afedadcc4548933224985Uwe Kleine-König * tag takes precedence. 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstaglist: ldr r10, [r9, #0] @ tag length 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds teq r10, #0 @ last tag (zero length)? 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds addne r9, r9, r10, lsl #2 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bne taglist 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mov r5, #4 @ Size of initrd tag (4 words) 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stmia r9, {r5, r6, r7, r8, r10} 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds b kernel_start @ call kernel 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Move the block of memory length r6 from address r4 to address r5 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmove: ldmia r4!, {r7 - r10} @ move 32-bytes at a time 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stmia r5!, {r7 - r10} 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ldmia r4!, {r7 - r10} 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stmia r5!, {r7 - r10} 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds subs r6, r6, #8 * 4 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs move 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mov pc, lr 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .size _start, . - _start 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 76077248fcce5edabb1b77ba3269e6c72341769d94Dave Martin .align 77077248fcce5edabb1b77ba3269e6c72341769d94Dave Martin 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .type data,#object 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsdata: .word initrd_start @ source initrd address 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .word initrd_phys @ destination initrd address 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .word initrd_size @ initrd size 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .word 0x54410001 @ r5 = ATAG_CORE 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .word 0x54420005 @ r6 = ATAG_INITRD2 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .word initrd_phys @ r7 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .word initrd_size @ r8 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .word params_phys @ r9 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .size data, . - data 89