xref: /OK3568_Linux_fs/u-boot/doc/README.arm-relocation (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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