1*4882a593SmuzhiyunTo make relocation on arm working, the following changes are done: 2*4882a593Smuzhiyun 3*4882a593SmuzhiyunAt arch level: add linker flag -pie 4*4882a593Smuzhiyun 5*4882a593Smuzhiyun This causes the linker to generate fixup tables .rel.dyn and .dynsym, 6*4882a593Smuzhiyun which must be applied to the relocated image before transferring 7*4882a593Smuzhiyun control to it. 8*4882a593Smuzhiyun 9*4882a593Smuzhiyun These fixups are described in the ARM ELF documentation as type 23 10*4882a593Smuzhiyun (program-base-relative) and 2 (symbol-relative) 11*4882a593Smuzhiyun 12*4882a593SmuzhiyunAt cpu level: modify linker file and add a relocation and fixup loop 13*4882a593Smuzhiyun 14*4882a593Smuzhiyun the linker file must be modified to include the .rel.dyn and .dynsym 15*4882a593Smuzhiyun tables in the binary image, and to provide symbols for the relocation 16*4882a593Smuzhiyun code to access these tables 17*4882a593Smuzhiyun 18*4882a593Smuzhiyun The relocation and fixup loop must be executed after executing 19*4882a593Smuzhiyun board_init_f at initial location and before executing board_init_r 20*4882a593Smuzhiyun at final location. 21*4882a593Smuzhiyun 22*4882a593SmuzhiyunAt board level: 23*4882a593Smuzhiyun 24*4882a593Smuzhiyun dram_init(): bd pointer is now at this point not accessible, so only 25*4882a593Smuzhiyun detect the real dramsize, and store it in gd->ram_size. Bst detected 26*4882a593Smuzhiyun with get_ram_size(). 27*4882a593Smuzhiyun 28*4882a593SmuzhiyunTODO: move also dram initialization there on boards where it is possible. 29*4882a593Smuzhiyun 30*4882a593Smuzhiyun Setup of the the bd_t dram bank info is done in the new function 31*4882a593Smuzhiyun dram_init_banksize() called after bd is accessible. 32*4882a593Smuzhiyun 33*4882a593SmuzhiyunAt lib level: 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun Board.c code is adapted from ppc code 36*4882a593Smuzhiyun 37*4882a593Smuzhiyun* WARNING ** WARNING ** WARNING ** WARNING ** WARNING ** WARNING ** WARNING * 38*4882a593Smuzhiyun 39*4882a593SmuzhiyunBoards which are not fixed to support relocation will be REMOVED! 40*4882a593Smuzhiyun 41*4882a593Smuzhiyun----------------------------------------------------------------------------- 42*4882a593Smuzhiyun 43*4882a593SmuzhiyunFor boards which boot from spl, it is possible to save one copy 44*4882a593Smuzhiyunif CONFIG_SYS_TEXT_BASE == relocation address! This prevents that uboot code 45*4882a593Smuzhiyunis copied again in relocate_code(). 46*4882a593Smuzhiyun 47*4882a593Smuzhiyunexample for the tx25 board booting from NAND Flash: 48*4882a593Smuzhiyun 49*4882a593Smuzhiyuna) cpu starts 50*4882a593Smuzhiyunb) it copies the first page in nand to internal ram 51*4882a593Smuzhiyun (spl code) 52*4882a593Smuzhiyunc) end executes this code 53*4882a593Smuzhiyund) this initialize CPU, RAM, ... and copy itself to RAM 54*4882a593Smuzhiyun (this bin must fit in one page, so board_init_f() 55*4882a593Smuzhiyun don;t fit in it ... ) 56*4882a593Smuzhiyune) there it copy u-boot to CONFIG_SYS_NAND_U_BOOT_DST and 57*4882a593Smuzhiyun starts this image @ CONFIG_SYS_NAND_U_BOOT_START 58*4882a593Smuzhiyunf) u-boot code steps through board_init_f() and calculates 59*4882a593Smuzhiyun the relocation address and copy itself to it 60*4882a593Smuzhiyun 61*4882a593SmuzhiyunIf CONFIG_SYS_TEXT_BASE == relocation address, the copying of u-boot 62*4882a593Smuzhiyunin f) could be saved. 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun----------------------------------------------------------------------------- 65*4882a593Smuzhiyun 66*4882a593SmuzhiyunTODO 67*4882a593Smuzhiyun 68*4882a593Smuzhiyun- fill in bd_t infos (check) 69*4882a593Smuzhiyun- adapt all boards 70*4882a593Smuzhiyun 71*4882a593Smuzhiyun- maybe adapt CONFIG_SYS_TEXT_BASE (this must be checked from board maintainers) 72*4882a593Smuzhiyun This *must* be done for boards, which boot from NOR flash 73*4882a593Smuzhiyun 74*4882a593Smuzhiyun on other boards if CONFIG_SYS_TEXT_BASE = relocation baseaddr, this saves 75*4882a593Smuzhiyun one copying from u-boot code. 76*4882a593Smuzhiyun 77*4882a593Smuzhiyun- new function dram_init_banksize() is actual board specific. Maybe 78*4882a593Smuzhiyun we make a weak default function in arch/arm/lib/board.c ? 79*4882a593Smuzhiyun 80*4882a593Smuzhiyun----------------------------------------------------------------------------- 81*4882a593Smuzhiyun 82*4882a593SmuzhiyunRelocation with SPL (example for the tx25 booting from NAND Flash): 83*4882a593Smuzhiyun 84*4882a593Smuzhiyun- cpu copies the first page from NAND to 0xbb000000 (IMX_NFC_BASE) 85*4882a593Smuzhiyun and start with code execution on this address. 86*4882a593Smuzhiyun 87*4882a593Smuzhiyun- The First page contains u-boot code from drivers/mtd/nand/raw/mxc_nand_spl.c 88*4882a593Smuzhiyun which inits the dram, cpu registers, reloacte itself to CONFIG_SPL_TEXT_BASE and loads 89*4882a593Smuzhiyun the "real" u-boot to CONFIG_SYS_NAND_U_BOOT_DST and starts execution 90*4882a593Smuzhiyun @CONFIG_SYS_NAND_U_BOOT_START 91*4882a593Smuzhiyun 92*4882a593Smuzhiyun- This u-boot does no RAM init, nor CPU register setup. Just look 93*4882a593Smuzhiyun where it has to copy and relocate itself to this address. If 94*4882a593Smuzhiyun relocate address = CONFIG_SYS_TEXT_BASE (not the same, as the 95*4882a593Smuzhiyun CONFIG_SPL_TEXT_BASE from the spl code), then there is no need 96*4882a593Smuzhiyun to copy, just go on with bss clear and jump to board_init_r. 97*4882a593Smuzhiyun 98*4882a593Smuzhiyun----------------------------------------------------------------------------- 99*4882a593Smuzhiyun 100*4882a593SmuzhiyunHow ELF relocations 23 and 2 work. 101*4882a593Smuzhiyun 102*4882a593SmuzhiyunTBC 103*4882a593Smuzhiyun 104*4882a593Smuzhiyun------------------------------------------------------------------------------------- 105*4882a593Smuzhiyun 106*4882a593SmuzhiyunDebugging u-boot in RAM: 107*4882a593Smuzhiyun(example on the qong board) 108*4882a593Smuzhiyun 109*4882a593Smuzhiyun----------------- 110*4882a593Smuzhiyun 111*4882a593Smuzhiyuna) start debugger 112*4882a593Smuzhiyun 113*4882a593Smuzhiyunarm-linux-gdb u-boot 114*4882a593Smuzhiyun 115*4882a593Smuzhiyun[hs@pollux u-boot]$ arm-linux-gdb u-boot 116*4882a593SmuzhiyunGNU gdb Red Hat Linux (6.7-2rh) 117*4882a593SmuzhiyunCopyright (C) 2007 Free Software Foundation, Inc. 118*4882a593SmuzhiyunLicense GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 119*4882a593SmuzhiyunThis is free software: you are free to change and redistribute it. 120*4882a593SmuzhiyunThere is NO WARRANTY, to the extent permitted by law. Type "show copying" 121*4882a593Smuzhiyunand "show warranty" for details. 122*4882a593SmuzhiyunThis GDB was configured as "--host=i686-pc-linux-gnu --target=arm-linux". 123*4882a593SmuzhiyunThe target architecture is set automatically (currently arm) 124*4882a593Smuzhiyun.. 125*4882a593Smuzhiyun(gdb) 126*4882a593Smuzhiyun 127*4882a593Smuzhiyun----------------- 128*4882a593Smuzhiyun 129*4882a593Smuzhiyunb) connect to target 130*4882a593Smuzhiyun 131*4882a593Smuzhiyuntarget remote bdi10:2001 132*4882a593Smuzhiyun 133*4882a593Smuzhiyun(gdb) target remote bdi10:2001 134*4882a593SmuzhiyunRemote debugging using bdi10:2001 135*4882a593Smuzhiyun0x8ff17f10 in ?? () 136*4882a593Smuzhiyun(gdb) 137*4882a593Smuzhiyun 138*4882a593Smuzhiyun----------------- 139*4882a593Smuzhiyun 140*4882a593Smuzhiyunc) discard symbol-file 141*4882a593Smuzhiyun 142*4882a593Smuzhiyun(gdb) symbol-file 143*4882a593SmuzhiyunDiscard symbol table from `/home/hs/celf/u-boot/u-boot'? (y or n) y 144*4882a593SmuzhiyunNo symbol file now. 145*4882a593Smuzhiyun(gdb) 146*4882a593Smuzhiyun 147*4882a593Smuzhiyun----------------- 148*4882a593Smuzhiyun 149*4882a593Smuzhiyund) load new symbol table: 150*4882a593Smuzhiyun 151*4882a593Smuzhiyun(gdb) add-symbol-file u-boot 0x8ff08000 152*4882a593Smuzhiyunadd symbol table from file "u-boot" at 153*4882a593Smuzhiyun .text_addr = 0x8ff08000 154*4882a593Smuzhiyun(y or n) y 155*4882a593SmuzhiyunReading symbols from /home/hs/celf/u-boot/u-boot...done. 156*4882a593Smuzhiyun(gdb) c 157*4882a593SmuzhiyunContinuing. 158*4882a593Smuzhiyun^C 159*4882a593SmuzhiyunProgram received signal SIGSTOP, Stopped (signal). 160*4882a593Smuzhiyun0x8ff17f18 in serial_getc () at serial_mxc.c:192 161*4882a593Smuzhiyun192 while (__REG(UART_PHYS + UTS) & UTS_RXEMPTY); 162*4882a593Smuzhiyun(gdb) 163*4882a593Smuzhiyun 164*4882a593Smuzhiyunadd-symbol-file u-boot 0x8ff08000 165*4882a593Smuzhiyun ^^^^^^^^^^ 166*4882a593Smuzhiyun get this address from u-boot bdinfo command 167*4882a593Smuzhiyun or get it from gd->relocaddr in gdb 168*4882a593Smuzhiyun 169*4882a593Smuzhiyun => bdinfo 170*4882a593Smuzhiyunrch_number = XXXXXXXXXX 171*4882a593Smuzhiyunboot_params = XXXXXXXXXX 172*4882a593SmuzhiyunDRAM bank = XXXXXXXXXX 173*4882a593Smuzhiyun-> start = XXXXXXXXXX 174*4882a593Smuzhiyun-> size = XXXXXXXXXX 175*4882a593Smuzhiyunethaddr = XXXXXXXXXX 176*4882a593Smuzhiyunip_addr = XXXXXXXXXX 177*4882a593Smuzhiyunbaudrate = XXXXXXXXXX 178*4882a593SmuzhiyunTLB addr = XXXXXXXXXX 179*4882a593Smuzhiyunrelocaddr = 0x8ff08000 180*4882a593Smuzhiyun ^^^^^^^^^^ 181*4882a593Smuzhiyunreloc off = XXXXXXXXXX 182*4882a593Smuzhiyunirq_sp = XXXXXXXXXX 183*4882a593Smuzhiyunsp start = XXXXXXXXXX 184*4882a593SmuzhiyunFB base = XXXXXXXXXX 185*4882a593Smuzhiyun 186*4882a593Smuzhiyunor interrupt execution by any means and re-load the symbols at the location 187*4882a593Smuzhiyunspecified by gd->relocaddr -- this is only valid after board_init_f. 188*4882a593Smuzhiyun 189*4882a593Smuzhiyun(gdb) set $s = gd->relocaddr 190*4882a593Smuzhiyun(gdb) symbol-file 191*4882a593Smuzhiyun(gdb) add-symbol-file u-boot $s 192*4882a593Smuzhiyun 193*4882a593SmuzhiyunNow you can use gdb as usual :-) 194