Commit 2dd46328fdc50284311908dfb1ca3d5ec1ddcb6e
image: fix Android ramdisk support when dtb is specified
If a dtb is specified on the command-line, the Android boot image ramdisk will not be found. Fix this so that we can specify the ramdisk address and dtb address. The syntax is to enter the Android boot image address for both the kernel and ramdisk. Signed-off-by: Rob Herring <robh@kernel.org>
Showing 1 changed file with 8 additions and 10 deletions Inline Diff
1 | /* | 1 | /* |
2 | * (C) Copyright 2008 Semihalf | 2 | * (C) Copyright 2008 Semihalf |
3 | * | 3 | * |
4 | * (C) Copyright 2000-2006 | 4 | * (C) Copyright 2000-2006 |
5 | * Wolfgang Denk, DENX Software Engineering, wd@denx.de. | 5 | * Wolfgang Denk, DENX Software Engineering, wd@denx.de. |
6 | * | 6 | * |
7 | * SPDX-License-Identifier: GPL-2.0+ | 7 | * SPDX-License-Identifier: GPL-2.0+ |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #ifndef USE_HOSTCC | 10 | #ifndef USE_HOSTCC |
11 | #include <common.h> | 11 | #include <common.h> |
12 | #include <watchdog.h> | 12 | #include <watchdog.h> |
13 | 13 | ||
14 | #ifdef CONFIG_SHOW_BOOT_PROGRESS | 14 | #ifdef CONFIG_SHOW_BOOT_PROGRESS |
15 | #include <status_led.h> | 15 | #include <status_led.h> |
16 | #endif | 16 | #endif |
17 | 17 | ||
18 | #ifdef CONFIG_HAS_DATAFLASH | 18 | #ifdef CONFIG_HAS_DATAFLASH |
19 | #include <dataflash.h> | 19 | #include <dataflash.h> |
20 | #endif | 20 | #endif |
21 | 21 | ||
22 | #ifdef CONFIG_LOGBUFFER | 22 | #ifdef CONFIG_LOGBUFFER |
23 | #include <logbuff.h> | 23 | #include <logbuff.h> |
24 | #endif | 24 | #endif |
25 | 25 | ||
26 | #include <rtc.h> | 26 | #include <rtc.h> |
27 | 27 | ||
28 | #include <environment.h> | 28 | #include <environment.h> |
29 | #include <image.h> | 29 | #include <image.h> |
30 | #include <mapmem.h> | 30 | #include <mapmem.h> |
31 | 31 | ||
32 | #if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT) | 32 | #if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT) |
33 | #include <libfdt.h> | 33 | #include <libfdt.h> |
34 | #include <fdt_support.h> | 34 | #include <fdt_support.h> |
35 | #endif | 35 | #endif |
36 | 36 | ||
37 | #include <u-boot/md5.h> | 37 | #include <u-boot/md5.h> |
38 | #include <u-boot/sha1.h> | 38 | #include <u-boot/sha1.h> |
39 | #include <asm/errno.h> | 39 | #include <asm/errno.h> |
40 | #include <asm/io.h> | 40 | #include <asm/io.h> |
41 | 41 | ||
42 | #ifdef CONFIG_CMD_BDI | 42 | #ifdef CONFIG_CMD_BDI |
43 | extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); | 43 | extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); |
44 | #endif | 44 | #endif |
45 | 45 | ||
46 | DECLARE_GLOBAL_DATA_PTR; | 46 | DECLARE_GLOBAL_DATA_PTR; |
47 | 47 | ||
48 | #if defined(CONFIG_IMAGE_FORMAT_LEGACY) | 48 | #if defined(CONFIG_IMAGE_FORMAT_LEGACY) |
49 | static const image_header_t *image_get_ramdisk(ulong rd_addr, uint8_t arch, | 49 | static const image_header_t *image_get_ramdisk(ulong rd_addr, uint8_t arch, |
50 | int verify); | 50 | int verify); |
51 | #endif | 51 | #endif |
52 | #else | 52 | #else |
53 | #include "mkimage.h" | 53 | #include "mkimage.h" |
54 | #include <u-boot/md5.h> | 54 | #include <u-boot/md5.h> |
55 | #include <time.h> | 55 | #include <time.h> |
56 | #include <image.h> | 56 | #include <image.h> |
57 | 57 | ||
58 | #ifndef __maybe_unused | 58 | #ifndef __maybe_unused |
59 | # define __maybe_unused /* unimplemented */ | 59 | # define __maybe_unused /* unimplemented */ |
60 | #endif | 60 | #endif |
61 | #endif /* !USE_HOSTCC*/ | 61 | #endif /* !USE_HOSTCC*/ |
62 | 62 | ||
63 | #include <u-boot/crc.h> | 63 | #include <u-boot/crc.h> |
64 | 64 | ||
65 | #ifndef CONFIG_SYS_BARGSIZE | 65 | #ifndef CONFIG_SYS_BARGSIZE |
66 | #define CONFIG_SYS_BARGSIZE 512 | 66 | #define CONFIG_SYS_BARGSIZE 512 |
67 | #endif | 67 | #endif |
68 | 68 | ||
69 | static const table_entry_t uimage_arch[] = { | 69 | static const table_entry_t uimage_arch[] = { |
70 | { IH_ARCH_INVALID, NULL, "Invalid ARCH", }, | 70 | { IH_ARCH_INVALID, NULL, "Invalid ARCH", }, |
71 | { IH_ARCH_ALPHA, "alpha", "Alpha", }, | 71 | { IH_ARCH_ALPHA, "alpha", "Alpha", }, |
72 | { IH_ARCH_ARM, "arm", "ARM", }, | 72 | { IH_ARCH_ARM, "arm", "ARM", }, |
73 | { IH_ARCH_I386, "x86", "Intel x86", }, | 73 | { IH_ARCH_I386, "x86", "Intel x86", }, |
74 | { IH_ARCH_IA64, "ia64", "IA64", }, | 74 | { IH_ARCH_IA64, "ia64", "IA64", }, |
75 | { IH_ARCH_M68K, "m68k", "M68K", }, | 75 | { IH_ARCH_M68K, "m68k", "M68K", }, |
76 | { IH_ARCH_MICROBLAZE, "microblaze", "MicroBlaze", }, | 76 | { IH_ARCH_MICROBLAZE, "microblaze", "MicroBlaze", }, |
77 | { IH_ARCH_MIPS, "mips", "MIPS", }, | 77 | { IH_ARCH_MIPS, "mips", "MIPS", }, |
78 | { IH_ARCH_MIPS64, "mips64", "MIPS 64 Bit", }, | 78 | { IH_ARCH_MIPS64, "mips64", "MIPS 64 Bit", }, |
79 | { IH_ARCH_NIOS2, "nios2", "NIOS II", }, | 79 | { IH_ARCH_NIOS2, "nios2", "NIOS II", }, |
80 | { IH_ARCH_PPC, "powerpc", "PowerPC", }, | 80 | { IH_ARCH_PPC, "powerpc", "PowerPC", }, |
81 | { IH_ARCH_PPC, "ppc", "PowerPC", }, | 81 | { IH_ARCH_PPC, "ppc", "PowerPC", }, |
82 | { IH_ARCH_S390, "s390", "IBM S390", }, | 82 | { IH_ARCH_S390, "s390", "IBM S390", }, |
83 | { IH_ARCH_SH, "sh", "SuperH", }, | 83 | { IH_ARCH_SH, "sh", "SuperH", }, |
84 | { IH_ARCH_SPARC, "sparc", "SPARC", }, | 84 | { IH_ARCH_SPARC, "sparc", "SPARC", }, |
85 | { IH_ARCH_SPARC64, "sparc64", "SPARC 64 Bit", }, | 85 | { IH_ARCH_SPARC64, "sparc64", "SPARC 64 Bit", }, |
86 | { IH_ARCH_BLACKFIN, "blackfin", "Blackfin", }, | 86 | { IH_ARCH_BLACKFIN, "blackfin", "Blackfin", }, |
87 | { IH_ARCH_AVR32, "avr32", "AVR32", }, | 87 | { IH_ARCH_AVR32, "avr32", "AVR32", }, |
88 | { IH_ARCH_NDS32, "nds32", "NDS32", }, | 88 | { IH_ARCH_NDS32, "nds32", "NDS32", }, |
89 | { IH_ARCH_OPENRISC, "or1k", "OpenRISC 1000",}, | 89 | { IH_ARCH_OPENRISC, "or1k", "OpenRISC 1000",}, |
90 | { IH_ARCH_SANDBOX, "sandbox", "Sandbox", }, | 90 | { IH_ARCH_SANDBOX, "sandbox", "Sandbox", }, |
91 | { IH_ARCH_ARM64, "arm64", "AArch64", }, | 91 | { IH_ARCH_ARM64, "arm64", "AArch64", }, |
92 | { IH_ARCH_ARC, "arc", "ARC", }, | 92 | { IH_ARCH_ARC, "arc", "ARC", }, |
93 | { IH_ARCH_X86_64, "x86_64", "AMD x86_64", }, | 93 | { IH_ARCH_X86_64, "x86_64", "AMD x86_64", }, |
94 | { -1, "", "", }, | 94 | { -1, "", "", }, |
95 | }; | 95 | }; |
96 | 96 | ||
97 | static const table_entry_t uimage_os[] = { | 97 | static const table_entry_t uimage_os[] = { |
98 | { IH_OS_INVALID, NULL, "Invalid OS", }, | 98 | { IH_OS_INVALID, NULL, "Invalid OS", }, |
99 | { IH_OS_LINUX, "linux", "Linux", }, | 99 | { IH_OS_LINUX, "linux", "Linux", }, |
100 | #if defined(CONFIG_LYNXKDI) || defined(USE_HOSTCC) | 100 | #if defined(CONFIG_LYNXKDI) || defined(USE_HOSTCC) |
101 | { IH_OS_LYNXOS, "lynxos", "LynxOS", }, | 101 | { IH_OS_LYNXOS, "lynxos", "LynxOS", }, |
102 | #endif | 102 | #endif |
103 | { IH_OS_NETBSD, "netbsd", "NetBSD", }, | 103 | { IH_OS_NETBSD, "netbsd", "NetBSD", }, |
104 | { IH_OS_OSE, "ose", "Enea OSE", }, | 104 | { IH_OS_OSE, "ose", "Enea OSE", }, |
105 | { IH_OS_PLAN9, "plan9", "Plan 9", }, | 105 | { IH_OS_PLAN9, "plan9", "Plan 9", }, |
106 | { IH_OS_RTEMS, "rtems", "RTEMS", }, | 106 | { IH_OS_RTEMS, "rtems", "RTEMS", }, |
107 | { IH_OS_U_BOOT, "u-boot", "U-Boot", }, | 107 | { IH_OS_U_BOOT, "u-boot", "U-Boot", }, |
108 | { IH_OS_VXWORKS, "vxworks", "VxWorks", }, | 108 | { IH_OS_VXWORKS, "vxworks", "VxWorks", }, |
109 | #if defined(CONFIG_CMD_ELF) || defined(USE_HOSTCC) | 109 | #if defined(CONFIG_CMD_ELF) || defined(USE_HOSTCC) |
110 | { IH_OS_QNX, "qnx", "QNX", }, | 110 | { IH_OS_QNX, "qnx", "QNX", }, |
111 | #endif | 111 | #endif |
112 | #if defined(CONFIG_INTEGRITY) || defined(USE_HOSTCC) | 112 | #if defined(CONFIG_INTEGRITY) || defined(USE_HOSTCC) |
113 | { IH_OS_INTEGRITY,"integrity", "INTEGRITY", }, | 113 | { IH_OS_INTEGRITY,"integrity", "INTEGRITY", }, |
114 | #endif | 114 | #endif |
115 | #ifdef USE_HOSTCC | 115 | #ifdef USE_HOSTCC |
116 | { IH_OS_4_4BSD, "4_4bsd", "4_4BSD", }, | 116 | { IH_OS_4_4BSD, "4_4bsd", "4_4BSD", }, |
117 | { IH_OS_DELL, "dell", "Dell", }, | 117 | { IH_OS_DELL, "dell", "Dell", }, |
118 | { IH_OS_ESIX, "esix", "Esix", }, | 118 | { IH_OS_ESIX, "esix", "Esix", }, |
119 | { IH_OS_FREEBSD, "freebsd", "FreeBSD", }, | 119 | { IH_OS_FREEBSD, "freebsd", "FreeBSD", }, |
120 | { IH_OS_IRIX, "irix", "Irix", }, | 120 | { IH_OS_IRIX, "irix", "Irix", }, |
121 | { IH_OS_NCR, "ncr", "NCR", }, | 121 | { IH_OS_NCR, "ncr", "NCR", }, |
122 | { IH_OS_OPENBSD, "openbsd", "OpenBSD", }, | 122 | { IH_OS_OPENBSD, "openbsd", "OpenBSD", }, |
123 | { IH_OS_PSOS, "psos", "pSOS", }, | 123 | { IH_OS_PSOS, "psos", "pSOS", }, |
124 | { IH_OS_SCO, "sco", "SCO", }, | 124 | { IH_OS_SCO, "sco", "SCO", }, |
125 | { IH_OS_SOLARIS, "solaris", "Solaris", }, | 125 | { IH_OS_SOLARIS, "solaris", "Solaris", }, |
126 | { IH_OS_SVR4, "svr4", "SVR4", }, | 126 | { IH_OS_SVR4, "svr4", "SVR4", }, |
127 | #endif | 127 | #endif |
128 | #if defined(CONFIG_BOOTM_OPENRTOS) || defined(USE_HOSTCC) | 128 | #if defined(CONFIG_BOOTM_OPENRTOS) || defined(USE_HOSTCC) |
129 | { IH_OS_OPENRTOS, "openrtos", "OpenRTOS", }, | 129 | { IH_OS_OPENRTOS, "openrtos", "OpenRTOS", }, |
130 | #endif | 130 | #endif |
131 | 131 | ||
132 | { -1, "", "", }, | 132 | { -1, "", "", }, |
133 | }; | 133 | }; |
134 | 134 | ||
135 | static const table_entry_t uimage_type[] = { | 135 | static const table_entry_t uimage_type[] = { |
136 | { IH_TYPE_AISIMAGE, "aisimage", "Davinci AIS image",}, | 136 | { IH_TYPE_AISIMAGE, "aisimage", "Davinci AIS image",}, |
137 | { IH_TYPE_FILESYSTEM, "filesystem", "Filesystem Image", }, | 137 | { IH_TYPE_FILESYSTEM, "filesystem", "Filesystem Image", }, |
138 | { IH_TYPE_FIRMWARE, "firmware", "Firmware", }, | 138 | { IH_TYPE_FIRMWARE, "firmware", "Firmware", }, |
139 | { IH_TYPE_FLATDT, "flat_dt", "Flat Device Tree", }, | 139 | { IH_TYPE_FLATDT, "flat_dt", "Flat Device Tree", }, |
140 | { IH_TYPE_GPIMAGE, "gpimage", "TI Keystone SPL Image",}, | 140 | { IH_TYPE_GPIMAGE, "gpimage", "TI Keystone SPL Image",}, |
141 | { IH_TYPE_KERNEL, "kernel", "Kernel Image", }, | 141 | { IH_TYPE_KERNEL, "kernel", "Kernel Image", }, |
142 | { IH_TYPE_KERNEL_NOLOAD, "kernel_noload", "Kernel Image (no loading done)", }, | 142 | { IH_TYPE_KERNEL_NOLOAD, "kernel_noload", "Kernel Image (no loading done)", }, |
143 | { IH_TYPE_KWBIMAGE, "kwbimage", "Kirkwood Boot Image",}, | 143 | { IH_TYPE_KWBIMAGE, "kwbimage", "Kirkwood Boot Image",}, |
144 | { IH_TYPE_IMXIMAGE, "imximage", "Freescale i.MX Boot Image",}, | 144 | { IH_TYPE_IMXIMAGE, "imximage", "Freescale i.MX Boot Image",}, |
145 | { IH_TYPE_INVALID, NULL, "Invalid Image", }, | 145 | { IH_TYPE_INVALID, NULL, "Invalid Image", }, |
146 | { IH_TYPE_MULTI, "multi", "Multi-File Image", }, | 146 | { IH_TYPE_MULTI, "multi", "Multi-File Image", }, |
147 | { IH_TYPE_OMAPIMAGE, "omapimage", "TI OMAP SPL With GP CH",}, | 147 | { IH_TYPE_OMAPIMAGE, "omapimage", "TI OMAP SPL With GP CH",}, |
148 | { IH_TYPE_PBLIMAGE, "pblimage", "Freescale PBL Boot Image",}, | 148 | { IH_TYPE_PBLIMAGE, "pblimage", "Freescale PBL Boot Image",}, |
149 | { IH_TYPE_RAMDISK, "ramdisk", "RAMDisk Image", }, | 149 | { IH_TYPE_RAMDISK, "ramdisk", "RAMDisk Image", }, |
150 | { IH_TYPE_SCRIPT, "script", "Script", }, | 150 | { IH_TYPE_SCRIPT, "script", "Script", }, |
151 | { IH_TYPE_SOCFPGAIMAGE, "socfpgaimage", "Altera SOCFPGA preloader",}, | 151 | { IH_TYPE_SOCFPGAIMAGE, "socfpgaimage", "Altera SOCFPGA preloader",}, |
152 | { IH_TYPE_STANDALONE, "standalone", "Standalone Program", }, | 152 | { IH_TYPE_STANDALONE, "standalone", "Standalone Program", }, |
153 | { IH_TYPE_UBLIMAGE, "ublimage", "Davinci UBL image",}, | 153 | { IH_TYPE_UBLIMAGE, "ublimage", "Davinci UBL image",}, |
154 | { IH_TYPE_MXSIMAGE, "mxsimage", "Freescale MXS Boot Image",}, | 154 | { IH_TYPE_MXSIMAGE, "mxsimage", "Freescale MXS Boot Image",}, |
155 | { IH_TYPE_ATMELIMAGE, "atmelimage", "ATMEL ROM-Boot Image",}, | 155 | { IH_TYPE_ATMELIMAGE, "atmelimage", "ATMEL ROM-Boot Image",}, |
156 | { IH_TYPE_X86_SETUP, "x86_setup", "x86 setup.bin", }, | 156 | { IH_TYPE_X86_SETUP, "x86_setup", "x86 setup.bin", }, |
157 | { IH_TYPE_LPC32XXIMAGE, "lpc32xximage", "LPC32XX Boot Image", }, | 157 | { IH_TYPE_LPC32XXIMAGE, "lpc32xximage", "LPC32XX Boot Image", }, |
158 | { -1, "", "", }, | 158 | { -1, "", "", }, |
159 | }; | 159 | }; |
160 | 160 | ||
161 | static const table_entry_t uimage_comp[] = { | 161 | static const table_entry_t uimage_comp[] = { |
162 | { IH_COMP_NONE, "none", "uncompressed", }, | 162 | { IH_COMP_NONE, "none", "uncompressed", }, |
163 | { IH_COMP_BZIP2, "bzip2", "bzip2 compressed", }, | 163 | { IH_COMP_BZIP2, "bzip2", "bzip2 compressed", }, |
164 | { IH_COMP_GZIP, "gzip", "gzip compressed", }, | 164 | { IH_COMP_GZIP, "gzip", "gzip compressed", }, |
165 | { IH_COMP_LZMA, "lzma", "lzma compressed", }, | 165 | { IH_COMP_LZMA, "lzma", "lzma compressed", }, |
166 | { IH_COMP_LZO, "lzo", "lzo compressed", }, | 166 | { IH_COMP_LZO, "lzo", "lzo compressed", }, |
167 | { -1, "", "", }, | 167 | { -1, "", "", }, |
168 | }; | 168 | }; |
169 | 169 | ||
170 | /*****************************************************************************/ | 170 | /*****************************************************************************/ |
171 | /* Legacy format routines */ | 171 | /* Legacy format routines */ |
172 | /*****************************************************************************/ | 172 | /*****************************************************************************/ |
173 | int image_check_hcrc(const image_header_t *hdr) | 173 | int image_check_hcrc(const image_header_t *hdr) |
174 | { | 174 | { |
175 | ulong hcrc; | 175 | ulong hcrc; |
176 | ulong len = image_get_header_size(); | 176 | ulong len = image_get_header_size(); |
177 | image_header_t header; | 177 | image_header_t header; |
178 | 178 | ||
179 | /* Copy header so we can blank CRC field for re-calculation */ | 179 | /* Copy header so we can blank CRC field for re-calculation */ |
180 | memmove(&header, (char *)hdr, image_get_header_size()); | 180 | memmove(&header, (char *)hdr, image_get_header_size()); |
181 | image_set_hcrc(&header, 0); | 181 | image_set_hcrc(&header, 0); |
182 | 182 | ||
183 | hcrc = crc32(0, (unsigned char *)&header, len); | 183 | hcrc = crc32(0, (unsigned char *)&header, len); |
184 | 184 | ||
185 | return (hcrc == image_get_hcrc(hdr)); | 185 | return (hcrc == image_get_hcrc(hdr)); |
186 | } | 186 | } |
187 | 187 | ||
188 | int image_check_dcrc(const image_header_t *hdr) | 188 | int image_check_dcrc(const image_header_t *hdr) |
189 | { | 189 | { |
190 | ulong data = image_get_data(hdr); | 190 | ulong data = image_get_data(hdr); |
191 | ulong len = image_get_data_size(hdr); | 191 | ulong len = image_get_data_size(hdr); |
192 | ulong dcrc = crc32_wd(0, (unsigned char *)data, len, CHUNKSZ_CRC32); | 192 | ulong dcrc = crc32_wd(0, (unsigned char *)data, len, CHUNKSZ_CRC32); |
193 | 193 | ||
194 | return (dcrc == image_get_dcrc(hdr)); | 194 | return (dcrc == image_get_dcrc(hdr)); |
195 | } | 195 | } |
196 | 196 | ||
197 | /** | 197 | /** |
198 | * image_multi_count - get component (sub-image) count | 198 | * image_multi_count - get component (sub-image) count |
199 | * @hdr: pointer to the header of the multi component image | 199 | * @hdr: pointer to the header of the multi component image |
200 | * | 200 | * |
201 | * image_multi_count() returns number of components in a multi | 201 | * image_multi_count() returns number of components in a multi |
202 | * component image. | 202 | * component image. |
203 | * | 203 | * |
204 | * Note: no checking of the image type is done, caller must pass | 204 | * Note: no checking of the image type is done, caller must pass |
205 | * a valid multi component image. | 205 | * a valid multi component image. |
206 | * | 206 | * |
207 | * returns: | 207 | * returns: |
208 | * number of components | 208 | * number of components |
209 | */ | 209 | */ |
210 | ulong image_multi_count(const image_header_t *hdr) | 210 | ulong image_multi_count(const image_header_t *hdr) |
211 | { | 211 | { |
212 | ulong i, count = 0; | 212 | ulong i, count = 0; |
213 | uint32_t *size; | 213 | uint32_t *size; |
214 | 214 | ||
215 | /* get start of the image payload, which in case of multi | 215 | /* get start of the image payload, which in case of multi |
216 | * component images that points to a table of component sizes */ | 216 | * component images that points to a table of component sizes */ |
217 | size = (uint32_t *)image_get_data(hdr); | 217 | size = (uint32_t *)image_get_data(hdr); |
218 | 218 | ||
219 | /* count non empty slots */ | 219 | /* count non empty slots */ |
220 | for (i = 0; size[i]; ++i) | 220 | for (i = 0; size[i]; ++i) |
221 | count++; | 221 | count++; |
222 | 222 | ||
223 | return count; | 223 | return count; |
224 | } | 224 | } |
225 | 225 | ||
226 | /** | 226 | /** |
227 | * image_multi_getimg - get component data address and size | 227 | * image_multi_getimg - get component data address and size |
228 | * @hdr: pointer to the header of the multi component image | 228 | * @hdr: pointer to the header of the multi component image |
229 | * @idx: index of the requested component | 229 | * @idx: index of the requested component |
230 | * @data: pointer to a ulong variable, will hold component data address | 230 | * @data: pointer to a ulong variable, will hold component data address |
231 | * @len: pointer to a ulong variable, will hold component size | 231 | * @len: pointer to a ulong variable, will hold component size |
232 | * | 232 | * |
233 | * image_multi_getimg() returns size and data address for the requested | 233 | * image_multi_getimg() returns size and data address for the requested |
234 | * component in a multi component image. | 234 | * component in a multi component image. |
235 | * | 235 | * |
236 | * Note: no checking of the image type is done, caller must pass | 236 | * Note: no checking of the image type is done, caller must pass |
237 | * a valid multi component image. | 237 | * a valid multi component image. |
238 | * | 238 | * |
239 | * returns: | 239 | * returns: |
240 | * data address and size of the component, if idx is valid | 240 | * data address and size of the component, if idx is valid |
241 | * 0 in data and len, if idx is out of range | 241 | * 0 in data and len, if idx is out of range |
242 | */ | 242 | */ |
243 | void image_multi_getimg(const image_header_t *hdr, ulong idx, | 243 | void image_multi_getimg(const image_header_t *hdr, ulong idx, |
244 | ulong *data, ulong *len) | 244 | ulong *data, ulong *len) |
245 | { | 245 | { |
246 | int i; | 246 | int i; |
247 | uint32_t *size; | 247 | uint32_t *size; |
248 | ulong offset, count, img_data; | 248 | ulong offset, count, img_data; |
249 | 249 | ||
250 | /* get number of component */ | 250 | /* get number of component */ |
251 | count = image_multi_count(hdr); | 251 | count = image_multi_count(hdr); |
252 | 252 | ||
253 | /* get start of the image payload, which in case of multi | 253 | /* get start of the image payload, which in case of multi |
254 | * component images that points to a table of component sizes */ | 254 | * component images that points to a table of component sizes */ |
255 | size = (uint32_t *)image_get_data(hdr); | 255 | size = (uint32_t *)image_get_data(hdr); |
256 | 256 | ||
257 | /* get address of the proper component data start, which means | 257 | /* get address of the proper component data start, which means |
258 | * skipping sizes table (add 1 for last, null entry) */ | 258 | * skipping sizes table (add 1 for last, null entry) */ |
259 | img_data = image_get_data(hdr) + (count + 1) * sizeof(uint32_t); | 259 | img_data = image_get_data(hdr) + (count + 1) * sizeof(uint32_t); |
260 | 260 | ||
261 | if (idx < count) { | 261 | if (idx < count) { |
262 | *len = uimage_to_cpu(size[idx]); | 262 | *len = uimage_to_cpu(size[idx]); |
263 | offset = 0; | 263 | offset = 0; |
264 | 264 | ||
265 | /* go over all indices preceding requested component idx */ | 265 | /* go over all indices preceding requested component idx */ |
266 | for (i = 0; i < idx; i++) { | 266 | for (i = 0; i < idx; i++) { |
267 | /* add up i-th component size, rounding up to 4 bytes */ | 267 | /* add up i-th component size, rounding up to 4 bytes */ |
268 | offset += (uimage_to_cpu(size[i]) + 3) & ~3 ; | 268 | offset += (uimage_to_cpu(size[i]) + 3) & ~3 ; |
269 | } | 269 | } |
270 | 270 | ||
271 | /* calculate idx-th component data address */ | 271 | /* calculate idx-th component data address */ |
272 | *data = img_data + offset; | 272 | *data = img_data + offset; |
273 | } else { | 273 | } else { |
274 | *len = 0; | 274 | *len = 0; |
275 | *data = 0; | 275 | *data = 0; |
276 | } | 276 | } |
277 | } | 277 | } |
278 | 278 | ||
279 | static void image_print_type(const image_header_t *hdr) | 279 | static void image_print_type(const image_header_t *hdr) |
280 | { | 280 | { |
281 | const char __maybe_unused *os, *arch, *type, *comp; | 281 | const char __maybe_unused *os, *arch, *type, *comp; |
282 | 282 | ||
283 | os = genimg_get_os_name(image_get_os(hdr)); | 283 | os = genimg_get_os_name(image_get_os(hdr)); |
284 | arch = genimg_get_arch_name(image_get_arch(hdr)); | 284 | arch = genimg_get_arch_name(image_get_arch(hdr)); |
285 | type = genimg_get_type_name(image_get_type(hdr)); | 285 | type = genimg_get_type_name(image_get_type(hdr)); |
286 | comp = genimg_get_comp_name(image_get_comp(hdr)); | 286 | comp = genimg_get_comp_name(image_get_comp(hdr)); |
287 | 287 | ||
288 | printf("%s %s %s (%s)\n", arch, os, type, comp); | 288 | printf("%s %s %s (%s)\n", arch, os, type, comp); |
289 | } | 289 | } |
290 | 290 | ||
291 | /** | 291 | /** |
292 | * image_print_contents - prints out the contents of the legacy format image | 292 | * image_print_contents - prints out the contents of the legacy format image |
293 | * @ptr: pointer to the legacy format image header | 293 | * @ptr: pointer to the legacy format image header |
294 | * @p: pointer to prefix string | 294 | * @p: pointer to prefix string |
295 | * | 295 | * |
296 | * image_print_contents() formats a multi line legacy image contents description. | 296 | * image_print_contents() formats a multi line legacy image contents description. |
297 | * The routine prints out all header fields followed by the size/offset data | 297 | * The routine prints out all header fields followed by the size/offset data |
298 | * for MULTI/SCRIPT images. | 298 | * for MULTI/SCRIPT images. |
299 | * | 299 | * |
300 | * returns: | 300 | * returns: |
301 | * no returned results | 301 | * no returned results |
302 | */ | 302 | */ |
303 | void image_print_contents(const void *ptr) | 303 | void image_print_contents(const void *ptr) |
304 | { | 304 | { |
305 | const image_header_t *hdr = (const image_header_t *)ptr; | 305 | const image_header_t *hdr = (const image_header_t *)ptr; |
306 | const char __maybe_unused *p; | 306 | const char __maybe_unused *p; |
307 | 307 | ||
308 | p = IMAGE_INDENT_STRING; | 308 | p = IMAGE_INDENT_STRING; |
309 | printf("%sImage Name: %.*s\n", p, IH_NMLEN, image_get_name(hdr)); | 309 | printf("%sImage Name: %.*s\n", p, IH_NMLEN, image_get_name(hdr)); |
310 | if (IMAGE_ENABLE_TIMESTAMP) { | 310 | if (IMAGE_ENABLE_TIMESTAMP) { |
311 | printf("%sCreated: ", p); | 311 | printf("%sCreated: ", p); |
312 | genimg_print_time((time_t)image_get_time(hdr)); | 312 | genimg_print_time((time_t)image_get_time(hdr)); |
313 | } | 313 | } |
314 | printf("%sImage Type: ", p); | 314 | printf("%sImage Type: ", p); |
315 | image_print_type(hdr); | 315 | image_print_type(hdr); |
316 | printf("%sData Size: ", p); | 316 | printf("%sData Size: ", p); |
317 | genimg_print_size(image_get_data_size(hdr)); | 317 | genimg_print_size(image_get_data_size(hdr)); |
318 | printf("%sLoad Address: %08x\n", p, image_get_load(hdr)); | 318 | printf("%sLoad Address: %08x\n", p, image_get_load(hdr)); |
319 | printf("%sEntry Point: %08x\n", p, image_get_ep(hdr)); | 319 | printf("%sEntry Point: %08x\n", p, image_get_ep(hdr)); |
320 | 320 | ||
321 | if (image_check_type(hdr, IH_TYPE_MULTI) || | 321 | if (image_check_type(hdr, IH_TYPE_MULTI) || |
322 | image_check_type(hdr, IH_TYPE_SCRIPT)) { | 322 | image_check_type(hdr, IH_TYPE_SCRIPT)) { |
323 | int i; | 323 | int i; |
324 | ulong data, len; | 324 | ulong data, len; |
325 | ulong count = image_multi_count(hdr); | 325 | ulong count = image_multi_count(hdr); |
326 | 326 | ||
327 | printf("%sContents:\n", p); | 327 | printf("%sContents:\n", p); |
328 | for (i = 0; i < count; i++) { | 328 | for (i = 0; i < count; i++) { |
329 | image_multi_getimg(hdr, i, &data, &len); | 329 | image_multi_getimg(hdr, i, &data, &len); |
330 | 330 | ||
331 | printf("%s Image %d: ", p, i); | 331 | printf("%s Image %d: ", p, i); |
332 | genimg_print_size(len); | 332 | genimg_print_size(len); |
333 | 333 | ||
334 | if (image_check_type(hdr, IH_TYPE_SCRIPT) && i > 0) { | 334 | if (image_check_type(hdr, IH_TYPE_SCRIPT) && i > 0) { |
335 | /* | 335 | /* |
336 | * the user may need to know offsets | 336 | * the user may need to know offsets |
337 | * if planning to do something with | 337 | * if planning to do something with |
338 | * multiple files | 338 | * multiple files |
339 | */ | 339 | */ |
340 | printf("%s Offset = 0x%08lx\n", p, data); | 340 | printf("%s Offset = 0x%08lx\n", p, data); |
341 | } | 341 | } |
342 | } | 342 | } |
343 | } | 343 | } |
344 | } | 344 | } |
345 | 345 | ||
346 | 346 | ||
347 | #ifndef USE_HOSTCC | 347 | #ifndef USE_HOSTCC |
348 | #if defined(CONFIG_IMAGE_FORMAT_LEGACY) | 348 | #if defined(CONFIG_IMAGE_FORMAT_LEGACY) |
349 | /** | 349 | /** |
350 | * image_get_ramdisk - get and verify ramdisk image | 350 | * image_get_ramdisk - get and verify ramdisk image |
351 | * @rd_addr: ramdisk image start address | 351 | * @rd_addr: ramdisk image start address |
352 | * @arch: expected ramdisk architecture | 352 | * @arch: expected ramdisk architecture |
353 | * @verify: checksum verification flag | 353 | * @verify: checksum verification flag |
354 | * | 354 | * |
355 | * image_get_ramdisk() returns a pointer to the verified ramdisk image | 355 | * image_get_ramdisk() returns a pointer to the verified ramdisk image |
356 | * header. Routine receives image start address and expected architecture | 356 | * header. Routine receives image start address and expected architecture |
357 | * flag. Verification done covers data and header integrity and os/type/arch | 357 | * flag. Verification done covers data and header integrity and os/type/arch |
358 | * fields checking. | 358 | * fields checking. |
359 | * | 359 | * |
360 | * If dataflash support is enabled routine checks for dataflash addresses | 360 | * If dataflash support is enabled routine checks for dataflash addresses |
361 | * and handles required dataflash reads. | 361 | * and handles required dataflash reads. |
362 | * | 362 | * |
363 | * returns: | 363 | * returns: |
364 | * pointer to a ramdisk image header, if image was found and valid | 364 | * pointer to a ramdisk image header, if image was found and valid |
365 | * otherwise, return NULL | 365 | * otherwise, return NULL |
366 | */ | 366 | */ |
367 | static const image_header_t *image_get_ramdisk(ulong rd_addr, uint8_t arch, | 367 | static const image_header_t *image_get_ramdisk(ulong rd_addr, uint8_t arch, |
368 | int verify) | 368 | int verify) |
369 | { | 369 | { |
370 | const image_header_t *rd_hdr = (const image_header_t *)rd_addr; | 370 | const image_header_t *rd_hdr = (const image_header_t *)rd_addr; |
371 | 371 | ||
372 | if (!image_check_magic(rd_hdr)) { | 372 | if (!image_check_magic(rd_hdr)) { |
373 | puts("Bad Magic Number\n"); | 373 | puts("Bad Magic Number\n"); |
374 | bootstage_error(BOOTSTAGE_ID_RD_MAGIC); | 374 | bootstage_error(BOOTSTAGE_ID_RD_MAGIC); |
375 | return NULL; | 375 | return NULL; |
376 | } | 376 | } |
377 | 377 | ||
378 | if (!image_check_hcrc(rd_hdr)) { | 378 | if (!image_check_hcrc(rd_hdr)) { |
379 | puts("Bad Header Checksum\n"); | 379 | puts("Bad Header Checksum\n"); |
380 | bootstage_error(BOOTSTAGE_ID_RD_HDR_CHECKSUM); | 380 | bootstage_error(BOOTSTAGE_ID_RD_HDR_CHECKSUM); |
381 | return NULL; | 381 | return NULL; |
382 | } | 382 | } |
383 | 383 | ||
384 | bootstage_mark(BOOTSTAGE_ID_RD_MAGIC); | 384 | bootstage_mark(BOOTSTAGE_ID_RD_MAGIC); |
385 | image_print_contents(rd_hdr); | 385 | image_print_contents(rd_hdr); |
386 | 386 | ||
387 | if (verify) { | 387 | if (verify) { |
388 | puts(" Verifying Checksum ... "); | 388 | puts(" Verifying Checksum ... "); |
389 | if (!image_check_dcrc(rd_hdr)) { | 389 | if (!image_check_dcrc(rd_hdr)) { |
390 | puts("Bad Data CRC\n"); | 390 | puts("Bad Data CRC\n"); |
391 | bootstage_error(BOOTSTAGE_ID_RD_CHECKSUM); | 391 | bootstage_error(BOOTSTAGE_ID_RD_CHECKSUM); |
392 | return NULL; | 392 | return NULL; |
393 | } | 393 | } |
394 | puts("OK\n"); | 394 | puts("OK\n"); |
395 | } | 395 | } |
396 | 396 | ||
397 | bootstage_mark(BOOTSTAGE_ID_RD_HDR_CHECKSUM); | 397 | bootstage_mark(BOOTSTAGE_ID_RD_HDR_CHECKSUM); |
398 | 398 | ||
399 | if (!image_check_os(rd_hdr, IH_OS_LINUX) || | 399 | if (!image_check_os(rd_hdr, IH_OS_LINUX) || |
400 | !image_check_arch(rd_hdr, arch) || | 400 | !image_check_arch(rd_hdr, arch) || |
401 | !image_check_type(rd_hdr, IH_TYPE_RAMDISK)) { | 401 | !image_check_type(rd_hdr, IH_TYPE_RAMDISK)) { |
402 | printf("No Linux %s Ramdisk Image\n", | 402 | printf("No Linux %s Ramdisk Image\n", |
403 | genimg_get_arch_name(arch)); | 403 | genimg_get_arch_name(arch)); |
404 | bootstage_error(BOOTSTAGE_ID_RAMDISK); | 404 | bootstage_error(BOOTSTAGE_ID_RAMDISK); |
405 | return NULL; | 405 | return NULL; |
406 | } | 406 | } |
407 | 407 | ||
408 | return rd_hdr; | 408 | return rd_hdr; |
409 | } | 409 | } |
410 | #endif | 410 | #endif |
411 | #endif /* !USE_HOSTCC */ | 411 | #endif /* !USE_HOSTCC */ |
412 | 412 | ||
413 | /*****************************************************************************/ | 413 | /*****************************************************************************/ |
414 | /* Shared dual-format routines */ | 414 | /* Shared dual-format routines */ |
415 | /*****************************************************************************/ | 415 | /*****************************************************************************/ |
416 | #ifndef USE_HOSTCC | 416 | #ifndef USE_HOSTCC |
417 | ulong load_addr = CONFIG_SYS_LOAD_ADDR; /* Default Load Address */ | 417 | ulong load_addr = CONFIG_SYS_LOAD_ADDR; /* Default Load Address */ |
418 | ulong save_addr; /* Default Save Address */ | 418 | ulong save_addr; /* Default Save Address */ |
419 | ulong save_size; /* Default Save Size (in bytes) */ | 419 | ulong save_size; /* Default Save Size (in bytes) */ |
420 | 420 | ||
421 | static int on_loadaddr(const char *name, const char *value, enum env_op op, | 421 | static int on_loadaddr(const char *name, const char *value, enum env_op op, |
422 | int flags) | 422 | int flags) |
423 | { | 423 | { |
424 | switch (op) { | 424 | switch (op) { |
425 | case env_op_create: | 425 | case env_op_create: |
426 | case env_op_overwrite: | 426 | case env_op_overwrite: |
427 | load_addr = simple_strtoul(value, NULL, 16); | 427 | load_addr = simple_strtoul(value, NULL, 16); |
428 | break; | 428 | break; |
429 | default: | 429 | default: |
430 | break; | 430 | break; |
431 | } | 431 | } |
432 | 432 | ||
433 | return 0; | 433 | return 0; |
434 | } | 434 | } |
435 | U_BOOT_ENV_CALLBACK(loadaddr, on_loadaddr); | 435 | U_BOOT_ENV_CALLBACK(loadaddr, on_loadaddr); |
436 | 436 | ||
437 | ulong getenv_bootm_low(void) | 437 | ulong getenv_bootm_low(void) |
438 | { | 438 | { |
439 | char *s = getenv("bootm_low"); | 439 | char *s = getenv("bootm_low"); |
440 | if (s) { | 440 | if (s) { |
441 | ulong tmp = simple_strtoul(s, NULL, 16); | 441 | ulong tmp = simple_strtoul(s, NULL, 16); |
442 | return tmp; | 442 | return tmp; |
443 | } | 443 | } |
444 | 444 | ||
445 | #if defined(CONFIG_SYS_SDRAM_BASE) | 445 | #if defined(CONFIG_SYS_SDRAM_BASE) |
446 | return CONFIG_SYS_SDRAM_BASE; | 446 | return CONFIG_SYS_SDRAM_BASE; |
447 | #elif defined(CONFIG_ARM) | 447 | #elif defined(CONFIG_ARM) |
448 | return gd->bd->bi_dram[0].start; | 448 | return gd->bd->bi_dram[0].start; |
449 | #else | 449 | #else |
450 | return 0; | 450 | return 0; |
451 | #endif | 451 | #endif |
452 | } | 452 | } |
453 | 453 | ||
454 | phys_size_t getenv_bootm_size(void) | 454 | phys_size_t getenv_bootm_size(void) |
455 | { | 455 | { |
456 | phys_size_t tmp; | 456 | phys_size_t tmp; |
457 | char *s = getenv("bootm_size"); | 457 | char *s = getenv("bootm_size"); |
458 | if (s) { | 458 | if (s) { |
459 | tmp = (phys_size_t)simple_strtoull(s, NULL, 16); | 459 | tmp = (phys_size_t)simple_strtoull(s, NULL, 16); |
460 | return tmp; | 460 | return tmp; |
461 | } | 461 | } |
462 | s = getenv("bootm_low"); | 462 | s = getenv("bootm_low"); |
463 | if (s) | 463 | if (s) |
464 | tmp = (phys_size_t)simple_strtoull(s, NULL, 16); | 464 | tmp = (phys_size_t)simple_strtoull(s, NULL, 16); |
465 | else | 465 | else |
466 | tmp = 0; | 466 | tmp = 0; |
467 | 467 | ||
468 | 468 | ||
469 | #if defined(CONFIG_ARM) && defined(CONFIG_NR_DRAM_BANKS) | 469 | #if defined(CONFIG_ARM) && defined(CONFIG_NR_DRAM_BANKS) |
470 | return gd->bd->bi_dram[0].size - tmp; | 470 | return gd->bd->bi_dram[0].size - tmp; |
471 | #else | 471 | #else |
472 | return gd->bd->bi_memsize - tmp; | 472 | return gd->bd->bi_memsize - tmp; |
473 | #endif | 473 | #endif |
474 | } | 474 | } |
475 | 475 | ||
476 | phys_size_t getenv_bootm_mapsize(void) | 476 | phys_size_t getenv_bootm_mapsize(void) |
477 | { | 477 | { |
478 | phys_size_t tmp; | 478 | phys_size_t tmp; |
479 | char *s = getenv("bootm_mapsize"); | 479 | char *s = getenv("bootm_mapsize"); |
480 | if (s) { | 480 | if (s) { |
481 | tmp = (phys_size_t)simple_strtoull(s, NULL, 16); | 481 | tmp = (phys_size_t)simple_strtoull(s, NULL, 16); |
482 | return tmp; | 482 | return tmp; |
483 | } | 483 | } |
484 | 484 | ||
485 | #if defined(CONFIG_SYS_BOOTMAPSZ) | 485 | #if defined(CONFIG_SYS_BOOTMAPSZ) |
486 | return CONFIG_SYS_BOOTMAPSZ; | 486 | return CONFIG_SYS_BOOTMAPSZ; |
487 | #else | 487 | #else |
488 | return getenv_bootm_size(); | 488 | return getenv_bootm_size(); |
489 | #endif | 489 | #endif |
490 | } | 490 | } |
491 | 491 | ||
492 | void memmove_wd(void *to, void *from, size_t len, ulong chunksz) | 492 | void memmove_wd(void *to, void *from, size_t len, ulong chunksz) |
493 | { | 493 | { |
494 | if (to == from) | 494 | if (to == from) |
495 | return; | 495 | return; |
496 | 496 | ||
497 | #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) | 497 | #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) |
498 | if (to > from) { | 498 | if (to > from) { |
499 | from += len; | 499 | from += len; |
500 | to += len; | 500 | to += len; |
501 | } | 501 | } |
502 | while (len > 0) { | 502 | while (len > 0) { |
503 | size_t tail = (len > chunksz) ? chunksz : len; | 503 | size_t tail = (len > chunksz) ? chunksz : len; |
504 | WATCHDOG_RESET(); | 504 | WATCHDOG_RESET(); |
505 | if (to > from) { | 505 | if (to > from) { |
506 | to -= tail; | 506 | to -= tail; |
507 | from -= tail; | 507 | from -= tail; |
508 | } | 508 | } |
509 | memmove(to, from, tail); | 509 | memmove(to, from, tail); |
510 | if (to < from) { | 510 | if (to < from) { |
511 | to += tail; | 511 | to += tail; |
512 | from += tail; | 512 | from += tail; |
513 | } | 513 | } |
514 | len -= tail; | 514 | len -= tail; |
515 | } | 515 | } |
516 | #else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */ | 516 | #else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */ |
517 | memmove(to, from, len); | 517 | memmove(to, from, len); |
518 | #endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ | 518 | #endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ |
519 | } | 519 | } |
520 | #endif /* !USE_HOSTCC */ | 520 | #endif /* !USE_HOSTCC */ |
521 | 521 | ||
522 | void genimg_print_size(uint32_t size) | 522 | void genimg_print_size(uint32_t size) |
523 | { | 523 | { |
524 | #ifndef USE_HOSTCC | 524 | #ifndef USE_HOSTCC |
525 | printf("%d Bytes = ", size); | 525 | printf("%d Bytes = ", size); |
526 | print_size(size, "\n"); | 526 | print_size(size, "\n"); |
527 | #else | 527 | #else |
528 | printf("%d Bytes = %.2f kB = %.2f MB\n", | 528 | printf("%d Bytes = %.2f kB = %.2f MB\n", |
529 | size, (double)size / 1.024e3, | 529 | size, (double)size / 1.024e3, |
530 | (double)size / 1.048576e6); | 530 | (double)size / 1.048576e6); |
531 | #endif | 531 | #endif |
532 | } | 532 | } |
533 | 533 | ||
534 | #if IMAGE_ENABLE_TIMESTAMP | 534 | #if IMAGE_ENABLE_TIMESTAMP |
535 | void genimg_print_time(time_t timestamp) | 535 | void genimg_print_time(time_t timestamp) |
536 | { | 536 | { |
537 | #ifndef USE_HOSTCC | 537 | #ifndef USE_HOSTCC |
538 | struct rtc_time tm; | 538 | struct rtc_time tm; |
539 | 539 | ||
540 | rtc_to_tm(timestamp, &tm); | 540 | rtc_to_tm(timestamp, &tm); |
541 | printf("%4d-%02d-%02d %2d:%02d:%02d UTC\n", | 541 | printf("%4d-%02d-%02d %2d:%02d:%02d UTC\n", |
542 | tm.tm_year, tm.tm_mon, tm.tm_mday, | 542 | tm.tm_year, tm.tm_mon, tm.tm_mday, |
543 | tm.tm_hour, tm.tm_min, tm.tm_sec); | 543 | tm.tm_hour, tm.tm_min, tm.tm_sec); |
544 | #else | 544 | #else |
545 | printf("%s", ctime(×tamp)); | 545 | printf("%s", ctime(×tamp)); |
546 | #endif | 546 | #endif |
547 | } | 547 | } |
548 | #endif | 548 | #endif |
549 | 549 | ||
550 | const table_entry_t *get_table_entry(const table_entry_t *table, int id) | 550 | const table_entry_t *get_table_entry(const table_entry_t *table, int id) |
551 | { | 551 | { |
552 | for (; table->id >= 0; ++table) { | 552 | for (; table->id >= 0; ++table) { |
553 | if (table->id == id) | 553 | if (table->id == id) |
554 | return table; | 554 | return table; |
555 | } | 555 | } |
556 | return NULL; | 556 | return NULL; |
557 | } | 557 | } |
558 | 558 | ||
559 | /** | 559 | /** |
560 | * get_table_entry_name - translate entry id to long name | 560 | * get_table_entry_name - translate entry id to long name |
561 | * @table: pointer to a translation table for entries of a specific type | 561 | * @table: pointer to a translation table for entries of a specific type |
562 | * @msg: message to be returned when translation fails | 562 | * @msg: message to be returned when translation fails |
563 | * @id: entry id to be translated | 563 | * @id: entry id to be translated |
564 | * | 564 | * |
565 | * get_table_entry_name() will go over translation table trying to find | 565 | * get_table_entry_name() will go over translation table trying to find |
566 | * entry that matches given id. If matching entry is found, its long | 566 | * entry that matches given id. If matching entry is found, its long |
567 | * name is returned to the caller. | 567 | * name is returned to the caller. |
568 | * | 568 | * |
569 | * returns: | 569 | * returns: |
570 | * long entry name if translation succeeds | 570 | * long entry name if translation succeeds |
571 | * msg otherwise | 571 | * msg otherwise |
572 | */ | 572 | */ |
573 | char *get_table_entry_name(const table_entry_t *table, char *msg, int id) | 573 | char *get_table_entry_name(const table_entry_t *table, char *msg, int id) |
574 | { | 574 | { |
575 | table = get_table_entry(table, id); | 575 | table = get_table_entry(table, id); |
576 | if (!table) | 576 | if (!table) |
577 | return msg; | 577 | return msg; |
578 | #if defined(USE_HOSTCC) || !defined(CONFIG_NEEDS_MANUAL_RELOC) | 578 | #if defined(USE_HOSTCC) || !defined(CONFIG_NEEDS_MANUAL_RELOC) |
579 | return table->lname; | 579 | return table->lname; |
580 | #else | 580 | #else |
581 | return table->lname + gd->reloc_off; | 581 | return table->lname + gd->reloc_off; |
582 | #endif | 582 | #endif |
583 | } | 583 | } |
584 | 584 | ||
585 | const char *genimg_get_os_name(uint8_t os) | 585 | const char *genimg_get_os_name(uint8_t os) |
586 | { | 586 | { |
587 | return (get_table_entry_name(uimage_os, "Unknown OS", os)); | 587 | return (get_table_entry_name(uimage_os, "Unknown OS", os)); |
588 | } | 588 | } |
589 | 589 | ||
590 | const char *genimg_get_arch_name(uint8_t arch) | 590 | const char *genimg_get_arch_name(uint8_t arch) |
591 | { | 591 | { |
592 | return (get_table_entry_name(uimage_arch, "Unknown Architecture", | 592 | return (get_table_entry_name(uimage_arch, "Unknown Architecture", |
593 | arch)); | 593 | arch)); |
594 | } | 594 | } |
595 | 595 | ||
596 | const char *genimg_get_type_name(uint8_t type) | 596 | const char *genimg_get_type_name(uint8_t type) |
597 | { | 597 | { |
598 | return (get_table_entry_name(uimage_type, "Unknown Image", type)); | 598 | return (get_table_entry_name(uimage_type, "Unknown Image", type)); |
599 | } | 599 | } |
600 | 600 | ||
601 | const char *genimg_get_type_short_name(uint8_t type) | 601 | const char *genimg_get_type_short_name(uint8_t type) |
602 | { | 602 | { |
603 | const table_entry_t *table; | 603 | const table_entry_t *table; |
604 | 604 | ||
605 | table = get_table_entry(uimage_type, type); | 605 | table = get_table_entry(uimage_type, type); |
606 | if (!table) | 606 | if (!table) |
607 | return "unknown"; | 607 | return "unknown"; |
608 | #if defined(USE_HOSTCC) || !defined(CONFIG_NEEDS_MANUAL_RELOC) | 608 | #if defined(USE_HOSTCC) || !defined(CONFIG_NEEDS_MANUAL_RELOC) |
609 | return table->sname; | 609 | return table->sname; |
610 | #else | 610 | #else |
611 | return table->sname + gd->reloc_off; | 611 | return table->sname + gd->reloc_off; |
612 | #endif | 612 | #endif |
613 | } | 613 | } |
614 | 614 | ||
615 | const char *genimg_get_comp_name(uint8_t comp) | 615 | const char *genimg_get_comp_name(uint8_t comp) |
616 | { | 616 | { |
617 | return (get_table_entry_name(uimage_comp, "Unknown Compression", | 617 | return (get_table_entry_name(uimage_comp, "Unknown Compression", |
618 | comp)); | 618 | comp)); |
619 | } | 619 | } |
620 | 620 | ||
621 | /** | 621 | /** |
622 | * get_table_entry_id - translate short entry name to id | 622 | * get_table_entry_id - translate short entry name to id |
623 | * @table: pointer to a translation table for entries of a specific type | 623 | * @table: pointer to a translation table for entries of a specific type |
624 | * @table_name: to be used in case of error | 624 | * @table_name: to be used in case of error |
625 | * @name: entry short name to be translated | 625 | * @name: entry short name to be translated |
626 | * | 626 | * |
627 | * get_table_entry_id() will go over translation table trying to find | 627 | * get_table_entry_id() will go over translation table trying to find |
628 | * entry that matches given short name. If matching entry is found, | 628 | * entry that matches given short name. If matching entry is found, |
629 | * its id returned to the caller. | 629 | * its id returned to the caller. |
630 | * | 630 | * |
631 | * returns: | 631 | * returns: |
632 | * entry id if translation succeeds | 632 | * entry id if translation succeeds |
633 | * -1 otherwise | 633 | * -1 otherwise |
634 | */ | 634 | */ |
635 | int get_table_entry_id(const table_entry_t *table, | 635 | int get_table_entry_id(const table_entry_t *table, |
636 | const char *table_name, const char *name) | 636 | const char *table_name, const char *name) |
637 | { | 637 | { |
638 | const table_entry_t *t; | 638 | const table_entry_t *t; |
639 | 639 | ||
640 | for (t = table; t->id >= 0; ++t) { | 640 | for (t = table; t->id >= 0; ++t) { |
641 | #ifdef CONFIG_NEEDS_MANUAL_RELOC | 641 | #ifdef CONFIG_NEEDS_MANUAL_RELOC |
642 | if (t->sname && strcasecmp(t->sname + gd->reloc_off, name) == 0) | 642 | if (t->sname && strcasecmp(t->sname + gd->reloc_off, name) == 0) |
643 | #else | 643 | #else |
644 | if (t->sname && strcasecmp(t->sname, name) == 0) | 644 | if (t->sname && strcasecmp(t->sname, name) == 0) |
645 | #endif | 645 | #endif |
646 | return (t->id); | 646 | return (t->id); |
647 | } | 647 | } |
648 | debug("Invalid %s Type: %s\n", table_name, name); | 648 | debug("Invalid %s Type: %s\n", table_name, name); |
649 | 649 | ||
650 | return -1; | 650 | return -1; |
651 | } | 651 | } |
652 | 652 | ||
653 | int genimg_get_os_id(const char *name) | 653 | int genimg_get_os_id(const char *name) |
654 | { | 654 | { |
655 | return (get_table_entry_id(uimage_os, "OS", name)); | 655 | return (get_table_entry_id(uimage_os, "OS", name)); |
656 | } | 656 | } |
657 | 657 | ||
658 | int genimg_get_arch_id(const char *name) | 658 | int genimg_get_arch_id(const char *name) |
659 | { | 659 | { |
660 | return (get_table_entry_id(uimage_arch, "CPU", name)); | 660 | return (get_table_entry_id(uimage_arch, "CPU", name)); |
661 | } | 661 | } |
662 | 662 | ||
663 | int genimg_get_type_id(const char *name) | 663 | int genimg_get_type_id(const char *name) |
664 | { | 664 | { |
665 | return (get_table_entry_id(uimage_type, "Image", name)); | 665 | return (get_table_entry_id(uimage_type, "Image", name)); |
666 | } | 666 | } |
667 | 667 | ||
668 | int genimg_get_comp_id(const char *name) | 668 | int genimg_get_comp_id(const char *name) |
669 | { | 669 | { |
670 | return (get_table_entry_id(uimage_comp, "Compression", name)); | 670 | return (get_table_entry_id(uimage_comp, "Compression", name)); |
671 | } | 671 | } |
672 | 672 | ||
673 | #ifndef USE_HOSTCC | 673 | #ifndef USE_HOSTCC |
674 | /** | 674 | /** |
675 | * genimg_get_kernel_addr_fit - get the real kernel address and return 2 | 675 | * genimg_get_kernel_addr_fit - get the real kernel address and return 2 |
676 | * FIT strings | 676 | * FIT strings |
677 | * @img_addr: a string might contain real image address | 677 | * @img_addr: a string might contain real image address |
678 | * @fit_uname_config: double pointer to a char, will hold pointer to a | 678 | * @fit_uname_config: double pointer to a char, will hold pointer to a |
679 | * configuration unit name | 679 | * configuration unit name |
680 | * @fit_uname_kernel: double pointer to a char, will hold pointer to a subimage | 680 | * @fit_uname_kernel: double pointer to a char, will hold pointer to a subimage |
681 | * name | 681 | * name |
682 | * | 682 | * |
683 | * genimg_get_kernel_addr_fit get the real kernel start address from a string | 683 | * genimg_get_kernel_addr_fit get the real kernel start address from a string |
684 | * which is normally the first argv of bootm/bootz | 684 | * which is normally the first argv of bootm/bootz |
685 | * | 685 | * |
686 | * returns: | 686 | * returns: |
687 | * kernel start address | 687 | * kernel start address |
688 | */ | 688 | */ |
689 | ulong genimg_get_kernel_addr_fit(char * const img_addr, | 689 | ulong genimg_get_kernel_addr_fit(char * const img_addr, |
690 | const char **fit_uname_config, | 690 | const char **fit_uname_config, |
691 | const char **fit_uname_kernel) | 691 | const char **fit_uname_kernel) |
692 | { | 692 | { |
693 | ulong kernel_addr; | 693 | ulong kernel_addr; |
694 | 694 | ||
695 | /* find out kernel image address */ | 695 | /* find out kernel image address */ |
696 | if (!img_addr) { | 696 | if (!img_addr) { |
697 | kernel_addr = load_addr; | 697 | kernel_addr = load_addr; |
698 | debug("* kernel: default image load address = 0x%08lx\n", | 698 | debug("* kernel: default image load address = 0x%08lx\n", |
699 | load_addr); | 699 | load_addr); |
700 | #if defined(CONFIG_FIT) | 700 | #if defined(CONFIG_FIT) |
701 | } else if (fit_parse_conf(img_addr, load_addr, &kernel_addr, | 701 | } else if (fit_parse_conf(img_addr, load_addr, &kernel_addr, |
702 | fit_uname_config)) { | 702 | fit_uname_config)) { |
703 | debug("* kernel: config '%s' from image at 0x%08lx\n", | 703 | debug("* kernel: config '%s' from image at 0x%08lx\n", |
704 | *fit_uname_config, kernel_addr); | 704 | *fit_uname_config, kernel_addr); |
705 | } else if (fit_parse_subimage(img_addr, load_addr, &kernel_addr, | 705 | } else if (fit_parse_subimage(img_addr, load_addr, &kernel_addr, |
706 | fit_uname_kernel)) { | 706 | fit_uname_kernel)) { |
707 | debug("* kernel: subimage '%s' from image at 0x%08lx\n", | 707 | debug("* kernel: subimage '%s' from image at 0x%08lx\n", |
708 | *fit_uname_kernel, kernel_addr); | 708 | *fit_uname_kernel, kernel_addr); |
709 | #endif | 709 | #endif |
710 | } else { | 710 | } else { |
711 | kernel_addr = simple_strtoul(img_addr, NULL, 16); | 711 | kernel_addr = simple_strtoul(img_addr, NULL, 16); |
712 | debug("* kernel: cmdline image address = 0x%08lx\n", | 712 | debug("* kernel: cmdline image address = 0x%08lx\n", |
713 | kernel_addr); | 713 | kernel_addr); |
714 | } | 714 | } |
715 | 715 | ||
716 | return kernel_addr; | 716 | return kernel_addr; |
717 | } | 717 | } |
718 | 718 | ||
719 | /** | 719 | /** |
720 | * genimg_get_kernel_addr() is the simple version of | 720 | * genimg_get_kernel_addr() is the simple version of |
721 | * genimg_get_kernel_addr_fit(). It ignores those return FIT strings | 721 | * genimg_get_kernel_addr_fit(). It ignores those return FIT strings |
722 | */ | 722 | */ |
723 | ulong genimg_get_kernel_addr(char * const img_addr) | 723 | ulong genimg_get_kernel_addr(char * const img_addr) |
724 | { | 724 | { |
725 | const char *fit_uname_config = NULL; | 725 | const char *fit_uname_config = NULL; |
726 | const char *fit_uname_kernel = NULL; | 726 | const char *fit_uname_kernel = NULL; |
727 | 727 | ||
728 | return genimg_get_kernel_addr_fit(img_addr, &fit_uname_config, | 728 | return genimg_get_kernel_addr_fit(img_addr, &fit_uname_config, |
729 | &fit_uname_kernel); | 729 | &fit_uname_kernel); |
730 | } | 730 | } |
731 | 731 | ||
732 | /** | 732 | /** |
733 | * genimg_get_format - get image format type | 733 | * genimg_get_format - get image format type |
734 | * @img_addr: image start address | 734 | * @img_addr: image start address |
735 | * | 735 | * |
736 | * genimg_get_format() checks whether provided address points to a valid | 736 | * genimg_get_format() checks whether provided address points to a valid |
737 | * legacy or FIT image. | 737 | * legacy or FIT image. |
738 | * | 738 | * |
739 | * New uImage format and FDT blob are based on a libfdt. FDT blob | 739 | * New uImage format and FDT blob are based on a libfdt. FDT blob |
740 | * may be passed directly or embedded in a FIT image. In both situations | 740 | * may be passed directly or embedded in a FIT image. In both situations |
741 | * genimg_get_format() must be able to dectect libfdt header. | 741 | * genimg_get_format() must be able to dectect libfdt header. |
742 | * | 742 | * |
743 | * returns: | 743 | * returns: |
744 | * image format type or IMAGE_FORMAT_INVALID if no image is present | 744 | * image format type or IMAGE_FORMAT_INVALID if no image is present |
745 | */ | 745 | */ |
746 | int genimg_get_format(const void *img_addr) | 746 | int genimg_get_format(const void *img_addr) |
747 | { | 747 | { |
748 | #if defined(CONFIG_IMAGE_FORMAT_LEGACY) | 748 | #if defined(CONFIG_IMAGE_FORMAT_LEGACY) |
749 | const image_header_t *hdr; | 749 | const image_header_t *hdr; |
750 | 750 | ||
751 | hdr = (const image_header_t *)img_addr; | 751 | hdr = (const image_header_t *)img_addr; |
752 | if (image_check_magic(hdr)) | 752 | if (image_check_magic(hdr)) |
753 | return IMAGE_FORMAT_LEGACY; | 753 | return IMAGE_FORMAT_LEGACY; |
754 | #endif | 754 | #endif |
755 | #if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT) | 755 | #if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT) |
756 | if (fdt_check_header(img_addr) == 0) | 756 | if (fdt_check_header(img_addr) == 0) |
757 | return IMAGE_FORMAT_FIT; | 757 | return IMAGE_FORMAT_FIT; |
758 | #endif | 758 | #endif |
759 | #ifdef CONFIG_ANDROID_BOOT_IMAGE | 759 | #ifdef CONFIG_ANDROID_BOOT_IMAGE |
760 | if (android_image_check_header(img_addr) == 0) | 760 | if (android_image_check_header(img_addr) == 0) |
761 | return IMAGE_FORMAT_ANDROID; | 761 | return IMAGE_FORMAT_ANDROID; |
762 | #endif | 762 | #endif |
763 | 763 | ||
764 | return IMAGE_FORMAT_INVALID; | 764 | return IMAGE_FORMAT_INVALID; |
765 | } | 765 | } |
766 | 766 | ||
767 | /** | 767 | /** |
768 | * genimg_get_image - get image from special storage (if necessary) | 768 | * genimg_get_image - get image from special storage (if necessary) |
769 | * @img_addr: image start address | 769 | * @img_addr: image start address |
770 | * | 770 | * |
771 | * genimg_get_image() checks if provided image start address is located | 771 | * genimg_get_image() checks if provided image start address is located |
772 | * in a dataflash storage. If so, image is moved to a system RAM memory. | 772 | * in a dataflash storage. If so, image is moved to a system RAM memory. |
773 | * | 773 | * |
774 | * returns: | 774 | * returns: |
775 | * image start address after possible relocation from special storage | 775 | * image start address after possible relocation from special storage |
776 | */ | 776 | */ |
777 | ulong genimg_get_image(ulong img_addr) | 777 | ulong genimg_get_image(ulong img_addr) |
778 | { | 778 | { |
779 | ulong ram_addr = img_addr; | 779 | ulong ram_addr = img_addr; |
780 | 780 | ||
781 | #ifdef CONFIG_HAS_DATAFLASH | 781 | #ifdef CONFIG_HAS_DATAFLASH |
782 | ulong h_size, d_size; | 782 | ulong h_size, d_size; |
783 | 783 | ||
784 | if (addr_dataflash(img_addr)) { | 784 | if (addr_dataflash(img_addr)) { |
785 | void *buf; | 785 | void *buf; |
786 | 786 | ||
787 | /* ger RAM address */ | 787 | /* ger RAM address */ |
788 | ram_addr = CONFIG_SYS_LOAD_ADDR; | 788 | ram_addr = CONFIG_SYS_LOAD_ADDR; |
789 | 789 | ||
790 | /* get header size */ | 790 | /* get header size */ |
791 | h_size = image_get_header_size(); | 791 | h_size = image_get_header_size(); |
792 | #if defined(CONFIG_FIT) | 792 | #if defined(CONFIG_FIT) |
793 | if (sizeof(struct fdt_header) > h_size) | 793 | if (sizeof(struct fdt_header) > h_size) |
794 | h_size = sizeof(struct fdt_header); | 794 | h_size = sizeof(struct fdt_header); |
795 | #endif | 795 | #endif |
796 | 796 | ||
797 | /* read in header */ | 797 | /* read in header */ |
798 | debug(" Reading image header from dataflash address " | 798 | debug(" Reading image header from dataflash address " |
799 | "%08lx to RAM address %08lx\n", img_addr, ram_addr); | 799 | "%08lx to RAM address %08lx\n", img_addr, ram_addr); |
800 | 800 | ||
801 | buf = map_sysmem(ram_addr, 0); | 801 | buf = map_sysmem(ram_addr, 0); |
802 | read_dataflash(img_addr, h_size, buf); | 802 | read_dataflash(img_addr, h_size, buf); |
803 | 803 | ||
804 | /* get data size */ | 804 | /* get data size */ |
805 | switch (genimg_get_format(buf)) { | 805 | switch (genimg_get_format(buf)) { |
806 | #if defined(CONFIG_IMAGE_FORMAT_LEGACY) | 806 | #if defined(CONFIG_IMAGE_FORMAT_LEGACY) |
807 | case IMAGE_FORMAT_LEGACY: | 807 | case IMAGE_FORMAT_LEGACY: |
808 | d_size = image_get_data_size(buf); | 808 | d_size = image_get_data_size(buf); |
809 | debug(" Legacy format image found at 0x%08lx, " | 809 | debug(" Legacy format image found at 0x%08lx, " |
810 | "size 0x%08lx\n", | 810 | "size 0x%08lx\n", |
811 | ram_addr, d_size); | 811 | ram_addr, d_size); |
812 | break; | 812 | break; |
813 | #endif | 813 | #endif |
814 | #if defined(CONFIG_FIT) | 814 | #if defined(CONFIG_FIT) |
815 | case IMAGE_FORMAT_FIT: | 815 | case IMAGE_FORMAT_FIT: |
816 | d_size = fit_get_size(buf) - h_size; | 816 | d_size = fit_get_size(buf) - h_size; |
817 | debug(" FIT/FDT format image found at 0x%08lx, " | 817 | debug(" FIT/FDT format image found at 0x%08lx, " |
818 | "size 0x%08lx\n", | 818 | "size 0x%08lx\n", |
819 | ram_addr, d_size); | 819 | ram_addr, d_size); |
820 | break; | 820 | break; |
821 | #endif | 821 | #endif |
822 | default: | 822 | default: |
823 | printf(" No valid image found at 0x%08lx\n", | 823 | printf(" No valid image found at 0x%08lx\n", |
824 | img_addr); | 824 | img_addr); |
825 | return ram_addr; | 825 | return ram_addr; |
826 | } | 826 | } |
827 | 827 | ||
828 | /* read in image data */ | 828 | /* read in image data */ |
829 | debug(" Reading image remaining data from dataflash address " | 829 | debug(" Reading image remaining data from dataflash address " |
830 | "%08lx to RAM address %08lx\n", img_addr + h_size, | 830 | "%08lx to RAM address %08lx\n", img_addr + h_size, |
831 | ram_addr + h_size); | 831 | ram_addr + h_size); |
832 | 832 | ||
833 | read_dataflash(img_addr + h_size, d_size, | 833 | read_dataflash(img_addr + h_size, d_size, |
834 | (char *)(buf + h_size)); | 834 | (char *)(buf + h_size)); |
835 | 835 | ||
836 | } | 836 | } |
837 | #endif /* CONFIG_HAS_DATAFLASH */ | 837 | #endif /* CONFIG_HAS_DATAFLASH */ |
838 | 838 | ||
839 | return ram_addr; | 839 | return ram_addr; |
840 | } | 840 | } |
841 | 841 | ||
842 | /** | 842 | /** |
843 | * fit_has_config - check if there is a valid FIT configuration | 843 | * fit_has_config - check if there is a valid FIT configuration |
844 | * @images: pointer to the bootm command headers structure | 844 | * @images: pointer to the bootm command headers structure |
845 | * | 845 | * |
846 | * fit_has_config() checks if there is a FIT configuration in use | 846 | * fit_has_config() checks if there is a FIT configuration in use |
847 | * (if FTI support is present). | 847 | * (if FTI support is present). |
848 | * | 848 | * |
849 | * returns: | 849 | * returns: |
850 | * 0, no FIT support or no configuration found | 850 | * 0, no FIT support or no configuration found |
851 | * 1, configuration found | 851 | * 1, configuration found |
852 | */ | 852 | */ |
853 | int genimg_has_config(bootm_headers_t *images) | 853 | int genimg_has_config(bootm_headers_t *images) |
854 | { | 854 | { |
855 | #if defined(CONFIG_FIT) | 855 | #if defined(CONFIG_FIT) |
856 | if (images->fit_uname_cfg) | 856 | if (images->fit_uname_cfg) |
857 | return 1; | 857 | return 1; |
858 | #endif | 858 | #endif |
859 | return 0; | 859 | return 0; |
860 | } | 860 | } |
861 | 861 | ||
862 | /** | 862 | /** |
863 | * boot_get_ramdisk - main ramdisk handling routine | 863 | * boot_get_ramdisk - main ramdisk handling routine |
864 | * @argc: command argument count | 864 | * @argc: command argument count |
865 | * @argv: command argument list | 865 | * @argv: command argument list |
866 | * @images: pointer to the bootm images structure | 866 | * @images: pointer to the bootm images structure |
867 | * @arch: expected ramdisk architecture | 867 | * @arch: expected ramdisk architecture |
868 | * @rd_start: pointer to a ulong variable, will hold ramdisk start address | 868 | * @rd_start: pointer to a ulong variable, will hold ramdisk start address |
869 | * @rd_end: pointer to a ulong variable, will hold ramdisk end | 869 | * @rd_end: pointer to a ulong variable, will hold ramdisk end |
870 | * | 870 | * |
871 | * boot_get_ramdisk() is responsible for finding a valid ramdisk image. | 871 | * boot_get_ramdisk() is responsible for finding a valid ramdisk image. |
872 | * Curently supported are the following ramdisk sources: | 872 | * Curently supported are the following ramdisk sources: |
873 | * - multicomponent kernel/ramdisk image, | 873 | * - multicomponent kernel/ramdisk image, |
874 | * - commandline provided address of decicated ramdisk image. | 874 | * - commandline provided address of decicated ramdisk image. |
875 | * | 875 | * |
876 | * returns: | 876 | * returns: |
877 | * 0, if ramdisk image was found and valid, or skiped | 877 | * 0, if ramdisk image was found and valid, or skiped |
878 | * rd_start and rd_end are set to ramdisk start/end addresses if | 878 | * rd_start and rd_end are set to ramdisk start/end addresses if |
879 | * ramdisk image is found and valid | 879 | * ramdisk image is found and valid |
880 | * | 880 | * |
881 | * 1, if ramdisk image is found but corrupted, or invalid | 881 | * 1, if ramdisk image is found but corrupted, or invalid |
882 | * rd_start and rd_end are set to 0 if no ramdisk exists | 882 | * rd_start and rd_end are set to 0 if no ramdisk exists |
883 | */ | 883 | */ |
884 | int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images, | 884 | int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images, |
885 | uint8_t arch, ulong *rd_start, ulong *rd_end) | 885 | uint8_t arch, ulong *rd_start, ulong *rd_end) |
886 | { | 886 | { |
887 | ulong rd_addr, rd_load; | 887 | ulong rd_addr, rd_load; |
888 | ulong rd_data, rd_len; | 888 | ulong rd_data, rd_len; |
889 | #if defined(CONFIG_IMAGE_FORMAT_LEGACY) | 889 | #if defined(CONFIG_IMAGE_FORMAT_LEGACY) |
890 | const image_header_t *rd_hdr; | 890 | const image_header_t *rd_hdr; |
891 | #endif | 891 | #endif |
892 | void *buf; | 892 | void *buf; |
893 | #ifdef CONFIG_SUPPORT_RAW_INITRD | 893 | #ifdef CONFIG_SUPPORT_RAW_INITRD |
894 | char *end; | 894 | char *end; |
895 | #endif | 895 | #endif |
896 | #if defined(CONFIG_FIT) | 896 | #if defined(CONFIG_FIT) |
897 | const char *fit_uname_config = images->fit_uname_cfg; | 897 | const char *fit_uname_config = images->fit_uname_cfg; |
898 | const char *fit_uname_ramdisk = NULL; | 898 | const char *fit_uname_ramdisk = NULL; |
899 | ulong default_addr; | 899 | ulong default_addr; |
900 | int rd_noffset; | 900 | int rd_noffset; |
901 | #endif | 901 | #endif |
902 | const char *select = NULL; | 902 | const char *select = NULL; |
903 | 903 | ||
904 | *rd_start = 0; | 904 | *rd_start = 0; |
905 | *rd_end = 0; | 905 | *rd_end = 0; |
906 | 906 | ||
907 | if (argc >= 2) | 907 | if (argc >= 2) |
908 | select = argv[1]; | 908 | select = argv[1]; |
909 | |||
909 | /* | 910 | /* |
910 | * Look for a '-' which indicates to ignore the | 911 | * Look for a '-' which indicates to ignore the |
911 | * ramdisk argument | 912 | * ramdisk argument |
912 | */ | 913 | */ |
913 | if (select && strcmp(select, "-") == 0) { | 914 | if (select && strcmp(select, "-") == 0) { |
914 | debug("## Skipping init Ramdisk\n"); | 915 | debug("## Skipping init Ramdisk\n"); |
915 | rd_len = rd_data = 0; | 916 | rd_len = rd_data = 0; |
916 | } else if (select || genimg_has_config(images)) { | 917 | } else if (select || genimg_has_config(images)) { |
917 | #if defined(CONFIG_FIT) | 918 | #if defined(CONFIG_FIT) |
918 | if (select) { | 919 | if (select) { |
919 | /* | 920 | /* |
920 | * If the init ramdisk comes from the FIT image and | 921 | * If the init ramdisk comes from the FIT image and |
921 | * the FIT image address is omitted in the command | 922 | * the FIT image address is omitted in the command |
922 | * line argument, try to use os FIT image address or | 923 | * line argument, try to use os FIT image address or |
923 | * default load address. | 924 | * default load address. |
924 | */ | 925 | */ |
925 | if (images->fit_uname_os) | 926 | if (images->fit_uname_os) |
926 | default_addr = (ulong)images->fit_hdr_os; | 927 | default_addr = (ulong)images->fit_hdr_os; |
927 | else | 928 | else |
928 | default_addr = load_addr; | 929 | default_addr = load_addr; |
929 | 930 | ||
930 | if (fit_parse_conf(select, default_addr, | 931 | if (fit_parse_conf(select, default_addr, |
931 | &rd_addr, &fit_uname_config)) { | 932 | &rd_addr, &fit_uname_config)) { |
932 | debug("* ramdisk: config '%s' from image at " | 933 | debug("* ramdisk: config '%s' from image at " |
933 | "0x%08lx\n", | 934 | "0x%08lx\n", |
934 | fit_uname_config, rd_addr); | 935 | fit_uname_config, rd_addr); |
935 | } else if (fit_parse_subimage(select, default_addr, | 936 | } else if (fit_parse_subimage(select, default_addr, |
936 | &rd_addr, &fit_uname_ramdisk)) { | 937 | &rd_addr, &fit_uname_ramdisk)) { |
937 | debug("* ramdisk: subimage '%s' from image at " | 938 | debug("* ramdisk: subimage '%s' from image at " |
938 | "0x%08lx\n", | 939 | "0x%08lx\n", |
939 | fit_uname_ramdisk, rd_addr); | 940 | fit_uname_ramdisk, rd_addr); |
940 | } else | 941 | } else |
941 | #endif | 942 | #endif |
942 | { | 943 | { |
943 | rd_addr = simple_strtoul(select, NULL, 16); | 944 | rd_addr = simple_strtoul(select, NULL, 16); |
944 | debug("* ramdisk: cmdline image address = " | 945 | debug("* ramdisk: cmdline image address = " |
945 | "0x%08lx\n", | 946 | "0x%08lx\n", |
946 | rd_addr); | 947 | rd_addr); |
947 | } | 948 | } |
948 | #if defined(CONFIG_FIT) | 949 | #if defined(CONFIG_FIT) |
949 | } else { | 950 | } else { |
950 | /* use FIT configuration provided in first bootm | 951 | /* use FIT configuration provided in first bootm |
951 | * command argument. If the property is not defined, | 952 | * command argument. If the property is not defined, |
952 | * quit silently. | 953 | * quit silently. |
953 | */ | 954 | */ |
954 | rd_addr = map_to_sysmem(images->fit_hdr_os); | 955 | rd_addr = map_to_sysmem(images->fit_hdr_os); |
955 | rd_noffset = fit_get_node_from_config(images, | 956 | rd_noffset = fit_get_node_from_config(images, |
956 | FIT_RAMDISK_PROP, rd_addr); | 957 | FIT_RAMDISK_PROP, rd_addr); |
957 | if (rd_noffset == -ENOLINK) | 958 | if (rd_noffset == -ENOLINK) |
958 | return 0; | 959 | return 0; |
959 | else if (rd_noffset < 0) | 960 | else if (rd_noffset < 0) |
960 | return 1; | 961 | return 1; |
961 | } | 962 | } |
962 | #endif | 963 | #endif |
963 | 964 | ||
964 | /* copy from dataflash if needed */ | 965 | /* copy from dataflash if needed */ |
965 | rd_addr = genimg_get_image(rd_addr); | 966 | rd_addr = genimg_get_image(rd_addr); |
966 | 967 | ||
967 | /* | 968 | /* |
968 | * Check if there is an initrd image at the | 969 | * Check if there is an initrd image at the |
969 | * address provided in the second bootm argument | 970 | * address provided in the second bootm argument |
970 | * check image type, for FIT images get FIT node. | 971 | * check image type, for FIT images get FIT node. |
971 | */ | 972 | */ |
972 | buf = map_sysmem(rd_addr, 0); | 973 | buf = map_sysmem(rd_addr, 0); |
973 | switch (genimg_get_format(buf)) { | 974 | switch (genimg_get_format(buf)) { |
974 | #if defined(CONFIG_IMAGE_FORMAT_LEGACY) | 975 | #if defined(CONFIG_IMAGE_FORMAT_LEGACY) |
975 | case IMAGE_FORMAT_LEGACY: | 976 | case IMAGE_FORMAT_LEGACY: |
976 | printf("## Loading init Ramdisk from Legacy " | 977 | printf("## Loading init Ramdisk from Legacy " |
977 | "Image at %08lx ...\n", rd_addr); | 978 | "Image at %08lx ...\n", rd_addr); |
978 | 979 | ||
979 | bootstage_mark(BOOTSTAGE_ID_CHECK_RAMDISK); | 980 | bootstage_mark(BOOTSTAGE_ID_CHECK_RAMDISK); |
980 | rd_hdr = image_get_ramdisk(rd_addr, arch, | 981 | rd_hdr = image_get_ramdisk(rd_addr, arch, |
981 | images->verify); | 982 | images->verify); |
982 | 983 | ||
983 | if (rd_hdr == NULL) | 984 | if (rd_hdr == NULL) |
984 | return 1; | 985 | return 1; |
985 | 986 | ||
986 | rd_data = image_get_data(rd_hdr); | 987 | rd_data = image_get_data(rd_hdr); |
987 | rd_len = image_get_data_size(rd_hdr); | 988 | rd_len = image_get_data_size(rd_hdr); |
988 | rd_load = image_get_load(rd_hdr); | 989 | rd_load = image_get_load(rd_hdr); |
989 | break; | 990 | break; |
990 | #endif | 991 | #endif |
991 | #if defined(CONFIG_FIT) | 992 | #if defined(CONFIG_FIT) |
992 | case IMAGE_FORMAT_FIT: | 993 | case IMAGE_FORMAT_FIT: |
993 | rd_noffset = fit_image_load(images, | 994 | rd_noffset = fit_image_load(images, |
994 | rd_addr, &fit_uname_ramdisk, | 995 | rd_addr, &fit_uname_ramdisk, |
995 | &fit_uname_config, arch, | 996 | &fit_uname_config, arch, |
996 | IH_TYPE_RAMDISK, | 997 | IH_TYPE_RAMDISK, |
997 | BOOTSTAGE_ID_FIT_RD_START, | 998 | BOOTSTAGE_ID_FIT_RD_START, |
998 | FIT_LOAD_OPTIONAL_NON_ZERO, | 999 | FIT_LOAD_OPTIONAL_NON_ZERO, |
999 | &rd_data, &rd_len); | 1000 | &rd_data, &rd_len); |
1000 | if (rd_noffset < 0) | 1001 | if (rd_noffset < 0) |
1001 | return 1; | 1002 | return 1; |
1002 | 1003 | ||
1003 | images->fit_hdr_rd = map_sysmem(rd_addr, 0); | 1004 | images->fit_hdr_rd = map_sysmem(rd_addr, 0); |
1004 | images->fit_uname_rd = fit_uname_ramdisk; | 1005 | images->fit_uname_rd = fit_uname_ramdisk; |
1005 | images->fit_noffset_rd = rd_noffset; | 1006 | images->fit_noffset_rd = rd_noffset; |
1006 | break; | 1007 | break; |
1007 | #endif | 1008 | #endif |
1009 | #ifdef CONFIG_ANDROID_BOOT_IMAGE | ||
1010 | case IMAGE_FORMAT_ANDROID: | ||
1011 | android_image_get_ramdisk((void *)images->os.start, | ||
1012 | &rd_data, &rd_len); | ||
1013 | break; | ||
1014 | #endif | ||
1008 | default: | 1015 | default: |
1009 | #ifdef CONFIG_SUPPORT_RAW_INITRD | 1016 | #ifdef CONFIG_SUPPORT_RAW_INITRD |
1010 | end = NULL; | 1017 | end = NULL; |
1011 | if (select) | 1018 | if (select) |
1012 | end = strchr(select, ':'); | 1019 | end = strchr(select, ':'); |
1013 | if (end) { | 1020 | if (end) { |
1014 | rd_len = simple_strtoul(++end, NULL, 16); | 1021 | rd_len = simple_strtoul(++end, NULL, 16); |
1015 | rd_data = rd_addr; | 1022 | rd_data = rd_addr; |
1016 | } else | 1023 | } else |
1017 | #endif | 1024 | #endif |
1018 | { | 1025 | { |
1019 | puts("Wrong Ramdisk Image Format\n"); | 1026 | puts("Wrong Ramdisk Image Format\n"); |
1020 | rd_data = rd_len = rd_load = 0; | 1027 | rd_data = rd_len = rd_load = 0; |
1021 | return 1; | 1028 | return 1; |
1022 | } | 1029 | } |
1023 | } | 1030 | } |
1024 | } else if (images->legacy_hdr_valid && | 1031 | } else if (images->legacy_hdr_valid && |
1025 | image_check_type(&images->legacy_hdr_os_copy, | 1032 | image_check_type(&images->legacy_hdr_os_copy, |
1026 | IH_TYPE_MULTI)) { | 1033 | IH_TYPE_MULTI)) { |
1027 | 1034 | ||
1028 | /* | 1035 | /* |
1029 | * Now check if we have a legacy mult-component image, | 1036 | * Now check if we have a legacy mult-component image, |
1030 | * get second entry data start address and len. | 1037 | * get second entry data start address and len. |
1031 | */ | 1038 | */ |
1032 | bootstage_mark(BOOTSTAGE_ID_RAMDISK); | 1039 | bootstage_mark(BOOTSTAGE_ID_RAMDISK); |
1033 | printf("## Loading init Ramdisk from multi component " | 1040 | printf("## Loading init Ramdisk from multi component " |
1034 | "Legacy Image at %08lx ...\n", | 1041 | "Legacy Image at %08lx ...\n", |
1035 | (ulong)images->legacy_hdr_os); | 1042 | (ulong)images->legacy_hdr_os); |
1036 | 1043 | ||
1037 | image_multi_getimg(images->legacy_hdr_os, 1, &rd_data, &rd_len); | 1044 | image_multi_getimg(images->legacy_hdr_os, 1, &rd_data, &rd_len); |
1038 | } | 1045 | } else { |
1039 | #ifdef CONFIG_ANDROID_BOOT_IMAGE | ||
1040 | else if ((genimg_get_format((void *)images->os.start) | ||
1041 | == IMAGE_FORMAT_ANDROID) && | ||
1042 | (!android_image_get_ramdisk((void *)images->os.start, | ||
1043 | &rd_data, &rd_len))) { | ||
1044 | /* empty */ | ||
1045 | } | ||
1046 | #endif | ||
1047 | else { | ||
1048 | /* | 1046 | /* |
1049 | * no initrd image | 1047 | * no initrd image |
1050 | */ | 1048 | */ |
1051 | bootstage_mark(BOOTSTAGE_ID_NO_RAMDISK); | 1049 | bootstage_mark(BOOTSTAGE_ID_NO_RAMDISK); |
1052 | rd_len = rd_data = 0; | 1050 | rd_len = rd_data = 0; |
1053 | } | 1051 | } |
1054 | 1052 | ||
1055 | if (!rd_data) { | 1053 | if (!rd_data) { |
1056 | debug("## No init Ramdisk\n"); | 1054 | debug("## No init Ramdisk\n"); |
1057 | } else { | 1055 | } else { |
1058 | *rd_start = rd_data; | 1056 | *rd_start = rd_data; |
1059 | *rd_end = rd_data + rd_len; | 1057 | *rd_end = rd_data + rd_len; |
1060 | } | 1058 | } |
1061 | debug(" ramdisk start = 0x%08lx, ramdisk end = 0x%08lx\n", | 1059 | debug(" ramdisk start = 0x%08lx, ramdisk end = 0x%08lx\n", |
1062 | *rd_start, *rd_end); | 1060 | *rd_start, *rd_end); |
1063 | 1061 | ||
1064 | return 0; | 1062 | return 0; |
1065 | } | 1063 | } |
1066 | 1064 | ||
1067 | #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH | 1065 | #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH |
1068 | /** | 1066 | /** |
1069 | * boot_ramdisk_high - relocate init ramdisk | 1067 | * boot_ramdisk_high - relocate init ramdisk |
1070 | * @lmb: pointer to lmb handle, will be used for memory mgmt | 1068 | * @lmb: pointer to lmb handle, will be used for memory mgmt |
1071 | * @rd_data: ramdisk data start address | 1069 | * @rd_data: ramdisk data start address |
1072 | * @rd_len: ramdisk data length | 1070 | * @rd_len: ramdisk data length |
1073 | * @initrd_start: pointer to a ulong variable, will hold final init ramdisk | 1071 | * @initrd_start: pointer to a ulong variable, will hold final init ramdisk |
1074 | * start address (after possible relocation) | 1072 | * start address (after possible relocation) |
1075 | * @initrd_end: pointer to a ulong variable, will hold final init ramdisk | 1073 | * @initrd_end: pointer to a ulong variable, will hold final init ramdisk |
1076 | * end address (after possible relocation) | 1074 | * end address (after possible relocation) |
1077 | * | 1075 | * |
1078 | * boot_ramdisk_high() takes a relocation hint from "initrd_high" environment | 1076 | * boot_ramdisk_high() takes a relocation hint from "initrd_high" environment |
1079 | * variable and if requested ramdisk data is moved to a specified location. | 1077 | * variable and if requested ramdisk data is moved to a specified location. |
1080 | * | 1078 | * |
1081 | * Initrd_start and initrd_end are set to final (after relocation) ramdisk | 1079 | * Initrd_start and initrd_end are set to final (after relocation) ramdisk |
1082 | * start/end addresses if ramdisk image start and len were provided, | 1080 | * start/end addresses if ramdisk image start and len were provided, |
1083 | * otherwise set initrd_start and initrd_end set to zeros. | 1081 | * otherwise set initrd_start and initrd_end set to zeros. |
1084 | * | 1082 | * |
1085 | * returns: | 1083 | * returns: |
1086 | * 0 - success | 1084 | * 0 - success |
1087 | * -1 - failure | 1085 | * -1 - failure |
1088 | */ | 1086 | */ |
1089 | int boot_ramdisk_high(struct lmb *lmb, ulong rd_data, ulong rd_len, | 1087 | int boot_ramdisk_high(struct lmb *lmb, ulong rd_data, ulong rd_len, |
1090 | ulong *initrd_start, ulong *initrd_end) | 1088 | ulong *initrd_start, ulong *initrd_end) |
1091 | { | 1089 | { |
1092 | char *s; | 1090 | char *s; |
1093 | ulong initrd_high; | 1091 | ulong initrd_high; |
1094 | int initrd_copy_to_ram = 1; | 1092 | int initrd_copy_to_ram = 1; |
1095 | 1093 | ||
1096 | if ((s = getenv("initrd_high")) != NULL) { | 1094 | if ((s = getenv("initrd_high")) != NULL) { |
1097 | /* a value of "no" or a similar string will act like 0, | 1095 | /* a value of "no" or a similar string will act like 0, |
1098 | * turning the "load high" feature off. This is intentional. | 1096 | * turning the "load high" feature off. This is intentional. |
1099 | */ | 1097 | */ |
1100 | initrd_high = simple_strtoul(s, NULL, 16); | 1098 | initrd_high = simple_strtoul(s, NULL, 16); |
1101 | if (initrd_high == ~0) | 1099 | if (initrd_high == ~0) |
1102 | initrd_copy_to_ram = 0; | 1100 | initrd_copy_to_ram = 0; |
1103 | } else { | 1101 | } else { |
1104 | /* not set, no restrictions to load high */ | 1102 | /* not set, no restrictions to load high */ |
1105 | initrd_high = ~0; | 1103 | initrd_high = ~0; |
1106 | } | 1104 | } |
1107 | 1105 | ||
1108 | 1106 | ||
1109 | #ifdef CONFIG_LOGBUFFER | 1107 | #ifdef CONFIG_LOGBUFFER |
1110 | /* Prevent initrd from overwriting logbuffer */ | 1108 | /* Prevent initrd from overwriting logbuffer */ |
1111 | lmb_reserve(lmb, logbuffer_base() - LOGBUFF_OVERHEAD, LOGBUFF_RESERVE); | 1109 | lmb_reserve(lmb, logbuffer_base() - LOGBUFF_OVERHEAD, LOGBUFF_RESERVE); |
1112 | #endif | 1110 | #endif |
1113 | 1111 | ||
1114 | debug("## initrd_high = 0x%08lx, copy_to_ram = %d\n", | 1112 | debug("## initrd_high = 0x%08lx, copy_to_ram = %d\n", |
1115 | initrd_high, initrd_copy_to_ram); | 1113 | initrd_high, initrd_copy_to_ram); |
1116 | 1114 | ||
1117 | if (rd_data) { | 1115 | if (rd_data) { |
1118 | if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */ | 1116 | if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */ |
1119 | debug(" in-place initrd\n"); | 1117 | debug(" in-place initrd\n"); |
1120 | *initrd_start = rd_data; | 1118 | *initrd_start = rd_data; |
1121 | *initrd_end = rd_data + rd_len; | 1119 | *initrd_end = rd_data + rd_len; |
1122 | lmb_reserve(lmb, rd_data, rd_len); | 1120 | lmb_reserve(lmb, rd_data, rd_len); |
1123 | } else { | 1121 | } else { |
1124 | if (initrd_high) | 1122 | if (initrd_high) |
1125 | *initrd_start = (ulong)lmb_alloc_base(lmb, | 1123 | *initrd_start = (ulong)lmb_alloc_base(lmb, |
1126 | rd_len, 0x1000, initrd_high); | 1124 | rd_len, 0x1000, initrd_high); |
1127 | else | 1125 | else |
1128 | *initrd_start = (ulong)lmb_alloc(lmb, rd_len, | 1126 | *initrd_start = (ulong)lmb_alloc(lmb, rd_len, |
1129 | 0x1000); | 1127 | 0x1000); |
1130 | 1128 | ||
1131 | if (*initrd_start == 0) { | 1129 | if (*initrd_start == 0) { |
1132 | puts("ramdisk - allocation error\n"); | 1130 | puts("ramdisk - allocation error\n"); |
1133 | goto error; | 1131 | goto error; |
1134 | } | 1132 | } |
1135 | bootstage_mark(BOOTSTAGE_ID_COPY_RAMDISK); | 1133 | bootstage_mark(BOOTSTAGE_ID_COPY_RAMDISK); |
1136 | 1134 | ||
1137 | *initrd_end = *initrd_start + rd_len; | 1135 | *initrd_end = *initrd_start + rd_len; |
1138 | printf(" Loading Ramdisk to %08lx, end %08lx ... ", | 1136 | printf(" Loading Ramdisk to %08lx, end %08lx ... ", |
1139 | *initrd_start, *initrd_end); | 1137 | *initrd_start, *initrd_end); |
1140 | 1138 | ||
1141 | memmove_wd((void *)*initrd_start, | 1139 | memmove_wd((void *)*initrd_start, |
1142 | (void *)rd_data, rd_len, CHUNKSZ); | 1140 | (void *)rd_data, rd_len, CHUNKSZ); |
1143 | 1141 | ||
1144 | #ifdef CONFIG_MP | 1142 | #ifdef CONFIG_MP |
1145 | /* | 1143 | /* |
1146 | * Ensure the image is flushed to memory to handle | 1144 | * Ensure the image is flushed to memory to handle |
1147 | * AMP boot scenarios in which we might not be | 1145 | * AMP boot scenarios in which we might not be |
1148 | * HW cache coherent | 1146 | * HW cache coherent |
1149 | */ | 1147 | */ |
1150 | flush_cache((unsigned long)*initrd_start, rd_len); | 1148 | flush_cache((unsigned long)*initrd_start, rd_len); |
1151 | #endif | 1149 | #endif |
1152 | puts("OK\n"); | 1150 | puts("OK\n"); |
1153 | } | 1151 | } |
1154 | } else { | 1152 | } else { |
1155 | *initrd_start = 0; | 1153 | *initrd_start = 0; |
1156 | *initrd_end = 0; | 1154 | *initrd_end = 0; |
1157 | } | 1155 | } |
1158 | debug(" ramdisk load start = 0x%08lx, ramdisk load end = 0x%08lx\n", | 1156 | debug(" ramdisk load start = 0x%08lx, ramdisk load end = 0x%08lx\n", |
1159 | *initrd_start, *initrd_end); | 1157 | *initrd_start, *initrd_end); |
1160 | 1158 | ||
1161 | return 0; | 1159 | return 0; |
1162 | 1160 | ||
1163 | error: | 1161 | error: |
1164 | return -1; | 1162 | return -1; |
1165 | } | 1163 | } |
1166 | #endif /* CONFIG_SYS_BOOT_RAMDISK_HIGH */ | 1164 | #endif /* CONFIG_SYS_BOOT_RAMDISK_HIGH */ |
1167 | 1165 | ||
1168 | int boot_get_setup(bootm_headers_t *images, uint8_t arch, | 1166 | int boot_get_setup(bootm_headers_t *images, uint8_t arch, |
1169 | ulong *setup_start, ulong *setup_len) | 1167 | ulong *setup_start, ulong *setup_len) |
1170 | { | 1168 | { |
1171 | #if defined(CONFIG_FIT) | 1169 | #if defined(CONFIG_FIT) |
1172 | return boot_get_setup_fit(images, arch, setup_start, setup_len); | 1170 | return boot_get_setup_fit(images, arch, setup_start, setup_len); |
1173 | #else | 1171 | #else |
1174 | return -ENOENT; | 1172 | return -ENOENT; |
1175 | #endif | 1173 | #endif |
1176 | } | 1174 | } |
1177 | 1175 | ||
1178 | #if defined(CONFIG_FIT) | 1176 | #if defined(CONFIG_FIT) |
1179 | int boot_get_loadable(int argc, char * const argv[], bootm_headers_t *images, | 1177 | int boot_get_loadable(int argc, char * const argv[], bootm_headers_t *images, |
1180 | uint8_t arch, const ulong *ld_start, ulong * const ld_len) | 1178 | uint8_t arch, const ulong *ld_start, ulong * const ld_len) |
1181 | { | 1179 | { |
1182 | /* | 1180 | /* |
1183 | * These variables are used to hold the current image location | 1181 | * These variables are used to hold the current image location |
1184 | * in system memory. | 1182 | * in system memory. |
1185 | */ | 1183 | */ |
1186 | ulong tmp_img_addr; | 1184 | ulong tmp_img_addr; |
1187 | /* | 1185 | /* |
1188 | * These two variables are requirements for fit_image_load, but | 1186 | * These two variables are requirements for fit_image_load, but |
1189 | * their values are not used | 1187 | * their values are not used |
1190 | */ | 1188 | */ |
1191 | ulong img_data, img_len; | 1189 | ulong img_data, img_len; |
1192 | void *buf; | 1190 | void *buf; |
1193 | int loadables_index; | 1191 | int loadables_index; |
1194 | int conf_noffset; | 1192 | int conf_noffset; |
1195 | int fit_img_result; | 1193 | int fit_img_result; |
1196 | char *uname; | 1194 | char *uname; |
1197 | 1195 | ||
1198 | /* Check to see if the images struct has a FIT configuration */ | 1196 | /* Check to see if the images struct has a FIT configuration */ |
1199 | if (!genimg_has_config(images)) { | 1197 | if (!genimg_has_config(images)) { |
1200 | debug("## FIT configuration was not specified\n"); | 1198 | debug("## FIT configuration was not specified\n"); |
1201 | return 0; | 1199 | return 0; |
1202 | } | 1200 | } |
1203 | 1201 | ||
1204 | /* | 1202 | /* |
1205 | * Obtain the os FIT header from the images struct | 1203 | * Obtain the os FIT header from the images struct |
1206 | * copy from dataflash if needed | 1204 | * copy from dataflash if needed |
1207 | */ | 1205 | */ |
1208 | tmp_img_addr = map_to_sysmem(images->fit_hdr_os); | 1206 | tmp_img_addr = map_to_sysmem(images->fit_hdr_os); |
1209 | tmp_img_addr = genimg_get_image(tmp_img_addr); | 1207 | tmp_img_addr = genimg_get_image(tmp_img_addr); |
1210 | buf = map_sysmem(tmp_img_addr, 0); | 1208 | buf = map_sysmem(tmp_img_addr, 0); |
1211 | /* | 1209 | /* |
1212 | * Check image type. For FIT images get FIT node | 1210 | * Check image type. For FIT images get FIT node |
1213 | * and attempt to locate a generic binary. | 1211 | * and attempt to locate a generic binary. |
1214 | */ | 1212 | */ |
1215 | switch (genimg_get_format(buf)) { | 1213 | switch (genimg_get_format(buf)) { |
1216 | case IMAGE_FORMAT_FIT: | 1214 | case IMAGE_FORMAT_FIT: |
1217 | conf_noffset = fit_conf_get_node(buf, images->fit_uname_cfg); | 1215 | conf_noffset = fit_conf_get_node(buf, images->fit_uname_cfg); |
1218 | 1216 | ||
1219 | for (loadables_index = 0; | 1217 | for (loadables_index = 0; |
1220 | !fdt_get_string_index(buf, conf_noffset, | 1218 | !fdt_get_string_index(buf, conf_noffset, |
1221 | FIT_LOADABLE_PROP, | 1219 | FIT_LOADABLE_PROP, |
1222 | loadables_index, | 1220 | loadables_index, |
1223 | (const char **)&uname) > 0; | 1221 | (const char **)&uname) > 0; |
1224 | loadables_index++) | 1222 | loadables_index++) |
1225 | { | 1223 | { |
1226 | fit_img_result = fit_image_load(images, | 1224 | fit_img_result = fit_image_load(images, |
1227 | tmp_img_addr, | 1225 | tmp_img_addr, |
1228 | (const char **)&uname, | 1226 | (const char **)&uname, |
1229 | &(images->fit_uname_cfg), arch, | 1227 | &(images->fit_uname_cfg), arch, |
1230 | IH_TYPE_LOADABLE, | 1228 | IH_TYPE_LOADABLE, |
1231 | BOOTSTAGE_ID_FIT_LOADABLE_START, | 1229 | BOOTSTAGE_ID_FIT_LOADABLE_START, |
1232 | FIT_LOAD_OPTIONAL_NON_ZERO, | 1230 | FIT_LOAD_OPTIONAL_NON_ZERO, |
1233 | &img_data, &img_len); | 1231 | &img_data, &img_len); |
1234 | if (fit_img_result < 0) { | 1232 | if (fit_img_result < 0) { |
1235 | /* Something went wrong! */ | 1233 | /* Something went wrong! */ |
1236 | return fit_img_result; | 1234 | return fit_img_result; |
1237 | } | 1235 | } |
1238 | } | 1236 | } |
1239 | break; | 1237 | break; |
1240 | default: | 1238 | default: |
1241 | printf("The given image format is not supported (corrupt?)\n"); | 1239 | printf("The given image format is not supported (corrupt?)\n"); |
1242 | return 1; | 1240 | return 1; |
1243 | } | 1241 | } |
1244 | 1242 | ||
1245 | return 0; | 1243 | return 0; |
1246 | } | 1244 | } |
1247 | #endif | 1245 | #endif |
1248 | 1246 | ||
1249 | #ifdef CONFIG_SYS_BOOT_GET_CMDLINE | 1247 | #ifdef CONFIG_SYS_BOOT_GET_CMDLINE |
1250 | /** | 1248 | /** |
1251 | * boot_get_cmdline - allocate and initialize kernel cmdline | 1249 | * boot_get_cmdline - allocate and initialize kernel cmdline |
1252 | * @lmb: pointer to lmb handle, will be used for memory mgmt | 1250 | * @lmb: pointer to lmb handle, will be used for memory mgmt |
1253 | * @cmd_start: pointer to a ulong variable, will hold cmdline start | 1251 | * @cmd_start: pointer to a ulong variable, will hold cmdline start |
1254 | * @cmd_end: pointer to a ulong variable, will hold cmdline end | 1252 | * @cmd_end: pointer to a ulong variable, will hold cmdline end |
1255 | * | 1253 | * |
1256 | * boot_get_cmdline() allocates space for kernel command line below | 1254 | * boot_get_cmdline() allocates space for kernel command line below |
1257 | * BOOTMAPSZ + getenv_bootm_low() address. If "bootargs" U-boot environemnt | 1255 | * BOOTMAPSZ + getenv_bootm_low() address. If "bootargs" U-boot environemnt |
1258 | * variable is present its contents is copied to allocated kernel | 1256 | * variable is present its contents is copied to allocated kernel |
1259 | * command line. | 1257 | * command line. |
1260 | * | 1258 | * |
1261 | * returns: | 1259 | * returns: |
1262 | * 0 - success | 1260 | * 0 - success |
1263 | * -1 - failure | 1261 | * -1 - failure |
1264 | */ | 1262 | */ |
1265 | int boot_get_cmdline(struct lmb *lmb, ulong *cmd_start, ulong *cmd_end) | 1263 | int boot_get_cmdline(struct lmb *lmb, ulong *cmd_start, ulong *cmd_end) |
1266 | { | 1264 | { |
1267 | char *cmdline; | 1265 | char *cmdline; |
1268 | char *s; | 1266 | char *s; |
1269 | 1267 | ||
1270 | cmdline = (char *)(ulong)lmb_alloc_base(lmb, CONFIG_SYS_BARGSIZE, 0xf, | 1268 | cmdline = (char *)(ulong)lmb_alloc_base(lmb, CONFIG_SYS_BARGSIZE, 0xf, |
1271 | getenv_bootm_mapsize() + getenv_bootm_low()); | 1269 | getenv_bootm_mapsize() + getenv_bootm_low()); |
1272 | 1270 | ||
1273 | if (cmdline == NULL) | 1271 | if (cmdline == NULL) |
1274 | return -1; | 1272 | return -1; |
1275 | 1273 | ||
1276 | if ((s = getenv("bootargs")) == NULL) | 1274 | if ((s = getenv("bootargs")) == NULL) |
1277 | s = ""; | 1275 | s = ""; |
1278 | 1276 | ||
1279 | strcpy(cmdline, s); | 1277 | strcpy(cmdline, s); |
1280 | 1278 | ||
1281 | *cmd_start = (ulong) & cmdline[0]; | 1279 | *cmd_start = (ulong) & cmdline[0]; |
1282 | *cmd_end = *cmd_start + strlen(cmdline); | 1280 | *cmd_end = *cmd_start + strlen(cmdline); |
1283 | 1281 | ||
1284 | debug("## cmdline at 0x%08lx ... 0x%08lx\n", *cmd_start, *cmd_end); | 1282 | debug("## cmdline at 0x%08lx ... 0x%08lx\n", *cmd_start, *cmd_end); |
1285 | 1283 | ||
1286 | return 0; | 1284 | return 0; |
1287 | } | 1285 | } |
1288 | #endif /* CONFIG_SYS_BOOT_GET_CMDLINE */ | 1286 | #endif /* CONFIG_SYS_BOOT_GET_CMDLINE */ |
1289 | 1287 | ||
1290 | #ifdef CONFIG_SYS_BOOT_GET_KBD | 1288 | #ifdef CONFIG_SYS_BOOT_GET_KBD |
1291 | /** | 1289 | /** |
1292 | * boot_get_kbd - allocate and initialize kernel copy of board info | 1290 | * boot_get_kbd - allocate and initialize kernel copy of board info |
1293 | * @lmb: pointer to lmb handle, will be used for memory mgmt | 1291 | * @lmb: pointer to lmb handle, will be used for memory mgmt |
1294 | * @kbd: double pointer to board info data | 1292 | * @kbd: double pointer to board info data |
1295 | * | 1293 | * |
1296 | * boot_get_kbd() allocates space for kernel copy of board info data below | 1294 | * boot_get_kbd() allocates space for kernel copy of board info data below |
1297 | * BOOTMAPSZ + getenv_bootm_low() address and kernel board info is initialized | 1295 | * BOOTMAPSZ + getenv_bootm_low() address and kernel board info is initialized |
1298 | * with the current u-boot board info data. | 1296 | * with the current u-boot board info data. |
1299 | * | 1297 | * |
1300 | * returns: | 1298 | * returns: |
1301 | * 0 - success | 1299 | * 0 - success |
1302 | * -1 - failure | 1300 | * -1 - failure |
1303 | */ | 1301 | */ |
1304 | int boot_get_kbd(struct lmb *lmb, bd_t **kbd) | 1302 | int boot_get_kbd(struct lmb *lmb, bd_t **kbd) |
1305 | { | 1303 | { |
1306 | *kbd = (bd_t *)(ulong)lmb_alloc_base(lmb, sizeof(bd_t), 0xf, | 1304 | *kbd = (bd_t *)(ulong)lmb_alloc_base(lmb, sizeof(bd_t), 0xf, |
1307 | getenv_bootm_mapsize() + getenv_bootm_low()); | 1305 | getenv_bootm_mapsize() + getenv_bootm_low()); |
1308 | if (*kbd == NULL) | 1306 | if (*kbd == NULL) |
1309 | return -1; | 1307 | return -1; |
1310 | 1308 | ||
1311 | **kbd = *(gd->bd); | 1309 | **kbd = *(gd->bd); |
1312 | 1310 | ||
1313 | debug("## kernel board info at 0x%08lx\n", (ulong)*kbd); | 1311 | debug("## kernel board info at 0x%08lx\n", (ulong)*kbd); |
1314 | 1312 | ||
1315 | #if defined(DEBUG) && defined(CONFIG_CMD_BDI) | 1313 | #if defined(DEBUG) && defined(CONFIG_CMD_BDI) |
1316 | do_bdinfo(NULL, 0, 0, NULL); | 1314 | do_bdinfo(NULL, 0, 0, NULL); |
1317 | #endif | 1315 | #endif |
1318 | 1316 | ||
1319 | return 0; | 1317 | return 0; |
1320 | } | 1318 | } |
1321 | #endif /* CONFIG_SYS_BOOT_GET_KBD */ | 1319 | #endif /* CONFIG_SYS_BOOT_GET_KBD */ |
1322 | 1320 | ||
1323 | #ifdef CONFIG_LMB | 1321 | #ifdef CONFIG_LMB |
1324 | int image_setup_linux(bootm_headers_t *images) | 1322 | int image_setup_linux(bootm_headers_t *images) |
1325 | { | 1323 | { |
1326 | ulong of_size = images->ft_len; | 1324 | ulong of_size = images->ft_len; |
1327 | char **of_flat_tree = &images->ft_addr; | 1325 | char **of_flat_tree = &images->ft_addr; |
1328 | ulong *initrd_start = &images->initrd_start; | 1326 | ulong *initrd_start = &images->initrd_start; |
1329 | ulong *initrd_end = &images->initrd_end; | 1327 | ulong *initrd_end = &images->initrd_end; |
1330 | struct lmb *lmb = &images->lmb; | 1328 | struct lmb *lmb = &images->lmb; |
1331 | ulong rd_len; | 1329 | ulong rd_len; |
1332 | int ret; | 1330 | int ret; |
1333 | 1331 | ||
1334 | if (IMAGE_ENABLE_OF_LIBFDT) | 1332 | if (IMAGE_ENABLE_OF_LIBFDT) |
1335 | boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree); | 1333 | boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree); |
1336 | 1334 | ||
1337 | if (IMAGE_BOOT_GET_CMDLINE) { | 1335 | if (IMAGE_BOOT_GET_CMDLINE) { |
1338 | ret = boot_get_cmdline(lmb, &images->cmdline_start, | 1336 | ret = boot_get_cmdline(lmb, &images->cmdline_start, |
1339 | &images->cmdline_end); | 1337 | &images->cmdline_end); |
1340 | if (ret) { | 1338 | if (ret) { |
1341 | puts("ERROR with allocation of cmdline\n"); | 1339 | puts("ERROR with allocation of cmdline\n"); |
1342 | return ret; | 1340 | return ret; |
1343 | } | 1341 | } |
1344 | } | 1342 | } |
1345 | if (IMAGE_ENABLE_RAMDISK_HIGH) { | 1343 | if (IMAGE_ENABLE_RAMDISK_HIGH) { |
1346 | rd_len = images->rd_end - images->rd_start; | 1344 | rd_len = images->rd_end - images->rd_start; |
1347 | ret = boot_ramdisk_high(lmb, images->rd_start, rd_len, | 1345 | ret = boot_ramdisk_high(lmb, images->rd_start, rd_len, |
1348 | initrd_start, initrd_end); | 1346 | initrd_start, initrd_end); |
1349 | if (ret) | 1347 | if (ret) |
1350 | return ret; | 1348 | return ret; |
1351 | } | 1349 | } |
1352 | 1350 | ||
1353 | if (IMAGE_ENABLE_OF_LIBFDT) { | 1351 | if (IMAGE_ENABLE_OF_LIBFDT) { |
1354 | ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size); | 1352 | ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size); |
1355 | if (ret) | 1353 | if (ret) |
1356 | return ret; | 1354 | return ret; |
1357 | } | 1355 | } |
1358 | 1356 | ||
1359 | if (IMAGE_ENABLE_OF_LIBFDT && of_size) { | 1357 | if (IMAGE_ENABLE_OF_LIBFDT && of_size) { |
1360 | ret = image_setup_libfdt(images, *of_flat_tree, of_size, lmb); | 1358 | ret = image_setup_libfdt(images, *of_flat_tree, of_size, lmb); |
1361 | if (ret) | 1359 | if (ret) |
1362 | return ret; | 1360 | return ret; |
-
mentioned in commit 1fec3c
-
mentioned in commit 1fec3c
-
mentioned in commit 1fec3c
-
mentioned in commit 1fec3c
-
mentioned in commit 1fec3c
-
mentioned in commit 1fec3c
-
mentioned in commit 1fec3c
-
mentioned in commit 1fec3c
-
mentioned in commit 1fec3c
-
mentioned in commit 1fec3c
-
mentioned in commit 1fec3c
-
mentioned in commit 1fec3c
-
mentioned in commit 1fec3c
-
mentioned in commit 1fec3c
-
mentioned in commit 1fec3c
-
mentioned in commit 1fec3c
-
mentioned in commit 1fec3c
-
mentioned in commit 1fec3c
-
mentioned in commit 1fec3c
-
mentioned in commit 1fec3c
-
mentioned in commit 1fec3c
-
mentioned in commit 1fec3c
-
mentioned in commit 1fec3c
-
mentioned in commit 1fec3c
-
mentioned in commit 1fec3c
-
mentioned in commit 1fec3c
-
mentioned in commit 1fec3c
-
mentioned in commit 1fec3c
-
mentioned in commit 1fec3c
-
mentioned in commit 1fec3c
-
mentioned in commit 1fec3c
-
mentioned in commit 1fec3c
-
mentioned in commit 1fec3c
-
mentioned in commit 1fec3c
-
mentioned in commit 1fec3c
-
mentioned in commit 1fec3c