Commit fca0cecff73db99d99ad094cca7980472b8a11b5
Committed by
Wolfgang Denk
1 parent
670cbde8da
Exists in
master
and in
54 other branches
bootm: Reduce the unnecessary memmove
Although load address and image start address are same address, bootm command always does memmove. That is unnecessary memmove and can be taken few milliseconds (about 500 msec to 1000 msec). If skip this memmove, we can reduce the boot time. Signed-off-by: Minkyu Kang <mk7.kang@samsung.com>
Showing 1 changed file with 4 additions and 2 deletions Inline Diff
common/cmd_bootm.c
1 | /* | 1 | /* |
2 | * (C) Copyright 2000-2006 | 2 | * (C) Copyright 2000-2006 |
3 | * Wolfgang Denk, DENX Software Engineering, wd@denx.de. | 3 | * Wolfgang Denk, DENX Software Engineering, wd@denx.de. |
4 | * | 4 | * |
5 | * See file CREDITS for list of people who contributed to this | 5 | * See file CREDITS for list of people who contributed to this |
6 | * project. | 6 | * project. |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or | 8 | * This program is free software; you can redistribute it and/or |
9 | * modify it under the terms of the GNU General Public License as | 9 | * modify it under the terms of the GNU General Public License as |
10 | * published by the Free Software Foundation; either version 2 of | 10 | * published by the Free Software Foundation; either version 2 of |
11 | * the License, or (at your option) any later version. | 11 | * the License, or (at your option) any later version. |
12 | * | 12 | * |
13 | * This program is distributed in the hope that it will be useful, | 13 | * This program is distributed in the hope that it will be useful, |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | * GNU General Public License for more details. | 16 | * GNU General Public License for more details. |
17 | * | 17 | * |
18 | * You should have received a copy of the GNU General Public License | 18 | * You should have received a copy of the GNU General Public License |
19 | * along with this program; if not, write to the Free Software | 19 | * along with this program; if not, write to the Free Software |
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
21 | * MA 02111-1307 USA | 21 | * MA 02111-1307 USA |
22 | */ | 22 | */ |
23 | 23 | ||
24 | 24 | ||
25 | /* | 25 | /* |
26 | * Boot support | 26 | * Boot support |
27 | */ | 27 | */ |
28 | #include <common.h> | 28 | #include <common.h> |
29 | #include <watchdog.h> | 29 | #include <watchdog.h> |
30 | #include <command.h> | 30 | #include <command.h> |
31 | #include <image.h> | 31 | #include <image.h> |
32 | #include <malloc.h> | 32 | #include <malloc.h> |
33 | #include <zlib.h> | 33 | #include <zlib.h> |
34 | #include <bzlib.h> | 34 | #include <bzlib.h> |
35 | #include <environment.h> | 35 | #include <environment.h> |
36 | #include <lmb.h> | 36 | #include <lmb.h> |
37 | #include <linux/ctype.h> | 37 | #include <linux/ctype.h> |
38 | #include <asm/byteorder.h> | 38 | #include <asm/byteorder.h> |
39 | 39 | ||
40 | #if defined(CONFIG_CMD_USB) | 40 | #if defined(CONFIG_CMD_USB) |
41 | #include <usb.h> | 41 | #include <usb.h> |
42 | #endif | 42 | #endif |
43 | 43 | ||
44 | #ifdef CONFIG_SYS_HUSH_PARSER | 44 | #ifdef CONFIG_SYS_HUSH_PARSER |
45 | #include <hush.h> | 45 | #include <hush.h> |
46 | #endif | 46 | #endif |
47 | 47 | ||
48 | #if defined(CONFIG_OF_LIBFDT) | 48 | #if defined(CONFIG_OF_LIBFDT) |
49 | #include <fdt.h> | 49 | #include <fdt.h> |
50 | #include <libfdt.h> | 50 | #include <libfdt.h> |
51 | #include <fdt_support.h> | 51 | #include <fdt_support.h> |
52 | #endif | 52 | #endif |
53 | 53 | ||
54 | #ifdef CONFIG_LZMA | 54 | #ifdef CONFIG_LZMA |
55 | #define _7ZIP_BYTE_DEFINED /* Byte already defined by zlib */ | 55 | #define _7ZIP_BYTE_DEFINED /* Byte already defined by zlib */ |
56 | #include <lzma/LzmaTypes.h> | 56 | #include <lzma/LzmaTypes.h> |
57 | #include <lzma/LzmaDecode.h> | 57 | #include <lzma/LzmaDecode.h> |
58 | #include <lzma/LzmaTools.h> | 58 | #include <lzma/LzmaTools.h> |
59 | #endif /* CONFIG_LZMA */ | 59 | #endif /* CONFIG_LZMA */ |
60 | 60 | ||
61 | DECLARE_GLOBAL_DATA_PTR; | 61 | DECLARE_GLOBAL_DATA_PTR; |
62 | 62 | ||
63 | extern int gunzip (void *dst, int dstlen, unsigned char *src, unsigned long *lenp); | 63 | extern int gunzip (void *dst, int dstlen, unsigned char *src, unsigned long *lenp); |
64 | #ifndef CONFIG_SYS_BOOTM_LEN | 64 | #ifndef CONFIG_SYS_BOOTM_LEN |
65 | #define CONFIG_SYS_BOOTM_LEN 0x800000 /* use 8MByte as default max gunzip size */ | 65 | #define CONFIG_SYS_BOOTM_LEN 0x800000 /* use 8MByte as default max gunzip size */ |
66 | #endif | 66 | #endif |
67 | 67 | ||
68 | #ifdef CONFIG_BZIP2 | 68 | #ifdef CONFIG_BZIP2 |
69 | extern void bz_internal_error(int); | 69 | extern void bz_internal_error(int); |
70 | #endif | 70 | #endif |
71 | 71 | ||
72 | #if defined(CONFIG_CMD_IMI) | 72 | #if defined(CONFIG_CMD_IMI) |
73 | static int image_info (unsigned long addr); | 73 | static int image_info (unsigned long addr); |
74 | #endif | 74 | #endif |
75 | 75 | ||
76 | #if defined(CONFIG_CMD_IMLS) | 76 | #if defined(CONFIG_CMD_IMLS) |
77 | #include <flash.h> | 77 | #include <flash.h> |
78 | extern flash_info_t flash_info[]; /* info for FLASH chips */ | 78 | extern flash_info_t flash_info[]; /* info for FLASH chips */ |
79 | static int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); | 79 | static int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); |
80 | #endif | 80 | #endif |
81 | 81 | ||
82 | #ifdef CONFIG_SILENT_CONSOLE | 82 | #ifdef CONFIG_SILENT_CONSOLE |
83 | static void fixup_silent_linux (void); | 83 | static void fixup_silent_linux (void); |
84 | #endif | 84 | #endif |
85 | 85 | ||
86 | static image_header_t *image_get_kernel (ulong img_addr, int verify); | 86 | static image_header_t *image_get_kernel (ulong img_addr, int verify); |
87 | #if defined(CONFIG_FIT) | 87 | #if defined(CONFIG_FIT) |
88 | static int fit_check_kernel (const void *fit, int os_noffset, int verify); | 88 | static int fit_check_kernel (const void *fit, int os_noffset, int verify); |
89 | #endif | 89 | #endif |
90 | 90 | ||
91 | static void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag,int argc, char *argv[], | 91 | static void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag,int argc, char *argv[], |
92 | bootm_headers_t *images, ulong *os_data, ulong *os_len); | 92 | bootm_headers_t *images, ulong *os_data, ulong *os_len); |
93 | extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); | 93 | extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); |
94 | 94 | ||
95 | /* | 95 | /* |
96 | * Continue booting an OS image; caller already has: | 96 | * Continue booting an OS image; caller already has: |
97 | * - copied image header to global variable `header' | 97 | * - copied image header to global variable `header' |
98 | * - checked header magic number, checksums (both header & image), | 98 | * - checked header magic number, checksums (both header & image), |
99 | * - verified image architecture (PPC) and type (KERNEL or MULTI), | 99 | * - verified image architecture (PPC) and type (KERNEL or MULTI), |
100 | * - loaded (first part of) image to header load address, | 100 | * - loaded (first part of) image to header load address, |
101 | * - disabled interrupts. | 101 | * - disabled interrupts. |
102 | */ | 102 | */ |
103 | typedef int boot_os_fn (int flag, int argc, char *argv[], | 103 | typedef int boot_os_fn (int flag, int argc, char *argv[], |
104 | bootm_headers_t *images); /* pointers to os/initrd/fdt */ | 104 | bootm_headers_t *images); /* pointers to os/initrd/fdt */ |
105 | 105 | ||
106 | #define CONFIG_BOOTM_LINUX 1 | 106 | #define CONFIG_BOOTM_LINUX 1 |
107 | #define CONFIG_BOOTM_NETBSD 1 | 107 | #define CONFIG_BOOTM_NETBSD 1 |
108 | #define CONFIG_BOOTM_RTEMS 1 | 108 | #define CONFIG_BOOTM_RTEMS 1 |
109 | 109 | ||
110 | #ifdef CONFIG_BOOTM_LINUX | 110 | #ifdef CONFIG_BOOTM_LINUX |
111 | extern boot_os_fn do_bootm_linux; | 111 | extern boot_os_fn do_bootm_linux; |
112 | #endif | 112 | #endif |
113 | #ifdef CONFIG_BOOTM_NETBSD | 113 | #ifdef CONFIG_BOOTM_NETBSD |
114 | static boot_os_fn do_bootm_netbsd; | 114 | static boot_os_fn do_bootm_netbsd; |
115 | #endif | 115 | #endif |
116 | #if defined(CONFIG_LYNXKDI) | 116 | #if defined(CONFIG_LYNXKDI) |
117 | static boot_os_fn do_bootm_lynxkdi; | 117 | static boot_os_fn do_bootm_lynxkdi; |
118 | extern void lynxkdi_boot (image_header_t *); | 118 | extern void lynxkdi_boot (image_header_t *); |
119 | #endif | 119 | #endif |
120 | #ifdef CONFIG_BOOTM_RTEMS | 120 | #ifdef CONFIG_BOOTM_RTEMS |
121 | static boot_os_fn do_bootm_rtems; | 121 | static boot_os_fn do_bootm_rtems; |
122 | #endif | 122 | #endif |
123 | #if defined(CONFIG_CMD_ELF) | 123 | #if defined(CONFIG_CMD_ELF) |
124 | static boot_os_fn do_bootm_vxworks; | 124 | static boot_os_fn do_bootm_vxworks; |
125 | static boot_os_fn do_bootm_qnxelf; | 125 | static boot_os_fn do_bootm_qnxelf; |
126 | int do_bootvx (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); | 126 | int do_bootvx (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); |
127 | int do_bootelf (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); | 127 | int do_bootelf (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); |
128 | #endif | 128 | #endif |
129 | #if defined(CONFIG_INTEGRITY) | 129 | #if defined(CONFIG_INTEGRITY) |
130 | static boot_os_fn do_bootm_integrity; | 130 | static boot_os_fn do_bootm_integrity; |
131 | #endif | 131 | #endif |
132 | 132 | ||
133 | boot_os_fn * boot_os[] = { | 133 | boot_os_fn * boot_os[] = { |
134 | #ifdef CONFIG_BOOTM_LINUX | 134 | #ifdef CONFIG_BOOTM_LINUX |
135 | [IH_OS_LINUX] = do_bootm_linux, | 135 | [IH_OS_LINUX] = do_bootm_linux, |
136 | #endif | 136 | #endif |
137 | #ifdef CONFIG_BOOTM_NETBSD | 137 | #ifdef CONFIG_BOOTM_NETBSD |
138 | [IH_OS_NETBSD] = do_bootm_netbsd, | 138 | [IH_OS_NETBSD] = do_bootm_netbsd, |
139 | #endif | 139 | #endif |
140 | #ifdef CONFIG_LYNXKDI | 140 | #ifdef CONFIG_LYNXKDI |
141 | [IH_OS_LYNXOS] = do_bootm_lynxkdi, | 141 | [IH_OS_LYNXOS] = do_bootm_lynxkdi, |
142 | #endif | 142 | #endif |
143 | #ifdef CONFIG_BOOTM_RTEMS | 143 | #ifdef CONFIG_BOOTM_RTEMS |
144 | [IH_OS_RTEMS] = do_bootm_rtems, | 144 | [IH_OS_RTEMS] = do_bootm_rtems, |
145 | #endif | 145 | #endif |
146 | #if defined(CONFIG_CMD_ELF) | 146 | #if defined(CONFIG_CMD_ELF) |
147 | [IH_OS_VXWORKS] = do_bootm_vxworks, | 147 | [IH_OS_VXWORKS] = do_bootm_vxworks, |
148 | [IH_OS_QNX] = do_bootm_qnxelf, | 148 | [IH_OS_QNX] = do_bootm_qnxelf, |
149 | #endif | 149 | #endif |
150 | #ifdef CONFIG_INTEGRITY | 150 | #ifdef CONFIG_INTEGRITY |
151 | [IH_OS_INTEGRITY] = do_bootm_integrity, | 151 | [IH_OS_INTEGRITY] = do_bootm_integrity, |
152 | #endif | 152 | #endif |
153 | }; | 153 | }; |
154 | 154 | ||
155 | ulong load_addr = CONFIG_SYS_LOAD_ADDR; /* Default Load Address */ | 155 | ulong load_addr = CONFIG_SYS_LOAD_ADDR; /* Default Load Address */ |
156 | static bootm_headers_t images; /* pointers to os/initrd/fdt images */ | 156 | static bootm_headers_t images; /* pointers to os/initrd/fdt images */ |
157 | 157 | ||
158 | void __board_lmb_reserve(struct lmb *lmb) | 158 | void __board_lmb_reserve(struct lmb *lmb) |
159 | { | 159 | { |
160 | /* please define platform specific board_lmb_reserve() */ | 160 | /* please define platform specific board_lmb_reserve() */ |
161 | } | 161 | } |
162 | void board_lmb_reserve(struct lmb *lmb) __attribute__((weak, alias("__board_lmb_reserve"))); | 162 | void board_lmb_reserve(struct lmb *lmb) __attribute__((weak, alias("__board_lmb_reserve"))); |
163 | 163 | ||
164 | void __arch_lmb_reserve(struct lmb *lmb) | 164 | void __arch_lmb_reserve(struct lmb *lmb) |
165 | { | 165 | { |
166 | /* please define platform specific arch_lmb_reserve() */ | 166 | /* please define platform specific arch_lmb_reserve() */ |
167 | } | 167 | } |
168 | void arch_lmb_reserve(struct lmb *lmb) __attribute__((weak, alias("__arch_lmb_reserve"))); | 168 | void arch_lmb_reserve(struct lmb *lmb) __attribute__((weak, alias("__arch_lmb_reserve"))); |
169 | 169 | ||
170 | #if defined(__ARM__) | 170 | #if defined(__ARM__) |
171 | #define IH_INITRD_ARCH IH_ARCH_ARM | 171 | #define IH_INITRD_ARCH IH_ARCH_ARM |
172 | #elif defined(__avr32__) | 172 | #elif defined(__avr32__) |
173 | #define IH_INITRD_ARCH IH_ARCH_AVR32 | 173 | #define IH_INITRD_ARCH IH_ARCH_AVR32 |
174 | #elif defined(__bfin__) | 174 | #elif defined(__bfin__) |
175 | #define IH_INITRD_ARCH IH_ARCH_BLACKFIN | 175 | #define IH_INITRD_ARCH IH_ARCH_BLACKFIN |
176 | #elif defined(__I386__) | 176 | #elif defined(__I386__) |
177 | #define IH_INITRD_ARCH IH_ARCH_I386 | 177 | #define IH_INITRD_ARCH IH_ARCH_I386 |
178 | #elif defined(__M68K__) | 178 | #elif defined(__M68K__) |
179 | #define IH_INITRD_ARCH IH_ARCH_M68K | 179 | #define IH_INITRD_ARCH IH_ARCH_M68K |
180 | #elif defined(__microblaze__) | 180 | #elif defined(__microblaze__) |
181 | #define IH_INITRD_ARCH IH_ARCH_MICROBLAZE | 181 | #define IH_INITRD_ARCH IH_ARCH_MICROBLAZE |
182 | #elif defined(__mips__) | 182 | #elif defined(__mips__) |
183 | #define IH_INITRD_ARCH IH_ARCH_MIPS | 183 | #define IH_INITRD_ARCH IH_ARCH_MIPS |
184 | #elif defined(__nios__) | 184 | #elif defined(__nios__) |
185 | #define IH_INITRD_ARCH IH_ARCH_NIOS | 185 | #define IH_INITRD_ARCH IH_ARCH_NIOS |
186 | #elif defined(__nios2__) | 186 | #elif defined(__nios2__) |
187 | #define IH_INITRD_ARCH IH_ARCH_NIOS2 | 187 | #define IH_INITRD_ARCH IH_ARCH_NIOS2 |
188 | #elif defined(__PPC__) | 188 | #elif defined(__PPC__) |
189 | #define IH_INITRD_ARCH IH_ARCH_PPC | 189 | #define IH_INITRD_ARCH IH_ARCH_PPC |
190 | #elif defined(__sh__) | 190 | #elif defined(__sh__) |
191 | #define IH_INITRD_ARCH IH_ARCH_SH | 191 | #define IH_INITRD_ARCH IH_ARCH_SH |
192 | #elif defined(__sparc__) | 192 | #elif defined(__sparc__) |
193 | #define IH_INITRD_ARCH IH_ARCH_SPARC | 193 | #define IH_INITRD_ARCH IH_ARCH_SPARC |
194 | #else | 194 | #else |
195 | # error Unknown CPU type | 195 | # error Unknown CPU type |
196 | #endif | 196 | #endif |
197 | 197 | ||
198 | static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | 198 | static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) |
199 | { | 199 | { |
200 | ulong mem_start; | 200 | ulong mem_start; |
201 | phys_size_t mem_size; | 201 | phys_size_t mem_size; |
202 | void *os_hdr; | 202 | void *os_hdr; |
203 | int ret; | 203 | int ret; |
204 | 204 | ||
205 | memset ((void *)&images, 0, sizeof (images)); | 205 | memset ((void *)&images, 0, sizeof (images)); |
206 | images.verify = getenv_yesno ("verify"); | 206 | images.verify = getenv_yesno ("verify"); |
207 | 207 | ||
208 | lmb_init(&images.lmb); | 208 | lmb_init(&images.lmb); |
209 | 209 | ||
210 | mem_start = getenv_bootm_low(); | 210 | mem_start = getenv_bootm_low(); |
211 | mem_size = getenv_bootm_size(); | 211 | mem_size = getenv_bootm_size(); |
212 | 212 | ||
213 | lmb_add(&images.lmb, (phys_addr_t)mem_start, mem_size); | 213 | lmb_add(&images.lmb, (phys_addr_t)mem_start, mem_size); |
214 | 214 | ||
215 | arch_lmb_reserve(&images.lmb); | 215 | arch_lmb_reserve(&images.lmb); |
216 | board_lmb_reserve(&images.lmb); | 216 | board_lmb_reserve(&images.lmb); |
217 | 217 | ||
218 | /* get kernel image header, start address and length */ | 218 | /* get kernel image header, start address and length */ |
219 | os_hdr = boot_get_kernel (cmdtp, flag, argc, argv, | 219 | os_hdr = boot_get_kernel (cmdtp, flag, argc, argv, |
220 | &images, &images.os.image_start, &images.os.image_len); | 220 | &images, &images.os.image_start, &images.os.image_len); |
221 | if (images.os.image_len == 0) { | 221 | if (images.os.image_len == 0) { |
222 | puts ("ERROR: can't get kernel image!\n"); | 222 | puts ("ERROR: can't get kernel image!\n"); |
223 | return 1; | 223 | return 1; |
224 | } | 224 | } |
225 | 225 | ||
226 | /* get image parameters */ | 226 | /* get image parameters */ |
227 | switch (genimg_get_format (os_hdr)) { | 227 | switch (genimg_get_format (os_hdr)) { |
228 | case IMAGE_FORMAT_LEGACY: | 228 | case IMAGE_FORMAT_LEGACY: |
229 | images.os.type = image_get_type (os_hdr); | 229 | images.os.type = image_get_type (os_hdr); |
230 | images.os.comp = image_get_comp (os_hdr); | 230 | images.os.comp = image_get_comp (os_hdr); |
231 | images.os.os = image_get_os (os_hdr); | 231 | images.os.os = image_get_os (os_hdr); |
232 | 232 | ||
233 | images.os.end = image_get_image_end (os_hdr); | 233 | images.os.end = image_get_image_end (os_hdr); |
234 | images.os.load = image_get_load (os_hdr); | 234 | images.os.load = image_get_load (os_hdr); |
235 | break; | 235 | break; |
236 | #if defined(CONFIG_FIT) | 236 | #if defined(CONFIG_FIT) |
237 | case IMAGE_FORMAT_FIT: | 237 | case IMAGE_FORMAT_FIT: |
238 | if (fit_image_get_type (images.fit_hdr_os, | 238 | if (fit_image_get_type (images.fit_hdr_os, |
239 | images.fit_noffset_os, &images.os.type)) { | 239 | images.fit_noffset_os, &images.os.type)) { |
240 | puts ("Can't get image type!\n"); | 240 | puts ("Can't get image type!\n"); |
241 | show_boot_progress (-109); | 241 | show_boot_progress (-109); |
242 | return 1; | 242 | return 1; |
243 | } | 243 | } |
244 | 244 | ||
245 | if (fit_image_get_comp (images.fit_hdr_os, | 245 | if (fit_image_get_comp (images.fit_hdr_os, |
246 | images.fit_noffset_os, &images.os.comp)) { | 246 | images.fit_noffset_os, &images.os.comp)) { |
247 | puts ("Can't get image compression!\n"); | 247 | puts ("Can't get image compression!\n"); |
248 | show_boot_progress (-110); | 248 | show_boot_progress (-110); |
249 | return 1; | 249 | return 1; |
250 | } | 250 | } |
251 | 251 | ||
252 | if (fit_image_get_os (images.fit_hdr_os, | 252 | if (fit_image_get_os (images.fit_hdr_os, |
253 | images.fit_noffset_os, &images.os.os)) { | 253 | images.fit_noffset_os, &images.os.os)) { |
254 | puts ("Can't get image OS!\n"); | 254 | puts ("Can't get image OS!\n"); |
255 | show_boot_progress (-111); | 255 | show_boot_progress (-111); |
256 | return 1; | 256 | return 1; |
257 | } | 257 | } |
258 | 258 | ||
259 | images.os.end = fit_get_end (images.fit_hdr_os); | 259 | images.os.end = fit_get_end (images.fit_hdr_os); |
260 | 260 | ||
261 | if (fit_image_get_load (images.fit_hdr_os, images.fit_noffset_os, | 261 | if (fit_image_get_load (images.fit_hdr_os, images.fit_noffset_os, |
262 | &images.os.load)) { | 262 | &images.os.load)) { |
263 | puts ("Can't get image load address!\n"); | 263 | puts ("Can't get image load address!\n"); |
264 | show_boot_progress (-112); | 264 | show_boot_progress (-112); |
265 | return 1; | 265 | return 1; |
266 | } | 266 | } |
267 | break; | 267 | break; |
268 | #endif | 268 | #endif |
269 | default: | 269 | default: |
270 | puts ("ERROR: unknown image format type!\n"); | 270 | puts ("ERROR: unknown image format type!\n"); |
271 | return 1; | 271 | return 1; |
272 | } | 272 | } |
273 | 273 | ||
274 | /* find kernel entry point */ | 274 | /* find kernel entry point */ |
275 | if (images.legacy_hdr_valid) { | 275 | if (images.legacy_hdr_valid) { |
276 | images.ep = image_get_ep (&images.legacy_hdr_os_copy); | 276 | images.ep = image_get_ep (&images.legacy_hdr_os_copy); |
277 | #if defined(CONFIG_FIT) | 277 | #if defined(CONFIG_FIT) |
278 | } else if (images.fit_uname_os) { | 278 | } else if (images.fit_uname_os) { |
279 | ret = fit_image_get_entry (images.fit_hdr_os, | 279 | ret = fit_image_get_entry (images.fit_hdr_os, |
280 | images.fit_noffset_os, &images.ep); | 280 | images.fit_noffset_os, &images.ep); |
281 | if (ret) { | 281 | if (ret) { |
282 | puts ("Can't get entry point property!\n"); | 282 | puts ("Can't get entry point property!\n"); |
283 | return 1; | 283 | return 1; |
284 | } | 284 | } |
285 | #endif | 285 | #endif |
286 | } else { | 286 | } else { |
287 | puts ("Could not find kernel entry point!\n"); | 287 | puts ("Could not find kernel entry point!\n"); |
288 | return 1; | 288 | return 1; |
289 | } | 289 | } |
290 | 290 | ||
291 | if (images.os.os == IH_OS_LINUX) { | 291 | if (images.os.os == IH_OS_LINUX) { |
292 | /* find ramdisk */ | 292 | /* find ramdisk */ |
293 | ret = boot_get_ramdisk (argc, argv, &images, IH_INITRD_ARCH, | 293 | ret = boot_get_ramdisk (argc, argv, &images, IH_INITRD_ARCH, |
294 | &images.rd_start, &images.rd_end); | 294 | &images.rd_start, &images.rd_end); |
295 | if (ret) { | 295 | if (ret) { |
296 | puts ("Ramdisk image is corrupt or invalid\n"); | 296 | puts ("Ramdisk image is corrupt or invalid\n"); |
297 | return 1; | 297 | return 1; |
298 | } | 298 | } |
299 | 299 | ||
300 | #if defined(CONFIG_OF_LIBFDT) | 300 | #if defined(CONFIG_OF_LIBFDT) |
301 | #if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) | 301 | #if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) |
302 | /* find flattened device tree */ | 302 | /* find flattened device tree */ |
303 | ret = boot_get_fdt (flag, argc, argv, &images, | 303 | ret = boot_get_fdt (flag, argc, argv, &images, |
304 | &images.ft_addr, &images.ft_len); | 304 | &images.ft_addr, &images.ft_len); |
305 | if (ret) { | 305 | if (ret) { |
306 | puts ("Could not find a valid device tree\n"); | 306 | puts ("Could not find a valid device tree\n"); |
307 | return 1; | 307 | return 1; |
308 | } | 308 | } |
309 | 309 | ||
310 | set_working_fdt_addr(images.ft_addr); | 310 | set_working_fdt_addr(images.ft_addr); |
311 | #endif | 311 | #endif |
312 | #endif | 312 | #endif |
313 | } | 313 | } |
314 | 314 | ||
315 | images.os.start = (ulong)os_hdr; | 315 | images.os.start = (ulong)os_hdr; |
316 | images.state = BOOTM_STATE_START; | 316 | images.state = BOOTM_STATE_START; |
317 | 317 | ||
318 | return 0; | 318 | return 0; |
319 | } | 319 | } |
320 | 320 | ||
321 | #define BOOTM_ERR_RESET -1 | 321 | #define BOOTM_ERR_RESET -1 |
322 | #define BOOTM_ERR_OVERLAP -2 | 322 | #define BOOTM_ERR_OVERLAP -2 |
323 | #define BOOTM_ERR_UNIMPLEMENTED -3 | 323 | #define BOOTM_ERR_UNIMPLEMENTED -3 |
324 | static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress) | 324 | static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress) |
325 | { | 325 | { |
326 | uint8_t comp = os.comp; | 326 | uint8_t comp = os.comp; |
327 | ulong load = os.load; | 327 | ulong load = os.load; |
328 | ulong blob_start = os.start; | 328 | ulong blob_start = os.start; |
329 | ulong blob_end = os.end; | 329 | ulong blob_end = os.end; |
330 | ulong image_start = os.image_start; | 330 | ulong image_start = os.image_start; |
331 | ulong image_len = os.image_len; | 331 | ulong image_len = os.image_len; |
332 | uint unc_len = CONFIG_SYS_BOOTM_LEN; | 332 | uint unc_len = CONFIG_SYS_BOOTM_LEN; |
333 | 333 | ||
334 | const char *type_name = genimg_get_type_name (os.type); | 334 | const char *type_name = genimg_get_type_name (os.type); |
335 | 335 | ||
336 | switch (comp) { | 336 | switch (comp) { |
337 | case IH_COMP_NONE: | 337 | case IH_COMP_NONE: |
338 | if (load == blob_start) { | 338 | if (load == blob_start) { |
339 | printf (" XIP %s ... ", type_name); | 339 | printf (" XIP %s ... ", type_name); |
340 | } else { | 340 | } else { |
341 | printf (" Loading %s ... ", type_name); | 341 | printf (" Loading %s ... ", type_name); |
342 | 342 | ||
343 | memmove_wd ((void *)load, | 343 | if (load != image_start) { |
344 | (void *)image_start, image_len, CHUNKSZ); | 344 | memmove_wd ((void *)load, |
345 | (void *)image_start, image_len, CHUNKSZ); | ||
346 | } | ||
345 | } | 347 | } |
346 | *load_end = load + image_len; | 348 | *load_end = load + image_len; |
347 | puts("OK\n"); | 349 | puts("OK\n"); |
348 | break; | 350 | break; |
349 | case IH_COMP_GZIP: | 351 | case IH_COMP_GZIP: |
350 | printf (" Uncompressing %s ... ", type_name); | 352 | printf (" Uncompressing %s ... ", type_name); |
351 | if (gunzip ((void *)load, unc_len, | 353 | if (gunzip ((void *)load, unc_len, |
352 | (uchar *)image_start, &image_len) != 0) { | 354 | (uchar *)image_start, &image_len) != 0) { |
353 | puts ("GUNZIP: uncompress, out-of-mem or overwrite error " | 355 | puts ("GUNZIP: uncompress, out-of-mem or overwrite error " |
354 | "- must RESET board to recover\n"); | 356 | "- must RESET board to recover\n"); |
355 | if (boot_progress) | 357 | if (boot_progress) |
356 | show_boot_progress (-6); | 358 | show_boot_progress (-6); |
357 | return BOOTM_ERR_RESET; | 359 | return BOOTM_ERR_RESET; |
358 | } | 360 | } |
359 | 361 | ||
360 | *load_end = load + image_len; | 362 | *load_end = load + image_len; |
361 | break; | 363 | break; |
362 | #ifdef CONFIG_BZIP2 | 364 | #ifdef CONFIG_BZIP2 |
363 | case IH_COMP_BZIP2: | 365 | case IH_COMP_BZIP2: |
364 | printf (" Uncompressing %s ... ", type_name); | 366 | printf (" Uncompressing %s ... ", type_name); |
365 | /* | 367 | /* |
366 | * If we've got less than 4 MB of malloc() space, | 368 | * If we've got less than 4 MB of malloc() space, |
367 | * use slower decompression algorithm which requires | 369 | * use slower decompression algorithm which requires |
368 | * at most 2300 KB of memory. | 370 | * at most 2300 KB of memory. |
369 | */ | 371 | */ |
370 | int i = BZ2_bzBuffToBuffDecompress ((char*)load, | 372 | int i = BZ2_bzBuffToBuffDecompress ((char*)load, |
371 | &unc_len, (char *)image_start, image_len, | 373 | &unc_len, (char *)image_start, image_len, |
372 | CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0); | 374 | CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0); |
373 | if (i != BZ_OK) { | 375 | if (i != BZ_OK) { |
374 | printf ("BUNZIP2: uncompress or overwrite error %d " | 376 | printf ("BUNZIP2: uncompress or overwrite error %d " |
375 | "- must RESET board to recover\n", i); | 377 | "- must RESET board to recover\n", i); |
376 | if (boot_progress) | 378 | if (boot_progress) |
377 | show_boot_progress (-6); | 379 | show_boot_progress (-6); |
378 | return BOOTM_ERR_RESET; | 380 | return BOOTM_ERR_RESET; |
379 | } | 381 | } |
380 | 382 | ||
381 | *load_end = load + unc_len; | 383 | *load_end = load + unc_len; |
382 | break; | 384 | break; |
383 | #endif /* CONFIG_BZIP2 */ | 385 | #endif /* CONFIG_BZIP2 */ |
384 | #ifdef CONFIG_LZMA | 386 | #ifdef CONFIG_LZMA |
385 | case IH_COMP_LZMA: | 387 | case IH_COMP_LZMA: |
386 | printf (" Uncompressing %s ... ", type_name); | 388 | printf (" Uncompressing %s ... ", type_name); |
387 | 389 | ||
388 | int ret = lzmaBuffToBuffDecompress( | 390 | int ret = lzmaBuffToBuffDecompress( |
389 | (unsigned char *)load, &unc_len, | 391 | (unsigned char *)load, &unc_len, |
390 | (unsigned char *)image_start, image_len); | 392 | (unsigned char *)image_start, image_len); |
391 | if (ret != LZMA_RESULT_OK) { | 393 | if (ret != LZMA_RESULT_OK) { |
392 | printf ("LZMA: uncompress or overwrite error %d " | 394 | printf ("LZMA: uncompress or overwrite error %d " |
393 | "- must RESET board to recover\n", ret); | 395 | "- must RESET board to recover\n", ret); |
394 | show_boot_progress (-6); | 396 | show_boot_progress (-6); |
395 | return BOOTM_ERR_RESET; | 397 | return BOOTM_ERR_RESET; |
396 | } | 398 | } |
397 | *load_end = load + unc_len; | 399 | *load_end = load + unc_len; |
398 | break; | 400 | break; |
399 | #endif /* CONFIG_LZMA */ | 401 | #endif /* CONFIG_LZMA */ |
400 | default: | 402 | default: |
401 | printf ("Unimplemented compression type %d\n", comp); | 403 | printf ("Unimplemented compression type %d\n", comp); |
402 | return BOOTM_ERR_UNIMPLEMENTED; | 404 | return BOOTM_ERR_UNIMPLEMENTED; |
403 | } | 405 | } |
404 | puts ("OK\n"); | 406 | puts ("OK\n"); |
405 | debug (" kernel loaded at 0x%08lx, end = 0x%08lx\n", load, *load_end); | 407 | debug (" kernel loaded at 0x%08lx, end = 0x%08lx\n", load, *load_end); |
406 | if (boot_progress) | 408 | if (boot_progress) |
407 | show_boot_progress (7); | 409 | show_boot_progress (7); |
408 | 410 | ||
409 | if ((load < blob_end) && (*load_end > blob_start)) { | 411 | if ((load < blob_end) && (*load_end > blob_start)) { |
410 | debug ("images.os.start = 0x%lX, images.os.end = 0x%lx\n", blob_start, blob_end); | 412 | debug ("images.os.start = 0x%lX, images.os.end = 0x%lx\n", blob_start, blob_end); |
411 | debug ("images.os.load = 0x%lx, load_end = 0x%lx\n", load, *load_end); | 413 | debug ("images.os.load = 0x%lx, load_end = 0x%lx\n", load, *load_end); |
412 | 414 | ||
413 | return BOOTM_ERR_OVERLAP; | 415 | return BOOTM_ERR_OVERLAP; |
414 | } | 416 | } |
415 | 417 | ||
416 | return 0; | 418 | return 0; |
417 | } | 419 | } |
418 | 420 | ||
419 | /* we overload the cmd field with our state machine info instead of a | 421 | /* we overload the cmd field with our state machine info instead of a |
420 | * function pointer */ | 422 | * function pointer */ |
421 | cmd_tbl_t cmd_bootm_sub[] = { | 423 | cmd_tbl_t cmd_bootm_sub[] = { |
422 | U_BOOT_CMD_MKENT(start, 0, 1, (void *)BOOTM_STATE_START, "", ""), | 424 | U_BOOT_CMD_MKENT(start, 0, 1, (void *)BOOTM_STATE_START, "", ""), |
423 | U_BOOT_CMD_MKENT(loados, 0, 1, (void *)BOOTM_STATE_LOADOS, "", ""), | 425 | U_BOOT_CMD_MKENT(loados, 0, 1, (void *)BOOTM_STATE_LOADOS, "", ""), |
424 | #if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) | 426 | #if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) |
425 | U_BOOT_CMD_MKENT(ramdisk, 0, 1, (void *)BOOTM_STATE_RAMDISK, "", ""), | 427 | U_BOOT_CMD_MKENT(ramdisk, 0, 1, (void *)BOOTM_STATE_RAMDISK, "", ""), |
426 | #endif | 428 | #endif |
427 | #ifdef CONFIG_OF_LIBFDT | 429 | #ifdef CONFIG_OF_LIBFDT |
428 | U_BOOT_CMD_MKENT(fdt, 0, 1, (void *)BOOTM_STATE_FDT, "", ""), | 430 | U_BOOT_CMD_MKENT(fdt, 0, 1, (void *)BOOTM_STATE_FDT, "", ""), |
429 | #endif | 431 | #endif |
430 | U_BOOT_CMD_MKENT(bdt, 0, 1, (void *)BOOTM_STATE_OS_BD_T, "", ""), | 432 | U_BOOT_CMD_MKENT(bdt, 0, 1, (void *)BOOTM_STATE_OS_BD_T, "", ""), |
431 | U_BOOT_CMD_MKENT(cmdline, 0, 1, (void *)BOOTM_STATE_OS_CMDLINE, "", ""), | 433 | U_BOOT_CMD_MKENT(cmdline, 0, 1, (void *)BOOTM_STATE_OS_CMDLINE, "", ""), |
432 | U_BOOT_CMD_MKENT(prep, 0, 1, (void *)BOOTM_STATE_OS_PREP, "", ""), | 434 | U_BOOT_CMD_MKENT(prep, 0, 1, (void *)BOOTM_STATE_OS_PREP, "", ""), |
433 | U_BOOT_CMD_MKENT(go, 0, 1, (void *)BOOTM_STATE_OS_GO, "", ""), | 435 | U_BOOT_CMD_MKENT(go, 0, 1, (void *)BOOTM_STATE_OS_GO, "", ""), |
434 | }; | 436 | }; |
435 | 437 | ||
436 | int do_bootm_subcommand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | 438 | int do_bootm_subcommand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) |
437 | { | 439 | { |
438 | int ret = 0; | 440 | int ret = 0; |
439 | int state; | 441 | int state; |
440 | cmd_tbl_t *c; | 442 | cmd_tbl_t *c; |
441 | boot_os_fn *boot_fn; | 443 | boot_os_fn *boot_fn; |
442 | 444 | ||
443 | c = find_cmd_tbl(argv[1], &cmd_bootm_sub[0], ARRAY_SIZE(cmd_bootm_sub)); | 445 | c = find_cmd_tbl(argv[1], &cmd_bootm_sub[0], ARRAY_SIZE(cmd_bootm_sub)); |
444 | 446 | ||
445 | if (c) { | 447 | if (c) { |
446 | state = (int)c->cmd; | 448 | state = (int)c->cmd; |
447 | 449 | ||
448 | /* treat start special since it resets the state machine */ | 450 | /* treat start special since it resets the state machine */ |
449 | if (state == BOOTM_STATE_START) { | 451 | if (state == BOOTM_STATE_START) { |
450 | argc--; | 452 | argc--; |
451 | argv++; | 453 | argv++; |
452 | return bootm_start(cmdtp, flag, argc, argv); | 454 | return bootm_start(cmdtp, flag, argc, argv); |
453 | } | 455 | } |
454 | } | 456 | } |
455 | /* Unrecognized command */ | 457 | /* Unrecognized command */ |
456 | else { | 458 | else { |
457 | cmd_usage(cmdtp); | 459 | cmd_usage(cmdtp); |
458 | return 1; | 460 | return 1; |
459 | } | 461 | } |
460 | 462 | ||
461 | if (images.state >= state) { | 463 | if (images.state >= state) { |
462 | printf ("Trying to execute a command out of order\n"); | 464 | printf ("Trying to execute a command out of order\n"); |
463 | cmd_usage(cmdtp); | 465 | cmd_usage(cmdtp); |
464 | return 1; | 466 | return 1; |
465 | } | 467 | } |
466 | 468 | ||
467 | images.state |= state; | 469 | images.state |= state; |
468 | boot_fn = boot_os[images.os.os]; | 470 | boot_fn = boot_os[images.os.os]; |
469 | 471 | ||
470 | switch (state) { | 472 | switch (state) { |
471 | ulong load_end; | 473 | ulong load_end; |
472 | case BOOTM_STATE_START: | 474 | case BOOTM_STATE_START: |
473 | /* should never occur */ | 475 | /* should never occur */ |
474 | break; | 476 | break; |
475 | case BOOTM_STATE_LOADOS: | 477 | case BOOTM_STATE_LOADOS: |
476 | ret = bootm_load_os(images.os, &load_end, 0); | 478 | ret = bootm_load_os(images.os, &load_end, 0); |
477 | if (ret) | 479 | if (ret) |
478 | return ret; | 480 | return ret; |
479 | 481 | ||
480 | lmb_reserve(&images.lmb, images.os.load, | 482 | lmb_reserve(&images.lmb, images.os.load, |
481 | (load_end - images.os.load)); | 483 | (load_end - images.os.load)); |
482 | break; | 484 | break; |
483 | #if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) | 485 | #if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) |
484 | case BOOTM_STATE_RAMDISK: | 486 | case BOOTM_STATE_RAMDISK: |
485 | { | 487 | { |
486 | ulong rd_len = images.rd_end - images.rd_start; | 488 | ulong rd_len = images.rd_end - images.rd_start; |
487 | char str[17]; | 489 | char str[17]; |
488 | 490 | ||
489 | ret = boot_ramdisk_high(&images.lmb, images.rd_start, | 491 | ret = boot_ramdisk_high(&images.lmb, images.rd_start, |
490 | rd_len, &images.initrd_start, &images.initrd_end); | 492 | rd_len, &images.initrd_start, &images.initrd_end); |
491 | if (ret) | 493 | if (ret) |
492 | return ret; | 494 | return ret; |
493 | 495 | ||
494 | sprintf(str, "%lx", images.initrd_start); | 496 | sprintf(str, "%lx", images.initrd_start); |
495 | setenv("initrd_start", str); | 497 | setenv("initrd_start", str); |
496 | sprintf(str, "%lx", images.initrd_end); | 498 | sprintf(str, "%lx", images.initrd_end); |
497 | setenv("initrd_end", str); | 499 | setenv("initrd_end", str); |
498 | } | 500 | } |
499 | break; | 501 | break; |
500 | #endif | 502 | #endif |
501 | #ifdef CONFIG_OF_LIBFDT | 503 | #ifdef CONFIG_OF_LIBFDT |
502 | case BOOTM_STATE_FDT: | 504 | case BOOTM_STATE_FDT: |
503 | { | 505 | { |
504 | ulong bootmap_base = getenv_bootm_low(); | 506 | ulong bootmap_base = getenv_bootm_low(); |
505 | ret = boot_relocate_fdt(&images.lmb, bootmap_base, | 507 | ret = boot_relocate_fdt(&images.lmb, bootmap_base, |
506 | &images.ft_addr, &images.ft_len); | 508 | &images.ft_addr, &images.ft_len); |
507 | break; | 509 | break; |
508 | } | 510 | } |
509 | #endif | 511 | #endif |
510 | case BOOTM_STATE_OS_CMDLINE: | 512 | case BOOTM_STATE_OS_CMDLINE: |
511 | ret = boot_fn(BOOTM_STATE_OS_CMDLINE, argc, argv, &images); | 513 | ret = boot_fn(BOOTM_STATE_OS_CMDLINE, argc, argv, &images); |
512 | if (ret) | 514 | if (ret) |
513 | printf ("cmdline subcommand not supported\n"); | 515 | printf ("cmdline subcommand not supported\n"); |
514 | break; | 516 | break; |
515 | case BOOTM_STATE_OS_BD_T: | 517 | case BOOTM_STATE_OS_BD_T: |
516 | ret = boot_fn(BOOTM_STATE_OS_BD_T, argc, argv, &images); | 518 | ret = boot_fn(BOOTM_STATE_OS_BD_T, argc, argv, &images); |
517 | if (ret) | 519 | if (ret) |
518 | printf ("bdt subcommand not supported\n"); | 520 | printf ("bdt subcommand not supported\n"); |
519 | break; | 521 | break; |
520 | case BOOTM_STATE_OS_PREP: | 522 | case BOOTM_STATE_OS_PREP: |
521 | ret = boot_fn(BOOTM_STATE_OS_PREP, argc, argv, &images); | 523 | ret = boot_fn(BOOTM_STATE_OS_PREP, argc, argv, &images); |
522 | if (ret) | 524 | if (ret) |
523 | printf ("prep subcommand not supported\n"); | 525 | printf ("prep subcommand not supported\n"); |
524 | break; | 526 | break; |
525 | case BOOTM_STATE_OS_GO: | 527 | case BOOTM_STATE_OS_GO: |
526 | disable_interrupts(); | 528 | disable_interrupts(); |
527 | boot_fn(BOOTM_STATE_OS_GO, argc, argv, &images); | 529 | boot_fn(BOOTM_STATE_OS_GO, argc, argv, &images); |
528 | break; | 530 | break; |
529 | } | 531 | } |
530 | 532 | ||
531 | return ret; | 533 | return ret; |
532 | } | 534 | } |
533 | 535 | ||
534 | /*******************************************************************/ | 536 | /*******************************************************************/ |
535 | /* bootm - boot application image from image in memory */ | 537 | /* bootm - boot application image from image in memory */ |
536 | /*******************************************************************/ | 538 | /*******************************************************************/ |
537 | static int relocated = 0; | 539 | static int relocated = 0; |
538 | 540 | ||
539 | int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | 541 | int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) |
540 | { | 542 | { |
541 | ulong iflag; | 543 | ulong iflag; |
542 | ulong load_end = 0; | 544 | ulong load_end = 0; |
543 | int ret; | 545 | int ret; |
544 | boot_os_fn *boot_fn; | 546 | boot_os_fn *boot_fn; |
545 | 547 | ||
546 | /* relocate boot function table */ | 548 | /* relocate boot function table */ |
547 | if (!relocated) { | 549 | if (!relocated) { |
548 | int i; | 550 | int i; |
549 | for (i = 0; i < ARRAY_SIZE(boot_os); i++) | 551 | for (i = 0; i < ARRAY_SIZE(boot_os); i++) |
550 | boot_os[i] += gd->reloc_off; | 552 | boot_os[i] += gd->reloc_off; |
551 | relocated = 1; | 553 | relocated = 1; |
552 | } | 554 | } |
553 | 555 | ||
554 | /* determine if we have a sub command */ | 556 | /* determine if we have a sub command */ |
555 | if (argc > 1) { | 557 | if (argc > 1) { |
556 | char *endp; | 558 | char *endp; |
557 | 559 | ||
558 | simple_strtoul(argv[1], &endp, 16); | 560 | simple_strtoul(argv[1], &endp, 16); |
559 | /* endp pointing to NULL means that argv[1] was just a | 561 | /* endp pointing to NULL means that argv[1] was just a |
560 | * valid number, pass it along to the normal bootm processing | 562 | * valid number, pass it along to the normal bootm processing |
561 | * | 563 | * |
562 | * If endp is ':' or '#' assume a FIT identifier so pass | 564 | * If endp is ':' or '#' assume a FIT identifier so pass |
563 | * along for normal processing. | 565 | * along for normal processing. |
564 | * | 566 | * |
565 | * Right now we assume the first arg should never be '-' | 567 | * Right now we assume the first arg should never be '-' |
566 | */ | 568 | */ |
567 | if ((*endp != 0) && (*endp != ':') && (*endp != '#')) | 569 | if ((*endp != 0) && (*endp != ':') && (*endp != '#')) |
568 | return do_bootm_subcommand(cmdtp, flag, argc, argv); | 570 | return do_bootm_subcommand(cmdtp, flag, argc, argv); |
569 | } | 571 | } |
570 | 572 | ||
571 | if (bootm_start(cmdtp, flag, argc, argv)) | 573 | if (bootm_start(cmdtp, flag, argc, argv)) |
572 | return 1; | 574 | return 1; |
573 | 575 | ||
574 | /* | 576 | /* |
575 | * We have reached the point of no return: we are going to | 577 | * We have reached the point of no return: we are going to |
576 | * overwrite all exception vector code, so we cannot easily | 578 | * overwrite all exception vector code, so we cannot easily |
577 | * recover from any failures any more... | 579 | * recover from any failures any more... |
578 | */ | 580 | */ |
579 | iflag = disable_interrupts(); | 581 | iflag = disable_interrupts(); |
580 | 582 | ||
581 | #if defined(CONFIG_CMD_USB) | 583 | #if defined(CONFIG_CMD_USB) |
582 | /* | 584 | /* |
583 | * turn off USB to prevent the host controller from writing to the | 585 | * turn off USB to prevent the host controller from writing to the |
584 | * SDRAM while Linux is booting. This could happen (at least for OHCI | 586 | * SDRAM while Linux is booting. This could happen (at least for OHCI |
585 | * controller), because the HCCA (Host Controller Communication Area) | 587 | * controller), because the HCCA (Host Controller Communication Area) |
586 | * lies within the SDRAM and the host controller writes continously to | 588 | * lies within the SDRAM and the host controller writes continously to |
587 | * this area (as busmaster!). The HccaFrameNumber is for example | 589 | * this area (as busmaster!). The HccaFrameNumber is for example |
588 | * updated every 1 ms within the HCCA structure in SDRAM! For more | 590 | * updated every 1 ms within the HCCA structure in SDRAM! For more |
589 | * details see the OpenHCI specification. | 591 | * details see the OpenHCI specification. |
590 | */ | 592 | */ |
591 | usb_stop(); | 593 | usb_stop(); |
592 | #endif | 594 | #endif |
593 | 595 | ||
594 | #ifdef CONFIG_AMIGAONEG3SE | 596 | #ifdef CONFIG_AMIGAONEG3SE |
595 | /* | 597 | /* |
596 | * We've possible left the caches enabled during | 598 | * We've possible left the caches enabled during |
597 | * bios emulation, so turn them off again | 599 | * bios emulation, so turn them off again |
598 | */ | 600 | */ |
599 | icache_disable(); | 601 | icache_disable(); |
600 | dcache_disable(); | 602 | dcache_disable(); |
601 | #endif | 603 | #endif |
602 | 604 | ||
603 | ret = bootm_load_os(images.os, &load_end, 1); | 605 | ret = bootm_load_os(images.os, &load_end, 1); |
604 | 606 | ||
605 | if (ret < 0) { | 607 | if (ret < 0) { |
606 | if (ret == BOOTM_ERR_RESET) | 608 | if (ret == BOOTM_ERR_RESET) |
607 | do_reset (cmdtp, flag, argc, argv); | 609 | do_reset (cmdtp, flag, argc, argv); |
608 | if (ret == BOOTM_ERR_OVERLAP) { | 610 | if (ret == BOOTM_ERR_OVERLAP) { |
609 | if (images.legacy_hdr_valid) { | 611 | if (images.legacy_hdr_valid) { |
610 | if (image_get_type (&images.legacy_hdr_os_copy) == IH_TYPE_MULTI) | 612 | if (image_get_type (&images.legacy_hdr_os_copy) == IH_TYPE_MULTI) |
611 | puts ("WARNING: legacy format multi component " | 613 | puts ("WARNING: legacy format multi component " |
612 | "image overwritten\n"); | 614 | "image overwritten\n"); |
613 | } else { | 615 | } else { |
614 | puts ("ERROR: new format image overwritten - " | 616 | puts ("ERROR: new format image overwritten - " |
615 | "must RESET the board to recover\n"); | 617 | "must RESET the board to recover\n"); |
616 | show_boot_progress (-113); | 618 | show_boot_progress (-113); |
617 | do_reset (cmdtp, flag, argc, argv); | 619 | do_reset (cmdtp, flag, argc, argv); |
618 | } | 620 | } |
619 | } | 621 | } |
620 | if (ret == BOOTM_ERR_UNIMPLEMENTED) { | 622 | if (ret == BOOTM_ERR_UNIMPLEMENTED) { |
621 | if (iflag) | 623 | if (iflag) |
622 | enable_interrupts(); | 624 | enable_interrupts(); |
623 | show_boot_progress (-7); | 625 | show_boot_progress (-7); |
624 | return 1; | 626 | return 1; |
625 | } | 627 | } |
626 | } | 628 | } |
627 | 629 | ||
628 | lmb_reserve(&images.lmb, images.os.load, (load_end - images.os.load)); | 630 | lmb_reserve(&images.lmb, images.os.load, (load_end - images.os.load)); |
629 | 631 | ||
630 | show_boot_progress (8); | 632 | show_boot_progress (8); |
631 | 633 | ||
632 | #ifdef CONFIG_SILENT_CONSOLE | 634 | #ifdef CONFIG_SILENT_CONSOLE |
633 | if (images.os.os == IH_OS_LINUX) | 635 | if (images.os.os == IH_OS_LINUX) |
634 | fixup_silent_linux(); | 636 | fixup_silent_linux(); |
635 | #endif | 637 | #endif |
636 | 638 | ||
637 | boot_fn = boot_os[images.os.os]; | 639 | boot_fn = boot_os[images.os.os]; |
638 | boot_fn(0, argc, argv, &images); | 640 | boot_fn(0, argc, argv, &images); |
639 | 641 | ||
640 | show_boot_progress (-9); | 642 | show_boot_progress (-9); |
641 | #ifdef DEBUG | 643 | #ifdef DEBUG |
642 | puts ("\n## Control returned to monitor - resetting...\n"); | 644 | puts ("\n## Control returned to monitor - resetting...\n"); |
643 | #endif | 645 | #endif |
644 | do_reset (cmdtp, flag, argc, argv); | 646 | do_reset (cmdtp, flag, argc, argv); |
645 | 647 | ||
646 | return 1; | 648 | return 1; |
647 | } | 649 | } |
648 | 650 | ||
649 | /** | 651 | /** |
650 | * image_get_kernel - verify legacy format kernel image | 652 | * image_get_kernel - verify legacy format kernel image |
651 | * @img_addr: in RAM address of the legacy format image to be verified | 653 | * @img_addr: in RAM address of the legacy format image to be verified |
652 | * @verify: data CRC verification flag | 654 | * @verify: data CRC verification flag |
653 | * | 655 | * |
654 | * image_get_kernel() verifies legacy image integrity and returns pointer to | 656 | * image_get_kernel() verifies legacy image integrity and returns pointer to |
655 | * legacy image header if image verification was completed successfully. | 657 | * legacy image header if image verification was completed successfully. |
656 | * | 658 | * |
657 | * returns: | 659 | * returns: |
658 | * pointer to a legacy image header if valid image was found | 660 | * pointer to a legacy image header if valid image was found |
659 | * otherwise return NULL | 661 | * otherwise return NULL |
660 | */ | 662 | */ |
661 | static image_header_t *image_get_kernel (ulong img_addr, int verify) | 663 | static image_header_t *image_get_kernel (ulong img_addr, int verify) |
662 | { | 664 | { |
663 | image_header_t *hdr = (image_header_t *)img_addr; | 665 | image_header_t *hdr = (image_header_t *)img_addr; |
664 | 666 | ||
665 | if (!image_check_magic(hdr)) { | 667 | if (!image_check_magic(hdr)) { |
666 | puts ("Bad Magic Number\n"); | 668 | puts ("Bad Magic Number\n"); |
667 | show_boot_progress (-1); | 669 | show_boot_progress (-1); |
668 | return NULL; | 670 | return NULL; |
669 | } | 671 | } |
670 | show_boot_progress (2); | 672 | show_boot_progress (2); |
671 | 673 | ||
672 | if (!image_check_hcrc (hdr)) { | 674 | if (!image_check_hcrc (hdr)) { |
673 | puts ("Bad Header Checksum\n"); | 675 | puts ("Bad Header Checksum\n"); |
674 | show_boot_progress (-2); | 676 | show_boot_progress (-2); |
675 | return NULL; | 677 | return NULL; |
676 | } | 678 | } |
677 | 679 | ||
678 | show_boot_progress (3); | 680 | show_boot_progress (3); |
679 | image_print_contents (hdr); | 681 | image_print_contents (hdr); |
680 | 682 | ||
681 | if (verify) { | 683 | if (verify) { |
682 | puts (" Verifying Checksum ... "); | 684 | puts (" Verifying Checksum ... "); |
683 | if (!image_check_dcrc (hdr)) { | 685 | if (!image_check_dcrc (hdr)) { |
684 | printf ("Bad Data CRC\n"); | 686 | printf ("Bad Data CRC\n"); |
685 | show_boot_progress (-3); | 687 | show_boot_progress (-3); |
686 | return NULL; | 688 | return NULL; |
687 | } | 689 | } |
688 | puts ("OK\n"); | 690 | puts ("OK\n"); |
689 | } | 691 | } |
690 | show_boot_progress (4); | 692 | show_boot_progress (4); |
691 | 693 | ||
692 | if (!image_check_target_arch (hdr)) { | 694 | if (!image_check_target_arch (hdr)) { |
693 | printf ("Unsupported Architecture 0x%x\n", image_get_arch (hdr)); | 695 | printf ("Unsupported Architecture 0x%x\n", image_get_arch (hdr)); |
694 | show_boot_progress (-4); | 696 | show_boot_progress (-4); |
695 | return NULL; | 697 | return NULL; |
696 | } | 698 | } |
697 | return hdr; | 699 | return hdr; |
698 | } | 700 | } |
699 | 701 | ||
700 | /** | 702 | /** |
701 | * fit_check_kernel - verify FIT format kernel subimage | 703 | * fit_check_kernel - verify FIT format kernel subimage |
702 | * @fit_hdr: pointer to the FIT image header | 704 | * @fit_hdr: pointer to the FIT image header |
703 | * os_noffset: kernel subimage node offset within FIT image | 705 | * os_noffset: kernel subimage node offset within FIT image |
704 | * @verify: data CRC verification flag | 706 | * @verify: data CRC verification flag |
705 | * | 707 | * |
706 | * fit_check_kernel() verifies integrity of the kernel subimage and from | 708 | * fit_check_kernel() verifies integrity of the kernel subimage and from |
707 | * specified FIT image. | 709 | * specified FIT image. |
708 | * | 710 | * |
709 | * returns: | 711 | * returns: |
710 | * 1, on success | 712 | * 1, on success |
711 | * 0, on failure | 713 | * 0, on failure |
712 | */ | 714 | */ |
713 | #if defined (CONFIG_FIT) | 715 | #if defined (CONFIG_FIT) |
714 | static int fit_check_kernel (const void *fit, int os_noffset, int verify) | 716 | static int fit_check_kernel (const void *fit, int os_noffset, int verify) |
715 | { | 717 | { |
716 | fit_image_print (fit, os_noffset, " "); | 718 | fit_image_print (fit, os_noffset, " "); |
717 | 719 | ||
718 | if (verify) { | 720 | if (verify) { |
719 | puts (" Verifying Hash Integrity ... "); | 721 | puts (" Verifying Hash Integrity ... "); |
720 | if (!fit_image_check_hashes (fit, os_noffset)) { | 722 | if (!fit_image_check_hashes (fit, os_noffset)) { |
721 | puts ("Bad Data Hash\n"); | 723 | puts ("Bad Data Hash\n"); |
722 | show_boot_progress (-104); | 724 | show_boot_progress (-104); |
723 | return 0; | 725 | return 0; |
724 | } | 726 | } |
725 | puts ("OK\n"); | 727 | puts ("OK\n"); |
726 | } | 728 | } |
727 | show_boot_progress (105); | 729 | show_boot_progress (105); |
728 | 730 | ||
729 | if (!fit_image_check_target_arch (fit, os_noffset)) { | 731 | if (!fit_image_check_target_arch (fit, os_noffset)) { |
730 | puts ("Unsupported Architecture\n"); | 732 | puts ("Unsupported Architecture\n"); |
731 | show_boot_progress (-105); | 733 | show_boot_progress (-105); |
732 | return 0; | 734 | return 0; |
733 | } | 735 | } |
734 | 736 | ||
735 | show_boot_progress (106); | 737 | show_boot_progress (106); |
736 | if (!fit_image_check_type (fit, os_noffset, IH_TYPE_KERNEL)) { | 738 | if (!fit_image_check_type (fit, os_noffset, IH_TYPE_KERNEL)) { |
737 | puts ("Not a kernel image\n"); | 739 | puts ("Not a kernel image\n"); |
738 | show_boot_progress (-106); | 740 | show_boot_progress (-106); |
739 | return 0; | 741 | return 0; |
740 | } | 742 | } |
741 | 743 | ||
742 | show_boot_progress (107); | 744 | show_boot_progress (107); |
743 | return 1; | 745 | return 1; |
744 | } | 746 | } |
745 | #endif /* CONFIG_FIT */ | 747 | #endif /* CONFIG_FIT */ |
746 | 748 | ||
747 | /** | 749 | /** |
748 | * boot_get_kernel - find kernel image | 750 | * boot_get_kernel - find kernel image |
749 | * @os_data: pointer to a ulong variable, will hold os data start address | 751 | * @os_data: pointer to a ulong variable, will hold os data start address |
750 | * @os_len: pointer to a ulong variable, will hold os data length | 752 | * @os_len: pointer to a ulong variable, will hold os data length |
751 | * | 753 | * |
752 | * boot_get_kernel() tries to find a kernel image, verifies its integrity | 754 | * boot_get_kernel() tries to find a kernel image, verifies its integrity |
753 | * and locates kernel data. | 755 | * and locates kernel data. |
754 | * | 756 | * |
755 | * returns: | 757 | * returns: |
756 | * pointer to image header if valid image was found, plus kernel start | 758 | * pointer to image header if valid image was found, plus kernel start |
757 | * address and length, otherwise NULL | 759 | * address and length, otherwise NULL |
758 | */ | 760 | */ |
759 | static void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], | 761 | static void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], |
760 | bootm_headers_t *images, ulong *os_data, ulong *os_len) | 762 | bootm_headers_t *images, ulong *os_data, ulong *os_len) |
761 | { | 763 | { |
762 | image_header_t *hdr; | 764 | image_header_t *hdr; |
763 | ulong img_addr; | 765 | ulong img_addr; |
764 | #if defined(CONFIG_FIT) | 766 | #if defined(CONFIG_FIT) |
765 | void *fit_hdr; | 767 | void *fit_hdr; |
766 | const char *fit_uname_config = NULL; | 768 | const char *fit_uname_config = NULL; |
767 | const char *fit_uname_kernel = NULL; | 769 | const char *fit_uname_kernel = NULL; |
768 | const void *data; | 770 | const void *data; |
769 | size_t len; | 771 | size_t len; |
770 | int cfg_noffset; | 772 | int cfg_noffset; |
771 | int os_noffset; | 773 | int os_noffset; |
772 | #endif | 774 | #endif |
773 | 775 | ||
774 | /* find out kernel image address */ | 776 | /* find out kernel image address */ |
775 | if (argc < 2) { | 777 | if (argc < 2) { |
776 | img_addr = load_addr; | 778 | img_addr = load_addr; |
777 | debug ("* kernel: default image load address = 0x%08lx\n", | 779 | debug ("* kernel: default image load address = 0x%08lx\n", |
778 | load_addr); | 780 | load_addr); |
779 | #if defined(CONFIG_FIT) | 781 | #if defined(CONFIG_FIT) |
780 | } else if (fit_parse_conf (argv[1], load_addr, &img_addr, | 782 | } else if (fit_parse_conf (argv[1], load_addr, &img_addr, |
781 | &fit_uname_config)) { | 783 | &fit_uname_config)) { |
782 | debug ("* kernel: config '%s' from image at 0x%08lx\n", | 784 | debug ("* kernel: config '%s' from image at 0x%08lx\n", |
783 | fit_uname_config, img_addr); | 785 | fit_uname_config, img_addr); |
784 | } else if (fit_parse_subimage (argv[1], load_addr, &img_addr, | 786 | } else if (fit_parse_subimage (argv[1], load_addr, &img_addr, |
785 | &fit_uname_kernel)) { | 787 | &fit_uname_kernel)) { |
786 | debug ("* kernel: subimage '%s' from image at 0x%08lx\n", | 788 | debug ("* kernel: subimage '%s' from image at 0x%08lx\n", |
787 | fit_uname_kernel, img_addr); | 789 | fit_uname_kernel, img_addr); |
788 | #endif | 790 | #endif |
789 | } else { | 791 | } else { |
790 | img_addr = simple_strtoul(argv[1], NULL, 16); | 792 | img_addr = simple_strtoul(argv[1], NULL, 16); |
791 | debug ("* kernel: cmdline image address = 0x%08lx\n", img_addr); | 793 | debug ("* kernel: cmdline image address = 0x%08lx\n", img_addr); |
792 | } | 794 | } |
793 | 795 | ||
794 | show_boot_progress (1); | 796 | show_boot_progress (1); |
795 | 797 | ||
796 | /* copy from dataflash if needed */ | 798 | /* copy from dataflash if needed */ |
797 | img_addr = genimg_get_image (img_addr); | 799 | img_addr = genimg_get_image (img_addr); |
798 | 800 | ||
799 | /* check image type, for FIT images get FIT kernel node */ | 801 | /* check image type, for FIT images get FIT kernel node */ |
800 | *os_data = *os_len = 0; | 802 | *os_data = *os_len = 0; |
801 | switch (genimg_get_format ((void *)img_addr)) { | 803 | switch (genimg_get_format ((void *)img_addr)) { |
802 | case IMAGE_FORMAT_LEGACY: | 804 | case IMAGE_FORMAT_LEGACY: |
803 | printf ("## Booting kernel from Legacy Image at %08lx ...\n", | 805 | printf ("## Booting kernel from Legacy Image at %08lx ...\n", |
804 | img_addr); | 806 | img_addr); |
805 | hdr = image_get_kernel (img_addr, images->verify); | 807 | hdr = image_get_kernel (img_addr, images->verify); |
806 | if (!hdr) | 808 | if (!hdr) |
807 | return NULL; | 809 | return NULL; |
808 | show_boot_progress (5); | 810 | show_boot_progress (5); |
809 | 811 | ||
810 | /* get os_data and os_len */ | 812 | /* get os_data and os_len */ |
811 | switch (image_get_type (hdr)) { | 813 | switch (image_get_type (hdr)) { |
812 | case IH_TYPE_KERNEL: | 814 | case IH_TYPE_KERNEL: |
813 | *os_data = image_get_data (hdr); | 815 | *os_data = image_get_data (hdr); |
814 | *os_len = image_get_data_size (hdr); | 816 | *os_len = image_get_data_size (hdr); |
815 | break; | 817 | break; |
816 | case IH_TYPE_MULTI: | 818 | case IH_TYPE_MULTI: |
817 | image_multi_getimg (hdr, 0, os_data, os_len); | 819 | image_multi_getimg (hdr, 0, os_data, os_len); |
818 | break; | 820 | break; |
819 | default: | 821 | default: |
820 | printf ("Wrong Image Type for %s command\n", cmdtp->name); | 822 | printf ("Wrong Image Type for %s command\n", cmdtp->name); |
821 | show_boot_progress (-5); | 823 | show_boot_progress (-5); |
822 | return NULL; | 824 | return NULL; |
823 | } | 825 | } |
824 | 826 | ||
825 | /* | 827 | /* |
826 | * copy image header to allow for image overwrites during kernel | 828 | * copy image header to allow for image overwrites during kernel |
827 | * decompression. | 829 | * decompression. |
828 | */ | 830 | */ |
829 | memmove (&images->legacy_hdr_os_copy, hdr, sizeof(image_header_t)); | 831 | memmove (&images->legacy_hdr_os_copy, hdr, sizeof(image_header_t)); |
830 | 832 | ||
831 | /* save pointer to image header */ | 833 | /* save pointer to image header */ |
832 | images->legacy_hdr_os = hdr; | 834 | images->legacy_hdr_os = hdr; |
833 | 835 | ||
834 | images->legacy_hdr_valid = 1; | 836 | images->legacy_hdr_valid = 1; |
835 | show_boot_progress (6); | 837 | show_boot_progress (6); |
836 | break; | 838 | break; |
837 | #if defined(CONFIG_FIT) | 839 | #if defined(CONFIG_FIT) |
838 | case IMAGE_FORMAT_FIT: | 840 | case IMAGE_FORMAT_FIT: |
839 | fit_hdr = (void *)img_addr; | 841 | fit_hdr = (void *)img_addr; |
840 | printf ("## Booting kernel from FIT Image at %08lx ...\n", | 842 | printf ("## Booting kernel from FIT Image at %08lx ...\n", |
841 | img_addr); | 843 | img_addr); |
842 | 844 | ||
843 | if (!fit_check_format (fit_hdr)) { | 845 | if (!fit_check_format (fit_hdr)) { |
844 | puts ("Bad FIT kernel image format!\n"); | 846 | puts ("Bad FIT kernel image format!\n"); |
845 | show_boot_progress (-100); | 847 | show_boot_progress (-100); |
846 | return NULL; | 848 | return NULL; |
847 | } | 849 | } |
848 | show_boot_progress (100); | 850 | show_boot_progress (100); |
849 | 851 | ||
850 | if (!fit_uname_kernel) { | 852 | if (!fit_uname_kernel) { |
851 | /* | 853 | /* |
852 | * no kernel image node unit name, try to get config | 854 | * no kernel image node unit name, try to get config |
853 | * node first. If config unit node name is NULL | 855 | * node first. If config unit node name is NULL |
854 | * fit_conf_get_node() will try to find default config node | 856 | * fit_conf_get_node() will try to find default config node |
855 | */ | 857 | */ |
856 | show_boot_progress (101); | 858 | show_boot_progress (101); |
857 | cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config); | 859 | cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config); |
858 | if (cfg_noffset < 0) { | 860 | if (cfg_noffset < 0) { |
859 | show_boot_progress (-101); | 861 | show_boot_progress (-101); |
860 | return NULL; | 862 | return NULL; |
861 | } | 863 | } |
862 | /* save configuration uname provided in the first | 864 | /* save configuration uname provided in the first |
863 | * bootm argument | 865 | * bootm argument |
864 | */ | 866 | */ |
865 | images->fit_uname_cfg = fdt_get_name (fit_hdr, cfg_noffset, NULL); | 867 | images->fit_uname_cfg = fdt_get_name (fit_hdr, cfg_noffset, NULL); |
866 | printf (" Using '%s' configuration\n", images->fit_uname_cfg); | 868 | printf (" Using '%s' configuration\n", images->fit_uname_cfg); |
867 | show_boot_progress (103); | 869 | show_boot_progress (103); |
868 | 870 | ||
869 | os_noffset = fit_conf_get_kernel_node (fit_hdr, cfg_noffset); | 871 | os_noffset = fit_conf_get_kernel_node (fit_hdr, cfg_noffset); |
870 | fit_uname_kernel = fit_get_name (fit_hdr, os_noffset, NULL); | 872 | fit_uname_kernel = fit_get_name (fit_hdr, os_noffset, NULL); |
871 | } else { | 873 | } else { |
872 | /* get kernel component image node offset */ | 874 | /* get kernel component image node offset */ |
873 | show_boot_progress (102); | 875 | show_boot_progress (102); |
874 | os_noffset = fit_image_get_node (fit_hdr, fit_uname_kernel); | 876 | os_noffset = fit_image_get_node (fit_hdr, fit_uname_kernel); |
875 | } | 877 | } |
876 | if (os_noffset < 0) { | 878 | if (os_noffset < 0) { |
877 | show_boot_progress (-103); | 879 | show_boot_progress (-103); |
878 | return NULL; | 880 | return NULL; |
879 | } | 881 | } |
880 | 882 | ||
881 | printf (" Trying '%s' kernel subimage\n", fit_uname_kernel); | 883 | printf (" Trying '%s' kernel subimage\n", fit_uname_kernel); |
882 | 884 | ||
883 | show_boot_progress (104); | 885 | show_boot_progress (104); |
884 | if (!fit_check_kernel (fit_hdr, os_noffset, images->verify)) | 886 | if (!fit_check_kernel (fit_hdr, os_noffset, images->verify)) |
885 | return NULL; | 887 | return NULL; |
886 | 888 | ||
887 | /* get kernel image data address and length */ | 889 | /* get kernel image data address and length */ |
888 | if (fit_image_get_data (fit_hdr, os_noffset, &data, &len)) { | 890 | if (fit_image_get_data (fit_hdr, os_noffset, &data, &len)) { |
889 | puts ("Could not find kernel subimage data!\n"); | 891 | puts ("Could not find kernel subimage data!\n"); |
890 | show_boot_progress (-107); | 892 | show_boot_progress (-107); |
891 | return NULL; | 893 | return NULL; |
892 | } | 894 | } |
893 | show_boot_progress (108); | 895 | show_boot_progress (108); |
894 | 896 | ||
895 | *os_len = len; | 897 | *os_len = len; |
896 | *os_data = (ulong)data; | 898 | *os_data = (ulong)data; |
897 | images->fit_hdr_os = fit_hdr; | 899 | images->fit_hdr_os = fit_hdr; |
898 | images->fit_uname_os = fit_uname_kernel; | 900 | images->fit_uname_os = fit_uname_kernel; |
899 | images->fit_noffset_os = os_noffset; | 901 | images->fit_noffset_os = os_noffset; |
900 | break; | 902 | break; |
901 | #endif | 903 | #endif |
902 | default: | 904 | default: |
903 | printf ("Wrong Image Format for %s command\n", cmdtp->name); | 905 | printf ("Wrong Image Format for %s command\n", cmdtp->name); |
904 | show_boot_progress (-108); | 906 | show_boot_progress (-108); |
905 | return NULL; | 907 | return NULL; |
906 | } | 908 | } |
907 | 909 | ||
908 | debug (" kernel data at 0x%08lx, len = 0x%08lx (%ld)\n", | 910 | debug (" kernel data at 0x%08lx, len = 0x%08lx (%ld)\n", |
909 | *os_data, *os_len, *os_len); | 911 | *os_data, *os_len, *os_len); |
910 | 912 | ||
911 | return (void *)img_addr; | 913 | return (void *)img_addr; |
912 | } | 914 | } |
913 | 915 | ||
914 | U_BOOT_CMD( | 916 | U_BOOT_CMD( |
915 | bootm, CONFIG_SYS_MAXARGS, 1, do_bootm, | 917 | bootm, CONFIG_SYS_MAXARGS, 1, do_bootm, |
916 | "boot application image from memory", | 918 | "boot application image from memory", |
917 | "[addr [arg ...]]\n - boot application image stored in memory\n" | 919 | "[addr [arg ...]]\n - boot application image stored in memory\n" |
918 | "\tpassing arguments 'arg ...'; when booting a Linux kernel,\n" | 920 | "\tpassing arguments 'arg ...'; when booting a Linux kernel,\n" |
919 | "\t'arg' can be the address of an initrd image\n" | 921 | "\t'arg' can be the address of an initrd image\n" |
920 | #if defined(CONFIG_OF_LIBFDT) | 922 | #if defined(CONFIG_OF_LIBFDT) |
921 | "\tWhen booting a Linux kernel which requires a flat device-tree\n" | 923 | "\tWhen booting a Linux kernel which requires a flat device-tree\n" |
922 | "\ta third argument is required which is the address of the\n" | 924 | "\ta third argument is required which is the address of the\n" |
923 | "\tdevice-tree blob. To boot that kernel without an initrd image,\n" | 925 | "\tdevice-tree blob. To boot that kernel without an initrd image,\n" |
924 | "\tuse a '-' for the second argument. If you do not pass a third\n" | 926 | "\tuse a '-' for the second argument. If you do not pass a third\n" |
925 | "\ta bd_info struct will be passed instead\n" | 927 | "\ta bd_info struct will be passed instead\n" |
926 | #endif | 928 | #endif |
927 | #if defined(CONFIG_FIT) | 929 | #if defined(CONFIG_FIT) |
928 | "\t\nFor the new multi component uImage format (FIT) addresses\n" | 930 | "\t\nFor the new multi component uImage format (FIT) addresses\n" |
929 | "\tmust be extened to include component or configuration unit name:\n" | 931 | "\tmust be extened to include component or configuration unit name:\n" |
930 | "\taddr:<subimg_uname> - direct component image specification\n" | 932 | "\taddr:<subimg_uname> - direct component image specification\n" |
931 | "\taddr#<conf_uname> - configuration specification\n" | 933 | "\taddr#<conf_uname> - configuration specification\n" |
932 | "\tUse iminfo command to get the list of existing component\n" | 934 | "\tUse iminfo command to get the list of existing component\n" |
933 | "\timages and configurations.\n" | 935 | "\timages and configurations.\n" |
934 | #endif | 936 | #endif |
935 | "\nSub-commands to do part of the bootm sequence. The sub-commands " | 937 | "\nSub-commands to do part of the bootm sequence. The sub-commands " |
936 | "must be\n" | 938 | "must be\n" |
937 | "issued in the order below (it's ok to not issue all sub-commands):\n" | 939 | "issued in the order below (it's ok to not issue all sub-commands):\n" |
938 | "\tstart [addr [arg ...]]\n" | 940 | "\tstart [addr [arg ...]]\n" |
939 | "\tloados - load OS image\n" | 941 | "\tloados - load OS image\n" |
940 | #if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) | 942 | #if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) |
941 | "\tramdisk - relocate initrd, set env initrd_start/initrd_end\n" | 943 | "\tramdisk - relocate initrd, set env initrd_start/initrd_end\n" |
942 | #endif | 944 | #endif |
943 | #if defined(CONFIG_OF_LIBFDT) | 945 | #if defined(CONFIG_OF_LIBFDT) |
944 | "\tfdt - relocate flat device tree\n" | 946 | "\tfdt - relocate flat device tree\n" |
945 | #endif | 947 | #endif |
946 | "\tbdt - OS specific bd_t processing\n" | 948 | "\tbdt - OS specific bd_t processing\n" |
947 | "\tcmdline - OS specific command line processing/setup\n" | 949 | "\tcmdline - OS specific command line processing/setup\n" |
948 | "\tprep - OS specific prep before relocation or go\n" | 950 | "\tprep - OS specific prep before relocation or go\n" |
949 | "\tgo - start OS\n" | 951 | "\tgo - start OS\n" |
950 | ); | 952 | ); |
951 | 953 | ||
952 | /*******************************************************************/ | 954 | /*******************************************************************/ |
953 | /* bootd - boot default image */ | 955 | /* bootd - boot default image */ |
954 | /*******************************************************************/ | 956 | /*******************************************************************/ |
955 | #if defined(CONFIG_CMD_BOOTD) | 957 | #if defined(CONFIG_CMD_BOOTD) |
956 | int do_bootd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | 958 | int do_bootd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) |
957 | { | 959 | { |
958 | int rcode = 0; | 960 | int rcode = 0; |
959 | 961 | ||
960 | #ifndef CONFIG_SYS_HUSH_PARSER | 962 | #ifndef CONFIG_SYS_HUSH_PARSER |
961 | if (run_command (getenv ("bootcmd"), flag) < 0) | 963 | if (run_command (getenv ("bootcmd"), flag) < 0) |
962 | rcode = 1; | 964 | rcode = 1; |
963 | #else | 965 | #else |
964 | if (parse_string_outer (getenv ("bootcmd"), | 966 | if (parse_string_outer (getenv ("bootcmd"), |
965 | FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP) != 0) | 967 | FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP) != 0) |
966 | rcode = 1; | 968 | rcode = 1; |
967 | #endif | 969 | #endif |
968 | return rcode; | 970 | return rcode; |
969 | } | 971 | } |
970 | 972 | ||
971 | U_BOOT_CMD( | 973 | U_BOOT_CMD( |
972 | boot, 1, 1, do_bootd, | 974 | boot, 1, 1, do_bootd, |
973 | "boot default, i.e., run 'bootcmd'", | 975 | "boot default, i.e., run 'bootcmd'", |
974 | NULL | 976 | NULL |
975 | ); | 977 | ); |
976 | 978 | ||
977 | /* keep old command name "bootd" for backward compatibility */ | 979 | /* keep old command name "bootd" for backward compatibility */ |
978 | U_BOOT_CMD( | 980 | U_BOOT_CMD( |
979 | bootd, 1, 1, do_bootd, | 981 | bootd, 1, 1, do_bootd, |
980 | "boot default, i.e., run 'bootcmd'", | 982 | "boot default, i.e., run 'bootcmd'", |
981 | NULL | 983 | NULL |
982 | ); | 984 | ); |
983 | 985 | ||
984 | #endif | 986 | #endif |
985 | 987 | ||
986 | 988 | ||
987 | /*******************************************************************/ | 989 | /*******************************************************************/ |
988 | /* iminfo - print header info for a requested image */ | 990 | /* iminfo - print header info for a requested image */ |
989 | /*******************************************************************/ | 991 | /*******************************************************************/ |
990 | #if defined(CONFIG_CMD_IMI) | 992 | #if defined(CONFIG_CMD_IMI) |
991 | int do_iminfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | 993 | int do_iminfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) |
992 | { | 994 | { |
993 | int arg; | 995 | int arg; |
994 | ulong addr; | 996 | ulong addr; |
995 | int rcode = 0; | 997 | int rcode = 0; |
996 | 998 | ||
997 | if (argc < 2) { | 999 | if (argc < 2) { |
998 | return image_info (load_addr); | 1000 | return image_info (load_addr); |
999 | } | 1001 | } |
1000 | 1002 | ||
1001 | for (arg = 1; arg < argc; ++arg) { | 1003 | for (arg = 1; arg < argc; ++arg) { |
1002 | addr = simple_strtoul (argv[arg], NULL, 16); | 1004 | addr = simple_strtoul (argv[arg], NULL, 16); |
1003 | if (image_info (addr) != 0) | 1005 | if (image_info (addr) != 0) |
1004 | rcode = 1; | 1006 | rcode = 1; |
1005 | } | 1007 | } |
1006 | return rcode; | 1008 | return rcode; |
1007 | } | 1009 | } |
1008 | 1010 | ||
1009 | static int image_info (ulong addr) | 1011 | static int image_info (ulong addr) |
1010 | { | 1012 | { |
1011 | void *hdr = (void *)addr; | 1013 | void *hdr = (void *)addr; |
1012 | 1014 | ||
1013 | printf ("\n## Checking Image at %08lx ...\n", addr); | 1015 | printf ("\n## Checking Image at %08lx ...\n", addr); |
1014 | 1016 | ||
1015 | switch (genimg_get_format (hdr)) { | 1017 | switch (genimg_get_format (hdr)) { |
1016 | case IMAGE_FORMAT_LEGACY: | 1018 | case IMAGE_FORMAT_LEGACY: |
1017 | puts (" Legacy image found\n"); | 1019 | puts (" Legacy image found\n"); |
1018 | if (!image_check_magic (hdr)) { | 1020 | if (!image_check_magic (hdr)) { |
1019 | puts (" Bad Magic Number\n"); | 1021 | puts (" Bad Magic Number\n"); |
1020 | return 1; | 1022 | return 1; |
1021 | } | 1023 | } |
1022 | 1024 | ||
1023 | if (!image_check_hcrc (hdr)) { | 1025 | if (!image_check_hcrc (hdr)) { |
1024 | puts (" Bad Header Checksum\n"); | 1026 | puts (" Bad Header Checksum\n"); |
1025 | return 1; | 1027 | return 1; |
1026 | } | 1028 | } |
1027 | 1029 | ||
1028 | image_print_contents (hdr); | 1030 | image_print_contents (hdr); |
1029 | 1031 | ||
1030 | puts (" Verifying Checksum ... "); | 1032 | puts (" Verifying Checksum ... "); |
1031 | if (!image_check_dcrc (hdr)) { | 1033 | if (!image_check_dcrc (hdr)) { |
1032 | puts (" Bad Data CRC\n"); | 1034 | puts (" Bad Data CRC\n"); |
1033 | return 1; | 1035 | return 1; |
1034 | } | 1036 | } |
1035 | puts ("OK\n"); | 1037 | puts ("OK\n"); |
1036 | return 0; | 1038 | return 0; |
1037 | #if defined(CONFIG_FIT) | 1039 | #if defined(CONFIG_FIT) |
1038 | case IMAGE_FORMAT_FIT: | 1040 | case IMAGE_FORMAT_FIT: |
1039 | puts (" FIT image found\n"); | 1041 | puts (" FIT image found\n"); |
1040 | 1042 | ||
1041 | if (!fit_check_format (hdr)) { | 1043 | if (!fit_check_format (hdr)) { |
1042 | puts ("Bad FIT image format!\n"); | 1044 | puts ("Bad FIT image format!\n"); |
1043 | return 1; | 1045 | return 1; |
1044 | } | 1046 | } |
1045 | 1047 | ||
1046 | fit_print_contents (hdr); | 1048 | fit_print_contents (hdr); |
1047 | 1049 | ||
1048 | if (!fit_all_image_check_hashes (hdr)) { | 1050 | if (!fit_all_image_check_hashes (hdr)) { |
1049 | puts ("Bad hash in FIT image!\n"); | 1051 | puts ("Bad hash in FIT image!\n"); |
1050 | return 1; | 1052 | return 1; |
1051 | } | 1053 | } |
1052 | 1054 | ||
1053 | return 0; | 1055 | return 0; |
1054 | #endif | 1056 | #endif |
1055 | default: | 1057 | default: |
1056 | puts ("Unknown image format!\n"); | 1058 | puts ("Unknown image format!\n"); |
1057 | break; | 1059 | break; |
1058 | } | 1060 | } |
1059 | 1061 | ||
1060 | return 1; | 1062 | return 1; |
1061 | } | 1063 | } |
1062 | 1064 | ||
1063 | U_BOOT_CMD( | 1065 | U_BOOT_CMD( |
1064 | iminfo, CONFIG_SYS_MAXARGS, 1, do_iminfo, | 1066 | iminfo, CONFIG_SYS_MAXARGS, 1, do_iminfo, |
1065 | "print header information for application image", | 1067 | "print header information for application image", |
1066 | "addr [addr ...]\n" | 1068 | "addr [addr ...]\n" |
1067 | " - print header information for application image starting at\n" | 1069 | " - print header information for application image starting at\n" |
1068 | " address 'addr' in memory; this includes verification of the\n" | 1070 | " address 'addr' in memory; this includes verification of the\n" |
1069 | " image contents (magic number, header and payload checksums)\n" | 1071 | " image contents (magic number, header and payload checksums)\n" |
1070 | ); | 1072 | ); |
1071 | #endif | 1073 | #endif |
1072 | 1074 | ||
1073 | 1075 | ||
1074 | /*******************************************************************/ | 1076 | /*******************************************************************/ |
1075 | /* imls - list all images found in flash */ | 1077 | /* imls - list all images found in flash */ |
1076 | /*******************************************************************/ | 1078 | /*******************************************************************/ |
1077 | #if defined(CONFIG_CMD_IMLS) | 1079 | #if defined(CONFIG_CMD_IMLS) |
1078 | int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | 1080 | int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) |
1079 | { | 1081 | { |
1080 | flash_info_t *info; | 1082 | flash_info_t *info; |
1081 | int i, j; | 1083 | int i, j; |
1082 | void *hdr; | 1084 | void *hdr; |
1083 | 1085 | ||
1084 | for (i = 0, info = &flash_info[0]; | 1086 | for (i = 0, info = &flash_info[0]; |
1085 | i < CONFIG_SYS_MAX_FLASH_BANKS; ++i, ++info) { | 1087 | i < CONFIG_SYS_MAX_FLASH_BANKS; ++i, ++info) { |
1086 | 1088 | ||
1087 | if (info->flash_id == FLASH_UNKNOWN) | 1089 | if (info->flash_id == FLASH_UNKNOWN) |
1088 | goto next_bank; | 1090 | goto next_bank; |
1089 | for (j = 0; j < info->sector_count; ++j) { | 1091 | for (j = 0; j < info->sector_count; ++j) { |
1090 | 1092 | ||
1091 | hdr = (void *)info->start[j]; | 1093 | hdr = (void *)info->start[j]; |
1092 | if (!hdr) | 1094 | if (!hdr) |
1093 | goto next_sector; | 1095 | goto next_sector; |
1094 | 1096 | ||
1095 | switch (genimg_get_format (hdr)) { | 1097 | switch (genimg_get_format (hdr)) { |
1096 | case IMAGE_FORMAT_LEGACY: | 1098 | case IMAGE_FORMAT_LEGACY: |
1097 | if (!image_check_hcrc (hdr)) | 1099 | if (!image_check_hcrc (hdr)) |
1098 | goto next_sector; | 1100 | goto next_sector; |
1099 | 1101 | ||
1100 | printf ("Legacy Image at %08lX:\n", (ulong)hdr); | 1102 | printf ("Legacy Image at %08lX:\n", (ulong)hdr); |
1101 | image_print_contents (hdr); | 1103 | image_print_contents (hdr); |
1102 | 1104 | ||
1103 | puts (" Verifying Checksum ... "); | 1105 | puts (" Verifying Checksum ... "); |
1104 | if (!image_check_dcrc (hdr)) { | 1106 | if (!image_check_dcrc (hdr)) { |
1105 | puts ("Bad Data CRC\n"); | 1107 | puts ("Bad Data CRC\n"); |
1106 | } else { | 1108 | } else { |
1107 | puts ("OK\n"); | 1109 | puts ("OK\n"); |
1108 | } | 1110 | } |
1109 | break; | 1111 | break; |
1110 | #if defined(CONFIG_FIT) | 1112 | #if defined(CONFIG_FIT) |
1111 | case IMAGE_FORMAT_FIT: | 1113 | case IMAGE_FORMAT_FIT: |
1112 | if (!fit_check_format (hdr)) | 1114 | if (!fit_check_format (hdr)) |
1113 | goto next_sector; | 1115 | goto next_sector; |
1114 | 1116 | ||
1115 | printf ("FIT Image at %08lX:\n", (ulong)hdr); | 1117 | printf ("FIT Image at %08lX:\n", (ulong)hdr); |
1116 | fit_print_contents (hdr); | 1118 | fit_print_contents (hdr); |
1117 | break; | 1119 | break; |
1118 | #endif | 1120 | #endif |
1119 | default: | 1121 | default: |
1120 | goto next_sector; | 1122 | goto next_sector; |
1121 | } | 1123 | } |
1122 | 1124 | ||
1123 | next_sector: ; | 1125 | next_sector: ; |
1124 | } | 1126 | } |
1125 | next_bank: ; | 1127 | next_bank: ; |
1126 | } | 1128 | } |
1127 | 1129 | ||
1128 | return (0); | 1130 | return (0); |
1129 | } | 1131 | } |
1130 | 1132 | ||
1131 | U_BOOT_CMD( | 1133 | U_BOOT_CMD( |
1132 | imls, 1, 1, do_imls, | 1134 | imls, 1, 1, do_imls, |
1133 | "list all images found in flash", | 1135 | "list all images found in flash", |
1134 | "\n" | 1136 | "\n" |
1135 | " - Prints information about all images found at sector\n" | 1137 | " - Prints information about all images found at sector\n" |
1136 | " boundaries in flash.\n" | 1138 | " boundaries in flash.\n" |
1137 | ); | 1139 | ); |
1138 | #endif | 1140 | #endif |
1139 | 1141 | ||
1140 | /*******************************************************************/ | 1142 | /*******************************************************************/ |
1141 | /* helper routines */ | 1143 | /* helper routines */ |
1142 | /*******************************************************************/ | 1144 | /*******************************************************************/ |
1143 | #ifdef CONFIG_SILENT_CONSOLE | 1145 | #ifdef CONFIG_SILENT_CONSOLE |
1144 | static void fixup_silent_linux () | 1146 | static void fixup_silent_linux () |
1145 | { | 1147 | { |
1146 | char buf[256], *start, *end; | 1148 | char buf[256], *start, *end; |
1147 | char *cmdline = getenv ("bootargs"); | 1149 | char *cmdline = getenv ("bootargs"); |
1148 | 1150 | ||
1149 | /* Only fix cmdline when requested */ | 1151 | /* Only fix cmdline when requested */ |
1150 | if (!(gd->flags & GD_FLG_SILENT)) | 1152 | if (!(gd->flags & GD_FLG_SILENT)) |
1151 | return; | 1153 | return; |
1152 | 1154 | ||
1153 | debug ("before silent fix-up: %s\n", cmdline); | 1155 | debug ("before silent fix-up: %s\n", cmdline); |
1154 | if (cmdline) { | 1156 | if (cmdline) { |
1155 | if ((start = strstr (cmdline, "console=")) != NULL) { | 1157 | if ((start = strstr (cmdline, "console=")) != NULL) { |
1156 | end = strchr (start, ' '); | 1158 | end = strchr (start, ' '); |
1157 | strncpy (buf, cmdline, (start - cmdline + 8)); | 1159 | strncpy (buf, cmdline, (start - cmdline + 8)); |
1158 | if (end) | 1160 | if (end) |
1159 | strcpy (buf + (start - cmdline + 8), end); | 1161 | strcpy (buf + (start - cmdline + 8), end); |
1160 | else | 1162 | else |
1161 | buf[start - cmdline + 8] = '\0'; | 1163 | buf[start - cmdline + 8] = '\0'; |
1162 | } else { | 1164 | } else { |
1163 | strcpy (buf, cmdline); | 1165 | strcpy (buf, cmdline); |
1164 | strcat (buf, " console="); | 1166 | strcat (buf, " console="); |
1165 | } | 1167 | } |
1166 | } else { | 1168 | } else { |
1167 | strcpy (buf, "console="); | 1169 | strcpy (buf, "console="); |
1168 | } | 1170 | } |
1169 | 1171 | ||
1170 | setenv ("bootargs", buf); | 1172 | setenv ("bootargs", buf); |
1171 | debug ("after silent fix-up: %s\n", buf); | 1173 | debug ("after silent fix-up: %s\n", buf); |
1172 | } | 1174 | } |
1173 | #endif /* CONFIG_SILENT_CONSOLE */ | 1175 | #endif /* CONFIG_SILENT_CONSOLE */ |
1174 | 1176 | ||
1175 | 1177 | ||
1176 | /*******************************************************************/ | 1178 | /*******************************************************************/ |
1177 | /* OS booting routines */ | 1179 | /* OS booting routines */ |
1178 | /*******************************************************************/ | 1180 | /*******************************************************************/ |
1179 | 1181 | ||
1180 | #ifdef CONFIG_BOOTM_NETBSD | 1182 | #ifdef CONFIG_BOOTM_NETBSD |
1181 | static int do_bootm_netbsd (int flag, int argc, char *argv[], | 1183 | static int do_bootm_netbsd (int flag, int argc, char *argv[], |
1182 | bootm_headers_t *images) | 1184 | bootm_headers_t *images) |
1183 | { | 1185 | { |
1184 | void (*loader)(bd_t *, image_header_t *, char *, char *); | 1186 | void (*loader)(bd_t *, image_header_t *, char *, char *); |
1185 | image_header_t *os_hdr, *hdr; | 1187 | image_header_t *os_hdr, *hdr; |
1186 | ulong kernel_data, kernel_len; | 1188 | ulong kernel_data, kernel_len; |
1187 | char *consdev; | 1189 | char *consdev; |
1188 | char *cmdline; | 1190 | char *cmdline; |
1189 | 1191 | ||
1190 | if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) | 1192 | if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) |
1191 | return 1; | 1193 | return 1; |
1192 | 1194 | ||
1193 | #if defined(CONFIG_FIT) | 1195 | #if defined(CONFIG_FIT) |
1194 | if (!images->legacy_hdr_valid) { | 1196 | if (!images->legacy_hdr_valid) { |
1195 | fit_unsupported_reset ("NetBSD"); | 1197 | fit_unsupported_reset ("NetBSD"); |
1196 | return 1; | 1198 | return 1; |
1197 | } | 1199 | } |
1198 | #endif | 1200 | #endif |
1199 | hdr = images->legacy_hdr_os; | 1201 | hdr = images->legacy_hdr_os; |
1200 | 1202 | ||
1201 | /* | 1203 | /* |
1202 | * Booting a (NetBSD) kernel image | 1204 | * Booting a (NetBSD) kernel image |
1203 | * | 1205 | * |
1204 | * This process is pretty similar to a standalone application: | 1206 | * This process is pretty similar to a standalone application: |
1205 | * The (first part of an multi-) image must be a stage-2 loader, | 1207 | * The (first part of an multi-) image must be a stage-2 loader, |
1206 | * which in turn is responsible for loading & invoking the actual | 1208 | * which in turn is responsible for loading & invoking the actual |
1207 | * kernel. The only differences are the parameters being passed: | 1209 | * kernel. The only differences are the parameters being passed: |
1208 | * besides the board info strucure, the loader expects a command | 1210 | * besides the board info strucure, the loader expects a command |
1209 | * line, the name of the console device, and (optionally) the | 1211 | * line, the name of the console device, and (optionally) the |
1210 | * address of the original image header. | 1212 | * address of the original image header. |
1211 | */ | 1213 | */ |
1212 | os_hdr = NULL; | 1214 | os_hdr = NULL; |
1213 | if (image_check_type (&images->legacy_hdr_os_copy, IH_TYPE_MULTI)) { | 1215 | if (image_check_type (&images->legacy_hdr_os_copy, IH_TYPE_MULTI)) { |
1214 | image_multi_getimg (hdr, 1, &kernel_data, &kernel_len); | 1216 | image_multi_getimg (hdr, 1, &kernel_data, &kernel_len); |
1215 | if (kernel_len) | 1217 | if (kernel_len) |
1216 | os_hdr = hdr; | 1218 | os_hdr = hdr; |
1217 | } | 1219 | } |
1218 | 1220 | ||
1219 | consdev = ""; | 1221 | consdev = ""; |
1220 | #if defined (CONFIG_8xx_CONS_SMC1) | 1222 | #if defined (CONFIG_8xx_CONS_SMC1) |
1221 | consdev = "smc1"; | 1223 | consdev = "smc1"; |
1222 | #elif defined (CONFIG_8xx_CONS_SMC2) | 1224 | #elif defined (CONFIG_8xx_CONS_SMC2) |
1223 | consdev = "smc2"; | 1225 | consdev = "smc2"; |
1224 | #elif defined (CONFIG_8xx_CONS_SCC2) | 1226 | #elif defined (CONFIG_8xx_CONS_SCC2) |
1225 | consdev = "scc2"; | 1227 | consdev = "scc2"; |
1226 | #elif defined (CONFIG_8xx_CONS_SCC3) | 1228 | #elif defined (CONFIG_8xx_CONS_SCC3) |
1227 | consdev = "scc3"; | 1229 | consdev = "scc3"; |
1228 | #endif | 1230 | #endif |
1229 | 1231 | ||
1230 | if (argc > 2) { | 1232 | if (argc > 2) { |
1231 | ulong len; | 1233 | ulong len; |
1232 | int i; | 1234 | int i; |
1233 | 1235 | ||
1234 | for (i = 2, len = 0; i < argc; i += 1) | 1236 | for (i = 2, len = 0; i < argc; i += 1) |
1235 | len += strlen (argv[i]) + 1; | 1237 | len += strlen (argv[i]) + 1; |
1236 | cmdline = malloc (len); | 1238 | cmdline = malloc (len); |
1237 | 1239 | ||
1238 | for (i = 2, len = 0; i < argc; i += 1) { | 1240 | for (i = 2, len = 0; i < argc; i += 1) { |
1239 | if (i > 2) | 1241 | if (i > 2) |
1240 | cmdline[len++] = ' '; | 1242 | cmdline[len++] = ' '; |
1241 | strcpy (&cmdline[len], argv[i]); | 1243 | strcpy (&cmdline[len], argv[i]); |
1242 | len += strlen (argv[i]); | 1244 | len += strlen (argv[i]); |
1243 | } | 1245 | } |
1244 | } else if ((cmdline = getenv ("bootargs")) == NULL) { | 1246 | } else if ((cmdline = getenv ("bootargs")) == NULL) { |
1245 | cmdline = ""; | 1247 | cmdline = ""; |
1246 | } | 1248 | } |
1247 | 1249 | ||
1248 | loader = (void (*)(bd_t *, image_header_t *, char *, char *))images->ep; | 1250 | loader = (void (*)(bd_t *, image_header_t *, char *, char *))images->ep; |
1249 | 1251 | ||
1250 | printf ("## Transferring control to NetBSD stage-2 loader (at address %08lx) ...\n", | 1252 | printf ("## Transferring control to NetBSD stage-2 loader (at address %08lx) ...\n", |
1251 | (ulong)loader); | 1253 | (ulong)loader); |
1252 | 1254 | ||
1253 | show_boot_progress (15); | 1255 | show_boot_progress (15); |
1254 | 1256 | ||
1255 | /* | 1257 | /* |
1256 | * NetBSD Stage-2 Loader Parameters: | 1258 | * NetBSD Stage-2 Loader Parameters: |
1257 | * r3: ptr to board info data | 1259 | * r3: ptr to board info data |
1258 | * r4: image address | 1260 | * r4: image address |
1259 | * r5: console device | 1261 | * r5: console device |
1260 | * r6: boot args string | 1262 | * r6: boot args string |
1261 | */ | 1263 | */ |
1262 | (*loader) (gd->bd, os_hdr, consdev, cmdline); | 1264 | (*loader) (gd->bd, os_hdr, consdev, cmdline); |
1263 | 1265 | ||
1264 | return 1; | 1266 | return 1; |
1265 | } | 1267 | } |
1266 | #endif /* CONFIG_BOOTM_NETBSD*/ | 1268 | #endif /* CONFIG_BOOTM_NETBSD*/ |
1267 | 1269 | ||
1268 | #ifdef CONFIG_LYNXKDI | 1270 | #ifdef CONFIG_LYNXKDI |
1269 | static int do_bootm_lynxkdi (int flag, int argc, char *argv[], | 1271 | static int do_bootm_lynxkdi (int flag, int argc, char *argv[], |
1270 | bootm_headers_t *images) | 1272 | bootm_headers_t *images) |
1271 | { | 1273 | { |
1272 | image_header_t *hdr = &images->legacy_hdr_os_copy; | 1274 | image_header_t *hdr = &images->legacy_hdr_os_copy; |
1273 | 1275 | ||
1274 | if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) | 1276 | if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) |
1275 | return 1; | 1277 | return 1; |
1276 | 1278 | ||
1277 | #if defined(CONFIG_FIT) | 1279 | #if defined(CONFIG_FIT) |
1278 | if (!images->legacy_hdr_valid) { | 1280 | if (!images->legacy_hdr_valid) { |
1279 | fit_unsupported_reset ("Lynx"); | 1281 | fit_unsupported_reset ("Lynx"); |
1280 | return 1; | 1282 | return 1; |
1281 | } | 1283 | } |
1282 | #endif | 1284 | #endif |
1283 | 1285 | ||
1284 | lynxkdi_boot ((image_header_t *)hdr); | 1286 | lynxkdi_boot ((image_header_t *)hdr); |
1285 | 1287 | ||
1286 | return 1; | 1288 | return 1; |
1287 | } | 1289 | } |
1288 | #endif /* CONFIG_LYNXKDI */ | 1290 | #endif /* CONFIG_LYNXKDI */ |
1289 | 1291 | ||
1290 | #ifdef CONFIG_BOOTM_RTEMS | 1292 | #ifdef CONFIG_BOOTM_RTEMS |
1291 | static int do_bootm_rtems (int flag, int argc, char *argv[], | 1293 | static int do_bootm_rtems (int flag, int argc, char *argv[], |
1292 | bootm_headers_t *images) | 1294 | bootm_headers_t *images) |
1293 | { | 1295 | { |
1294 | void (*entry_point)(bd_t *); | 1296 | void (*entry_point)(bd_t *); |
1295 | 1297 | ||
1296 | if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) | 1298 | if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) |
1297 | return 1; | 1299 | return 1; |
1298 | 1300 | ||
1299 | #if defined(CONFIG_FIT) | 1301 | #if defined(CONFIG_FIT) |
1300 | if (!images->legacy_hdr_valid) { | 1302 | if (!images->legacy_hdr_valid) { |
1301 | fit_unsupported_reset ("RTEMS"); | 1303 | fit_unsupported_reset ("RTEMS"); |
1302 | return 1; | 1304 | return 1; |
1303 | } | 1305 | } |
1304 | #endif | 1306 | #endif |
1305 | 1307 | ||
1306 | entry_point = (void (*)(bd_t *))images->ep; | 1308 | entry_point = (void (*)(bd_t *))images->ep; |
1307 | 1309 | ||
1308 | printf ("## Transferring control to RTEMS (at address %08lx) ...\n", | 1310 | printf ("## Transferring control to RTEMS (at address %08lx) ...\n", |
1309 | (ulong)entry_point); | 1311 | (ulong)entry_point); |
1310 | 1312 | ||
1311 | show_boot_progress (15); | 1313 | show_boot_progress (15); |
1312 | 1314 | ||
1313 | /* | 1315 | /* |
1314 | * RTEMS Parameters: | 1316 | * RTEMS Parameters: |
1315 | * r3: ptr to board info data | 1317 | * r3: ptr to board info data |
1316 | */ | 1318 | */ |
1317 | (*entry_point)(gd->bd); | 1319 | (*entry_point)(gd->bd); |
1318 | 1320 | ||
1319 | return 1; | 1321 | return 1; |
1320 | } | 1322 | } |
1321 | #endif /* CONFIG_BOOTM_RTEMS */ | 1323 | #endif /* CONFIG_BOOTM_RTEMS */ |
1322 | 1324 | ||
1323 | #if defined(CONFIG_CMD_ELF) | 1325 | #if defined(CONFIG_CMD_ELF) |
1324 | static int do_bootm_vxworks (int flag, int argc, char *argv[], | 1326 | static int do_bootm_vxworks (int flag, int argc, char *argv[], |
1325 | bootm_headers_t *images) | 1327 | bootm_headers_t *images) |
1326 | { | 1328 | { |
1327 | char str[80]; | 1329 | char str[80]; |
1328 | 1330 | ||
1329 | if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) | 1331 | if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) |
1330 | return 1; | 1332 | return 1; |
1331 | 1333 | ||
1332 | #if defined(CONFIG_FIT) | 1334 | #if defined(CONFIG_FIT) |
1333 | if (!images->legacy_hdr_valid) { | 1335 | if (!images->legacy_hdr_valid) { |
1334 | fit_unsupported_reset ("VxWorks"); | 1336 | fit_unsupported_reset ("VxWorks"); |
1335 | return 1; | 1337 | return 1; |
1336 | } | 1338 | } |
1337 | #endif | 1339 | #endif |
1338 | 1340 | ||
1339 | sprintf(str, "%lx", images->ep); /* write entry-point into string */ | 1341 | sprintf(str, "%lx", images->ep); /* write entry-point into string */ |
1340 | setenv("loadaddr", str); | 1342 | setenv("loadaddr", str); |
1341 | do_bootvx(NULL, 0, 0, NULL); | 1343 | do_bootvx(NULL, 0, 0, NULL); |
1342 | 1344 | ||
1343 | return 1; | 1345 | return 1; |
1344 | } | 1346 | } |
1345 | 1347 | ||
1346 | static int do_bootm_qnxelf(int flag, int argc, char *argv[], | 1348 | static int do_bootm_qnxelf(int flag, int argc, char *argv[], |
1347 | bootm_headers_t *images) | 1349 | bootm_headers_t *images) |
1348 | { | 1350 | { |
1349 | char *local_args[2]; | 1351 | char *local_args[2]; |
1350 | char str[16]; | 1352 | char str[16]; |
1351 | 1353 | ||
1352 | if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) | 1354 | if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) |
1353 | return 1; | 1355 | return 1; |
1354 | 1356 | ||
1355 | #if defined(CONFIG_FIT) | 1357 | #if defined(CONFIG_FIT) |
1356 | if (!images->legacy_hdr_valid) { | 1358 | if (!images->legacy_hdr_valid) { |
1357 | fit_unsupported_reset ("QNX"); | 1359 | fit_unsupported_reset ("QNX"); |
1358 | return 1; | 1360 | return 1; |
1359 | } | 1361 | } |
1360 | #endif | 1362 | #endif |
1361 | 1363 | ||
1362 | sprintf(str, "%lx", images->ep); /* write entry-point into string */ | 1364 | sprintf(str, "%lx", images->ep); /* write entry-point into string */ |
1363 | local_args[0] = argv[0]; | 1365 | local_args[0] = argv[0]; |
1364 | local_args[1] = str; /* and provide it via the arguments */ | 1366 | local_args[1] = str; /* and provide it via the arguments */ |
1365 | do_bootelf(NULL, 0, 2, local_args); | 1367 | do_bootelf(NULL, 0, 2, local_args); |
1366 | 1368 | ||
1367 | return 1; | 1369 | return 1; |
1368 | } | 1370 | } |
1369 | #endif | 1371 | #endif |
1370 | 1372 | ||
1371 | #ifdef CONFIG_INTEGRITY | 1373 | #ifdef CONFIG_INTEGRITY |
1372 | static int do_bootm_integrity (int flag, int argc, char *argv[], | 1374 | static int do_bootm_integrity (int flag, int argc, char *argv[], |
1373 | bootm_headers_t *images) | 1375 | bootm_headers_t *images) |
1374 | { | 1376 | { |
1375 | void (*entry_point)(void); | 1377 | void (*entry_point)(void); |
1376 | 1378 | ||
1377 | if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) | 1379 | if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) |
1378 | return 1; | 1380 | return 1; |
1379 | 1381 | ||
1380 | #if defined(CONFIG_FIT) | 1382 | #if defined(CONFIG_FIT) |
1381 | if (!images->legacy_hdr_valid) { | 1383 | if (!images->legacy_hdr_valid) { |
1382 | fit_unsupported_reset ("INTEGRITY"); | 1384 | fit_unsupported_reset ("INTEGRITY"); |
1383 | return 1; | 1385 | return 1; |
1384 | } | 1386 | } |
1385 | #endif | 1387 | #endif |
1386 | 1388 | ||
1387 | entry_point = (void (*)(void))images->ep; | 1389 | entry_point = (void (*)(void))images->ep; |
1388 | 1390 | ||
1389 | printf ("## Transferring control to INTEGRITY (at address %08lx) ...\n", | 1391 | printf ("## Transferring control to INTEGRITY (at address %08lx) ...\n", |
1390 | (ulong)entry_point); | 1392 | (ulong)entry_point); |
1391 | 1393 | ||
1392 | show_boot_progress (15); | 1394 | show_boot_progress (15); |
1393 | 1395 | ||
1394 | /* | 1396 | /* |
1395 | * INTEGRITY Parameters: | 1397 | * INTEGRITY Parameters: |
1396 | * None | 1398 | * None |
1397 | */ | 1399 | */ |
1398 | (*entry_point)(); | 1400 | (*entry_point)(); |
1399 | 1401 | ||
1400 | return 1; | 1402 | return 1; |
1401 | } | 1403 | } |
1402 | #endif | 1404 | #endif |
1403 | 1405 |