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