/*1* Copyright (C) Paul Mackerras 1997.2*3* This program is free software; you can redistribute it and/or4* modify it under the terms of the GNU General Public License5* as published by the Free Software Foundation; either version6* 2 of the License, or (at your option) any later version.7*8* NOTE: this code runs in 32 bit mode, is position-independent,9* and is packaged as ELF32.10*/1112#include "ppc_asm.h"1314.text15/* A procedure descriptor used when booting this as a COFF file.16* When making COFF, this comes first in the link and we're17* linked at 0x500000.18*/19.globl _zimage_start_opd20_zimage_start_opd:21.long 0x500000, 0, 0, 02223p_start: .long _start24p_etext: .long _etext25p_bss_start: .long __bss_start26p_end: .long _end2728.weak _platform_stack_top29p_pstack: .long _platform_stack_top3031.weak _zimage_start32.globl _zimage_start33_zimage_start:34.globl _zimage_start_lib35_zimage_start_lib:36/* Work out the offset between the address we were linked at37and the address where we're running. */38bl .+439p_base: mflr r10 /* r10 now points to runtime addr of p_base */40/* grab the link address of the dynamic section in r11 */41addis r11,r10,(_GLOBAL_OFFSET_TABLE_-p_base)@ha42lwz r11,(_GLOBAL_OFFSET_TABLE_-p_base)@l(r11)43cmpwi r11,044beq 3f /* if not linked -pie */45/* get the runtime address of the dynamic section in r12 */46.weak __dynamic_start47addis r12,r10,(__dynamic_start-p_base)@ha48addi r12,r12,(__dynamic_start-p_base)@l49subf r11,r11,r12 /* runtime - linktime offset */5051/* The dynamic section contains a series of tagged entries.52* We need the RELA and RELACOUNT entries. */53RELA = 754RELACOUNT = 0x6ffffff955li r9,056li r0,0579: lwz r8,0(r12) /* get tag */58cmpwi r8,059beq 10f /* end of list */60cmpwi r8,RELA61bne 11f62lwz r9,4(r12) /* get RELA pointer in r9 */63b 12f6411: addis r8,r8,(-RELACOUNT)@ha65cmpwi r8,RELACOUNT@l66bne 12f67lwz r0,4(r12) /* get RELACOUNT value in r0 */6812: addi r12,r12,869b 9b7071/* The relocation section contains a list of relocations.72* We now do the R_PPC_RELATIVE ones, which point to words73* which need to be initialized with addend + offset.74* The R_PPC_RELATIVE ones come first and there are RELACOUNT75* of them. */7610: /* skip relocation if we don't have both */77cmpwi r0,078beq 3f79cmpwi r9,080beq 3f8182add r9,r9,r11 /* Relocate RELA pointer */83mtctr r0842: lbz r0,4+3(r9) /* ELF32_R_INFO(reloc->r_info) */85cmpwi r0,22 /* R_PPC_RELATIVE */86bne 3f87lwz r12,0(r9) /* reloc->r_offset */88lwz r0,8(r9) /* reloc->r_addend */89add r0,r0,r1190stwx r0,r11,r1291addi r9,r9,1292bdnz 2b9394/* Do a cache flush for our text, in case the loader didn't */953: lwz r9,p_start-p_base(r10) /* note: these are relocated now */96lwz r8,p_etext-p_base(r10)974: dcbf r0,r998icbi r0,r999addi r9,r9,0x20100cmplw cr0,r9,r8101blt 4b102sync103isync104105/* Clear the BSS */106lwz r9,p_bss_start-p_base(r10)107lwz r8,p_end-p_base(r10)108li r0,01095: stw r0,0(r9)110addi r9,r9,4111cmplw cr0,r9,r8112blt 5b113114/* Possibly set up a custom stack */115lwz r8,p_pstack-p_base(r10)116cmpwi r8,0117beq 6f118lwz r1,0(r8)119li r0,0120stwu r0,-16(r1) /* establish a stack frame */1216:122123/* Call platform_init() */124bl platform_init125126/* Call start */127b start128129130