2 * (C) Copyright 2000-2006
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5 * See file CREDITS for list of people who contributed to this
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
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
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
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
33 #include <LzmaWrapper.h>
34 #include <environment.h>
35 #include <asm/byteorder.h>
37 DECLARE_GLOBAL_DATA_PTR;
40 extern int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
43 extern void eth_halt(void);
45 #if (CONFIG_COMMANDS & CFG_CMD_DATE) || defined(CONFIG_TIMESTAMP)
50 * Continue booting an OS image; caller already has:
51 * - copied image header to global variable `header'
52 * - checked header magic number, checksums (both header & image),
53 * - verified image architecture (PPC) and type (KERNEL or MULTI),
54 * - loaded (first part of) image to header load address,
55 * - disabled interrupts.
57 extern void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
59 #ifdef CONFIG_SILENT_CONSOLE
60 static void fixup_silent_linux(void);
63 #if (CONFIG_COMMANDS & CFG_CMD_IMI)
64 static int image_info(unsigned long addr);
67 image_header_t header;
68 ulong load_addr = CFG_LOAD_ADDR; /* default load address */
70 #if !defined(CONFIG_FOR_8DEVICES_CARAMBOLA2) && \
71 !defined(CONFIG_FOR_DLINK_DIR505_A1) && \
72 !defined(CONFIG_FOR_DRAGINO_V2)
73 void fake_image_header(image_header_t *hdr, tplink_image_header_t *tpl_hdr){
74 memset(hdr, 0, sizeof(image_header_t));
76 /* Build new header */
77 hdr->ih_magic = htonl(IH_MAGIC);
80 hdr->ih_size = htonl(tpl_hdr->kernelLen);
81 hdr->ih_load = htonl(tpl_hdr->kernelTextAddr);
82 hdr->ih_ep = htonl(tpl_hdr->kernelEntryPoint);
84 hdr->ih_os = IH_OS_LINUX;
85 hdr->ih_arch = IH_CPU_MIPS;
86 hdr->ih_type = IH_TYPE_KERNEL;
87 hdr->ih_comp = IH_COMP_LZMA;
89 strncpy((char *)hdr->ih_name, (char *)tpl_hdr->signiture_1, IH_NMLEN);
91 #endif /* if !defined(CONFIG_FOR_8DEVICES_CARAMBOLA2) && !defined(CONFIG_FOR_DLINK_DIR505_A1) && !defined(CONFIG_FOR_DRAGINO_V2) */
93 int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){
94 ulong addr, data, len;
95 uint unc_len = CFG_BOOTM_LEN;
97 image_header_t *hdr = &header;
98 #if !defined(CONFIG_FOR_8DEVICES_CARAMBOLA2) && \
99 !defined(CONFIG_FOR_DLINK_DIR505_A1) && \
100 !defined(CONFIG_FOR_DRAGINO_V2)
101 tplink_image_header_t *fileTag;
107 addr = simple_strtoul(argv[1], NULL, 16);
110 printf("Booting image at: 0x%08lX\n", addr);
112 #if defined(CONFIG_FOR_8DEVICES_CARAMBOLA2) || \
113 defined(CONFIG_FOR_DLINK_DIR505_A1) || \
114 defined(CONFIG_FOR_DRAGINO_V2)
115 memmove(&header, (char *)addr, sizeof(image_header_t));
116 print_image_hdr(hdr);
118 data = addr + sizeof(image_header_t);
120 fileTag = (tplink_image_header_t *)addr;
121 print_image_hdr(fileTag);
123 fake_image_header(hdr, fileTag);
125 data = addr + TAG_LEN;
128 len = ntohl(hdr->ih_size);
131 * We have reached the point of no return: we are going to
132 * overwrite all exception vector code, so we cannot easily
133 * recover from any failures any more...
135 #ifdef CONFIG_NETCONSOLE
137 * Stop the ethernet stack if NetConsole could have
143 #if defined(CONFIG_AR7100) || defined(CONFIG_AR7240)
145 * Flush everything, restore caches for linux
147 //mips_cache_flush();
148 //mips_icache_flush_ix();
150 /* XXX - this causes problems when booting from flash */
151 /* dcache_disable(); */
154 /* case IH_COMP_LZMA:*/
155 puts("Uncompressing kernel image... ");
157 i = lzma_inflate((unsigned char *)data, len, (unsigned char*)ntohl(hdr->ih_load), (int *)&unc_len);
159 if(i != LZMA_RESULT_OK){
160 printf("## Error: LZMA error num: %d\n", i);
166 #ifdef CONFIG_SILENT_CONSOLE
167 fixup_silent_linux();
170 do_bootm_linux(cmdtp, flag, argc, argv);
173 puts("\n## Error: control returned to monitor - resetting...\n");
174 do_reset(cmdtp, flag, argc, argv);
180 U_BOOT_CMD(bootm, 2, 1, do_bootm, "boot application image from memory\n", "[addr]\n"
181 "\t- boot application image stored in memory at address 'addr'\n");
183 #ifdef CONFIG_SILENT_CONSOLE
184 static void fixup_silent_linux(){
185 char buf[256], *start, *end;
186 char *cmdline = getenv("bootargs");
188 /* Only fix cmdline when requested */
189 if(!(gd->flags & GD_FLG_SILENT)){
194 printf("before silent fix-up: %s\n", cmdline);
198 if((start = strstr(cmdline, "console=")) != NULL){
199 end = strchr(start, ' ');
200 strncpy(buf, cmdline, (start - cmdline + 8));
202 strcpy(buf + (start - cmdline + 8), end);
204 buf[start - cmdline + 8] = '\0';
207 strcpy(buf, cmdline);
208 strcat(buf, " console=");
211 strcpy(buf, "console=");
214 setenv("bootargs", buf);
215 debug("after silent fix-up: %s\n", buf);
217 #endif /* CONFIG_SILENT_CONSOLE */
219 #if defined(CONFIG_FOR_8DEVICES_CARAMBOLA2) || \
220 defined(CONFIG_FOR_DLINK_DIR505_A1) || \
221 defined(CONFIG_FOR_DRAGINO_V2)
222 static void print_type(image_header_t *hdr){
223 char *os, *arch, *type, *comp;
252 switch(hdr->ih_arch){
254 arch = "Invalid CPU";
272 arch = "MIPS 64 Bit";
287 arch = "SPARC 64 Bit";
292 case IH_CPU_MICROBLAZE:
302 arch = "Unknown Architecture";
306 switch(hdr->ih_type){
307 case IH_TYPE_INVALID:
308 type = "Invalid Image";
310 case IH_TYPE_STANDALONE:
311 type = "Standalone Program";
314 type = "Kernel Image";
316 case IH_TYPE_RAMDISK:
317 type = "RAMDisk Image";
320 type = "Multi-File Image";
322 case IH_TYPE_FIRMWARE:
329 type = "Unknown Image";
333 switch(hdr->ih_comp){
335 comp = "uncompressed";
338 comp = "gzip compressed";
341 comp = "bzip2 compressed";
344 comp = "lzma compressed";
347 comp = "unknown compression";
351 printf("%s %s %s (%s)", arch, os, type, comp);
354 void print_image_hdr(image_header_t *hdr){
355 #if (CONFIG_COMMANDS & CFG_CMD_DATE) || defined(CONFIG_TIMESTAMP)
356 time_t timestamp = (time_t)ntohl(hdr->ih_time);
360 printf("\n Image name: %.*s\n", IH_NMLEN, hdr->ih_name);
362 #if (CONFIG_COMMANDS & CFG_CMD_DATE) || defined(CONFIG_TIMESTAMP)
363 to_tm(timestamp, &tm);
364 printf(" Created: %4d-%02d-%02d %2d:%02d:%02d UTC\n", tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
365 #endif /* CFG_CMD_DATE, CONFIG_TIMESTAMP */
367 puts(" Image type: ");
370 printf("\n Data size: %d Bytes = ", ntohl(hdr->ih_size));
371 print_size(ntohl(hdr->ih_size), "\n");
373 printf(" Load address: 0x%08X\n Entry point: 0x%08X\n", ntohl(hdr->ih_load), ntohl(hdr->ih_ep));
375 if(hdr->ih_type == IH_TYPE_MULTI){
378 ulong *len_ptr = (ulong *)((ulong)hdr + sizeof(image_header_t));
380 puts(" Contents:\n");
382 for(i = 0; (len = ntohl(*len_ptr)); ++i, ++len_ptr){
383 printf(" Image %d: %8ld Bytes = ", i, len);
384 print_size(len, "\n");
391 void print_image_hdr(tplink_image_header_t *hdr){
392 printf("\n Image name: %.*s %.*s\n", SIG_LEN, hdr->signiture_1, SIG_LEN_2, hdr->signiture_2);
393 puts(" Image type: MIPS Linux Kernel Image (lzma compressed)\n");
394 printf(" Data size: %d Bytes = ", ntohl(hdr->kernelLen));
395 print_size(ntohl(hdr->kernelLen), "\n");
396 printf(" Load address: 0x%08X\n Entry point: 0x%08X\n\n", ntohl(hdr->kernelTextAddr), ntohl(hdr->kernelEntryPoint));
398 #endif /* defined(CONFIG_FOR_8DEVICES_CARAMBOLA2) || defined(CONFIG_FOR_DLINK_DIR505_A1) || defined(CONFIG_FOR_DRAGINO_V2) */
400 #if (CONFIG_COMMANDS & CFG_CMD_IMI)
401 int do_iminfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){
406 addr = simple_strtoul(argv[1], NULL, 16);
407 return image_info(addr);
410 if(cmdtp->help != NULL){
411 printf("Usage:\n%s %s\n", cmdtp->name, cmdtp->help);
413 printf("Usage:\n%s %s\n", cmdtp->name, cmdtp->usage);
416 printf("Usage:\n%s %s\n", cmdtp->name, cmdtp->usage);
424 static int image_info(ulong addr){
425 ulong data, len, checksum;
426 image_header_t *hdr = &header;
428 printf("\nChecking image at 0x%08lX...\n", addr);
430 /* Copy header so we can blank CRC field for re-calculation */
431 memmove(&header, (char *)addr, sizeof(image_header_t));
433 data = (ulong)&header;
434 len = sizeof(image_header_t);
436 checksum = ntohl(hdr->ih_hcrc);
439 if(crc32(0, (uchar *)data, len) != checksum){
440 puts("## Error: bad header checksum!\n");
444 /* for multi-file images we need the data part, too */
445 print_image_hdr((image_header_t *)addr);
447 data = addr + sizeof(image_header_t);
448 len = ntohl(hdr->ih_size);
450 puts(" Verifying checksum... ");
452 if(crc32(0, (uchar *)data, len) != ntohl(hdr->ih_dcrc)){
453 puts("bad data CRC!\n");
462 U_BOOT_CMD(iminfo, 2, 1, do_iminfo, "print firmware header\n", "address\n"
463 "\t- print header information for firmware image startting at address 'address'\n"
466 #endif /* CFG_CMD_IMI */