Merge branch 'new-image' of git://www.denx.de/git/u-boot-testing
Conflicts: common/cmd_bootm.c cpu/mpc8xx/cpu.c Signed-off-by: Bartlomiej Sieka <tur@semihalf.com>
This commit is contained in:
commit
27f33e9f45
4
Makefile
4
Makefile
@ -2890,7 +2890,9 @@ clobber: clean
|
||||
@rm -f $(OBJS) $(obj)*.bak $(obj)ctags $(obj)etags $(obj)TAGS \
|
||||
$(obj)cscope.* $(obj)*.*~
|
||||
@rm -f $(obj)u-boot $(obj)u-boot.map $(obj)u-boot.hex $(ALL)
|
||||
@rm -f $(obj)tools/{crc32.c,environment.c,env/crc32.c,sha1.c,inca-swap-bytes}
|
||||
@rm -f $(obj)tools/{crc32.c,environment.c,env/crc32.c,md5.c,sha1.c,inca-swap-bytes}
|
||||
@rm -f $(obj)tools/{image.c,fdt.c,fdt_ro.c,fdt_rw.c,fdt_strerror.c}
|
||||
@rm -f $(obj)tools/{fdt_wip.c,libfdt_internal.h}
|
||||
@rm -f $(obj)cpu/mpc824x/bedbug_603e.c
|
||||
@rm -f $(obj)include/asm/proc $(obj)include/asm/arch $(obj)include/asm
|
||||
@[ ! -d $(obj)nand_spl ] || find $(obj)nand_spl -lname "*" -print | xargs rm -f
|
||||
|
114
README
114
README
@ -1660,6 +1660,8 @@ The following options need to be configured:
|
||||
example, some LED's) on your board. At the moment,
|
||||
the following checkpoints are implemented:
|
||||
|
||||
Legacy uImage format:
|
||||
|
||||
Arg Where When
|
||||
1 common/cmd_bootm.c before attempting to boot an image
|
||||
-1 common/cmd_bootm.c Image header has bad magic number
|
||||
@ -1670,25 +1672,26 @@ The following options need to be configured:
|
||||
4 common/cmd_bootm.c Image data has correct checksum
|
||||
-4 common/cmd_bootm.c Image is for unsupported architecture
|
||||
5 common/cmd_bootm.c Architecture check OK
|
||||
-5 common/cmd_bootm.c Wrong Image Type (not kernel, multi, standalone)
|
||||
-5 common/cmd_bootm.c Wrong Image Type (not kernel, multi)
|
||||
6 common/cmd_bootm.c Image Type check OK
|
||||
-6 common/cmd_bootm.c gunzip uncompression error
|
||||
-7 common/cmd_bootm.c Unimplemented compression type
|
||||
7 common/cmd_bootm.c Uncompression OK
|
||||
-8 common/cmd_bootm.c Wrong Image Type (not kernel, multi, standalone)
|
||||
8 common/cmd_bootm.c Image Type check OK
|
||||
8 common/cmd_bootm.c No uncompress/copy overwrite error
|
||||
-9 common/cmd_bootm.c Unsupported OS (not Linux, BSD, VxWorks, QNX)
|
||||
9 common/cmd_bootm.c Start initial ramdisk verification
|
||||
-10 common/cmd_bootm.c Ramdisk header has bad magic number
|
||||
-11 common/cmd_bootm.c Ramdisk header has bad checksum
|
||||
10 common/cmd_bootm.c Ramdisk header is OK
|
||||
-12 common/cmd_bootm.c Ramdisk data has bad checksum
|
||||
11 common/cmd_bootm.c Ramdisk data has correct checksum
|
||||
12 common/cmd_bootm.c Ramdisk verification complete, start loading
|
||||
-13 common/cmd_bootm.c Wrong Image Type (not PPC Linux Ramdisk)
|
||||
13 common/cmd_bootm.c Start multifile image verification
|
||||
14 common/cmd_bootm.c No initial ramdisk, no multifile, continue.
|
||||
15 common/cmd_bootm.c All preparation done, transferring control to OS
|
||||
|
||||
9 common/image.c Start initial ramdisk verification
|
||||
-10 common/image.c Ramdisk header has bad magic number
|
||||
-11 common/image.c Ramdisk header has bad checksum
|
||||
10 common/image.c Ramdisk header is OK
|
||||
-12 common/image.c Ramdisk data has bad checksum
|
||||
11 common/image.c Ramdisk data has correct checksum
|
||||
12 common/image.c Ramdisk verification complete, start loading
|
||||
-13 common/image.c Wrong Image Type (not PPC Linux Ramdisk)
|
||||
13 common/image.c Start multifile image verification
|
||||
14 common/image.c No initial ramdisk, no multifile, continue.
|
||||
|
||||
15 lib_<arch>/bootm.c All preparation done, transferring control to OS
|
||||
|
||||
-30 lib_ppc/board.c Fatal error, hang the system
|
||||
-31 post/post.c POST test failed, detected by post_output_backlog()
|
||||
@ -1758,6 +1761,59 @@ The following options need to be configured:
|
||||
-83 common/cmd_net.c some error in automatic boot or autoscript
|
||||
84 common/cmd_net.c end without errors
|
||||
|
||||
FIT uImage format:
|
||||
|
||||
Arg Where When
|
||||
100 common/cmd_bootm.c Kernel FIT Image has correct format
|
||||
-100 common/cmd_bootm.c Kernel FIT Image has incorrect format
|
||||
101 common/cmd_bootm.c No Kernel subimage unit name, using configuration
|
||||
-101 common/cmd_bootm.c Can't get configuration for kernel subimage
|
||||
102 common/cmd_bootm.c Kernel unit name specified
|
||||
-103 common/cmd_bootm.c Can't get kernel subimage node offset
|
||||
103 common/cmd_bootm.c Found configuration node
|
||||
104 common/cmd_bootm.c Got kernel subimage node offset
|
||||
-104 common/cmd_bootm.c Kernel subimage hash verification failed
|
||||
105 common/cmd_bootm.c Kernel subimage hash verification OK
|
||||
-105 common/cmd_bootm.c Kernel subimage is for unsupported architecture
|
||||
106 common/cmd_bootm.c Architecture check OK
|
||||
-106 common/cmd_bootm.c Kernel subimage has wrong typea
|
||||
107 common/cmd_bootm.c Kernel subimge type OK
|
||||
-107 common/cmd_bootm.c Can't get kernel subimage data/size
|
||||
108 common/cmd_bootm.c Got kernel subimage data/size
|
||||
-108 common/cmd_bootm.c Wrong image type (not legacy, FIT)
|
||||
-109 common/cmd_bootm.c Can't get kernel subimage type
|
||||
-110 common/cmd_bootm.c Can't get kernel subimage comp
|
||||
-111 common/cmd_bootm.c Can't get kernel subimage os
|
||||
-112 common/cmd_bootm.c Can't get kernel subimage load address
|
||||
-113 common/cmd_bootm.c Image uncompress/copy overwrite error
|
||||
|
||||
120 common/image.c Start initial ramdisk verification
|
||||
-120 common/image.c Ramdisk FIT image has incorrect format
|
||||
121 common/image.c Ramdisk FIT image has correct format
|
||||
122 common/image.c No Ramdisk subimage unit name, using configuration
|
||||
-122 common/image.c Can't get configuration for ramdisk subimage
|
||||
123 common/image.c Ramdisk unit name specified
|
||||
-124 common/image.c Can't get ramdisk subimage node offset
|
||||
125 common/image.c Got ramdisk subimage node offset
|
||||
-125 common/image.c Ramdisk subimage hash verification failed
|
||||
126 common/image.c Ramdisk subimage hash verification OK
|
||||
-126 common/image.c Ramdisk subimage for unsupported architecture
|
||||
127 common/image.c Architecture check OK
|
||||
-127 common/image.c Can't get ramdisk subimage data/size
|
||||
128 common/image.c Got ramdisk subimage data/size
|
||||
129 common/image.c Can't get ramdisk load address
|
||||
-129 common/image.c Got ramdisk load address
|
||||
|
||||
-130 common/cmd_doc.c Icorrect FIT image format
|
||||
131 common/cmd_doc.c FIT image format OK
|
||||
|
||||
-140 common/cmd_ide.c Icorrect FIT image format
|
||||
141 common/cmd_ide.c FIT image format OK
|
||||
|
||||
-150 common/cmd_nand.c Icorrect FIT image format
|
||||
151 common/cmd_nand.c FIT image format OK
|
||||
|
||||
|
||||
Modem Support:
|
||||
--------------
|
||||
|
||||
@ -2634,6 +2690,14 @@ Some configuration options can be set using Environment Variables:
|
||||
configuration from the BOOTP server, but not try to
|
||||
load any image using TFTP
|
||||
|
||||
autoscript - if set to "yes" commands like "loadb", "loady",
|
||||
"bootp", "tftpb", "rarpboot" and "nfs" will attempt
|
||||
to automatically run script images (by internally
|
||||
calling "autoscript").
|
||||
|
||||
autoscript_uname - if script image is in a format (FIT) this
|
||||
variable is used to get script subimage unit name.
|
||||
|
||||
autostart - if set to "yes", an image loaded using the "bootp",
|
||||
"rarpboot", "tftpboot" or "diskboot" commands will
|
||||
be automatically started (by internally calling
|
||||
@ -2848,10 +2912,24 @@ o If neither SROM nor the environment contain a MAC address, an error
|
||||
Image Formats:
|
||||
==============
|
||||
|
||||
The "boot" commands of this monitor operate on "image" files which
|
||||
can be basicly anything, preceeded by a special header; see the
|
||||
definitions in include/image.h for details; basicly, the header
|
||||
defines the following image properties:
|
||||
U-Boot is capable of booting (and performing other auxiliary operations on)
|
||||
images in two formats:
|
||||
|
||||
New uImage format (FIT)
|
||||
-----------------------
|
||||
|
||||
Flexible and powerful format based on Flattened Image Tree -- FIT (similar
|
||||
to Flattened Device Tree). It allows the use of images with multiple
|
||||
components (several kernels, ramdisks, etc.), with contents protected by
|
||||
SHA1, MD5 or CRC32. More details are found in the doc/uImage.FIT directory.
|
||||
|
||||
|
||||
Old uImage format
|
||||
-----------------
|
||||
|
||||
Old image format is based on binary files which can be basically anything,
|
||||
preceded by a special header; see the definitions in include/image.h for
|
||||
details; basically, the header defines the following image properties:
|
||||
|
||||
* Target Operating System (Provisions for OpenBSD, NetBSD, FreeBSD,
|
||||
4.4BSD, Linux, SVR4, Esix, Solaris, Irix, SCO, Dell, NCR, VxWorks,
|
||||
|
@ -139,8 +139,15 @@ int misc_init_r (void)
|
||||
struct rtc_time tm;
|
||||
char bootcmd[32];
|
||||
|
||||
hdr = (image_header_t *) (CFG_MONITOR_BASE - sizeof (image_header_t));
|
||||
timestamp = (time_t) hdr->ih_time;
|
||||
hdr = (image_header_t *) (CFG_MONITOR_BASE - image_get_header_size ());
|
||||
#if defined(CONFIG_FIT)
|
||||
if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
|
||||
puts ("Non legacy image format not supported\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
timestamp = (time_t)image_get_time (hdr);
|
||||
to_tm (timestamp, &tm);
|
||||
printf ("Welcome to U-Boot on Cray L1. Compiled %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);
|
||||
|
||||
|
@ -89,24 +89,28 @@ extern block_dev_desc_t ide_dev_desc[CFG_IDE_MAXDEVICE];
|
||||
int au_check_cksum_valid(int i, long nbytes)
|
||||
{
|
||||
image_header_t *hdr;
|
||||
unsigned long checksum;
|
||||
|
||||
hdr = (image_header_t *)LOAD_ADDR;
|
||||
#if defined(CONFIG_FIT)
|
||||
if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
|
||||
puts ("Non legacy image format not supported\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((au_image[i].type == AU_FIRMWARE) && (au_image[i].size != ntohl(hdr->ih_size))) {
|
||||
if ((au_image[i].type == AU_FIRMWARE) &&
|
||||
(au_image[i].size != image_get_data_size (hdr))) {
|
||||
printf ("Image %s has wrong size\n", au_image[i].name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (nbytes != (sizeof(*hdr) + ntohl(hdr->ih_size))) {
|
||||
if (nbytes != (image_get_image_size (hdr))) {
|
||||
printf ("Image %s bad total SIZE\n", au_image[i].name);
|
||||
return -1;
|
||||
}
|
||||
/* check the data CRC */
|
||||
checksum = ntohl(hdr->ih_dcrc);
|
||||
|
||||
if (crc32 (0, (uchar *)(LOAD_ADDR + sizeof(*hdr)), ntohl(hdr->ih_size))
|
||||
!= checksum) {
|
||||
/* check the data CRC */
|
||||
if (!image_check_dcrc (hdr)) {
|
||||
printf ("Image %s bad data checksum\n", au_image[i].name);
|
||||
return -1;
|
||||
}
|
||||
@ -120,51 +124,53 @@ int au_check_header_valid(int i, long nbytes)
|
||||
unsigned long checksum;
|
||||
|
||||
hdr = (image_header_t *)LOAD_ADDR;
|
||||
#if defined(CONFIG_FIT)
|
||||
if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
|
||||
puts ("Non legacy image format not supported\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* check the easy ones first */
|
||||
#undef CHECK_VALID_DEBUG
|
||||
#ifdef CHECK_VALID_DEBUG
|
||||
printf("magic %#x %#x ", ntohl(hdr->ih_magic), IH_MAGIC);
|
||||
printf("arch %#x %#x ", hdr->ih_arch, IH_CPU_PPC);
|
||||
printf("size %#x %#lx ", ntohl(hdr->ih_size), nbytes);
|
||||
printf("type %#x %#x ", hdr->ih_type, IH_TYPE_KERNEL);
|
||||
printf("magic %#x %#x ", image_get_magic (hdr), IH_MAGIC);
|
||||
printf("arch %#x %#x ", image_get_arch (hdr), IH_ARCH_PPC);
|
||||
printf("size %#x %#lx ", image_get_data_size (hdr), nbytes);
|
||||
printf("type %#x %#x ", image_get_type (hdr), IH_TYPE_KERNEL);
|
||||
#endif
|
||||
if (nbytes < sizeof(*hdr))
|
||||
if (nbytes < image_get_header_size ())
|
||||
{
|
||||
printf ("Image %s bad header SIZE\n", au_image[i].name);
|
||||
return -1;
|
||||
}
|
||||
if (ntohl(hdr->ih_magic) != IH_MAGIC || hdr->ih_arch != IH_CPU_PPC)
|
||||
if (!image_check_magic (hdr) || !image_check_arch (hdr, IH_ARCH_PPC))
|
||||
{
|
||||
printf ("Image %s bad MAGIC or ARCH\n", au_image[i].name);
|
||||
return -1;
|
||||
}
|
||||
/* check the hdr CRC */
|
||||
checksum = ntohl(hdr->ih_hcrc);
|
||||
hdr->ih_hcrc = 0;
|
||||
|
||||
if (crc32 (0, (uchar *)hdr, sizeof(*hdr)) != checksum) {
|
||||
if (!image_check_hcrc (hdr)) {
|
||||
printf ("Image %s bad header checksum\n", au_image[i].name);
|
||||
return -1;
|
||||
}
|
||||
hdr->ih_hcrc = htonl(checksum);
|
||||
|
||||
/* check the type - could do this all in one gigantic if() */
|
||||
if ((au_image[i].type == AU_FIRMWARE) && (hdr->ih_type != IH_TYPE_FIRMWARE)) {
|
||||
if ((au_image[i].type == AU_FIRMWARE) && !image_check_type (hdr, IH_TYPE_FIRMWARE)) {
|
||||
printf ("Image %s wrong type\n", au_image[i].name);
|
||||
return -1;
|
||||
}
|
||||
if ((au_image[i].type == AU_SCRIPT) && (hdr->ih_type != IH_TYPE_SCRIPT)) {
|
||||
if ((au_image[i].type == AU_SCRIPT) && !image_check_type (hdr, IH_TYPE_SCRIPT)) {
|
||||
printf ("Image %s wrong type\n", au_image[i].name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* recycle checksum */
|
||||
checksum = ntohl(hdr->ih_size);
|
||||
checksum = image_get_data_size (hdr);
|
||||
|
||||
#if 0 /* test-only */
|
||||
/* for kernel and app the image header must also fit into flash */
|
||||
if (idx != IDX_DISK)
|
||||
checksum += sizeof(*hdr);
|
||||
checksum += image_get_header_size ();
|
||||
/* check the size does not exceed space in flash. HUSH scripts */
|
||||
/* all have ausize[] set to 0 */
|
||||
if ((ausize[idx] != 0) && (ausize[idx] < checksum)) {
|
||||
@ -190,17 +196,23 @@ int au_do_update(int i, long sz)
|
||||
#endif
|
||||
|
||||
hdr = (image_header_t *)LOAD_ADDR;
|
||||
#if defined(CONFIG_FIT)
|
||||
if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
|
||||
puts ("Non legacy image format not supported\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (au_image[i].type) {
|
||||
case AU_SCRIPT:
|
||||
printf("Executing script %s\n", au_image[i].name);
|
||||
|
||||
/* execute a script */
|
||||
if (hdr->ih_type == IH_TYPE_SCRIPT) {
|
||||
addr = (char *)((char *)hdr + sizeof(*hdr));
|
||||
if (image_check_type (hdr, IH_TYPE_SCRIPT)) {
|
||||
addr = (char *)((char *)hdr + image_get_header_size ());
|
||||
/* stick a NULL at the end of the script, otherwise */
|
||||
/* parse_string_outer() runs off the end. */
|
||||
addr[ntohl(hdr->ih_size)] = 0;
|
||||
addr[image_get_data_size (hdr)] = 0;
|
||||
addr += 8;
|
||||
|
||||
/*
|
||||
@ -231,8 +243,8 @@ int au_do_update(int i, long sz)
|
||||
*/
|
||||
if (au_image[i].type == AU_FIRMWARE) {
|
||||
char *orig = (char*)start;
|
||||
char *new = (char *)((char *)hdr + sizeof(*hdr));
|
||||
nbytes = ntohl(hdr->ih_size);
|
||||
char *new = (char *)((char *)hdr + image_get_header_size ());
|
||||
nbytes = image_get_data_size (hdr);
|
||||
|
||||
while(--nbytes) {
|
||||
if (*orig++ != *new++) {
|
||||
@ -272,12 +284,12 @@ int au_do_update(int i, long sz)
|
||||
/* strip the header - except for the kernel and ramdisk */
|
||||
if (au_image[i].type != AU_FIRMWARE) {
|
||||
addr = (char *)hdr;
|
||||
off = sizeof(*hdr);
|
||||
nbytes = sizeof(*hdr) + ntohl(hdr->ih_size);
|
||||
off = image_get_header_size ();
|
||||
nbytes = image_get_image_size (hdr);
|
||||
} else {
|
||||
addr = (char *)((char *)hdr + sizeof(*hdr));
|
||||
addr = (char *)((char *)hdr + image_get_header_size ());
|
||||
off = 0;
|
||||
nbytes = ntohl(hdr->ih_size);
|
||||
nbytes = image_get_data_size (hdr);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -305,15 +317,15 @@ int au_do_update(int i, long sz)
|
||||
* check the dcrc of the copy
|
||||
*/
|
||||
if (au_image[i].type != AU_NAND) {
|
||||
rc = crc32 (0, (uchar *)(start + off), ntohl(hdr->ih_size));
|
||||
rc = crc32 (0, (uchar *)(start + off), image_get_data_size (hdr));
|
||||
} else {
|
||||
#if defined(CONFIG_CMD_NAND) && defined(CFG_NAND_LEGACY)
|
||||
rc = nand_legacy_rw(nand_dev_desc, NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP,
|
||||
start, nbytes, (size_t *)&total, (uchar *)addr);
|
||||
rc = crc32 (0, (uchar *)(addr + off), ntohl(hdr->ih_size));
|
||||
rc = crc32 (0, (uchar *)(addr + off), image_get_data_size (hdr));
|
||||
#endif
|
||||
}
|
||||
if (rc != ntohl(hdr->ih_dcrc)) {
|
||||
if (rc != image_get_dcrc (hdr)) {
|
||||
printf ("Image %s Bad Data Checksum After COPY\n", au_image[i].name);
|
||||
return -1;
|
||||
}
|
||||
@ -497,10 +509,10 @@ int do_auto_update(void)
|
||||
|
||||
printf("Reading %s ...", au_image[i].name);
|
||||
/* just read the header */
|
||||
sz = do_fat_read(au_image[i].name, LOAD_ADDR, sizeof(image_header_t), LS_NO);
|
||||
sz = do_fat_read(au_image[i].name, LOAD_ADDR, image_get_header_size (), LS_NO);
|
||||
debug ("read %s sz %ld hdr %d\n",
|
||||
au_image[i].name, sz, sizeof(image_header_t));
|
||||
if (sz <= 0 || sz < sizeof(image_header_t)) {
|
||||
au_image[i].name, sz, image_get_header_size ());
|
||||
if (sz <= 0 || sz < image_get_header_size ()) {
|
||||
puts(" not found\n");
|
||||
continue;
|
||||
}
|
||||
@ -510,8 +522,8 @@ int do_auto_update(void)
|
||||
}
|
||||
sz = do_fat_read(au_image[i].name, LOAD_ADDR, MAX_LOADSZ, LS_NO);
|
||||
debug ("read %s sz %ld hdr %d\n",
|
||||
au_image[i].name, sz, sizeof(image_header_t));
|
||||
if (sz <= 0 || sz <= sizeof(image_header_t)) {
|
||||
au_image[i].name, sz, image_get_header_size ());
|
||||
if (sz <= 0 || sz <= image_get_header_size ()) {
|
||||
puts(" not found\n");
|
||||
continue;
|
||||
}
|
||||
|
@ -141,18 +141,21 @@ extern void lcd_enable(void);
|
||||
int au_check_cksum_valid(int idx, long nbytes)
|
||||
{
|
||||
image_header_t *hdr;
|
||||
unsigned long checksum;
|
||||
|
||||
hdr = (image_header_t *)LOAD_ADDR;
|
||||
#if defined(CONFIG_FIT)
|
||||
if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
|
||||
puts ("Non legacy image format not supported\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (nbytes != (sizeof(*hdr) + ntohl(hdr->ih_size))) {
|
||||
if (nbytes != image_get_image_size (hdr)) {
|
||||
printf ("Image %s bad total SIZE\n", aufile[idx]);
|
||||
return -1;
|
||||
}
|
||||
/* check the data CRC */
|
||||
checksum = ntohl(hdr->ih_dcrc);
|
||||
|
||||
if (crc32 (0, (uchar *)(LOAD_ADDR + sizeof(*hdr)), ntohl(hdr->ih_size)) != checksum) {
|
||||
if (!image_check_dcrc (hdr)) {
|
||||
printf ("Image %s bad data checksum\n", aufile[idx]);
|
||||
return -1;
|
||||
}
|
||||
@ -165,59 +168,62 @@ int au_check_header_valid(int idx, long nbytes)
|
||||
unsigned long checksum, fsize;
|
||||
|
||||
hdr = (image_header_t *)LOAD_ADDR;
|
||||
#if defined(CONFIG_FIT)
|
||||
if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
|
||||
puts ("Non legacy image format not supported\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* check the easy ones first */
|
||||
#undef CHECK_VALID_DEBUG
|
||||
#ifdef CHECK_VALID_DEBUG
|
||||
printf("magic %#x %#x ", ntohl(hdr->ih_magic), IH_MAGIC);
|
||||
printf("arch %#x %#x ", hdr->ih_arch, IH_CPU_ARM);
|
||||
printf("size %#x %#lx ", ntohl(hdr->ih_size), nbytes);
|
||||
printf("type %#x %#x ", hdr->ih_type, IH_TYPE_KERNEL);
|
||||
printf("magic %#x %#x ", image_get_magic (hdr), IH_MAGIC);
|
||||
printf("arch %#x %#x ", image_get_arch (hdr), IH_ARCH_ARM);
|
||||
printf("size %#x %#lx ", image_get_data_size (hdr), nbytes);
|
||||
printf("type %#x %#x ", image_get_type (hdr), IH_TYPE_KERNEL);
|
||||
#endif
|
||||
if (nbytes < sizeof(*hdr)) {
|
||||
if (nbytes < image_get_header_size ()) {
|
||||
printf ("Image %s bad header SIZE\n", aufile[idx]);
|
||||
ausize[idx] = 0;
|
||||
return -1;
|
||||
}
|
||||
if (ntohl(hdr->ih_magic) != IH_MAGIC || hdr->ih_arch != IH_CPU_PPC) {
|
||||
if (!image_check_magic (hdr) || !image_check_arch (hdr, IH_ARCH_PPC)) {
|
||||
printf ("Image %s bad MAGIC or ARCH\n", aufile[idx]);
|
||||
ausize[idx] = 0;
|
||||
return -1;
|
||||
}
|
||||
/* check the hdr CRC */
|
||||
checksum = ntohl(hdr->ih_hcrc);
|
||||
hdr->ih_hcrc = 0;
|
||||
|
||||
if (crc32 (0, (uchar *)hdr, sizeof(*hdr)) != checksum) {
|
||||
if (!image_check_hcrc (hdr)) {
|
||||
printf ("Image %s bad header checksum\n", aufile[idx]);
|
||||
ausize[idx] = 0;
|
||||
return -1;
|
||||
}
|
||||
hdr->ih_hcrc = htonl(checksum);
|
||||
/* check the type - could do this all in one gigantic if() */
|
||||
if ((idx == IDX_FIRMWARE) && (hdr->ih_type != IH_TYPE_FIRMWARE)) {
|
||||
if ((idx == IDX_FIRMWARE) && !image_check_type (hdr, IH_TYPE_FIRMWARE)) {
|
||||
printf ("Image %s wrong type\n", aufile[idx]);
|
||||
ausize[idx] = 0;
|
||||
return -1;
|
||||
}
|
||||
if ((idx == IDX_KERNEL) && (hdr->ih_type != IH_TYPE_KERNEL)) {
|
||||
if ((idx == IDX_KERNEL) && !image_check_type (hdr, IH_TYPE_KERNEL)) {
|
||||
printf ("Image %s wrong type\n", aufile[idx]);
|
||||
ausize[idx] = 0;
|
||||
return -1;
|
||||
}
|
||||
if ((idx == IDX_ROOTFS) &&
|
||||
( (hdr->ih_type != IH_TYPE_RAMDISK) && (hdr->ih_type != IH_TYPE_FILESYSTEM) )
|
||||
) {
|
||||
(!image_check_type (hdr, IH_TYPE_RAMDISK) &&
|
||||
!image_check_type (hdr, IH_TYPE_FILESYSTEM))) {
|
||||
printf ("Image %s wrong type\n", aufile[idx]);
|
||||
ausize[idx] = 0;
|
||||
return -1;
|
||||
}
|
||||
/* recycle checksum */
|
||||
checksum = ntohl(hdr->ih_size);
|
||||
checksum = image_get_data_size (hdr);
|
||||
|
||||
fsize = checksum + sizeof(*hdr);
|
||||
fsize = checksum + image_get_header_size ();
|
||||
/* for kernel and ramdisk the image header must also fit into flash */
|
||||
if (idx == IDX_KERNEL || hdr->ih_type == IH_TYPE_RAMDISK)
|
||||
checksum += sizeof(*hdr);
|
||||
if (idx == IDX_KERNEL || image_check_type (hdr, IH_TYPE_RAMDISK))
|
||||
checksum += image_get_header_size ();
|
||||
|
||||
/* check the size does not exceed space in flash. HUSH scripts */
|
||||
if ((ausize[idx] != 0) && (ausize[idx] < checksum)) {
|
||||
@ -240,13 +246,19 @@ int au_do_update(int idx, long sz)
|
||||
uint nbytes;
|
||||
|
||||
hdr = (image_header_t *)LOAD_ADDR;
|
||||
#if defined(CONFIG_FIT)
|
||||
if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
|
||||
puts ("Non legacy image format not supported\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* execute a script */
|
||||
if (hdr->ih_type == IH_TYPE_SCRIPT) {
|
||||
addr = (char *)((char *)hdr + sizeof(*hdr));
|
||||
if (image_check_type (hdr, IH_TYPE_SCRIPT)) {
|
||||
addr = (char *)((char *)hdr + image_get_header_size ());
|
||||
/* stick a NULL at the end of the script, otherwise */
|
||||
/* parse_string_outer() runs off the end. */
|
||||
addr[ntohl(hdr->ih_size)] = 0;
|
||||
addr[image_get_data_size (hdr)] = 0;
|
||||
addr += 8;
|
||||
parse_string_outer(addr, FLAG_PARSE_SEMICOLON);
|
||||
return 0;
|
||||
@ -278,19 +290,20 @@ int au_do_update(int idx, long sz)
|
||||
#endif
|
||||
|
||||
/* strip the header - except for the kernel and ramdisk */
|
||||
if (hdr->ih_type == IH_TYPE_KERNEL || hdr->ih_type == IH_TYPE_RAMDISK) {
|
||||
if (image_check_type (hdr, IH_TYPE_KERNEL) ||
|
||||
image_check_type (hdr, IH_TYPE_RAMDISK)) {
|
||||
addr = (char *)hdr;
|
||||
off = sizeof(*hdr);
|
||||
nbytes = sizeof(*hdr) + ntohl(hdr->ih_size);
|
||||
off = image_get_header_size ();
|
||||
nbytes = image_get_image_size (hdr);
|
||||
} else {
|
||||
addr = (char *)((char *)hdr + sizeof(*hdr));
|
||||
addr = (char *)((char *)hdr + image_get_header_size ());
|
||||
#ifdef AU_UPDATE_TEST
|
||||
/* copy it to where Linux goes */
|
||||
if (idx == IDX_FIRMWARE)
|
||||
start = aufl_layout[1].start;
|
||||
#endif
|
||||
off = 0;
|
||||
nbytes = ntohl(hdr->ih_size);
|
||||
nbytes = image_get_data_size (hdr);
|
||||
}
|
||||
|
||||
/* copy the data from RAM to FLASH */
|
||||
@ -306,7 +319,8 @@ int au_do_update(int idx, long sz)
|
||||
#endif
|
||||
|
||||
/* check the data CRC of the copy */
|
||||
if (crc32 (0, (uchar *)(start + off), ntohl(hdr->ih_size)) != ntohl(hdr->ih_dcrc)) {
|
||||
if (crc32 (0, (uchar *)(start + off), image_get_data_size (hdr)) !=
|
||||
image_get_dcrc (hdr)) {
|
||||
printf ("Image %s Bad Data Checksum after COPY\n", aufile[idx]);
|
||||
return -1;
|
||||
}
|
||||
@ -442,10 +456,10 @@ int do_auto_update(void)
|
||||
for (i = 0; i < AU_MAXFILES; i++) {
|
||||
ulong imsize;
|
||||
/* just read the header */
|
||||
sz = file_fat_read(aufile[i], LOAD_ADDR, sizeof(image_header_t));
|
||||
sz = file_fat_read(aufile[i], LOAD_ADDR, image_get_header_size ());
|
||||
debug ("read %s sz %ld hdr %d\n",
|
||||
aufile[i], sz, sizeof(image_header_t));
|
||||
if (sz <= 0 || sz < sizeof(image_header_t)) {
|
||||
aufile[i], sz, image_get_header_size ());
|
||||
if (sz <= 0 || sz < image_get_header_size ()) {
|
||||
debug ("%s not found\n", aufile[i]);
|
||||
ausize[i] = 0;
|
||||
continue;
|
||||
@ -474,14 +488,14 @@ int do_auto_update(void)
|
||||
sz = file_fat_read(aufile[i], LOAD_ADDR, ausize[i]);
|
||||
|
||||
debug ("read %s sz %ld hdr %d\n",
|
||||
aufile[i], sz, sizeof(image_header_t));
|
||||
aufile[i], sz, image_get_header_size ());
|
||||
|
||||
if (sz != ausize[i]) {
|
||||
printf ("%s: size %d read %d?\n", aufile[i], ausize[i], sz);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sz <= 0 || sz <= sizeof(image_header_t)) {
|
||||
if (sz <= 0 || sz <= image_get_header_size ()) {
|
||||
debug ("%s not found\n", aufile[i]);
|
||||
continue;
|
||||
}
|
||||
|
@ -57,9 +57,6 @@ extern int mem_test(ulong start, ulong ramsize, int quiet);
|
||||
|
||||
extern flash_info_t flash_info[]; /* info for FLASH chips */
|
||||
|
||||
static image_header_t header;
|
||||
|
||||
|
||||
static int
|
||||
mpl_prg(uchar *src, ulong size)
|
||||
{
|
||||
@ -77,7 +74,7 @@ mpl_prg(uchar *src, ulong size)
|
||||
info = &flash_info[0];
|
||||
|
||||
#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405) || defined(CONFIG_PATI)
|
||||
if (ntohl(magic[0]) != IH_MAGIC) {
|
||||
if (uimage_to_cpu (magic[0]) != IH_MAGIC) {
|
||||
puts("Bad Magic number\n");
|
||||
return -1;
|
||||
}
|
||||
@ -179,44 +176,46 @@ mpl_prg(uchar *src, ulong size)
|
||||
static int
|
||||
mpl_prg_image(uchar *ld_addr)
|
||||
{
|
||||
unsigned long len, checksum;
|
||||
unsigned long len;
|
||||
uchar *data;
|
||||
image_header_t *hdr = &header;
|
||||
image_header_t *hdr = (image_header_t *)ld_addr;
|
||||
int rc;
|
||||
|
||||
/* Copy header so we can blank CRC field for re-calculation */
|
||||
memcpy (&header, (char *)ld_addr, sizeof(image_header_t));
|
||||
if (ntohl(hdr->ih_magic) != IH_MAGIC) {
|
||||
#if defined(CONFIG_FIT)
|
||||
if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
|
||||
puts ("Non legacy image format not supported\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!image_check_magic (hdr)) {
|
||||
puts("Bad Magic Number\n");
|
||||
return 1;
|
||||
}
|
||||
print_image_hdr(hdr);
|
||||
if (hdr->ih_os != IH_OS_U_BOOT) {
|
||||
image_print_contents (hdr);
|
||||
if (!image_check_os (hdr, IH_OS_U_BOOT)) {
|
||||
puts("No U-Boot Image\n");
|
||||
return 1;
|
||||
}
|
||||
if (hdr->ih_type != IH_TYPE_FIRMWARE) {
|
||||
if (!image_check_type (hdr, IH_TYPE_FIRMWARE)) {
|
||||
puts("No Firmware Image\n");
|
||||
return 1;
|
||||
}
|
||||
data = (uchar *)&header;
|
||||
len = sizeof(image_header_t);
|
||||
checksum = ntohl(hdr->ih_hcrc);
|
||||
hdr->ih_hcrc = 0;
|
||||
if (crc32 (0, (uchar *)data, len) != checksum) {
|
||||
if (!image_check_hcrc (hdr)) {
|
||||
puts("Bad Header Checksum\n");
|
||||
return 1;
|
||||
}
|
||||
data = ld_addr + sizeof(image_header_t);
|
||||
len = ntohl(hdr->ih_size);
|
||||
puts("Verifying Checksum ... ");
|
||||
if (crc32 (0, (uchar *)data, len) != ntohl(hdr->ih_dcrc)) {
|
||||
if (!image_check_dcrc (hdr)) {
|
||||
puts("Bad Data CRC\n");
|
||||
return 1;
|
||||
}
|
||||
puts("OK\n");
|
||||
|
||||
if (hdr->ih_comp != IH_COMP_NONE) {
|
||||
data = (uchar *)image_get_data (hdr);
|
||||
len = image_get_data_size (hdr);
|
||||
|
||||
if (image_get_comp (hdr) != IH_COMP_NONE) {
|
||||
uchar *buf;
|
||||
/* reserve space for uncompressed image */
|
||||
if ((buf = malloc(IMAGE_SIZE)) == NULL) {
|
||||
@ -224,7 +223,7 @@ mpl_prg_image(uchar *ld_addr)
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch (hdr->ih_comp) {
|
||||
switch (image_get_comp (hdr)) {
|
||||
case IH_COMP_GZIP:
|
||||
puts("Uncompressing (GZIP) ... ");
|
||||
rc = gunzip ((void *)(buf), IMAGE_SIZE, data, &len);
|
||||
@ -253,7 +252,8 @@ mpl_prg_image(uchar *ld_addr)
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
printf ("Unimplemented compression type %d\n", hdr->ih_comp);
|
||||
printf ("Unimplemented compression type %d\n",
|
||||
image_get_comp (hdr));
|
||||
free(buf);
|
||||
return 1;
|
||||
}
|
||||
|
@ -157,8 +157,15 @@ int do_loadpci (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
char *s;
|
||||
|
||||
if (((s = getenv("autoscript")) != NULL) && (strcmp(s,"yes") == 0)) {
|
||||
printf("Running autoscript at addr 0x%08lX ...\n", load_addr);
|
||||
rcode = autoscript (bd, load_addr);
|
||||
printf ("Running autoscript at addr 0x%08lX", load_addr);
|
||||
|
||||
s = getenv ("autoscript_uname");
|
||||
if (s)
|
||||
printf (":%s ...\n", s);
|
||||
else
|
||||
puts (" ...\n");
|
||||
|
||||
rcode = autoscript (load_addr, s);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -131,45 +131,44 @@ static int fpga_reset (fpga_t* fpga)
|
||||
static int fpga_load (fpga_t* fpga, ulong addr, int checkall)
|
||||
{
|
||||
volatile uchar *fpga_addr = (volatile uchar *)fpga->conf_base;
|
||||
image_header_t hdr;
|
||||
ulong len, checksum;
|
||||
uchar *data = (uchar *)&hdr;
|
||||
char *s, msg[32];
|
||||
image_header_t *hdr = (image_header_t *)addr;
|
||||
ulong len;
|
||||
uchar *data;
|
||||
char msg[32];
|
||||
int verify, i;
|
||||
|
||||
#if defined(CONFIG_FIT)
|
||||
if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
|
||||
puts ("Non legacy image format not supported\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Check the image header and data of the net-list
|
||||
*/
|
||||
memcpy (&hdr, (char *)addr, sizeof(image_header_t));
|
||||
|
||||
if (hdr.ih_magic != IH_MAGIC) {
|
||||
if (!image_check_magic (hdr)) {
|
||||
strcpy (msg, "Bad Image Magic Number");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
len = sizeof(image_header_t);
|
||||
|
||||
checksum = hdr.ih_hcrc;
|
||||
hdr.ih_hcrc = 0;
|
||||
|
||||
if (crc32 (0, data, len) != checksum) {
|
||||
if (!image_check_hcrc (hdr)) {
|
||||
strcpy (msg, "Bad Image Header CRC");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
data = (uchar*)(addr + sizeof(image_header_t));
|
||||
len = hdr.ih_size;
|
||||
data = (uchar*)image_get_data (hdr);
|
||||
len = image_get_data_size (hdr);
|
||||
|
||||
s = getenv ("verify");
|
||||
verify = (s && (*s == 'n')) ? 0 : 1;
|
||||
verify = getenv_verify ();
|
||||
if (verify) {
|
||||
if (crc32 (0, data, len) != hdr.ih_dcrc) {
|
||||
if (!image_check_dcrc (hdr)) {
|
||||
strcpy (msg, "Bad Image Data CRC");
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
|
||||
if (checkall && fpga_get_version(fpga, (char *)(hdr.ih_name)) < 0)
|
||||
if (checkall && fpga_get_version(fpga, image_get_name (hdr)) < 0)
|
||||
return 1;
|
||||
|
||||
/* align length */
|
||||
@ -184,7 +183,7 @@ static int fpga_load (fpga_t* fpga, ulong addr, int checkall)
|
||||
goto failure;
|
||||
}
|
||||
|
||||
printf ("(%s)... ", hdr.ih_name);
|
||||
printf ("(%s)... ", image_get_name (hdr));
|
||||
/*
|
||||
* Copy data to FPGA
|
||||
*/
|
||||
@ -341,7 +340,14 @@ int fpga_init (void)
|
||||
}
|
||||
|
||||
hdr = (image_header_t *)addr;
|
||||
if ((new_id = fpga_get_version(fpga, (char *)(hdr->ih_name))) == -1)
|
||||
#if defined(CONFIG_FIT)
|
||||
if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
|
||||
puts ("Non legacy image format not supported\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((new_id = fpga_get_version(fpga, image_get_name (hdr))) == -1)
|
||||
return 1;
|
||||
|
||||
do_load = 1;
|
||||
|
@ -209,21 +209,21 @@ int
|
||||
au_check_cksum_valid(int idx, long nbytes)
|
||||
{
|
||||
image_header_t *hdr;
|
||||
unsigned long checksum;
|
||||
|
||||
hdr = (image_header_t *)LOAD_ADDR;
|
||||
#if defined(CONFIG_FIT)
|
||||
if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
|
||||
puts ("Non legacy image format not supported\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (nbytes != (sizeof(*hdr) + ntohl(hdr->ih_size)))
|
||||
{
|
||||
if (nbytes != image_get_image_size (hdr)) {
|
||||
printf ("Image %s bad total SIZE\n", aufile[idx]);
|
||||
return -1;
|
||||
}
|
||||
/* check the data CRC */
|
||||
checksum = ntohl(hdr->ih_dcrc);
|
||||
|
||||
if (crc32 (0, (uchar *)(LOAD_ADDR + sizeof(*hdr)), ntohl(hdr->ih_size))
|
||||
!= checksum)
|
||||
{
|
||||
if (!image_check_dcrc (hdr)) {
|
||||
printf ("Image %s bad data checksum\n", aufile[idx]);
|
||||
return -1;
|
||||
}
|
||||
@ -238,54 +238,55 @@ au_check_header_valid(int idx, long nbytes)
|
||||
unsigned char buf[4];
|
||||
|
||||
hdr = (image_header_t *)LOAD_ADDR;
|
||||
#if defined(CONFIG_FIT)
|
||||
if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
|
||||
puts ("Non legacy image format not supported\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* check the easy ones first */
|
||||
#undef CHECK_VALID_DEBUG
|
||||
#ifdef CHECK_VALID_DEBUG
|
||||
printf("magic %#x %#x ", ntohl(hdr->ih_magic), IH_MAGIC);
|
||||
printf("arch %#x %#x ", hdr->ih_arch, IH_CPU_ARM);
|
||||
printf("size %#x %#lx ", ntohl(hdr->ih_size), nbytes);
|
||||
printf("type %#x %#x ", hdr->ih_type, IH_TYPE_KERNEL);
|
||||
printf("magic %#x %#x ", image_get_magic (hdr), IH_MAGIC);
|
||||
printf("arch %#x %#x ", image_get_arch (hdr), IH_ARCH_ARM);
|
||||
printf("size %#x %#lx ", image_get_data_size (hdr), nbytes);
|
||||
printf("type %#x %#x ", image_get_type (hdr), IH_TYPE_KERNEL);
|
||||
#endif
|
||||
if (nbytes < sizeof(*hdr))
|
||||
{
|
||||
if (nbytes < image_get_header_size ()) {
|
||||
printf ("Image %s bad header SIZE\n", aufile[idx]);
|
||||
return -1;
|
||||
}
|
||||
if (ntohl(hdr->ih_magic) != IH_MAGIC || hdr->ih_arch != IH_CPU_ARM)
|
||||
{
|
||||
if (!image_check_magic (hdr) || !image_check_arch (hdr, IH_ARCH_ARM)) {
|
||||
printf ("Image %s bad MAGIC or ARCH\n", aufile[idx]);
|
||||
return -1;
|
||||
}
|
||||
/* check the hdr CRC */
|
||||
checksum = ntohl(hdr->ih_hcrc);
|
||||
hdr->ih_hcrc = 0;
|
||||
|
||||
if (crc32 (0, (uchar *)hdr, sizeof(*hdr)) != checksum) {
|
||||
if (!image_check_hcrc (hdr)) {
|
||||
printf ("Image %s bad header checksum\n", aufile[idx]);
|
||||
return -1;
|
||||
}
|
||||
hdr->ih_hcrc = htonl(checksum);
|
||||
/* check the type - could do this all in one gigantic if() */
|
||||
if ((idx == IDX_FIRMWARE) && (hdr->ih_type != IH_TYPE_FIRMWARE)) {
|
||||
if ((idx == IDX_FIRMWARE) &&
|
||||
!image_check_type (hdr, IH_TYPE_FIRMWARE)) {
|
||||
printf ("Image %s wrong type\n", aufile[idx]);
|
||||
return -1;
|
||||
}
|
||||
if ((idx == IDX_KERNEL) && (hdr->ih_type != IH_TYPE_KERNEL)) {
|
||||
if ((idx == IDX_KERNEL) && !image_check_type (hdr, IH_TYPE_KERNEL)) {
|
||||
printf ("Image %s wrong type\n", aufile[idx]);
|
||||
return -1;
|
||||
}
|
||||
if ((idx == IDX_DISK) && (hdr->ih_type != IH_TYPE_FILESYSTEM)) {
|
||||
if ((idx == IDX_DISK) && !image_check_type (hdr, IH_TYPE_FILESYSTEM)) {
|
||||
printf ("Image %s wrong type\n", aufile[idx]);
|
||||
return -1;
|
||||
}
|
||||
if ((idx == IDX_APP) && (hdr->ih_type != IH_TYPE_RAMDISK)
|
||||
&& (hdr->ih_type != IH_TYPE_FILESYSTEM)) {
|
||||
if ((idx == IDX_APP) && !image_check_type (hdr, IH_TYPE_RAMDISK)
|
||||
&& !image_check_type (hdr, IH_TYPE_FILESYSTEM)) {
|
||||
printf ("Image %s wrong type\n", aufile[idx]);
|
||||
return -1;
|
||||
}
|
||||
if ((idx == IDX_PREPARE || idx == IDX_PREINST || idx == IDX_POSTINST)
|
||||
&& (hdr->ih_type != IH_TYPE_SCRIPT))
|
||||
{
|
||||
&& !image_check_type (hdr, IH_TYPE_SCRIPT)) {
|
||||
printf ("Image %s wrong type\n", aufile[idx]);
|
||||
return -1;
|
||||
}
|
||||
@ -293,10 +294,10 @@ au_check_header_valid(int idx, long nbytes)
|
||||
if (idx == IDX_PREPARE)
|
||||
return 0;
|
||||
/* recycle checksum */
|
||||
checksum = ntohl(hdr->ih_size);
|
||||
checksum = image_get_data_size (hdr);
|
||||
/* for kernel and app the image header must also fit into flash */
|
||||
if ((idx != IDX_DISK) && (idx != IDX_FIRMWARE))
|
||||
checksum += sizeof(*hdr);
|
||||
checksum += image_get_header_size ();
|
||||
/* check the size does not exceed space in flash. HUSH scripts */
|
||||
/* all have ausize[] set to 0 */
|
||||
if ((ausize[idx] != 0) && (ausize[idx] < checksum)) {
|
||||
@ -310,10 +311,10 @@ au_check_header_valid(int idx, long nbytes)
|
||||
printf ("buf[0] %#x buf[1] %#x buf[2] %#x buf[3] %#x "
|
||||
"as int %#x time %#x\n",
|
||||
buf[0], buf[1], buf[2], buf[3],
|
||||
*((unsigned int *)buf), ntohl(hdr->ih_time));
|
||||
*((unsigned int *)buf), image_get_time (hdr));
|
||||
#endif
|
||||
/* check it */
|
||||
if (*((unsigned int *)buf) >= ntohl(hdr->ih_time)) {
|
||||
if (*((unsigned int *)buf) >= image_get_time (hdr)) {
|
||||
printf ("Image %s is too old\n", aufile[idx]);
|
||||
return -1;
|
||||
}
|
||||
@ -335,16 +336,22 @@ au_do_update(int idx, long sz)
|
||||
uint nbytes;
|
||||
|
||||
hdr = (image_header_t *)LOAD_ADDR;
|
||||
#if defined(CONFIG_FIT)
|
||||
if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
|
||||
puts ("Non legacy image format not supported\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* disable the power switch */
|
||||
*CPLD_VFD_BK |= POWER_OFF;
|
||||
|
||||
/* execute a script */
|
||||
if (hdr->ih_type == IH_TYPE_SCRIPT) {
|
||||
addr = (char *)((char *)hdr + sizeof(*hdr));
|
||||
if (image_check_type (hdr, IH_TYPE_SCRIPT)) {
|
||||
addr = (char *)((char *)hdr + image_get_header_size ());
|
||||
/* stick a NULL at the end of the script, otherwise */
|
||||
/* parse_string_outer() runs off the end. */
|
||||
addr[ntohl(hdr->ih_size)] = 0;
|
||||
addr[image_get_data_size (hdr)] = 0;
|
||||
addr += 8;
|
||||
parse_string_outer(addr, FLAG_PARSE_SEMICOLON);
|
||||
return 0;
|
||||
@ -372,19 +379,20 @@ au_do_update(int idx, long sz)
|
||||
flash_sect_erase(start, end);
|
||||
wait_ms(100);
|
||||
/* strip the header - except for the kernel and ramdisk */
|
||||
if (hdr->ih_type == IH_TYPE_KERNEL || hdr->ih_type == IH_TYPE_RAMDISK) {
|
||||
if (image_check_type (hdr, IH_TYPE_KERNEL) ||
|
||||
image_check_type (hdr, IH_TYPE_RAMDISK)) {
|
||||
addr = (char *)hdr;
|
||||
off = sizeof(*hdr);
|
||||
nbytes = sizeof(*hdr) + ntohl(hdr->ih_size);
|
||||
off = image_get_header_size ();
|
||||
nbytes = image_get_image_size (hdr);
|
||||
} else {
|
||||
addr = (char *)((char *)hdr + sizeof(*hdr));
|
||||
addr = (char *)((char *)hdr + image_get_header_size ());
|
||||
#ifdef AU_UPDATE_TEST
|
||||
/* copy it to where Linux goes */
|
||||
if (idx == IDX_FIRMWARE)
|
||||
start = aufl_layout[1].start;
|
||||
#endif
|
||||
off = 0;
|
||||
nbytes = ntohl(hdr->ih_size);
|
||||
nbytes = image_get_data_size (hdr);
|
||||
}
|
||||
|
||||
/* copy the data from RAM to FLASH */
|
||||
@ -396,7 +404,8 @@ au_do_update(int idx, long sz)
|
||||
}
|
||||
|
||||
/* check the dcrc of the copy */
|
||||
if (crc32 (0, (uchar *)(start + off), ntohl(hdr->ih_size)) != ntohl(hdr->ih_dcrc)) {
|
||||
if (crc32 (0, (uchar *)(start + off), image_get_data_size (hdr)) !=
|
||||
image_get_dcrc (hdr)) {
|
||||
printf ("Image %s Bad Data Checksum After COPY\n", aufile[idx]);
|
||||
return -1;
|
||||
}
|
||||
@ -423,17 +432,24 @@ au_update_eeprom(int idx)
|
||||
}
|
||||
|
||||
hdr = (image_header_t *)LOAD_ADDR;
|
||||
#if defined(CONFIG_FIT)
|
||||
if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
|
||||
puts ("Non legacy image format not supported\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* write the time field into EEPROM */
|
||||
off = auee_off[idx].time;
|
||||
val = ntohl(hdr->ih_time);
|
||||
val = image_get_time (hdr);
|
||||
i2c_write_multiple(0x54, off, 1, &val, sizeof(val));
|
||||
/* write the size field into EEPROM */
|
||||
off = auee_off[idx].size;
|
||||
val = ntohl(hdr->ih_size);
|
||||
val = image_get_data_size (hdr);
|
||||
i2c_write_multiple(0x54, off, 1, &val, sizeof(val));
|
||||
/* write the dcrc field into EEPROM */
|
||||
off = auee_off[idx].dcrc;
|
||||
val = ntohl(hdr->ih_dcrc);
|
||||
val = image_get_dcrc (hdr);
|
||||
i2c_write_multiple(0x54, off, 1, &val, sizeof(val));
|
||||
/* enable the power switch */
|
||||
*CPLD_VFD_BK &= ~POWER_OFF;
|
||||
@ -577,10 +593,10 @@ do_auto_update(void)
|
||||
/* just loop thru all the possible files */
|
||||
for (i = 0; i < AU_MAXFILES; i++) {
|
||||
/* just read the header */
|
||||
sz = file_fat_read(aufile[i], LOAD_ADDR, sizeof(image_header_t));
|
||||
sz = file_fat_read(aufile[i], LOAD_ADDR, image_get_header_size ());
|
||||
debug ("read %s sz %ld hdr %d\n",
|
||||
aufile[i], sz, sizeof(image_header_t));
|
||||
if (sz <= 0 || sz < sizeof(image_header_t)) {
|
||||
aufile[i], sz, image_get_header_size ());
|
||||
if (sz <= 0 || sz < image_get_header_size ()) {
|
||||
debug ("%s not found\n", aufile[i]);
|
||||
continue;
|
||||
}
|
||||
@ -590,8 +606,8 @@ do_auto_update(void)
|
||||
}
|
||||
sz = file_fat_read(aufile[i], LOAD_ADDR, MAX_LOADSZ);
|
||||
debug ("read %s sz %ld hdr %d\n",
|
||||
aufile[i], sz, sizeof(image_header_t));
|
||||
if (sz <= 0 || sz <= sizeof(image_header_t)) {
|
||||
aufile[i], sz, image_get_header_size ());
|
||||
if (sz <= 0 || sz <= image_get_header_size ()) {
|
||||
debug ("%s not found\n", aufile[i]);
|
||||
continue;
|
||||
}
|
||||
|
@ -36,6 +36,8 @@ COBJS-y += cmd_autoscript.o
|
||||
COBJS-$(CONFIG_CMD_BDI) += cmd_bdinfo.o
|
||||
COBJS-$(CONFIG_CMD_BEDBUG) += cmd_bedbug.o
|
||||
COBJS-$(CONFIG_CMD_BMP) += cmd_bmp.o
|
||||
COBJS-y += image.o
|
||||
COBJS-y += gunzip.o
|
||||
COBJS-y += cmd_boot.o
|
||||
COBJS-$(CONFIG_CMD_BOOTLDR) += cmd_bootldr.o
|
||||
COBJS-y += cmd_bootm.o
|
||||
@ -94,6 +96,7 @@ COBJS-$(CONFIG_CMD_STRINGS) += cmd_strings.o
|
||||
COBJS-$(CONFIG_CMD_TERMINAL) += cmd_terminal.o
|
||||
COBJS-$(CONFIG_CMD_UNIVERSE) += cmd_universe.o
|
||||
COBJS-$(CONFIG_CMD_USB) += cmd_usb.o
|
||||
COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o
|
||||
COBJS-y += cmd_vfd.o
|
||||
COBJS-y += command.o
|
||||
COBJS-y += console.o
|
||||
|
@ -49,57 +49,110 @@
|
||||
|
||||
#if defined(CONFIG_AUTOSCRIPT) || defined(CONFIG_CMD_AUTOSCRIPT)
|
||||
|
||||
extern image_header_t header; /* from cmd_bootm.c */
|
||||
int
|
||||
autoscript (ulong addr)
|
||||
autoscript (ulong addr, const char *fit_uname)
|
||||
{
|
||||
ulong crc, data, len;
|
||||
image_header_t *hdr = &header;
|
||||
ulong *len_ptr;
|
||||
char *cmd;
|
||||
int rcode = 0;
|
||||
int verify;
|
||||
ulong len;
|
||||
image_header_t *hdr;
|
||||
ulong *data;
|
||||
char *cmd;
|
||||
int rcode = 0;
|
||||
int verify;
|
||||
#if defined(CONFIG_FIT)
|
||||
const void* fit_hdr;
|
||||
int noffset;
|
||||
const void *fit_data;
|
||||
size_t fit_len;
|
||||
#endif
|
||||
|
||||
cmd = getenv ("verify");
|
||||
verify = (cmd && (*cmd == 'n')) ? 0 : 1;
|
||||
verify = getenv_verify ();
|
||||
|
||||
switch (genimg_get_format ((void *)addr)) {
|
||||
case IMAGE_FORMAT_LEGACY:
|
||||
hdr = (image_header_t *)addr;
|
||||
|
||||
memmove (hdr, (char *)addr, sizeof(image_header_t));
|
||||
|
||||
if (ntohl(hdr->ih_magic) != IH_MAGIC) {
|
||||
puts ("Bad magic number\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
crc = ntohl(hdr->ih_hcrc);
|
||||
hdr->ih_hcrc = 0;
|
||||
len = sizeof (image_header_t);
|
||||
data = (ulong)hdr;
|
||||
if (crc32(0, (uchar *)data, len) != crc) {
|
||||
puts ("Bad header crc\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
data = addr + sizeof(image_header_t);
|
||||
len = ntohl(hdr->ih_size);
|
||||
|
||||
if (verify) {
|
||||
if (crc32(0, (uchar *)data, len) != ntohl(hdr->ih_dcrc)) {
|
||||
puts ("Bad data crc\n");
|
||||
if (!image_check_magic (hdr)) {
|
||||
puts ("Bad magic number\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (hdr->ih_type != IH_TYPE_SCRIPT) {
|
||||
puts ("Bad image type\n");
|
||||
return 1;
|
||||
}
|
||||
if (!image_check_hcrc (hdr)) {
|
||||
puts ("Bad header crc\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* get length of script */
|
||||
len_ptr = (ulong *)data;
|
||||
if (verify) {
|
||||
if (!image_check_dcrc (hdr)) {
|
||||
puts ("Bad data crc\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ((len = ntohl(*len_ptr)) == 0) {
|
||||
puts ("Empty Script\n");
|
||||
if (!image_check_type (hdr, IH_TYPE_SCRIPT)) {
|
||||
puts ("Bad image type\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* get length of script */
|
||||
data = (ulong *)image_get_data (hdr);
|
||||
|
||||
if ((len = uimage_to_cpu (*data)) == 0) {
|
||||
puts ("Empty Script\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* scripts are just multi-image files with one component, seek
|
||||
* past the zero-terminated sequence of image lengths to get
|
||||
* to the actual image data
|
||||
*/
|
||||
while (*data++);
|
||||
break;
|
||||
#if defined(CONFIG_FIT)
|
||||
case IMAGE_FORMAT_FIT:
|
||||
if (fit_uname == NULL) {
|
||||
puts ("No FIT subimage unit name\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
fit_hdr = (const void *)addr;
|
||||
if (!fit_check_format (fit_hdr)) {
|
||||
puts ("Bad FIT image format\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* get script component image node offset */
|
||||
noffset = fit_image_get_node (fit_hdr, fit_uname);
|
||||
if (noffset < 0) {
|
||||
printf ("Can't find '%s' FIT subimage\n", fit_uname);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!fit_image_check_type (fit_hdr, noffset, IH_TYPE_SCRIPT)) {
|
||||
puts ("Not a image image\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* verify integrity */
|
||||
if (verify) {
|
||||
if (!fit_image_check_hashes (fit_hdr, noffset)) {
|
||||
puts ("Bad Data Hash\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* get script subimage data address and length */
|
||||
if (fit_image_get_data (fit_hdr, noffset, &fit_data, &fit_len)) {
|
||||
puts ("Could not find script subimage data\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
data = (ulong *)fit_data;
|
||||
len = (ulong)fit_len;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
puts ("Wrong image format for autoscript\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -109,10 +162,8 @@ autoscript (ulong addr)
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (*len_ptr++);
|
||||
|
||||
/* make sure cmd is null terminated */
|
||||
memmove (cmd, (char *)len_ptr, len);
|
||||
memmove (cmd, (char *)data, len);
|
||||
*(cmd + len) = 0;
|
||||
|
||||
#ifdef CFG_HUSH_PARSER /*?? */
|
||||
@ -158,25 +209,35 @@ do_autoscript (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
{
|
||||
ulong addr;
|
||||
int rcode;
|
||||
const char *fit_uname = NULL;
|
||||
|
||||
/* Find script image */
|
||||
if (argc < 2) {
|
||||
addr = CFG_LOAD_ADDR;
|
||||
debug ("* autoscr: default load address = 0x%08lx\n", addr);
|
||||
#if defined(CONFIG_FIT)
|
||||
} else if (fit_parse_subimage (argv[1], load_addr, &addr, &fit_uname)) {
|
||||
debug ("* autoscr: subimage '%s' from FIT image at 0x%08lx\n",
|
||||
fit_uname, addr);
|
||||
#endif
|
||||
} else {
|
||||
addr = simple_strtoul (argv[1],0,16);
|
||||
addr = simple_strtoul(argv[1], NULL, 16);
|
||||
debug ("* autoscr: cmdline image address = 0x%08lx\n", addr);
|
||||
}
|
||||
|
||||
printf ("## Executing script at %08lx\n",addr);
|
||||
rcode = autoscript (addr);
|
||||
printf ("## Executing script at %08lx\n", addr);
|
||||
rcode = autoscript (addr, fit_uname);
|
||||
return rcode;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_CMD_AUTOSCRIPT)
|
||||
U_BOOT_CMD(
|
||||
autoscr, 2, 0, do_autoscript,
|
||||
"autoscr - run script from memory\n",
|
||||
"[addr] - run script starting at addr"
|
||||
" - A valid autoscr header must be present\n"
|
||||
#if defined(CONFIG_FIT)
|
||||
"For FIT format uImage addr must include subimage\n"
|
||||
"unit name in the form of addr:<subimg_uname>\n"
|
||||
#endif
|
||||
);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
2057
common/cmd_bootm.c
2057
common/cmd_bootm.c
File diff suppressed because it is too large
Load Diff
@ -205,6 +205,9 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
ulong offset = 0;
|
||||
image_header_t *hdr;
|
||||
int rcode = 0;
|
||||
#if defined(CONFIG_FIT)
|
||||
const void *fit_hdr;
|
||||
#endif
|
||||
|
||||
show_boot_progress (34);
|
||||
switch (argc) {
|
||||
@ -261,21 +264,36 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
}
|
||||
show_boot_progress (38);
|
||||
|
||||
hdr = (image_header_t *)addr;
|
||||
switch (genimg_get_format ((void *)addr)) {
|
||||
case IMAGE_FORMAT_LEGACY:
|
||||
hdr = (image_header_t *)addr;
|
||||
|
||||
if (hdr->ih_magic == IH_MAGIC) {
|
||||
image_print_contents (hdr);
|
||||
|
||||
print_image_hdr (hdr);
|
||||
cnt = image_get_image_size (hdr);
|
||||
break;
|
||||
#if defined(CONFIG_FIT)
|
||||
case IMAGE_FORMAT_FIT:
|
||||
fit_hdr = (const void *)addr;
|
||||
if (!fit_check_format (fit_hdr)) {
|
||||
show_boot_progress (-130);
|
||||
puts ("** Bad FIT image format\n");
|
||||
return 1;
|
||||
}
|
||||
show_boot_progress (131);
|
||||
puts ("Fit image detected...\n");
|
||||
|
||||
cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t));
|
||||
cnt -= SECTORSIZE;
|
||||
} else {
|
||||
puts ("\n** Bad Magic Number **\n");
|
||||
cnt = fit_get_size (fit_hdr);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
show_boot_progress (-39);
|
||||
puts ("** Unknown image type\n");
|
||||
return 1;
|
||||
}
|
||||
show_boot_progress (39);
|
||||
|
||||
cnt -= SECTORSIZE;
|
||||
if (doc_rw (doc_dev_desc + dev, 1, offset + SECTORSIZE, cnt,
|
||||
NULL, (u_char *)(addr+SECTORSIZE))) {
|
||||
printf ("** Read error on %d\n", dev);
|
||||
@ -284,6 +302,12 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
}
|
||||
show_boot_progress (40);
|
||||
|
||||
#if defined(CONFIG_FIT)
|
||||
/* This cannot be done earlier, we need complete FIT image in RAM first */
|
||||
if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT)
|
||||
fit_print_contents ((const void *)addr);
|
||||
#endif
|
||||
|
||||
/* Loading ok, update default load address */
|
||||
|
||||
load_addr = addr;
|
||||
|
@ -788,6 +788,9 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
int i,nrofblk;
|
||||
char *ep;
|
||||
int rcode = 0;
|
||||
#if defined(CONFIG_FIT)
|
||||
const void *fit_hdr;
|
||||
#endif
|
||||
|
||||
switch (argc) {
|
||||
case 1:
|
||||
@ -835,14 +838,31 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
printf("result%d: 0x%02X\n",i,pCMD->result[i]);
|
||||
return 1;
|
||||
}
|
||||
hdr = (image_header_t *)addr;
|
||||
if (ntohl(hdr->ih_magic) != IH_MAGIC) {
|
||||
printf ("Bad Magic Number\n");
|
||||
|
||||
switch (genimg_get_format ((void *)addr)) {
|
||||
case IMAGE_FORMAT_LEGACY:
|
||||
hdr = (image_header_t *)addr;
|
||||
image_print_contents (hdr);
|
||||
|
||||
imsize = image_get_image_size (hdr);
|
||||
break;
|
||||
#if defined(CONFIG_FIT)
|
||||
case IMAGE_FORMAT_FIT:
|
||||
fit_hdr = (const void *)addr;
|
||||
if (!fit_check_format (fit_hdr)) {
|
||||
puts ("** Bad FIT image format\n");
|
||||
return 1;
|
||||
}
|
||||
puts ("Fit image detected...\n");
|
||||
|
||||
imsize = fit_get_size (fit_hdr);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
puts ("** Unknown image type\n");
|
||||
return 1;
|
||||
}
|
||||
print_image_hdr(hdr);
|
||||
|
||||
imsize= ntohl(hdr->ih_size)+sizeof(image_header_t);
|
||||
nrofblk=imsize/512;
|
||||
if((imsize%512)>0)
|
||||
nrofblk++;
|
||||
@ -858,23 +878,28 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
printf("OK %ld Bytes loaded.\n",imsize);
|
||||
|
||||
flush_cache (addr, imsize);
|
||||
|
||||
#if defined(CONFIG_FIT)
|
||||
/* This cannot be done earlier, we need complete FIT image in RAM first */
|
||||
if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT)
|
||||
fit_print_contents ((const void *)addr);
|
||||
#endif
|
||||
|
||||
/* Loading ok, update default load address */
|
||||
|
||||
load_addr = addr;
|
||||
if(hdr->ih_type == IH_TYPE_KERNEL) {
|
||||
/* Check if we should attempt an auto-start */
|
||||
if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) {
|
||||
char *local_args[2];
|
||||
extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
|
||||
|
||||
local_args[0] = argv[0];
|
||||
local_args[1] = NULL;
|
||||
/* Check if we should attempt an auto-start */
|
||||
if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) {
|
||||
char *local_args[2];
|
||||
extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
|
||||
|
||||
printf ("Automatic boot of image at addr 0x%08lX ...\n", addr);
|
||||
local_args[0] = argv[0];
|
||||
local_args[1] = NULL;
|
||||
|
||||
do_bootm (cmdtp, 0, 1, local_args);
|
||||
rcode ++;
|
||||
}
|
||||
printf ("Automatic boot of image at addr 0x%08lX ...\n", addr);
|
||||
|
||||
do_bootm (cmdtp, 0, 1, local_args);
|
||||
rcode ++;
|
||||
}
|
||||
return rcode;
|
||||
}
|
||||
|
@ -164,6 +164,10 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
||||
char *devstr = getenv ("fpga");
|
||||
char *datastr = getenv ("fpgadata");
|
||||
int rc = FPGA_FAIL;
|
||||
#if defined (CONFIG_FIT)
|
||||
const char *fit_uname = NULL;
|
||||
ulong fit_addr;
|
||||
#endif
|
||||
|
||||
if (devstr)
|
||||
dev = (int) simple_strtoul (devstr, NULL, 16);
|
||||
@ -173,9 +177,22 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
||||
switch (argc) {
|
||||
case 5: /* fpga <op> <dev> <data> <datasize> */
|
||||
data_size = simple_strtoul (argv[4], NULL, 16);
|
||||
|
||||
case 4: /* fpga <op> <dev> <data> */
|
||||
fpga_data = (void *) simple_strtoul (argv[3], NULL, 16);
|
||||
#if defined(CONFIG_FIT)
|
||||
if (fit_parse_subimage (argv[3], (ulong)fpga_data,
|
||||
&fit_addr, &fit_uname)) {
|
||||
fpga_data = (void *)fit_addr;
|
||||
debug ("* fpga: subimage '%s' from FIT image at 0x%08lx\n",
|
||||
fit_uname, fit_addr);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
fpga_data = (void *) simple_strtoul (argv[3], NULL, 16);
|
||||
debug ("* fpga: cmdline image address = 0x%08lx\n", (ulong)fpga_data);
|
||||
}
|
||||
PRINTF ("%s: fpga_data = 0x%x\n", __FUNCTION__, (uint) fpga_data);
|
||||
|
||||
case 3: /* fpga <op> <dev | data addr> */
|
||||
dev = (int) simple_strtoul (argv[2], NULL, 16);
|
||||
PRINTF ("%s: device = %d\n", __FUNCTION__, dev);
|
||||
@ -183,14 +200,29 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
||||
if ((argc == 3) && (dev > fpga_count ())) { /* must be buffer ptr */
|
||||
PRINTF ("%s: Assuming buffer pointer in arg 3\n",
|
||||
__FUNCTION__);
|
||||
fpga_data = (void *) dev;
|
||||
|
||||
#if defined(CONFIG_FIT)
|
||||
if (fit_parse_subimage (argv[2], (ulong)fpga_data,
|
||||
&fit_addr, &fit_uname)) {
|
||||
fpga_data = (void *)fit_addr;
|
||||
debug ("* fpga: subimage '%s' from FIT image at 0x%08lx\n",
|
||||
fit_uname, fit_addr);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
fpga_data = (void *) dev;
|
||||
debug ("* fpga: cmdline image address = 0x%08lx\n", (ulong)fpga_data);
|
||||
}
|
||||
|
||||
PRINTF ("%s: fpga_data = 0x%x\n",
|
||||
__FUNCTION__, (uint) fpga_data);
|
||||
dev = FPGA_INVALID_DEVICE; /* reset device num */
|
||||
}
|
||||
|
||||
case 2: /* fpga <op> */
|
||||
op = (int) fpga_get_op (argv[1]);
|
||||
break;
|
||||
|
||||
default:
|
||||
PRINTF ("%s: Too many or too few args (%d)\n",
|
||||
__FUNCTION__, argc);
|
||||
@ -216,19 +248,61 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
||||
break;
|
||||
|
||||
case FPGA_LOADMK:
|
||||
{
|
||||
image_header_t header;
|
||||
image_header_t *hdr = &header;
|
||||
ulong data;
|
||||
switch (genimg_get_format (fpga_data)) {
|
||||
case IMAGE_FORMAT_LEGACY:
|
||||
{
|
||||
image_header_t *hdr = (image_header_t *)fpga_data;
|
||||
ulong data;
|
||||
|
||||
memmove (&header, (char *)fpga_data, sizeof(image_header_t));
|
||||
if (ntohl(hdr->ih_magic) != IH_MAGIC) {
|
||||
puts ("Bad Magic Number\n");
|
||||
return 1;
|
||||
data = (ulong)image_get_data (hdr);
|
||||
data_size = image_get_data_size (hdr);
|
||||
rc = fpga_load (dev, (void *)data, data_size);
|
||||
}
|
||||
data = ((ulong)fpga_data + sizeof(image_header_t));
|
||||
data_size = ntohl(hdr->ih_size);
|
||||
rc = fpga_load (dev, (void *)data, data_size);
|
||||
break;
|
||||
#if defined(CONFIG_FIT)
|
||||
case IMAGE_FORMAT_FIT:
|
||||
{
|
||||
const void *fit_hdr = (const void *)fpga_data;
|
||||
int noffset;
|
||||
void *fit_data;
|
||||
|
||||
if (fit_uname == NULL) {
|
||||
puts ("No FIT subimage unit name\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!fit_check_format (fit_hdr)) {
|
||||
puts ("Bad FIT image format\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* get fpga component image node offset */
|
||||
noffset = fit_image_get_node (fit_hdr, fit_uname);
|
||||
if (noffset < 0) {
|
||||
printf ("Can't find '%s' FIT subimage\n", fit_uname);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* verify integrity */
|
||||
if (!fit_image_check_hashes (fit_hdr, noffset)) {
|
||||
puts ("Bad Data Hash\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* get fpga subimage data address and length */
|
||||
if (fit_image_get_data (fit_hdr, noffset, &fit_data, &data_size)) {
|
||||
puts ("Could not find fpga subimage data\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
rc = fpga_load (dev, fit_data, data_size);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
puts ("** Unknown image type\n");
|
||||
rc = FPGA_FAIL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -283,4 +357,9 @@ U_BOOT_CMD (fpga, 6, 1, do_fpga,
|
||||
"\tload\tLoad device from memory buffer\n"
|
||||
"\tloadb\tLoad device from bitstream buffer (Xilinx devices only)\n"
|
||||
"\tloadmk\tLoad device generated with mkimage\n"
|
||||
"\tdump\tLoad device to memory buffer\n");
|
||||
"\tdump\tLoad device to memory buffer\n"
|
||||
#if defined(CONFIG_FIT)
|
||||
"\tFor loadmk operating on FIT format uImage address must include\n"
|
||||
"\tsubimage unit name in the form of addr:<subimg_uname>\n"
|
||||
#endif
|
||||
);
|
||||
|
@ -366,10 +366,13 @@ int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
char *boot_device = NULL;
|
||||
char *ep;
|
||||
int dev, part = 0;
|
||||
ulong addr, cnt, checksum;
|
||||
ulong addr, cnt;
|
||||
disk_partition_t info;
|
||||
image_header_t *hdr;
|
||||
int rcode = 0;
|
||||
#if defined(CONFIG_FIT)
|
||||
const void *fit_hdr;
|
||||
#endif
|
||||
|
||||
show_boot_progress (41);
|
||||
switch (argc) {
|
||||
@ -446,29 +449,43 @@ int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
}
|
||||
show_boot_progress (48);
|
||||
|
||||
hdr = (image_header_t *)addr;
|
||||
switch (genimg_get_format ((void *)addr)) {
|
||||
case IMAGE_FORMAT_LEGACY:
|
||||
hdr = (image_header_t *)addr;
|
||||
|
||||
if (ntohl(hdr->ih_magic) != IH_MAGIC) {
|
||||
printf("\n** Bad Magic Number **\n");
|
||||
show_boot_progress (49);
|
||||
|
||||
if (!image_check_hcrc (hdr)) {
|
||||
puts ("\n** Bad Header Checksum **\n");
|
||||
show_boot_progress (-50);
|
||||
return 1;
|
||||
}
|
||||
show_boot_progress (50);
|
||||
|
||||
image_print_contents (hdr);
|
||||
|
||||
cnt = image_get_image_size (hdr);
|
||||
break;
|
||||
#if defined(CONFIG_FIT)
|
||||
case IMAGE_FORMAT_FIT:
|
||||
fit_hdr = (const void *)addr;
|
||||
if (!fit_check_format (fit_hdr)) {
|
||||
show_boot_progress (-140);
|
||||
puts ("** Bad FIT image format\n");
|
||||
return 1;
|
||||
}
|
||||
show_boot_progress (141);
|
||||
puts ("Fit image detected...\n");
|
||||
|
||||
cnt = fit_get_size (fit_hdr);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
show_boot_progress (-49);
|
||||
puts ("** Unknown image type\n");
|
||||
return 1;
|
||||
}
|
||||
show_boot_progress (49);
|
||||
|
||||
checksum = ntohl(hdr->ih_hcrc);
|
||||
hdr->ih_hcrc = 0;
|
||||
|
||||
if (crc32 (0, (uchar *)hdr, sizeof(image_header_t)) != checksum) {
|
||||
puts ("\n** Bad Header Checksum **\n");
|
||||
show_boot_progress (-50);
|
||||
return 1;
|
||||
}
|
||||
show_boot_progress (50);
|
||||
hdr->ih_hcrc = htonl(checksum); /* restore checksum for later use */
|
||||
|
||||
print_image_hdr (hdr);
|
||||
|
||||
cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t));
|
||||
cnt += info.blksz - 1;
|
||||
cnt /= info.blksz;
|
||||
cnt -= 1;
|
||||
@ -481,6 +498,11 @@ int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
}
|
||||
show_boot_progress (51);
|
||||
|
||||
#if defined(CONFIG_FIT)
|
||||
/* This cannot be done earlier, we need complete FIT image in RAM first */
|
||||
if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT)
|
||||
fit_print_contents ((const void *)addr);
|
||||
#endif
|
||||
|
||||
/* Loading ok, update default load address */
|
||||
|
||||
|
@ -521,8 +521,15 @@ int do_load_serial_bin (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
char *s;
|
||||
|
||||
if (((s = getenv("autoscript")) != NULL) && (strcmp(s,"yes") == 0)) {
|
||||
printf("Running autoscript at addr 0x%08lX ...\n", load_addr);
|
||||
rcode = autoscript (load_addr);
|
||||
printf ("Running autoscript at addr 0x%08lX", load_addr);
|
||||
|
||||
s = getenv ("autoscript_uname");
|
||||
if (s)
|
||||
printf (":%s ...\n", s);
|
||||
else
|
||||
puts (" ...\n");
|
||||
|
||||
rcode = autoscript (load_addr, s);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -484,6 +484,9 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand,
|
||||
ulong cnt;
|
||||
image_header_t *hdr;
|
||||
int jffs2 = 0;
|
||||
#if defined(CONFIG_FIT)
|
||||
const void *fit_hdr;
|
||||
#endif
|
||||
|
||||
s = strchr(cmd, '.');
|
||||
if (s != NULL &&
|
||||
@ -512,18 +515,35 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand,
|
||||
}
|
||||
show_boot_progress (56);
|
||||
|
||||
hdr = (image_header_t *) addr;
|
||||
switch (genimg_get_format ((void *)addr)) {
|
||||
case IMAGE_FORMAT_LEGACY:
|
||||
hdr = (image_header_t *)addr;
|
||||
|
||||
if (ntohl(hdr->ih_magic) != IH_MAGIC) {
|
||||
printf("\n** Bad Magic Number 0x%x **\n", hdr->ih_magic);
|
||||
show_boot_progress (57);
|
||||
image_print_contents (hdr);
|
||||
|
||||
cnt = image_get_image_size (hdr);
|
||||
break;
|
||||
#if defined(CONFIG_FIT)
|
||||
case IMAGE_FORMAT_FIT:
|
||||
fit_hdr = (const void *)addr;
|
||||
if (!fit_check_format (fit_hdr)) {
|
||||
show_boot_progress (-150);
|
||||
puts ("** Bad FIT image format\n");
|
||||
return 1;
|
||||
}
|
||||
show_boot_progress (151);
|
||||
puts ("Fit image detected...\n");
|
||||
|
||||
cnt = fit_get_size (fit_hdr);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
show_boot_progress (-57);
|
||||
puts ("** Unknown image type\n");
|
||||
return 1;
|
||||
}
|
||||
show_boot_progress (57);
|
||||
|
||||
print_image_hdr(hdr);
|
||||
|
||||
cnt = (ntohl(hdr->ih_size) + sizeof (image_header_t));
|
||||
if (jffs2) {
|
||||
nand_read_options_t opts;
|
||||
memset(&opts, 0, sizeof(opts));
|
||||
@ -543,6 +563,12 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand,
|
||||
}
|
||||
show_boot_progress (58);
|
||||
|
||||
#if defined(CONFIG_FIT)
|
||||
/* This cannot be done earlier, we need complete FIT image in RAM first */
|
||||
if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT)
|
||||
fit_print_contents ((const void *)addr);
|
||||
#endif
|
||||
|
||||
/* Loading ok, update default load address */
|
||||
|
||||
load_addr = addr;
|
||||
@ -925,6 +951,10 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
ulong offset = 0;
|
||||
image_header_t *hdr;
|
||||
int rcode = 0;
|
||||
#if defined(CONFIG_FIT)
|
||||
const void *fit_hdr;
|
||||
#endif
|
||||
|
||||
show_boot_progress (52);
|
||||
switch (argc) {
|
||||
case 1:
|
||||
@ -980,17 +1010,31 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
}
|
||||
show_boot_progress (56);
|
||||
|
||||
hdr = (image_header_t *)addr;
|
||||
switch (genimg_get_format ((void *)addr)) {
|
||||
case IMAGE_FORMAT_LEGACY:
|
||||
hdr = (image_header_t *)addr;
|
||||
image_print_contents (hdr);
|
||||
|
||||
if (ntohl(hdr->ih_magic) == IH_MAGIC) {
|
||||
|
||||
print_image_hdr (hdr);
|
||||
|
||||
cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t));
|
||||
cnt = image_get_image_size (hdr);
|
||||
cnt -= SECTORSIZE;
|
||||
} else {
|
||||
printf ("\n** Bad Magic Number 0x%x **\n", ntohl(hdr->ih_magic));
|
||||
break;
|
||||
#if defined(CONFIG_FIT)
|
||||
case IMAGE_FORMAT_FIT:
|
||||
fit_hdr = (const void *)addr;
|
||||
if (!fit_check_format (fit_hdr)) {
|
||||
show_boot_progress (-150);
|
||||
puts ("** Bad FIT image format\n");
|
||||
return 1;
|
||||
}
|
||||
show_boot_progress (151);
|
||||
puts ("Fit image detected...\n");
|
||||
|
||||
cnt = fit_get_size (fit_hdr);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
show_boot_progress (-57);
|
||||
puts ("** Unknown image type\n");
|
||||
return 1;
|
||||
}
|
||||
show_boot_progress (57);
|
||||
@ -1004,6 +1048,12 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
}
|
||||
show_boot_progress (58);
|
||||
|
||||
#if defined(CONFIG_FIT)
|
||||
/* This cannot be done earlier, we need complete FIT image in RAM first */
|
||||
if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT)
|
||||
fit_print_contents ((const void *)addr);
|
||||
#endif
|
||||
|
||||
/* Loading ok, update default load address */
|
||||
|
||||
load_addr = addr;
|
||||
|
@ -220,9 +220,16 @@ netboot_common (proto_t proto, cmd_tbl_t *cmdtp, int argc, char *argv[])
|
||||
|
||||
#ifdef CONFIG_AUTOSCRIPT
|
||||
if (((s = getenv("autoscript")) != NULL) && (strcmp(s,"yes") == 0)) {
|
||||
printf("Running autoscript at addr 0x%08lX ...\n", load_addr);
|
||||
printf ("Running autoscript at addr 0x%08lX", load_addr);
|
||||
|
||||
s = getenv ("autoscript_uname");
|
||||
if (s)
|
||||
printf (":%s ...\n", s);
|
||||
else
|
||||
puts (" ...\n");
|
||||
|
||||
show_boot_progress (83);
|
||||
rcode = autoscript (load_addr);
|
||||
rcode = autoscript (load_addr, s);
|
||||
}
|
||||
#endif
|
||||
if (rcode < 0)
|
||||
|
@ -207,10 +207,13 @@ int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
char *boot_device = NULL;
|
||||
char *ep;
|
||||
int dev, part = 0;
|
||||
ulong addr, cnt, checksum;
|
||||
ulong addr, cnt;
|
||||
disk_partition_t info;
|
||||
image_header_t *hdr;
|
||||
int rcode = 0;
|
||||
#if defined(CONFIG_FIT)
|
||||
const void *fit_hdr;
|
||||
#endif
|
||||
|
||||
switch (argc) {
|
||||
case 1:
|
||||
@ -273,24 +276,35 @@ int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
hdr = (image_header_t *)addr;
|
||||
switch (genimg_get_format ((void *)addr)) {
|
||||
case IMAGE_FORMAT_LEGACY:
|
||||
hdr = (image_header_t *)addr;
|
||||
|
||||
if (ntohl(hdr->ih_magic) == IH_MAGIC) {
|
||||
printf("\n** Bad Magic Number **\n");
|
||||
if (!image_check_hcrc (hdr)) {
|
||||
puts ("\n** Bad Header Checksum **\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
image_print_contents (hdr);
|
||||
cnt = image_get_image_size (hdr);
|
||||
break;
|
||||
#if defined(CONFIG_FIT)
|
||||
case IMAGE_FORMAT_FIT:
|
||||
fit_hdr = (const void *)addr;
|
||||
if (!fit_check_format (fit_hdr)) {
|
||||
puts ("** Bad FIT image format\n");
|
||||
return 1;
|
||||
}
|
||||
puts ("Fit image detected...\n");
|
||||
|
||||
cnt = fit_get_size (fit_hdr);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
puts ("** Unknown image type\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
checksum = ntohl(hdr->ih_hcrc);
|
||||
hdr->ih_hcrc = 0;
|
||||
|
||||
if (crc32 (0, (uchar *)hdr, sizeof(image_header_t)) != checksum) {
|
||||
puts ("\n** Bad Header Checksum **\n");
|
||||
return 1;
|
||||
}
|
||||
hdr->ih_hcrc = htonl(checksum); /* restore checksum for later use */
|
||||
|
||||
print_image_hdr (hdr);
|
||||
cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t));
|
||||
cnt += info.blksz - 1;
|
||||
cnt /= info.blksz;
|
||||
cnt -= 1;
|
||||
@ -300,6 +314,13 @@ int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
printf ("** Read error on %d:%d\n", dev, part);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_FIT)
|
||||
/* This cannot be done earlier, we need complete FIT image in RAM first */
|
||||
if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT)
|
||||
fit_print_contents ((const void *)addr);
|
||||
#endif
|
||||
|
||||
/* Loading ok, update default load address */
|
||||
load_addr = addr;
|
||||
|
||||
|
@ -311,11 +311,13 @@ int do_usbboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
char *boot_device = NULL;
|
||||
char *ep;
|
||||
int dev, part=1, rcode;
|
||||
ulong addr, cnt, checksum;
|
||||
ulong addr, cnt;
|
||||
disk_partition_t info;
|
||||
image_header_t *hdr;
|
||||
block_dev_desc_t *stor_dev;
|
||||
|
||||
#if defined(CONFIG_FIT)
|
||||
const void *fit_hdr;
|
||||
#endif
|
||||
|
||||
switch (argc) {
|
||||
case 1:
|
||||
@ -386,25 +388,36 @@ int do_usbboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
hdr = (image_header_t *)addr;
|
||||
switch (genimg_get_format ((void *)addr)) {
|
||||
case IMAGE_FORMAT_LEGACY:
|
||||
hdr = (image_header_t *)addr;
|
||||
|
||||
if (ntohl(hdr->ih_magic) != IH_MAGIC) {
|
||||
printf("\n** Bad Magic Number **\n");
|
||||
if (!image_check_hcrc (hdr)) {
|
||||
puts ("\n** Bad Header Checksum **\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
image_print_contents (hdr);
|
||||
|
||||
cnt = image_get_image_size (hdr);
|
||||
break;
|
||||
#if defined(CONFIG_FIT)
|
||||
case IMAGE_FORMAT_FIT:
|
||||
fit_hdr = (const void *)addr;
|
||||
if (!fit_check_format (fit_hdr)) {
|
||||
puts ("** Bad FIT image format\n");
|
||||
return 1;
|
||||
}
|
||||
puts ("Fit image detected...\n");
|
||||
|
||||
cnt = fit_get_size (fit_hdr);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
puts ("** Unknown image type\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
checksum = ntohl(hdr->ih_hcrc);
|
||||
hdr->ih_hcrc = 0;
|
||||
|
||||
if (crc32 (0, (uchar *)hdr, sizeof(image_header_t)) != checksum) {
|
||||
puts ("\n** Bad Header Checksum **\n");
|
||||
return 1;
|
||||
}
|
||||
hdr->ih_hcrc = htonl(checksum); /* restore checksum for later use */
|
||||
|
||||
print_image_hdr (hdr);
|
||||
|
||||
cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t));
|
||||
cnt += info.blksz - 1;
|
||||
cnt /= info.blksz;
|
||||
cnt -= 1;
|
||||
@ -414,6 +427,13 @@ int do_usbboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
printf ("\n** Read error on %d:%d\n", dev, part);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_FIT)
|
||||
/* This cannot be done earlier, we need complete FIT image in RAM first */
|
||||
if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT)
|
||||
fit_print_contents ((const void *)addr);
|
||||
#endif
|
||||
|
||||
/* Loading ok, update default load address */
|
||||
load_addr = addr;
|
||||
|
||||
|
@ -24,7 +24,6 @@
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_CMD_XIMG)
|
||||
|
||||
/*
|
||||
* Multi Image extract
|
||||
@ -37,92 +36,136 @@
|
||||
int
|
||||
do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
||||
{
|
||||
ulong addr = load_addr, dest = 0;
|
||||
ulong data, len, checksum;
|
||||
ulong *len_ptr;
|
||||
int i, verify, part = 0;
|
||||
char pbuf[10], *s;
|
||||
image_header_t header;
|
||||
ulong addr = load_addr;
|
||||
ulong dest = 0;
|
||||
ulong data, len, count;
|
||||
int verify;
|
||||
int part = 0;
|
||||
char pbuf[10];
|
||||
image_header_t *hdr;
|
||||
#if defined(CONFIG_FIT)
|
||||
const char *uname = NULL;
|
||||
const void* fit_hdr;
|
||||
int noffset;
|
||||
const void *fit_data;
|
||||
size_t fit_len;
|
||||
#endif
|
||||
|
||||
s = getenv("verify");
|
||||
verify = (s && (*s == 'n')) ? 0 : 1;
|
||||
verify = getenv_verify ();
|
||||
|
||||
if (argc > 1) {
|
||||
addr = simple_strtoul(argv[1], NULL, 16);
|
||||
}
|
||||
if (argc > 2) {
|
||||
part = simple_strtoul(argv[2], NULL, 16);
|
||||
#if defined(CONFIG_FIT)
|
||||
uname = argv[2];
|
||||
#endif
|
||||
}
|
||||
if (argc > 3) {
|
||||
dest = simple_strtoul(argv[3], NULL, 16);
|
||||
}
|
||||
|
||||
printf("## Copying from image at %08lx ...\n", addr);
|
||||
switch (genimg_get_format ((void *)addr)) {
|
||||
case IMAGE_FORMAT_LEGACY:
|
||||
|
||||
/* Copy header so we can blank CRC field for re-calculation */
|
||||
memmove(&header, (char *) addr, sizeof (image_header_t));
|
||||
printf("## Copying part %d from legacy image "
|
||||
"at %08lx ...\n", part, addr);
|
||||
|
||||
if (ntohl(header.ih_magic) != IH_MAGIC) {
|
||||
printf("Bad Magic Number\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
data = (ulong) & header;
|
||||
len = sizeof (image_header_t);
|
||||
|
||||
checksum = ntohl(header.ih_hcrc);
|
||||
header.ih_hcrc = 0;
|
||||
|
||||
if (crc32(0, (char *) data, len) != checksum) {
|
||||
printf("Bad Header Checksum\n");
|
||||
return 1;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
print_image_hdr((image_header_t *) addr);
|
||||
#endif
|
||||
|
||||
data = addr + sizeof (image_header_t);
|
||||
len = ntohl(header.ih_size);
|
||||
|
||||
if (header.ih_type != IH_TYPE_MULTI) {
|
||||
printf("Wrong Image Type for %s command\n", cmdtp->name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (header.ih_comp != IH_COMP_NONE) {
|
||||
printf("Wrong Compression Type for %s command\n", cmdtp->name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (verify) {
|
||||
printf(" Verifying Checksum ... ");
|
||||
if (crc32(0, (char *) data, len) != ntohl(header.ih_dcrc)) {
|
||||
printf("Bad Data CRC\n");
|
||||
hdr = (image_header_t *)addr;
|
||||
if (!image_check_magic (hdr)) {
|
||||
printf("Bad Magic Number\n");
|
||||
return 1;
|
||||
}
|
||||
printf("OK\n");
|
||||
}
|
||||
|
||||
len_ptr = (ulong *) data;
|
||||
if (!image_check_hcrc (hdr)) {
|
||||
printf("Bad Header Checksum\n");
|
||||
return 1;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
image_print_contents (hdr);
|
||||
#endif
|
||||
|
||||
data += 4; /* terminator */
|
||||
for (i = 0; len_ptr[i]; ++i) {
|
||||
data += 4;
|
||||
if (argc > 2 && part > i) {
|
||||
u_long tail;
|
||||
len = ntohl(len_ptr[i]);
|
||||
tail = len % 4;
|
||||
data += len;
|
||||
if (tail) {
|
||||
data += 4 - tail;
|
||||
if (!image_check_type (hdr, IH_TYPE_MULTI)) {
|
||||
printf("Wrong Image Type for %s command\n",
|
||||
cmdtp->name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (image_get_comp (hdr) != IH_COMP_NONE) {
|
||||
printf("Wrong Compression Type for %s command\n",
|
||||
cmdtp->name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (verify) {
|
||||
printf(" Verifying Checksum ... ");
|
||||
if (!image_check_dcrc (hdr)) {
|
||||
printf("Bad Data CRC\n");
|
||||
return 1;
|
||||
}
|
||||
printf("OK\n");
|
||||
}
|
||||
|
||||
count = image_multi_count (hdr);
|
||||
if (part >= count) {
|
||||
printf("Bad Image Part\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
image_multi_getimg (hdr, part, &data, &len);
|
||||
break;
|
||||
#if defined(CONFIG_FIT)
|
||||
case IMAGE_FORMAT_FIT:
|
||||
if (uname == NULL) {
|
||||
puts ("No FIT subimage unit name\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("## Copying '%s' subimage from FIT image "
|
||||
"at %08lx ...\n", uname, addr);
|
||||
|
||||
fit_hdr = (const void *)addr;
|
||||
if (!fit_check_format (fit_hdr)) {
|
||||
puts ("Bad FIT image format\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* get subimage node offset */
|
||||
noffset = fit_image_get_node (fit_hdr, uname);
|
||||
if (noffset < 0) {
|
||||
printf ("Can't find '%s' FIT subimage\n", uname);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (fit_image_check_comp (fit_hdr, noffset, IH_COMP_NONE)) {
|
||||
printf("Wrong Compression Type for %s command\n",
|
||||
cmdtp->name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* verify integrity */
|
||||
if (verify) {
|
||||
if (!fit_image_check_hashes (fit_hdr, noffset)) {
|
||||
puts ("Bad Data Hash\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (argc > 2 && part >= i) {
|
||||
printf("Bad Image Part\n");
|
||||
|
||||
/* get subimage data address and length */
|
||||
if (fit_image_get_data (fit_hdr, noffset, &fit_data, &fit_len)) {
|
||||
puts ("Could not find script subimage data\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
data = (ulong)fit_data;
|
||||
len = (ulong)fit_len;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
puts ("Invalid image type for imxtract\n");
|
||||
return 1;
|
||||
}
|
||||
len = ntohl(len_ptr[part]);
|
||||
|
||||
if (argc > 3) {
|
||||
memcpy((char *) dest, (char *) data, len);
|
||||
@ -139,6 +182,9 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
||||
U_BOOT_CMD(imxtract, 4, 1, do_imgextract,
|
||||
"imxtract- extract a part of a multi-image\n",
|
||||
"addr part [dest]\n"
|
||||
" - extract <part> from image at <addr> and copy to <dest>\n");
|
||||
|
||||
" - extract <part> from legacy image at <addr> and copy to <dest>\n"
|
||||
#if defined(CONFIG_FIT)
|
||||
"addr uname [dest]\n"
|
||||
" - extract <uname> subimage from FIT image at <addr> and copy to <dest>\n"
|
||||
#endif
|
||||
);
|
||||
|
113
common/gunzip.c
Normal file
113
common/gunzip.c
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* (C) Copyright 2000-2006
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <watchdog.h>
|
||||
#include <command.h>
|
||||
#include <image.h>
|
||||
#include <malloc.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#define ZALLOC_ALIGNMENT 16
|
||||
#define HEAD_CRC 2
|
||||
#define EXTRA_FIELD 4
|
||||
#define ORIG_NAME 8
|
||||
#define COMMENT 0x10
|
||||
#define RESERVED 0xe0
|
||||
#define DEFLATED 8
|
||||
|
||||
int gunzip(void *, int, unsigned char *, unsigned long *);
|
||||
void *zalloc(void *, unsigned, unsigned);
|
||||
void zfree(void *, void *, unsigned);
|
||||
|
||||
void *zalloc(void *x, unsigned items, unsigned size)
|
||||
{
|
||||
void *p;
|
||||
|
||||
size *= items;
|
||||
size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1);
|
||||
|
||||
p = malloc (size);
|
||||
|
||||
return (p);
|
||||
}
|
||||
|
||||
void zfree(void *x, void *addr, unsigned nb)
|
||||
{
|
||||
free (addr);
|
||||
}
|
||||
|
||||
int gunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp)
|
||||
{
|
||||
z_stream s;
|
||||
int r, i, flags;
|
||||
|
||||
/* skip header */
|
||||
i = 10;
|
||||
flags = src[3];
|
||||
if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
|
||||
puts ("Error: Bad gzipped data\n");
|
||||
return (-1);
|
||||
}
|
||||
if ((flags & EXTRA_FIELD) != 0)
|
||||
i = 12 + src[10] + (src[11] << 8);
|
||||
if ((flags & ORIG_NAME) != 0)
|
||||
while (src[i++] != 0)
|
||||
;
|
||||
if ((flags & COMMENT) != 0)
|
||||
while (src[i++] != 0)
|
||||
;
|
||||
if ((flags & HEAD_CRC) != 0)
|
||||
i += 2;
|
||||
if (i >= *lenp) {
|
||||
puts ("Error: gunzip out of data in header\n");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
s.zalloc = zalloc;
|
||||
s.zfree = zfree;
|
||||
#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
|
||||
s.outcb = (cb_func)WATCHDOG_RESET;
|
||||
#else
|
||||
s.outcb = Z_NULL;
|
||||
#endif /* CONFIG_HW_WATCHDOG */
|
||||
|
||||
r = inflateInit2(&s, -MAX_WBITS);
|
||||
if (r != Z_OK) {
|
||||
printf ("Error: inflateInit2() returned %d\n", r);
|
||||
return (-1);
|
||||
}
|
||||
s.next_in = src + i;
|
||||
s.avail_in = *lenp - i;
|
||||
s.next_out = dst;
|
||||
s.avail_out = dstlen;
|
||||
r = inflate(&s, Z_FINISH);
|
||||
if (r != Z_OK && r != Z_STREAM_END) {
|
||||
printf ("Error: inflate() returned %d\n", r);
|
||||
return (-1);
|
||||
}
|
||||
*lenp = s.next_out - (unsigned char *) dst;
|
||||
inflateEnd(&s);
|
||||
|
||||
return (0);
|
||||
}
|
2541
common/image.c
Normal file
2541
common/image.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -23,45 +23,45 @@
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#if defined(CONFIG_MPC8260) || defined(CONFIG_440EP) || defined(CONFIG_440GR)
|
||||
void lynxkdi_boot ( image_header_t *hdr )
|
||||
void lynxkdi_boot (image_header_t *hdr)
|
||||
{
|
||||
void (*lynxkdi)(void) = (void(*)(void)) ntohl(hdr->ih_ep);
|
||||
void (*lynxkdi)(void) = (void(*)(void))image_get_ep (hdr);
|
||||
lynxos_bootparms_t *parms = (lynxos_bootparms_t *)0x0020;
|
||||
bd_t *kbd;
|
||||
u32 *psz = (u32 *)(ntohl(hdr->ih_load) + 0x0204);
|
||||
u32 *psz = (u32 *)(image_get_load (hdr) + 0x0204);
|
||||
|
||||
memset( parms, 0, sizeof(*parms));
|
||||
memset (parms, 0, sizeof(*parms));
|
||||
kbd = gd->bd;
|
||||
parms->clock_ref = kbd->bi_busfreq;
|
||||
parms->dramsz = kbd->bi_memsize;
|
||||
memcpy(parms->ethaddr, kbd->bi_enetaddr, 6);
|
||||
mtspr(SPRN_SPRG2, 0x0020);
|
||||
memcpy (parms->ethaddr, kbd->bi_enetaddr, 6);
|
||||
mtspr (SPRN_SPRG2, 0x0020);
|
||||
|
||||
/* Do a simple check for Bluecat so we can pass the
|
||||
* kernel command line parameters.
|
||||
*/
|
||||
if( le32_to_cpu(*psz) == ntohl(hdr->ih_size) ){ /* FIXME: NOT SURE HERE ! */
|
||||
char *args;
|
||||
char *cmdline = (char *)(ntohl(hdr->ih_load) + 0x020c);
|
||||
int len;
|
||||
if (le32_to_cpu (*psz) == image_get_data_size (hdr)) { /* FIXME: NOT SURE HERE ! */
|
||||
char *args;
|
||||
char *cmdline = (char *)(image_get_load (hdr) + 0x020c);
|
||||
int len;
|
||||
|
||||
printf("Booting Bluecat KDI ...\n");
|
||||
udelay(200*1000); /* Allow serial port to flush */
|
||||
if ((args = getenv("bootargs")) == NULL)
|
||||
args = "";
|
||||
/* Prepend the cmdline */
|
||||
len = strlen(args);
|
||||
if( len && (len + strlen(cmdline) + 2 < (0x0400 - 0x020c))) {
|
||||
memmove( cmdline + strlen(args) + 1, cmdline, strlen(cmdline) );
|
||||
strcpy( cmdline, args );
|
||||
cmdline[len] = ' ';
|
||||
}
|
||||
printf ("Booting Bluecat KDI ...\n");
|
||||
udelay (200*1000); /* Allow serial port to flush */
|
||||
if ((args = getenv ("bootargs")) == NULL)
|
||||
args = "";
|
||||
/* Prepend the cmdline */
|
||||
len = strlen (args);
|
||||
if (len && (len + strlen (cmdline) + 2 < (0x0400 - 0x020c))) {
|
||||
memmove (cmdline + strlen (args) + 1, cmdline, strlen (cmdline));
|
||||
strcpy (cmdline, args);
|
||||
cmdline[len] = ' ';
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("Booting LynxOS KDI ...\n");
|
||||
printf ("Booting LynxOS KDI ...\n");
|
||||
}
|
||||
|
||||
lynxkdi();
|
||||
lynxkdi ();
|
||||
}
|
||||
#else
|
||||
#error "Lynx KDI support not implemented for configured CPU"
|
||||
|
@ -114,7 +114,7 @@ unsigned long get_tbclk (void)
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#ifdef CONFIG_OF_LIBFDT
|
||||
#if defined(CONFIG_OF_LIBFDT) && defined (CONFIG_OF_BOARD_SETUP)
|
||||
void ft_cpu_setup(void *blob, bd_t *bd)
|
||||
{
|
||||
int div = in_8((void*)CFG_MBAR + 0x204) & 0x0020 ? 8 : 4;
|
||||
|
@ -300,7 +300,7 @@ void watchdog_reset (void)
|
||||
#endif /* CONFIG_WATCHDOG */
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
#if defined(CONFIG_OF_LIBFDT)
|
||||
#if defined(CONFIG_OF_LIBFDT) && defined (CONFIG_OF_BOARD_SETUP)
|
||||
void ft_cpu_setup (void *blob, bd_t *bd)
|
||||
{
|
||||
char * cpu_path = "/cpus/" OF_CPU;
|
||||
|
191
doc/uImage.FIT/command_syntax_extensions.txt
Normal file
191
doc/uImage.FIT/command_syntax_extensions.txt
Normal file
@ -0,0 +1,191 @@
|
||||
Command syntax extensions for the new uImage format
|
||||
===================================================
|
||||
|
||||
Author: Bartlomiej Sieka <tur@semihalf.com>
|
||||
|
||||
With the introduction of the new uImage format, bootm command (and other
|
||||
commands as well) have to understand new syntax of the arguments. This is
|
||||
necessary in order to specify objects contained in the new uImage, on which
|
||||
bootm has to operate. This note attempts to first summarize bootm usage
|
||||
scenarios, and then introduces new argument syntax.
|
||||
|
||||
|
||||
bootm usage scenarios
|
||||
---------------------
|
||||
|
||||
Below is a summary of bootm usage scenarios, focused on booting a PowerPC
|
||||
Linux kernel. The purpose of the following list is to document a complete list
|
||||
of supported bootm usages.
|
||||
|
||||
Note: U-Boot supports two methods of booting a PowerPC Linux kernel: old way,
|
||||
i.e., without passing the Flattened Device Tree (FDT), and new way, where the
|
||||
kernel is passed a pointer to the FDT. The boot method is indicated for each
|
||||
scenario.
|
||||
|
||||
|
||||
1. bootm boot image at the current address, equivalent to 2,3,8
|
||||
|
||||
Old uImage:
|
||||
2. bootm <addr1> /* single image at <addr1> */
|
||||
3. bootm <addr1> /* multi-image at <addr1> */
|
||||
4. bootm <addr1> - /* multi-image at <addr1> */
|
||||
5. bootm <addr1> <addr2> /* single image at <addr1> */
|
||||
6. bootm <addr1> <addr2> <addr3> /* single image at <addr1> */
|
||||
7. bootm <addr1> - <addr3> /* single image at <addr1> */
|
||||
|
||||
New uImage:
|
||||
8. bootm <addr1>
|
||||
9. bootm [<addr1>]:<subimg1>
|
||||
10. bootm [<addr1>]#<conf>
|
||||
11. bootm [<addr1>]:<subimg1> [<addr2>]:<subimg2>
|
||||
12. bootm [<addr1>]:<subimg1> [<addr2>]:<subimg2> [<addr3>]:<subimg3>
|
||||
13. bootm [<addr1>]:<subimg1> [<addr2>]:<subimg2> <addr3>
|
||||
14. bootm [<addr1>]:<subimg1> - [<addr3>]:<subimg3>
|
||||
15. bootm [<addr1>]:<subimg1> - <addr3>
|
||||
|
||||
|
||||
Ad. 1. This is equivalent to cases 2,3,8, depending on the type of image at
|
||||
the current image address.
|
||||
- boot method: see cases 2,3,8
|
||||
|
||||
Ad. 2. Boot kernel image located at <addr1>.
|
||||
- boot method: non-FDT
|
||||
|
||||
Ad. 3. First and second components of the image at <addr1> are assumed to be a
|
||||
kernel and a ramdisk, respectively. The kernel is booted with initrd loaded
|
||||
with the ramdisk from the image.
|
||||
- boot method: depends on the number of components at <addr1>, and on whether
|
||||
U-Boot is compiled with OF support:
|
||||
|
||||
| 2 components | 3 components |
|
||||
| (kernel, initrd) | (kernel, initrd, fdt) |
|
||||
---------------------------------------------------------------------
|
||||
#ifdef CONFIG_OF_* | non-FDT | FDT |
|
||||
#ifndef CONFIG_OF_* | non-FDT | non-FDT |
|
||||
|
||||
Ad. 4. Similar to case 3, but the kernel is booted without initrd. Second
|
||||
component of the multi-image is irrelevant (it can be a dummy, 1-byte file).
|
||||
- boot method: see case 3
|
||||
|
||||
Ad. 5. Boot kernel image located at <addr1> with initrd loaded with ramdisk
|
||||
from the image at <addr2>.
|
||||
- boot method: non-FDT
|
||||
|
||||
Ad. 6. <addr1> is the address of a kernel image, <addr2> is the address of a
|
||||
ramdisk image, and <addr3> is the address of a FDT binary blob. Kernel is
|
||||
booted with initrd loaded with ramdisk from the image at <addr2>.
|
||||
- boot method: FDT
|
||||
|
||||
Ad. 7. <addr1> is the address of a kernel image and <addr3> is the address of
|
||||
a FDT binary blob. Kernel is booted without initrd.
|
||||
- boot method: FDT
|
||||
|
||||
Ad. 8. Image at <addr1> is assumed to contain a default configuration, which
|
||||
is booted.
|
||||
- boot method: FDT or non-FDT, depending on whether the default configuration
|
||||
defines FDT
|
||||
|
||||
Ad. 9. Similar to case 2: boot kernel stored in <subimg1> from the image at
|
||||
address <addr1>.
|
||||
- boot method: non-FDT
|
||||
|
||||
Ad. 10. Boot configuration <conf> from the image at <addr1>.
|
||||
- boot method: FDT or non-FDT, depending on whether the configuration given
|
||||
defines FDT
|
||||
|
||||
Ad. 11. Equivalent to case 5: boot kernel stored in <subimg1> from the image
|
||||
at <addr1> with initrd loaded with ramdisk <subimg2> from the image at
|
||||
<addr2>.
|
||||
- boot method: non-FDT
|
||||
|
||||
Ad. 12. Equivalent to case 6: boot kernel stored in <subimg1> from the image
|
||||
at <addr1> with initrd loaded with ramdisk <subimg2> from the image at
|
||||
<addr2>, and pass FDT blob <subimg3> from the image at <addr3>.
|
||||
- boot method: FDT
|
||||
|
||||
Ad. 13. Similar to case 12, the difference being that <addr3> is the address
|
||||
of FDT binary blob that is to be passed to the kernel.
|
||||
- boot method: FDT
|
||||
|
||||
Ad. 14. Equivalent to case 7: boot kernel stored in <subimg1> from the image
|
||||
at <addr1>, without initrd, and pass FDT blob <subimg3> from the image at
|
||||
<addr3>.
|
||||
- boot method: FDT
|
||||
|
||||
Ad. 15. Similar to case 14, the difference being that <addr3> is the address
|
||||
of the FDT binary blob that is to be passed to the kernel.
|
||||
- boot method: FDT
|
||||
|
||||
|
||||
New uImage argument syntax
|
||||
--------------------------
|
||||
|
||||
New uImage support introduces two new forms for bootm arguments, with the
|
||||
following syntax:
|
||||
|
||||
- new uImage sub-image specification
|
||||
<addr>:<sub-image unit_name>
|
||||
|
||||
- new uImage configuration specification
|
||||
<addr>#<configuration unit_name>
|
||||
|
||||
|
||||
Examples:
|
||||
|
||||
- boot kernel "kernel@1" stored in a new uImage located at 200000:
|
||||
bootm 200000:kernel@1
|
||||
|
||||
- boot configuration "cfg@1" from a new uImage located at 200000:
|
||||
bootm 200000#cfg@1
|
||||
|
||||
- boot "kernel@1" from a new uImage at 200000 with initrd "ramdisk@2" found in
|
||||
some other new uImage stored at address 800000:
|
||||
bootm 200000:kernel@1 800000:ramdisk@2
|
||||
|
||||
- boot "kernel@2" from a new uImage at 200000, with initrd "ramdisk@1" and FDT
|
||||
"fdt@1", both stored in some other new uImage located at 800000:
|
||||
bootm 200000:kernel@1 800000:ramdisk@1 800000:fdt@1
|
||||
|
||||
- boot kernel "kernel@2" with initrd "ramdisk@2", both stored in a new uImage
|
||||
at address 200000, with a raw FDT blob stored at address 600000:
|
||||
bootm 200000:kernel@2 200000:ramdisk@2 600000
|
||||
|
||||
- boot kernel "kernel@2" from new uImage at 200000 with FDT "fdt@1" from the
|
||||
same new uImage:
|
||||
bootm 200000:kernel@2 - 200000:fdt@1
|
||||
|
||||
|
||||
Note on current image address
|
||||
-----------------------------
|
||||
|
||||
When bootm is called without arguments, the image at current image address is
|
||||
booted. The current image address is the address set most recently by a load
|
||||
command, etc, and is by default equal to CFG_LOAD_ADDR. For example, consider
|
||||
the following commands:
|
||||
|
||||
tftp 200000 /tftpboot/kernel
|
||||
bootm
|
||||
Last command is equivalent to:
|
||||
bootm 200000
|
||||
|
||||
In case of the new uImage argument syntax, the address portion of any argument
|
||||
can be omitted. If <addr3> is omitted, then it is assumed that image at
|
||||
<addr2> should be used. Similarly, when <addr2> is omitted, is is assumed that
|
||||
image at <addr1> should be used. If <addr1> is omitted, it is assumed that the
|
||||
current image address is to be used. For example, consider the following
|
||||
commands:
|
||||
|
||||
tftp 200000 /tftpboot/uImage
|
||||
bootm :kernel@1
|
||||
Last command is equivalent to:
|
||||
bootm 200000:kernel@1
|
||||
|
||||
tftp 200000 /tftpboot/uImage
|
||||
bootm 400000:kernel@1 :ramdisk@1
|
||||
Last command is equivalent to:
|
||||
bootm 400000:kernel@1 400000:ramdisk@1
|
||||
|
||||
tftp 200000 /tftpboot/uImage
|
||||
bootm :kernel@1 400000:ramdisk@1 :fdt@1
|
||||
Last command is equivalent to:
|
||||
bootm 200000:kernel@1 400000:ramdisk@1 400000:fdt@1
|
297
doc/uImage.FIT/howto.txt
Normal file
297
doc/uImage.FIT/howto.txt
Normal file
@ -0,0 +1,297 @@
|
||||
How to use images in the new image format
|
||||
=========================================
|
||||
|
||||
Author: Bartlomiej Sieka <tur@semihalf.com>
|
||||
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
The new uImage format allows more flexibility in handling images of various
|
||||
types (kernel, ramdisk, etc.), it also enhances integrity protection of images
|
||||
with sha1 and md5 checksums.
|
||||
|
||||
Two auxiliary tools are needed on the development host system in order to
|
||||
create an uImage in the new format: mkimage and dtc, although only one
|
||||
(mkimage) is invoked directly. dtc is called from within mkimage and operates
|
||||
behind the scenes, but needs to be present in the $PATH nevertheless. It is
|
||||
important that the dtc used has support for binary includes -- refer to
|
||||
www.jdl.com for its latest version. mkimage (together with dtc) takes as input
|
||||
an image source file, which describes the contents of the image and defines
|
||||
its various properties used during booting. By convention, image source file
|
||||
has the ".its" extension, also, the details of its format are given in
|
||||
doc/source_file_format.txt. The actual data that is to be included in the
|
||||
uImage (kernel, ramdisk, etc.) is specified in the image source file in the
|
||||
form of paths to appropriate data files. The outcome of the image creation
|
||||
process is a binary file (by convention with the ".itb" extension) that
|
||||
contains all the referenced data (kernel, ramdisk, etc.) and other information
|
||||
needed by U-Boot to handle the uImage properly. The uImage file is then
|
||||
transferred to the target (e.g., via tftp) and booted using the bootm command.
|
||||
|
||||
To summarize the prerequisites needed for new uImage creation:
|
||||
- mkimage
|
||||
- dtc (with support for binary includes)
|
||||
- image source file (*.its)
|
||||
- image data file(s)
|
||||
|
||||
|
||||
Here's a graphical overview of the image creation and booting process:
|
||||
|
||||
image source file mkimage + dtc transfer to target
|
||||
+ ---------------> image file --------------------> bootm
|
||||
image data files(s)
|
||||
|
||||
|
||||
Example 1 -- old-style (non-FDT) kernel booting
|
||||
-----------------------------------------------
|
||||
|
||||
Consider a simple scenario, where a PPC Linux kernel built from sources on the
|
||||
development host is to be booted old-style (non-FDT) by U-Boot on an embedded
|
||||
target. Assume that the outcome of the build is vmlinux.bin.gz, a file which
|
||||
contains a gzip-compressed PPC Linux kernel (the only data file in this case).
|
||||
The uImage can be produced using the image source file
|
||||
doc/uImage.FIT/kernel.its (note that kernel.its assumes that vmlinux.bin.gz is
|
||||
in the current working directory; if desired, an alternative path can be
|
||||
specified in the kernel.its file). Here's how to create the image and inspect
|
||||
its contents:
|
||||
|
||||
[on the host system]
|
||||
$ mkimage -f kernel.its kernel.itb
|
||||
DTC: dts->dtb on file "kernel.its"
|
||||
$
|
||||
$ mkimage -l kernel.itb
|
||||
FIT description: Simple image with single Linux kernel
|
||||
Created: Tue Mar 11 17:26:15 2008
|
||||
Image 0 (kernel@1)
|
||||
Description: Vanilla Linux kernel
|
||||
Type: Kernel Image
|
||||
Compression: gzip compressed
|
||||
Data Size: 943347 Bytes = 921.24 kB = 0.90 MB
|
||||
Architecture: PowerPC
|
||||
OS: Linux
|
||||
Load Address: 0x00000000
|
||||
Entry Point: 0x00000000
|
||||
Hash algo: crc32
|
||||
Hash value: 2ae2bb40
|
||||
Hash algo: sha1
|
||||
Hash value: 3c200f34e2c226ddc789240cca0c59fc54a67cf4
|
||||
Default Configuration: 'config@1'
|
||||
Configuration 0 (config@1)
|
||||
Description: Boot Linux kernel
|
||||
Kernel: kernel@1
|
||||
|
||||
|
||||
The resulting image file kernel.itb can be now transferred to the target,
|
||||
inspected and booted (note that first three U-Boot commands below are shown
|
||||
for completeness -- they are part of the standard booting procedure and not
|
||||
specific to the new image format).
|
||||
|
||||
[on the target system]
|
||||
=> print nfsargs
|
||||
nfsargs=setenv bootargs root=/dev/nfs rw nfsroot=${serverip}:${rootpath}
|
||||
=> print addip
|
||||
addip=setenv bootargs ${bootargs} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:${netdev}:off panic=1
|
||||
=> run nfsargs addip
|
||||
=> tftp 900000 /path/to/tftp/location/kernel.itb
|
||||
Using FEC ETHERNET device
|
||||
TFTP from server 192.168.1.1; our IP address is 192.168.160.5
|
||||
Filename '/path/to/tftp/location/kernel.itb'.
|
||||
Load address: 0x900000
|
||||
Loading: #################################################################
|
||||
done
|
||||
Bytes transferred = 944464 (e6950 hex)
|
||||
=> iminfo
|
||||
|
||||
## Checking Image at 00900000 ...
|
||||
FIT image found
|
||||
FIT description: Simple image with single Linux kernel
|
||||
Created: 2008-03-11 16:26:15 UTC
|
||||
Image 0 (kernel@1)
|
||||
Description: Vanilla Linux kernel
|
||||
Type: Kernel Image
|
||||
Compression: gzip compressed
|
||||
Data Start: 0x009000e0
|
||||
Data Size: 943347 Bytes = 921.2 kB
|
||||
Architecture: PowerPC
|
||||
OS: Linux
|
||||
Load Address: 0x00000000
|
||||
Entry Point: 0x00000000
|
||||
Hash algo: crc32
|
||||
Hash value: 2ae2bb40
|
||||
Hash algo: sha1
|
||||
Hash value: 3c200f34e2c226ddc789240cca0c59fc54a67cf4
|
||||
Default Configuration: 'config@1'
|
||||
Configuration 0 (config@1)
|
||||
Description: Boot Linux kernel
|
||||
Kernel: kernel@1
|
||||
|
||||
=> bootm
|
||||
## Booting kernel from FIT Image at 00900000 ...
|
||||
Using 'config@1' configuration
|
||||
Trying 'kernel@1' kernel subimage
|
||||
Description: Vanilla Linux kernel
|
||||
Type: Kernel Image
|
||||
Compression: gzip compressed
|
||||
Data Start: 0x009000e0
|
||||
Data Size: 943347 Bytes = 921.2 kB
|
||||
Architecture: PowerPC
|
||||
OS: Linux
|
||||
Load Address: 0x00000000
|
||||
Entry Point: 0x00000000
|
||||
Hash algo: crc32
|
||||
Hash value: 2ae2bb40
|
||||
Hash algo: sha1
|
||||
Hash value: 3c200f34e2c226ddc789240cca0c59fc54a67cf4
|
||||
Verifying Hash Integrity ... crc32+ sha1+ OK
|
||||
Uncompressing Kernel Image ... OK
|
||||
Memory BAT mapping: BAT2=256Mb, BAT3=0Mb, residual: 0Mb
|
||||
Linux version 2.4.25 (m8@hekate) (gcc version 4.0.0 (DENX ELDK 4.0 4.0.0)) #2 czw lip 5 17:56:18 CEST 2007
|
||||
On node 0 totalpages: 65536
|
||||
zone(0): 65536 pages.
|
||||
zone(1): 0 pages.
|
||||
zone(2): 0 pages.
|
||||
Kernel command line: root=/dev/nfs rw nfsroot=192.168.1.1:/opt/eldk-4.1/ppc_6xx ip=192.168.160.5:192.168.1.1::255.255.0.0:lite5200b:eth0:off panic=1
|
||||
Calibrating delay loop... 307.20 BogoMIPS
|
||||
|
||||
|
||||
Example 2 -- new-style (FDT) kernel booting
|
||||
-------------------------------------------
|
||||
|
||||
Consider another simple scenario, where a PPC Linux kernel is to be booted
|
||||
new-style, i.e., with a FDT blob. In this case there are two prerequisite data
|
||||
files: vmlinux.bin.gz (Linux kernel) and target.dtb (FDT blob). The uImage can
|
||||
be produced using image source file doc/uImage.FIT/kernel_fdt.its like this
|
||||
(note again, that both prerequisite data files are assumed to be present in
|
||||
the current working directory -- image source file kernel_fdt.its can be
|
||||
modified to take the files from some other location if needed):
|
||||
|
||||
[on the host system]
|
||||
$ mkimage -f kernel_fdt.its kernel_fdt.itb
|
||||
DTC: dts->dtb on file "kernel_fdt.its"
|
||||
$
|
||||
$ mkimage -l kernel_fdt.itb
|
||||
FIT description: Simple image with single Linux kernel and FDT blob
|
||||
Created: Tue Mar 11 16:29:22 2008
|
||||
Image 0 (kernel@1)
|
||||
Description: Vanilla Linux kernel
|
||||
Type: Kernel Image
|
||||
Compression: gzip compressed
|
||||
Data Size: 1092037 Bytes = 1066.44 kB = 1.04 MB
|
||||
Architecture: PowerPC
|
||||
OS: Linux
|
||||
Load Address: 0x00000000
|
||||
Entry Point: 0x00000000
|
||||
Hash algo: crc32
|
||||
Hash value: 2c0cc807
|
||||
Hash algo: sha1
|
||||
Hash value: 264b59935470e42c418744f83935d44cdf59a3bb
|
||||
Image 1 (fdt@1)
|
||||
Description: Flattened Device Tree blob
|
||||
Type: Flat Device Tree
|
||||
Compression: uncompressed
|
||||
Data Size: 16384 Bytes = 16.00 kB = 0.02 MB
|
||||
Architecture: PowerPC
|
||||
Hash algo: crc32
|
||||
Hash value: 0d655d71
|
||||
Hash algo: sha1
|
||||
Hash value: 25ab4e15cd4b8a5144610394560d9c318ce52def
|
||||
Default Configuration: 'conf@1'
|
||||
Configuration 0 (conf@1)
|
||||
Description: Boot Linux kernel with FDT blob
|
||||
Kernel: kernel@1
|
||||
FDT: fdt@1
|
||||
|
||||
|
||||
The resulting image file kernel_fdt.itb can be now transferred to the target,
|
||||
inspected and booted:
|
||||
|
||||
[on the target system]
|
||||
=> tftp 900000 /path/to/tftp/location/kernel_fdt.itb
|
||||
Using FEC ETHERNET device
|
||||
TFTP from server 192.168.1.1; our IP address is 192.168.160.5
|
||||
Filename '/path/to/tftp/location/kernel_fdt.itb'.
|
||||
Load address: 0x900000
|
||||
Loading: #################################################################
|
||||
###########
|
||||
done
|
||||
Bytes transferred = 1109776 (10ef10 hex)
|
||||
=> iminfo
|
||||
|
||||
## Checking Image at 00900000 ...
|
||||
FIT image found
|
||||
FIT description: Simple image with single Linux kernel and FDT blob
|
||||
Created: 2008-03-11 15:29:22 UTC
|
||||
Image 0 (kernel@1)
|
||||
Description: Vanilla Linux kernel
|
||||
Type: Kernel Image
|
||||
Compression: gzip compressed
|
||||
Data Start: 0x009000ec
|
||||
Data Size: 1092037 Bytes = 1 MB
|
||||
Architecture: PowerPC
|
||||
OS: Linux
|
||||
Load Address: 0x00000000
|
||||
Entry Point: 0x00000000
|
||||
Hash algo: crc32
|
||||
Hash value: 2c0cc807
|
||||
Hash algo: sha1
|
||||
Hash value: 264b59935470e42c418744f83935d44cdf59a3bb
|
||||
Image 1 (fdt@1)
|
||||
Description: Flattened Device Tree blob
|
||||
Type: Flat Device Tree
|
||||
Compression: uncompressed
|
||||
Data Start: 0x00a0abdc
|
||||
Data Size: 16384 Bytes = 16 kB
|
||||
Architecture: PowerPC
|
||||
Hash algo: crc32
|
||||
Hash value: 0d655d71
|
||||
Hash algo: sha1
|
||||
Hash value: 25ab4e15cd4b8a5144610394560d9c318ce52def
|
||||
Default Configuration: 'conf@1'
|
||||
Configuration 0 (conf@1)
|
||||
Description: Boot Linux kernel with FDT blob
|
||||
Kernel: kernel@1
|
||||
FDT: fdt@1
|
||||
=> bootm
|
||||
## Booting kernel from FIT Image at 00900000 ...
|
||||
Using 'conf@1' configuration
|
||||
Trying 'kernel@1' kernel subimage
|
||||
Description: Vanilla Linux kernel
|
||||
Type: Kernel Image
|
||||
Compression: gzip compressed
|
||||
Data Start: 0x009000ec
|
||||
Data Size: 1092037 Bytes = 1 MB
|
||||
Architecture: PowerPC
|
||||
OS: Linux
|
||||
Load Address: 0x00000000
|
||||
Entry Point: 0x00000000
|
||||
Hash algo: crc32
|
||||
Hash value: 2c0cc807
|
||||
Hash algo: sha1
|
||||
Hash value: 264b59935470e42c418744f83935d44cdf59a3bb
|
||||
Verifying Hash Integrity ... crc32+ sha1+ OK
|
||||
Uncompressing Kernel Image ... OK
|
||||
## Flattened Device Tree from FIT Image at 00900000
|
||||
Using 'conf@1' configuration
|
||||
Trying 'fdt@1' FDT blob subimage
|
||||
Description: Flattened Device Tree blob
|
||||
Type: Flat Device Tree
|
||||
Compression: uncompressed
|
||||
Data Start: 0x00a0abdc
|
||||
Data Size: 16384 Bytes = 16 kB
|
||||
Architecture: PowerPC
|
||||
Hash algo: crc32
|
||||
Hash value: 0d655d71
|
||||
Hash algo: sha1
|
||||
Hash value: 25ab4e15cd4b8a5144610394560d9c318ce52def
|
||||
Verifying Hash Integrity ... crc32+ sha1+ OK
|
||||
Booting using the fdt blob at 0xa0abdc
|
||||
Loading Device Tree to 007fc000, end 007fffff ... OK
|
||||
[ 0.000000] Using lite5200 machine description
|
||||
[ 0.000000] Linux version 2.6.24-rc6-gaebecdfc (m8@hekate) (gcc version 4.0.0 (DENX ELDK 4.1 4.0.0)) #1 Sat Jan 12 15:38:48 CET 2008
|
||||
|
||||
|
||||
Example 3 -- advanced booting
|
||||
-----------------------------
|
||||
|
||||
Refer to doc/uImage.FIT/multi.its for an image source file that allows more
|
||||
sophisticated booting scenarios (multiple kernels, ramdisks and fdt blobs).
|
34
doc/uImage.FIT/kernel.its
Normal file
34
doc/uImage.FIT/kernel.its
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Simple U-boot uImage source file containing a single kernel
|
||||
*/
|
||||
/ {
|
||||
description = "Simple image with single Linux kernel";
|
||||
#address-cells = <1>;
|
||||
|
||||
images {
|
||||
kernel@1 {
|
||||
description = "Vanilla Linux kernel";
|
||||
data = /incbin/("./vmlinux.bin.gz");
|
||||
type = "kernel";
|
||||
arch = "ppc";
|
||||
os = "linux";
|
||||
compression = "gzip";
|
||||
load = <00000000>;
|
||||
entry = <00000000>;
|
||||
hash@1 {
|
||||
algo = "crc32";
|
||||
};
|
||||
hash@2 {
|
||||
algo = "sha1";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
configurations {
|
||||
default = "config@1";
|
||||
config@1 {
|
||||
description = "Boot Linux kernel";
|
||||
kernel = "kernel@1";
|
||||
};
|
||||
};
|
||||
};
|
48
doc/uImage.FIT/kernel_fdt.its
Normal file
48
doc/uImage.FIT/kernel_fdt.its
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Simple U-boot uImage source file containing a single kernel and FDT blob
|
||||
*/
|
||||
/ {
|
||||
description = "Simple image with single Linux kernel and FDT blob";
|
||||
#address-cells = <1>;
|
||||
|
||||
images {
|
||||
kernel@1 {
|
||||
description = "Vanilla Linux kernel";
|
||||
data = /incbin/("./vmlinux.bin.gz");
|
||||
type = "kernel";
|
||||
arch = "ppc";
|
||||
os = "linux";
|
||||
compression = "gzip";
|
||||
load = <00000000>;
|
||||
entry = <00000000>;
|
||||
hash@1 {
|
||||
algo = "crc32";
|
||||
};
|
||||
hash@2 {
|
||||
algo = "sha1";
|
||||
};
|
||||
};
|
||||
fdt@1 {
|
||||
description = "Flattened Device Tree blob";
|
||||
data = /incbin/("./target.dtb");
|
||||
type = "flat_dt";
|
||||
arch = "ppc";
|
||||
compression = "none";
|
||||
hash@1 {
|
||||
algo = "crc32";
|
||||
};
|
||||
hash@2 {
|
||||
algo = "sha1";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
configurations {
|
||||
default = "conf@1";
|
||||
conf@1 {
|
||||
description = "Boot Linux kernel with FDT blob";
|
||||
kernel = "kernel@1";
|
||||
fdt = "fdt@1";
|
||||
};
|
||||
};
|
||||
};
|
124
doc/uImage.FIT/multi.its
Normal file
124
doc/uImage.FIT/multi.its
Normal file
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* U-boot uImage source file with multiple kernels, ramdisks and FDT blobs
|
||||
*/
|
||||
/ {
|
||||
description = "Various kernels, ramdisks and FDT blobs";
|
||||
#address-cells = <1>;
|
||||
|
||||
images {
|
||||
kernel@1 {
|
||||
description = "vanilla-2.6.23";
|
||||
data = /incbin/("./vmlinux.bin.gz");
|
||||
type = "kernel";
|
||||
arch = "ppc";
|
||||
os = "linux";
|
||||
compression = "gzip";
|
||||
load = <00000000>;
|
||||
entry = <00000000>;
|
||||
hash@1 {
|
||||
algo = "md5";
|
||||
};
|
||||
hash@2 {
|
||||
algo = "sha1";
|
||||
};
|
||||
};
|
||||
|
||||
kernel@2 {
|
||||
description = "2.6.23-denx";
|
||||
data = /incbin/("./2.6.23-denx.bin.gz");
|
||||
type = "kernel";
|
||||
arch = "ppc";
|
||||
os = "linux";
|
||||
compression = "gzip";
|
||||
load = <00000000>;
|
||||
entry = <00000000>;
|
||||
hash@1 {
|
||||
algo = "sha1";
|
||||
};
|
||||
};
|
||||
|
||||
kernel@3 {
|
||||
description = "2.4.25-denx";
|
||||
data = /incbin/("./2.4.25-denx.bin.gz");
|
||||
type = "kernel";
|
||||
arch = "ppc";
|
||||
os = "linux";
|
||||
compression = "gzip";
|
||||
load = <00000000>;
|
||||
entry = <00000000>;
|
||||
hash@1 {
|
||||
algo = "md5";
|
||||
};
|
||||
};
|
||||
|
||||
ramdisk@1 {
|
||||
description = "eldk-4.2-ramdisk";
|
||||
data = /incbin/("./eldk-4.2-ramdisk");
|
||||
type = "ramdisk";
|
||||
arch = "ppc";
|
||||
compression = "gzip";
|
||||
hash@1 {
|
||||
algo = "sha1";
|
||||
};
|
||||
};
|
||||
|
||||
ramdisk@2 {
|
||||
description = "eldk-3.1-ramdisk";
|
||||
data = /incbin/("./eldk-3.1-ramdisk");
|
||||
type = "ramdisk";
|
||||
arch = "ppc";
|
||||
compression = "gzip";
|
||||
hash@1 {
|
||||
algo = "crc32";
|
||||
};
|
||||
};
|
||||
|
||||
fdt@1 {
|
||||
description = "tqm5200-fdt";
|
||||
data = /incbin/("./tqm5200.dtb");
|
||||
type = "flat_dt";
|
||||
arch = "ppc";
|
||||
compression = "none";
|
||||
hash@1 {
|
||||
algo = "crc32";
|
||||
};
|
||||
};
|
||||
|
||||
fdt@2 {
|
||||
description = "tqm5200s-fdt";
|
||||
data = /incbin/("./tqm5200s.dtb");
|
||||
type = "flat_dt";
|
||||
arch = "ppc";
|
||||
compression = "none";
|
||||
load = <00700000>;
|
||||
hash@1 {
|
||||
algo = "sha1";
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
configurations {
|
||||
default = "config@1";
|
||||
|
||||
config@1 {
|
||||
description = "tqm5200 vanilla-2.6.23 configuration";
|
||||
kernel = "kernel@1";
|
||||
ramdisk = "ramdisk@1";
|
||||
fdt = "fdt@1";
|
||||
};
|
||||
|
||||
config@2 {
|
||||
description = "tqm5200s denx-2.6.23 configuration";
|
||||
kernel = "kernel@2";
|
||||
ramdisk = "ramdisk@1";
|
||||
fdt = "fdt@2";
|
||||
};
|
||||
|
||||
config@3 {
|
||||
description = "tqm5200s denx-2.4.25 configuration";
|
||||
kernel = "kernel@3";
|
||||
ramdisk = "ramdisk@2";
|
||||
};
|
||||
};
|
||||
};
|
262
doc/uImage.FIT/source_file_format.txt
Normal file
262
doc/uImage.FIT/source_file_format.txt
Normal file
@ -0,0 +1,262 @@
|
||||
U-boot new uImage source file format (bindings definition)
|
||||
==========================================================
|
||||
|
||||
Author: Marian Balakowicz <m8@semihalf.com>
|
||||
|
||||
1) Introduction
|
||||
---------------
|
||||
|
||||
Evolution of the 2.6 Linux kernel for embedded PowerPC systems introduced new
|
||||
booting method which requires that hardware description is available to the
|
||||
kernel in the form of Flattened Device Tree.
|
||||
|
||||
Booting with a Flattened Device Tree is much more flexible and is intended to
|
||||
replace direct passing of 'struct bd_info' which was used to boot pre-FDT
|
||||
kernels.
|
||||
|
||||
However, U-boot needs to support both techniques to provide backward
|
||||
compatibility for platforms which are not FDT ready. Number of elements
|
||||
playing role in the booting process has increased and now includes the FDT
|
||||
blob. Kernel image, FDT blob and possibly ramdisk image - all must be placed
|
||||
in the system memory and passed to bootm as a arguments. Some of them may be
|
||||
missing: FDT is not present for legacy platforms, ramdisk is always optional.
|
||||
Additionally, old uImage format has been extended to support multi sub-images
|
||||
but the support is limited by simple format of the legacy uImage structure.
|
||||
Single binary header 'struct image_header' is not flexible enough to cover all
|
||||
possible scenarios.
|
||||
|
||||
All those factors combined clearly show that there is a need for new, more
|
||||
flexible, multi component uImage format.
|
||||
|
||||
|
||||
2) New uImage format assumptions
|
||||
--------------------------------
|
||||
|
||||
a) Implementation
|
||||
|
||||
Libfdt has been selected for the new uImage format implementation as (1) it
|
||||
provides needed functionality, (2) is actively maintained and developed and
|
||||
(3) increases code reuse as it is already part of the U-boot source tree.
|
||||
|
||||
b) Terminology
|
||||
|
||||
This document defines new uImage structure by providing FDT bindings for new
|
||||
uImage internals. Bindings are defined from U-boot perspective, i.e. describe
|
||||
final form of the uImage at the moment when it reaches U-boot. User
|
||||
perspective may be simpler, as some of the properties (like timestamps and
|
||||
hashes) will need to be filled in automatically by the U-boot mkimage tool.
|
||||
|
||||
To avoid confusion with the kernel FDT the following naming convention is
|
||||
proposed for the new uImage format related terms:
|
||||
|
||||
FIT - Flattened uImage Tree
|
||||
|
||||
FIT is formally a flattened device tree (in the libfdt meaning), which
|
||||
conforms to bindings defined in this document.
|
||||
|
||||
.its - image tree source
|
||||
.itb - image tree blob
|
||||
|
||||
c) Image building procedure
|
||||
|
||||
The following picture shows how the new uImage is prepared. Input consists of
|
||||
image source file (.its) and a set of data files. Image is created with the
|
||||
help of standard U-boot mkimage tool which in turn uses dtc (device tree
|
||||
compiler) to produce image tree blob (.itb). Resulting .itb file is is the
|
||||
actual binary of a new uImage.
|
||||
|
||||
|
||||
tqm5200.its
|
||||
+
|
||||
vmlinux.bin.gz mkimage + dtc xfer to target
|
||||
eldk-4.2-ramdisk --------------> tqm5200.itb --------------> bootm
|
||||
tqm5200.dtb /|\
|
||||
... |
|
||||
'new uImage'
|
||||
|
||||
- create .its file, automatically filled-in properties are omitted
|
||||
- call mkimage tool on a .its file
|
||||
- mkimage calls dtc to create .itb image and assures that
|
||||
missing properties are added
|
||||
- .itb (new uImage) is uploaded onto the target and used therein
|
||||
|
||||
|
||||
d) Unique identifiers
|
||||
|
||||
To identify FIT sub-nodes representing images, hashes, configurations (which
|
||||
are defined in the following sections), the "unit name" of the given sub-node
|
||||
is used as it's identifier as it assures uniqueness without additional
|
||||
checking required.
|
||||
|
||||
|
||||
3) Root node properties
|
||||
-----------------------
|
||||
|
||||
Root node of the uImage Tree should have the following layout:
|
||||
|
||||
/ o image-tree
|
||||
|- description = "image description"
|
||||
|- timestamp = <12399321>
|
||||
|- #address-cells = <1>
|
||||
|
|
||||
o images
|
||||
| |
|
||||
| o img@1 {...}
|
||||
| o img@2 {...}
|
||||
| ...
|
||||
|
|
||||
o configurations
|
||||
|- default = "cfg@1"
|
||||
|
|
||||
o cfg@1 {...}
|
||||
o cfg@2 {...}
|
||||
...
|
||||
|
||||
|
||||
Optional property:
|
||||
- description : Textual description of the uImage
|
||||
|
||||
Mandatory property:
|
||||
- timestamp : Last image modification time being counted in seconds since
|
||||
1970-01-01 00:00:00 - to be automatically calculated by mkimage tool.
|
||||
|
||||
Conditionally mandatory property:
|
||||
- #address-cells : Number of 32bit cells required to represent entry and
|
||||
load addresses supplied within sub-image nodes. May be omitted when no
|
||||
entry or load addresses are used.
|
||||
|
||||
Mandatory node:
|
||||
- images : This node contains a set of sub-nodes, each of them representing
|
||||
single component sub-image (like kernel, ramdisk, etc.). At least one
|
||||
sub-image is required.
|
||||
|
||||
Optional node:
|
||||
- configurations : Contains a set of available configuration nodes and
|
||||
defines a default configuration.
|
||||
|
||||
|
||||
4) '/images' node
|
||||
-----------------
|
||||
|
||||
This node is a container node for component sub-image nodes. Each sub-node of
|
||||
the '/images' node should have the following layout:
|
||||
|
||||
o image@1
|
||||
|- description = "component sub-image description"
|
||||
|- data = /incbin/("path/to/data/file.bin")
|
||||
|- type = "sub-image type name"
|
||||
|- arch = "ARCH name"
|
||||
|- os = "OS name"
|
||||
|- compression = "compression name"
|
||||
|- load = <00000000>
|
||||
|- entry = <00000000>
|
||||
|
|
||||
o hash@1 {...}
|
||||
o hash@2 {...}
|
||||
...
|
||||
|
||||
Mandatory properties:
|
||||
- description : Textual description of the component sub-image
|
||||
- type : Name of component sub-image type, supported types are:
|
||||
"standalone", "kernel", "ramdisk", "firmware", "script", "filesystem",
|
||||
"fdt".
|
||||
- data : Path to the external file which contains this node's binary data.
|
||||
- compression : Compression used by included data. Supported compressions
|
||||
are "gzip" and "bzip2". If no compression is used compression property
|
||||
should be set to "none".
|
||||
|
||||
Conditionally mandatory property:
|
||||
- os : OS name, mandatory for type="kernel", valid OS names are: "openbsd",
|
||||
"netbsd", "freebsd", "4_4bsd", "linux", "svr4", "esix", "solaris", "irix",
|
||||
"sco", "dell", "ncr", "lynxos", "vxworks", "psos", "qnx", "u_boot",
|
||||
"rtems", "artos", "unity".
|
||||
- arch : Architecture name, mandatory for types: "standalone", "kernel",
|
||||
"firmware", "ramdisk" and "fdt". Valid architecture names are: "alpha",
|
||||
"arm", "i386", "ia64", "mips", "mips64", "ppc", "s390", "sh", "sparc",
|
||||
"sparc64", "m68k", "nios", "microblaze", "nios2", "blackfin", "avr32",
|
||||
"st200".
|
||||
- entry : entry point address, address size is determined by
|
||||
'#address-cells' property of the root node. Mandatory for for types:
|
||||
"standalone" and "kernel".
|
||||
- load : load address, address size is determined by '#address-cells'
|
||||
property of the root node. Mandatory for types: "standalone" and "kernel".
|
||||
|
||||
Optional nodes:
|
||||
- hash@1 : Each hash sub-node represents separate hash or checksum
|
||||
calculated for node's data according to specified algorithm.
|
||||
|
||||
|
||||
5) Hash nodes
|
||||
-------------
|
||||
|
||||
o hash@1
|
||||
|- algo = "hash or checksum algorithm name"
|
||||
|- value = [hash or checksum value]
|
||||
|
||||
Mandatory properties:
|
||||
- algo : Algorithm name, supported are "crc32", "md5" and "sha1".
|
||||
- value : Actual checksum or hash value, correspondingly 4, 16 or 20 bytes
|
||||
long.
|
||||
|
||||
|
||||
6) '/configurations' node
|
||||
-------------------------
|
||||
|
||||
The 'configurations' node is optional. If present, it allows to create a
|
||||
convenient, labeled boot configurations, which combine together kernel images
|
||||
with their ramdisks and fdt blobs.
|
||||
|
||||
The 'configurations' node has has the following structure:
|
||||
|
||||
o configurations
|
||||
|- default = "default configuration sub-node unit name"
|
||||
|
|
||||
o config@1 {...}
|
||||
o config@2 {...}
|
||||
...
|
||||
|
||||
|
||||
Optional property:
|
||||
- default : Selects one of the configuration sub-nodes as a default
|
||||
configuration.
|
||||
|
||||
Mandatory nodes:
|
||||
- configuration-sub-node-unit-name : At least one of the configuration
|
||||
sub-nodes is required.
|
||||
|
||||
|
||||
7) Configuration nodes
|
||||
----------------------
|
||||
|
||||
Each configuration has the following structure:
|
||||
|
||||
o config@1
|
||||
|- description = "configuration description"
|
||||
|- kernel = "kernel sub-node unit name"
|
||||
|- ramdisk = "ramdisk sub-node unit name"
|
||||
|- fdt = "fdt sub-node unit-name"
|
||||
|
||||
|
||||
Mandatory properties:
|
||||
- description : Textual configuration description.
|
||||
- kernel : Unit name of the corresponding kernel image (image sub-node of a
|
||||
"kernel" type).
|
||||
|
||||
Optional properties:
|
||||
- ramdisk : Unit name of the corresponding ramdisk image (component image
|
||||
node of a "ramdisk" type).
|
||||
- fdt : Unit name of the corresponding fdt blob (component image node of a
|
||||
"fdt type").
|
||||
|
||||
The FDT blob is required to properly boot FDT based kernel, so the minimal
|
||||
configuration for 2.6 FDT kernel is (kernel, fdt) pair.
|
||||
|
||||
Older, 2.4 kernel and 2.6 non-FDT kernel do not use FDT blob, in such cases
|
||||
'struct bd_info' must be passed instead of FDT blob, thus fdt property *must
|
||||
not* be specified in a configuration node.
|
||||
|
||||
|
||||
8) Examples
|
||||
-----------
|
||||
|
||||
Please see doc/uImage.FIT/*.its for actual image source files.
|
@ -17,8 +17,9 @@
|
||||
* and release the resulting code under the GPL.
|
||||
*/
|
||||
|
||||
#define _PPC_STRING_H_ /* avoid unnecessary str/mem functions */
|
||||
#define _LINUX_STRING_H_ /* avoid unnecessary str/mem functions */
|
||||
/* avoid unnecessary memcpy function */
|
||||
#define __HAVE_ARCH_MEMCPY
|
||||
#define _PPC_STRING_H_
|
||||
|
||||
#include <common.h>
|
||||
#include <exports.h>
|
||||
|
@ -29,24 +29,8 @@
|
||||
|
||||
static z_stream stream;
|
||||
|
||||
#define ZALLOC_ALIGNMENT 16
|
||||
|
||||
static void *zalloc (void *x, unsigned items, unsigned size)
|
||||
{
|
||||
void *p;
|
||||
|
||||
size *= items;
|
||||
size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1);
|
||||
|
||||
p = malloc (size);
|
||||
|
||||
return (p);
|
||||
}
|
||||
|
||||
static void zfree (void *x, void *addr, unsigned nb)
|
||||
{
|
||||
free (addr);
|
||||
}
|
||||
void *zalloc(void *, unsigned, unsigned);
|
||||
void zfree(void *, void *, unsigned);
|
||||
|
||||
/* Returns length of decompressed data. */
|
||||
int cramfs_uncompress_block (void *dst, void *src, int srclen)
|
||||
|
@ -70,6 +70,5 @@ void *load_zimage(char *image, unsigned long kernel_size,
|
||||
int auto_boot);
|
||||
|
||||
void boot_zimage(void *setup_base);
|
||||
image_header_t *fake_zimage_header(image_header_t *hdr, void *ptr, int size);
|
||||
|
||||
#endif
|
||||
|
@ -222,10 +222,7 @@ int mac_read_from_eeprom(void);
|
||||
void flash_perror (int);
|
||||
|
||||
/* common/cmd_autoscript.c */
|
||||
int autoscript (ulong addr);
|
||||
|
||||
/* common/cmd_bootm.c */
|
||||
void print_image_hdr (image_header_t *hdr);
|
||||
int autoscript (ulong addr, const char *fit_uname);
|
||||
|
||||
extern ulong load_addr; /* Default Load Address */
|
||||
|
||||
|
@ -27,6 +27,12 @@
|
||||
#ifndef __CONFIG_H
|
||||
#define __CONFIG_H
|
||||
|
||||
|
||||
/* new uImage format support */
|
||||
#define CONFIG_FIT 1
|
||||
#define CONFIG_OF_LIBFDT 1
|
||||
#define CONFIG_FIT_VERBOSE 1 /* enable fit_format_{error,warning}() */
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* High Level Configuration Options
|
||||
*----------------------------------------------------------------------*/
|
||||
|
479
include/image.h
479
include/image.h
@ -1,4 +1,6 @@
|
||||
/*
|
||||
* (C) Copyright 2008 Semihalf
|
||||
*
|
||||
* (C) Copyright 2000-2005
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
@ -31,6 +33,34 @@
|
||||
#ifndef __IMAGE_H__
|
||||
#define __IMAGE_H__
|
||||
|
||||
#include <asm/byteorder.h>
|
||||
#include <command.h>
|
||||
|
||||
#ifndef USE_HOSTCC
|
||||
#include <lmb.h>
|
||||
#include <linux/string.h>
|
||||
#include <asm/u-boot.h>
|
||||
|
||||
#else
|
||||
|
||||
/* new uImage format support enabled on host */
|
||||
#define CONFIG_FIT 1
|
||||
#define CONFIG_OF_LIBFDT 1
|
||||
#define CONFIG_FIT_VERBOSE 1 /* enable fit_format_{error,warning}() */
|
||||
|
||||
#endif /* USE_HOSTCC */
|
||||
|
||||
#if defined(CONFIG_FIT) && !defined(CONFIG_OF_LIBFDT)
|
||||
#error "CONFIG_OF_LIBFDT not enabled, required by CONFIG_FIT!"
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_FIT)
|
||||
#include <fdt.h>
|
||||
#include <libfdt.h>
|
||||
#include <fdt_support.h>
|
||||
#define CONFIG_MD5 /* FIT images need MD5 support */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Operating System Codes
|
||||
*/
|
||||
@ -59,25 +89,25 @@
|
||||
/*
|
||||
* CPU Architecture Codes (supported by Linux)
|
||||
*/
|
||||
#define IH_CPU_INVALID 0 /* Invalid CPU */
|
||||
#define IH_CPU_ALPHA 1 /* Alpha */
|
||||
#define IH_CPU_ARM 2 /* ARM */
|
||||
#define IH_CPU_I386 3 /* Intel x86 */
|
||||
#define IH_CPU_IA64 4 /* IA64 */
|
||||
#define IH_CPU_MIPS 5 /* MIPS */
|
||||
#define IH_CPU_MIPS64 6 /* MIPS 64 Bit */
|
||||
#define IH_CPU_PPC 7 /* PowerPC */
|
||||
#define IH_CPU_S390 8 /* IBM S390 */
|
||||
#define IH_CPU_SH 9 /* SuperH */
|
||||
#define IH_CPU_SPARC 10 /* Sparc */
|
||||
#define IH_CPU_SPARC64 11 /* Sparc 64 Bit */
|
||||
#define IH_CPU_M68K 12 /* M68K */
|
||||
#define IH_CPU_NIOS 13 /* Nios-32 */
|
||||
#define IH_CPU_MICROBLAZE 14 /* MicroBlaze */
|
||||
#define IH_CPU_NIOS2 15 /* Nios-II */
|
||||
#define IH_CPU_BLACKFIN 16 /* Blackfin */
|
||||
#define IH_CPU_AVR32 17 /* AVR32 */
|
||||
#define IH_CPU_ST200 18 /* STMicroelectronics ST200 */
|
||||
#define IH_ARCH_INVALID 0 /* Invalid CPU */
|
||||
#define IH_ARCH_ALPHA 1 /* Alpha */
|
||||
#define IH_ARCH_ARM 2 /* ARM */
|
||||
#define IH_ARCH_I386 3 /* Intel x86 */
|
||||
#define IH_ARCH_IA64 4 /* IA64 */
|
||||
#define IH_ARCH_MIPS 5 /* MIPS */
|
||||
#define IH_ARCH_MIPS64 6 /* MIPS 64 Bit */
|
||||
#define IH_ARCH_PPC 7 /* PowerPC */
|
||||
#define IH_ARCH_S390 8 /* IBM S390 */
|
||||
#define IH_ARCH_SH 9 /* SuperH */
|
||||
#define IH_ARCH_SPARC 10 /* Sparc */
|
||||
#define IH_ARCH_SPARC64 11 /* Sparc 64 Bit */
|
||||
#define IH_ARCH_M68K 12 /* M68K */
|
||||
#define IH_ARCH_NIOS 13 /* Nios-32 */
|
||||
#define IH_ARCH_MICROBLAZE 14 /* MicroBlaze */
|
||||
#define IH_ARCH_NIOS2 15 /* Nios-II */
|
||||
#define IH_ARCH_BLACKFIN 16 /* Blackfin */
|
||||
#define IH_ARCH_AVR32 17 /* AVR32 */
|
||||
#define IH_ARCH_ST200 18 /* STMicroelectronics ST200 */
|
||||
|
||||
/*
|
||||
* Image Types
|
||||
@ -139,9 +169,9 @@
|
||||
#define IH_NMLEN 32 /* Image Name Length */
|
||||
|
||||
/*
|
||||
* all data in network byte order (aka natural aka bigendian)
|
||||
* Legacy format image header,
|
||||
* all data in network byte order (aka natural aka bigendian).
|
||||
*/
|
||||
|
||||
typedef struct image_header {
|
||||
uint32_t ih_magic; /* Image Header Magic Number */
|
||||
uint32_t ih_hcrc; /* Image Header CRC Checksum */
|
||||
@ -157,5 +187,412 @@ typedef struct image_header {
|
||||
uint8_t ih_name[IH_NMLEN]; /* Image Name */
|
||||
} image_header_t;
|
||||
|
||||
/*
|
||||
* Legacy and FIT format headers used by do_bootm() and do_bootm_<os>()
|
||||
* routines.
|
||||
*/
|
||||
typedef struct bootm_headers {
|
||||
/*
|
||||
* Legacy os image header, if it is a multi component image
|
||||
* then boot_get_ramdisk() and get_fdt() will attempt to get
|
||||
* data from second and third component accordingly.
|
||||
*/
|
||||
image_header_t *legacy_hdr_os;
|
||||
ulong legacy_hdr_valid;
|
||||
|
||||
#if defined(CONFIG_FIT)
|
||||
const char *fit_uname_cfg; /* configuration node unit name */
|
||||
|
||||
void *fit_hdr_os; /* os FIT image header */
|
||||
const char *fit_uname_os; /* os subimage node unit name */
|
||||
int fit_noffset_os; /* os subimage node offset */
|
||||
|
||||
void *fit_hdr_rd; /* init ramdisk FIT image header */
|
||||
const char *fit_uname_rd; /* init ramdisk subimage node unit name */
|
||||
int fit_noffset_rd; /* init ramdisk subimage node offset */
|
||||
|
||||
#if defined(CONFIG_PPC)
|
||||
void *fit_hdr_fdt; /* FDT blob FIT image header */
|
||||
const char *fit_uname_fdt; /* FDT blob subimage node unit name */
|
||||
int fit_noffset_fdt;/* FDT blob subimage node offset */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int verify; /* getenv("verify")[0] != 'n' */
|
||||
int autostart; /* getenv("autostart")[0] != 'n' */
|
||||
struct lmb *lmb; /* for memory mgmt */
|
||||
} bootm_headers_t;
|
||||
|
||||
/*
|
||||
* Some systems (for example LWMON) have very short watchdog periods;
|
||||
* we must make sure to split long operations like memmove() or
|
||||
* crc32() into reasonable chunks.
|
||||
*/
|
||||
#define CHUNKSZ (64 * 1024)
|
||||
|
||||
#define uimage_to_cpu(x) ntohl(x)
|
||||
#define cpu_to_uimage(x) htonl(x)
|
||||
|
||||
const char *genimg_get_os_name (uint8_t os);
|
||||
const char *genimg_get_arch_name (uint8_t arch);
|
||||
const char *genimg_get_type_name (uint8_t type);
|
||||
const char *genimg_get_comp_name (uint8_t comp);
|
||||
int genimg_get_os_id (const char *name);
|
||||
int genimg_get_arch_id (const char *name);
|
||||
int genimg_get_type_id (const char *name);
|
||||
int genimg_get_comp_id (const char *name);
|
||||
|
||||
#ifndef USE_HOSTCC
|
||||
/* Image format types, returned by _get_format() routine */
|
||||
#define IMAGE_FORMAT_INVALID 0x00
|
||||
#define IMAGE_FORMAT_LEGACY 0x01 /* legacy image_header based format */
|
||||
#define IMAGE_FORMAT_FIT 0x02 /* new, libfdt based format */
|
||||
|
||||
int genimg_get_format (void *img_addr);
|
||||
int genimg_has_config (bootm_headers_t *images);
|
||||
ulong genimg_get_image (ulong img_addr);
|
||||
|
||||
int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images,
|
||||
uint8_t arch, ulong *rd_start, ulong *rd_end);
|
||||
|
||||
#if defined(CONFIG_PPC) || defined(CONFIG_M68K)
|
||||
int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len,
|
||||
ulong *initrd_start, ulong *initrd_end);
|
||||
|
||||
int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end,
|
||||
ulong bootmap_base);
|
||||
int boot_get_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base);
|
||||
#endif /* CONFIG_PPC || CONFIG_M68K */
|
||||
#endif /* !USE_HOSTCC */
|
||||
|
||||
/*******************************************************************/
|
||||
/* Legacy format specific code (prefixed with image_) */
|
||||
/*******************************************************************/
|
||||
static inline uint32_t image_get_header_size (void)
|
||||
{
|
||||
return (sizeof (image_header_t));
|
||||
}
|
||||
|
||||
#define image_get_hdr_l(f) \
|
||||
static inline uint32_t image_get_##f(image_header_t *hdr) \
|
||||
{ \
|
||||
return uimage_to_cpu (hdr->ih_##f); \
|
||||
}
|
||||
image_get_hdr_l (magic);
|
||||
image_get_hdr_l (hcrc);
|
||||
image_get_hdr_l (time);
|
||||
image_get_hdr_l (size);
|
||||
image_get_hdr_l (load);
|
||||
image_get_hdr_l (ep);
|
||||
image_get_hdr_l (dcrc);
|
||||
|
||||
#define image_get_hdr_b(f) \
|
||||
static inline uint8_t image_get_##f(image_header_t *hdr) \
|
||||
{ \
|
||||
return hdr->ih_##f; \
|
||||
}
|
||||
image_get_hdr_b (os);
|
||||
image_get_hdr_b (arch);
|
||||
image_get_hdr_b (type);
|
||||
image_get_hdr_b (comp);
|
||||
|
||||
static inline char *image_get_name (image_header_t *hdr)
|
||||
{
|
||||
return (char *)hdr->ih_name;
|
||||
}
|
||||
|
||||
static inline uint32_t image_get_data_size (image_header_t *hdr)
|
||||
{
|
||||
return image_get_size (hdr);
|
||||
}
|
||||
|
||||
/**
|
||||
* image_get_data - get image payload start address
|
||||
* @hdr: image header
|
||||
*
|
||||
* image_get_data() returns address of the image payload. For single
|
||||
* component images it is image data start. For multi component
|
||||
* images it points to the null terminated table of sub-images sizes.
|
||||
*
|
||||
* returns:
|
||||
* image payload data start address
|
||||
*/
|
||||
static inline ulong image_get_data (image_header_t *hdr)
|
||||
{
|
||||
return ((ulong)hdr + image_get_header_size ());
|
||||
}
|
||||
|
||||
static inline uint32_t image_get_image_size (image_header_t *hdr)
|
||||
{
|
||||
return (image_get_size (hdr) + image_get_header_size ());
|
||||
}
|
||||
static inline ulong image_get_image_end (image_header_t *hdr)
|
||||
{
|
||||
return ((ulong)hdr + image_get_image_size (hdr));
|
||||
}
|
||||
|
||||
#define image_set_hdr_l(f) \
|
||||
static inline void image_set_##f(image_header_t *hdr, uint32_t val) \
|
||||
{ \
|
||||
hdr->ih_##f = cpu_to_uimage (val); \
|
||||
}
|
||||
image_set_hdr_l (magic);
|
||||
image_set_hdr_l (hcrc);
|
||||
image_set_hdr_l (time);
|
||||
image_set_hdr_l (size);
|
||||
image_set_hdr_l (load);
|
||||
image_set_hdr_l (ep);
|
||||
image_set_hdr_l (dcrc);
|
||||
|
||||
#define image_set_hdr_b(f) \
|
||||
static inline void image_set_##f(image_header_t *hdr, uint8_t val) \
|
||||
{ \
|
||||
hdr->ih_##f = val; \
|
||||
}
|
||||
image_set_hdr_b (os);
|
||||
image_set_hdr_b (arch);
|
||||
image_set_hdr_b (type);
|
||||
image_set_hdr_b (comp);
|
||||
|
||||
static inline void image_set_name (image_header_t *hdr, const char *name)
|
||||
{
|
||||
strncpy (image_get_name (hdr), name, IH_NMLEN);
|
||||
}
|
||||
|
||||
int image_check_hcrc (image_header_t *hdr);
|
||||
int image_check_dcrc (image_header_t *hdr);
|
||||
#ifndef USE_HOSTCC
|
||||
int image_check_dcrc_wd (image_header_t *hdr, ulong chunksize);
|
||||
int getenv_verify (void);
|
||||
int getenv_autostart (void);
|
||||
ulong getenv_bootm_low(void);
|
||||
ulong getenv_bootm_size(void);
|
||||
void memmove_wd (void *to, void *from, size_t len, ulong chunksz);
|
||||
#endif
|
||||
|
||||
static inline int image_check_magic (image_header_t *hdr)
|
||||
{
|
||||
return (image_get_magic (hdr) == IH_MAGIC);
|
||||
}
|
||||
static inline int image_check_type (image_header_t *hdr, uint8_t type)
|
||||
{
|
||||
return (image_get_type (hdr) == type);
|
||||
}
|
||||
static inline int image_check_arch (image_header_t *hdr, uint8_t arch)
|
||||
{
|
||||
return (image_get_arch (hdr) == arch);
|
||||
}
|
||||
static inline int image_check_os (image_header_t *hdr, uint8_t os)
|
||||
{
|
||||
return (image_get_os (hdr) == os);
|
||||
}
|
||||
|
||||
ulong image_multi_count (image_header_t *hdr);
|
||||
void image_multi_getimg (image_header_t *hdr, ulong idx,
|
||||
ulong *data, ulong *len);
|
||||
|
||||
inline void image_print_contents (image_header_t *hdr);
|
||||
inline void image_print_contents_noindent (image_header_t *hdr);
|
||||
|
||||
#ifndef USE_HOSTCC
|
||||
static inline int image_check_target_arch (image_header_t *hdr)
|
||||
{
|
||||
#if defined(__ARM__)
|
||||
if (!image_check_arch (hdr, IH_ARCH_ARM))
|
||||
#elif defined(__avr32__)
|
||||
if (!image_check_arch (hdr, IH_ARCH_AVR32))
|
||||
#elif defined(__bfin__)
|
||||
if (!image_check_arch (hdr, IH_ARCH_BLACKFIN))
|
||||
#elif defined(__I386__)
|
||||
if (!image_check_arch (hdr, IH_ARCH_I386))
|
||||
#elif defined(__M68K__)
|
||||
if (!image_check_arch (hdr, IH_ARCH_M68K))
|
||||
#elif defined(__microblaze__)
|
||||
if (!image_check_arch (hdr, IH_ARCH_MICROBLAZE))
|
||||
#elif defined(__mips__)
|
||||
if (!image_check_arch (hdr, IH_ARCH_MIPS))
|
||||
#elif defined(__nios__)
|
||||
if (!image_check_arch (hdr, IH_ARCH_NIOS))
|
||||
#elif defined(__nios2__)
|
||||
if (!image_check_arch (hdr, IH_ARCH_NIOS2))
|
||||
#elif defined(__PPC__)
|
||||
if (!image_check_arch (hdr, IH_ARCH_PPC))
|
||||
#elif defined(__sh__)
|
||||
if (!image_check_arch (hdr, IH_ARCH_SH))
|
||||
#else
|
||||
# error Unknown CPU type
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif /* USE_HOSTCC */
|
||||
|
||||
/*******************************************************************/
|
||||
/* New uImage format specific code (prefixed with fit_) */
|
||||
/*******************************************************************/
|
||||
#if defined(CONFIG_FIT)
|
||||
|
||||
#define FIT_IMAGES_PATH "/images"
|
||||
#define FIT_CONFS_PATH "/configurations"
|
||||
|
||||
/* hash node */
|
||||
#define FIT_HASH_NODENAME "hash"
|
||||
#define FIT_ALGO_PROP "algo"
|
||||
#define FIT_VALUE_PROP "value"
|
||||
|
||||
/* image node */
|
||||
#define FIT_DATA_PROP "data"
|
||||
#define FIT_TIMESTAMP_PROP "timestamp"
|
||||
#define FIT_DESC_PROP "description"
|
||||
#define FIT_ARCH_PROP "arch"
|
||||
#define FIT_TYPE_PROP "type"
|
||||
#define FIT_OS_PROP "os"
|
||||
#define FIT_COMP_PROP "compression"
|
||||
#define FIT_ENTRY_PROP "entry"
|
||||
#define FIT_LOAD_PROP "load"
|
||||
|
||||
/* configuration node */
|
||||
#define FIT_KERNEL_PROP "kernel"
|
||||
#define FIT_RAMDISK_PROP "ramdisk"
|
||||
#define FIT_FDT_PROP "fdt"
|
||||
#define FIT_DEFAULT_PROP "default"
|
||||
|
||||
#define FIT_MAX_HASH_LEN 20 /* max(crc32_len(4), sha1_len(20)) */
|
||||
|
||||
/* cmdline argument format parsing */
|
||||
inline int fit_parse_conf (const char *spec, ulong addr_curr,
|
||||
ulong *addr, const char **conf_name);
|
||||
inline int fit_parse_subimage (const char *spec, ulong addr_curr,
|
||||
ulong *addr, const char **image_name);
|
||||
|
||||
inline void fit_print_contents (const void *fit);
|
||||
inline void fit_print_contents_noindent (const void *fit);
|
||||
void fit_image_print (const void *fit, int noffset, const char *p);
|
||||
void fit_image_print_hash (const void *fit, int noffset, const char *p);
|
||||
|
||||
/**
|
||||
* fit_get_end - get FIT image size
|
||||
* @fit: pointer to the FIT format image header
|
||||
*
|
||||
* returns:
|
||||
* size of the FIT image (blob) in memory
|
||||
*/
|
||||
static inline ulong fit_get_size (const void *fit)
|
||||
{
|
||||
return fdt_totalsize (fit);
|
||||
}
|
||||
|
||||
/**
|
||||
* fit_get_end - get FIT image end
|
||||
* @fit: pointer to the FIT format image header
|
||||
*
|
||||
* returns:
|
||||
* end address of the FIT image (blob) in memory
|
||||
*/
|
||||
static inline ulong fit_get_end (const void *fit)
|
||||
{
|
||||
return (ulong)fit + fdt_totalsize (fit);
|
||||
}
|
||||
|
||||
/**
|
||||
* fit_get_name - get FIT node name
|
||||
* @fit: pointer to the FIT format image header
|
||||
*
|
||||
* returns:
|
||||
* NULL, on error
|
||||
* pointer to node name, on success
|
||||
*/
|
||||
static inline const char *fit_get_name (const void *fit_hdr,
|
||||
int noffset, int *len)
|
||||
{
|
||||
return fdt_get_name (fit_hdr, noffset, len);
|
||||
}
|
||||
|
||||
int fit_get_desc (const void *fit, int noffset, char **desc);
|
||||
int fit_get_timestamp (const void *fit, int noffset, time_t *timestamp);
|
||||
|
||||
int fit_image_get_node (const void *fit, const char *image_uname);
|
||||
int fit_image_get_os (const void *fit, int noffset, uint8_t *os);
|
||||
int fit_image_get_arch (const void *fit, int noffset, uint8_t *arch);
|
||||
int fit_image_get_type (const void *fit, int noffset, uint8_t *type);
|
||||
int fit_image_get_comp (const void *fit, int noffset, uint8_t *comp);
|
||||
int fit_image_get_load (const void *fit, int noffset, ulong *load);
|
||||
int fit_image_get_entry (const void *fit, int noffset, ulong *entry);
|
||||
int fit_image_get_data (const void *fit, int noffset,
|
||||
const void **data, size_t *size);
|
||||
|
||||
int fit_image_hash_get_algo (const void *fit, int noffset, char **algo);
|
||||
int fit_image_hash_get_value (const void *fit, int noffset, uint8_t **value,
|
||||
int *value_len);
|
||||
|
||||
int fit_set_timestamp (void *fit, int noffset, time_t timestamp);
|
||||
int fit_set_hashes (void *fit);
|
||||
int fit_image_set_hashes (void *fit, int image_noffset);
|
||||
int fit_image_hash_set_value (void *fit, int noffset, uint8_t *value,
|
||||
int value_len);
|
||||
|
||||
int fit_image_check_hashes (const void *fit, int noffset);
|
||||
int fit_image_check_os (const void *fit, int noffset, uint8_t os);
|
||||
int fit_image_check_arch (const void *fit, int noffset, uint8_t arch);
|
||||
int fit_image_check_type (const void *fit, int noffset, uint8_t type);
|
||||
int fit_image_check_comp (const void *fit, int noffset, uint8_t comp);
|
||||
int fit_check_format (const void *fit);
|
||||
|
||||
int fit_conf_get_node (const void *fit, const char *conf_uname);
|
||||
int fit_conf_get_kernel_node (const void *fit, int noffset);
|
||||
int fit_conf_get_ramdisk_node (const void *fit, int noffset);
|
||||
int fit_conf_get_fdt_node (const void *fit, int noffset);
|
||||
|
||||
void fit_conf_print (const void *fit, int noffset, const char *p);
|
||||
|
||||
#ifndef USE_HOSTCC
|
||||
static inline int fit_image_check_target_arch (const void *fdt, int node)
|
||||
{
|
||||
#if defined(__ARM__)
|
||||
if (!fit_image_check_arch (fdt, node, IH_ARCH_ARM))
|
||||
#elif defined(__avr32__)
|
||||
if (!fit_image_check_arch (fdt, node, IH_ARCH_AVR32))
|
||||
#elif defined(__bfin__)
|
||||
if (!fit_image_check_arch (fdt, node, IH_ARCH_BLACKFIN))
|
||||
#elif defined(__I386__)
|
||||
if (!fit_image_check_arch (fdt, node, IH_ARCH_I386))
|
||||
#elif defined(__M68K__)
|
||||
if (!fit_image_check_arch (fdt, node, IH_ARCH_M68K))
|
||||
#elif defined(__microblaze__)
|
||||
if (!fit_image_check_arch (fdt, node, IH_ARCH_MICROBLAZE))
|
||||
#elif defined(__mips__)
|
||||
if (!fit_image_check_arch (fdt, node, IH_ARCH_MIPS))
|
||||
#elif defined(__nios__)
|
||||
if (!fit_image_check_arch (fdt, node, IH_ARCH_NIOS))
|
||||
#elif defined(__nios2__)
|
||||
if (!fit_image_check_arch (fdt, node, IH_ARCH_NIOS2))
|
||||
#elif defined(__PPC__)
|
||||
if (!fit_image_check_arch (fdt, node, IH_ARCH_PPC))
|
||||
#elif defined(__sh__)
|
||||
if (!fit_image_check_arch (fdt, node, IH_ARCH_SH))
|
||||
#else
|
||||
# error Unknown CPU type
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif /* USE_HOSTCC */
|
||||
|
||||
#ifdef CONFIG_FIT_VERBOSE
|
||||
#define fit_unsupported(msg) printf ("! %s:%d " \
|
||||
"FIT images not supported for '%s'\n", \
|
||||
__FILE__, __LINE__, (msg))
|
||||
|
||||
#define fit_unsupported_reset(msg) printf ("! %s:%d " \
|
||||
"FIT images not supported for '%s' " \
|
||||
"- must reset board to recover!\n", \
|
||||
__FILE__, __LINE__, (msg))
|
||||
#else
|
||||
#define fit_unsupported(msg)
|
||||
#define fit_unsupported_reset(msg)
|
||||
#endif /* CONFIG_FIT_VERBOSE */
|
||||
#endif /* CONFIG_FIT */
|
||||
|
||||
#endif /* __IMAGE_H__ */
|
||||
|
@ -24,7 +24,11 @@
|
||||
#include <stddef.h>
|
||||
#include <linux/types.h>
|
||||
#include <asm/byteorder.h>
|
||||
#ifdef USE_HOSTCC
|
||||
#include <string.h>
|
||||
#else
|
||||
#include <linux/string.h>
|
||||
#endif /* USE_HOSTCC */
|
||||
|
||||
extern struct fdt_header *fdt; /* Pointer to the working fdt */
|
||||
|
||||
|
54
include/lmb.h
Normal file
54
include/lmb.h
Normal file
@ -0,0 +1,54 @@
|
||||
#ifndef _LINUX_LMB_H
|
||||
#define _LINUX_LMB_H
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <asm/types.h>
|
||||
/*
|
||||
* Logical memory blocks.
|
||||
*
|
||||
* Copyright (C) 2001 Peter Bergner, IBM Corp.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#define MAX_LMB_REGIONS 8
|
||||
|
||||
struct lmb_property {
|
||||
ulong base;
|
||||
ulong size;
|
||||
};
|
||||
|
||||
struct lmb_region {
|
||||
unsigned long cnt;
|
||||
ulong size;
|
||||
struct lmb_property region[MAX_LMB_REGIONS+1];
|
||||
};
|
||||
|
||||
struct lmb {
|
||||
struct lmb_region memory;
|
||||
struct lmb_region reserved;
|
||||
};
|
||||
|
||||
extern struct lmb lmb;
|
||||
|
||||
extern void lmb_init(struct lmb *lmb);
|
||||
extern long lmb_add(struct lmb *lmb, ulong base, ulong size);
|
||||
extern long lmb_reserve(struct lmb *lmb, ulong base, ulong size);
|
||||
extern ulong lmb_alloc(struct lmb *lmb, ulong size, ulong align);
|
||||
extern ulong lmb_alloc_base(struct lmb *lmb, ulong size, ulong align, ulong max_addr);
|
||||
extern ulong __lmb_alloc_base(struct lmb *lmb, ulong size, ulong align, ulong max_addr);
|
||||
extern int lmb_is_reserved(struct lmb *lmb, ulong addr);
|
||||
|
||||
extern void lmb_dump_all(struct lmb *lmb);
|
||||
|
||||
static inline ulong
|
||||
lmb_size_bytes(struct lmb_region *type, unsigned long region_nr)
|
||||
{
|
||||
return type->region[region_nr].size;
|
||||
}
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* _LINUX_LMB_H */
|
23
include/md5.h
Normal file
23
include/md5.h
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* This file was transplanted with slight modifications from Linux sources
|
||||
* (fs/cifs/md5.h) into U-Boot by Bartlomiej Sieka <tur@semihalf.com>.
|
||||
*/
|
||||
|
||||
#ifndef _MD5_H
|
||||
#define _MD5_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct MD5Context {
|
||||
__u32 buf[4];
|
||||
__u32 bits[2];
|
||||
unsigned char in[64];
|
||||
};
|
||||
|
||||
/*
|
||||
* Calculate and store in 'output' the MD5 digest of 'len' bytes at
|
||||
* 'input'. 'output' must have enough space to hold 16 bytes.
|
||||
*/
|
||||
void md5 (unsigned char *input, int len, unsigned char output[16]);
|
||||
|
||||
#endif /* _MD5_H */
|
@ -25,13 +25,21 @@ include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = $(obj)lib$(ARCH).a
|
||||
|
||||
SOBJS = _ashldi3.o _ashrdi3.o _divsi3.o _modsi3.o _udivsi3.o _umodsi3.o
|
||||
SOBJS-y += _ashldi3.o
|
||||
SOBJS-y += _ashrdi3.o
|
||||
SOBJS-y += _divsi3.o
|
||||
SOBJS-y += _modsi3.o
|
||||
SOBJS-y += _udivsi3.o
|
||||
SOBJS-y += _umodsi3.o
|
||||
|
||||
COBJS = armlinux.o board.o \
|
||||
cache.o div0.o interrupts.o
|
||||
COBJS-y += board.o
|
||||
COBJS-y += bootm.o
|
||||
COBJS-y += cache.o
|
||||
COBJS-y += div0.o
|
||||
COBJS-y += interrupts.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
|
||||
SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS)
|
||||
$(AR) $(ARFLAGS) $@ $(OBJS)
|
||||
|
@ -26,15 +26,9 @@
|
||||
#include <image.h>
|
||||
#include <zlib.h>
|
||||
#include <asm/byteorder.h>
|
||||
#ifdef CONFIG_HAS_DATAFLASH
|
||||
#include <dataflash.h>
|
||||
#endif
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/*cmd_boot.c*/
|
||||
extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
|
||||
|
||||
#if defined (CONFIG_SETUP_MEMORY_TAGS) || \
|
||||
defined (CONFIG_CMDLINE_TAG) || \
|
||||
defined (CONFIG_INITRD_TAG) || \
|
||||
@ -62,30 +56,43 @@ static void setup_end_tag (bd_t *bd);
|
||||
static void setup_videolfb_tag (gd_t *gd);
|
||||
# endif
|
||||
|
||||
|
||||
static struct tag *params;
|
||||
#endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */
|
||||
|
||||
extern image_header_t header; /* from cmd_bootm.c */
|
||||
|
||||
extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
|
||||
|
||||
void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||
ulong addr, ulong *len_ptr, int verify)
|
||||
bootm_headers_t *images)
|
||||
{
|
||||
ulong len = 0, checksum;
|
||||
ulong initrd_start, initrd_end;
|
||||
ulong data;
|
||||
void (*theKernel)(int zero, int arch, uint params);
|
||||
image_header_t *hdr = &header;
|
||||
bd_t *bd = gd->bd;
|
||||
int machid = bd->bi_arch_number;
|
||||
char *s;
|
||||
ulong initrd_start, initrd_end;
|
||||
ulong ep = 0;
|
||||
bd_t *bd = gd->bd;
|
||||
char *s;
|
||||
int machid = bd->bi_arch_number;
|
||||
void (*theKernel)(int zero, int arch, uint params);
|
||||
int ret;
|
||||
|
||||
#ifdef CONFIG_CMDLINE_TAG
|
||||
char *commandline = getenv ("bootargs");
|
||||
#endif
|
||||
|
||||
theKernel = (void (*)(int, int, uint))ntohl(hdr->ih_ep);
|
||||
/* find kernel entry point */
|
||||
if (images->legacy_hdr_valid) {
|
||||
ep = image_get_ep (images->legacy_hdr_os);
|
||||
#if defined(CONFIG_FIT)
|
||||
} else if (images->fit_uname_os) {
|
||||
ret = fit_image_get_entry (images->fit_hdr_os,
|
||||
images->fit_noffset_os, &ep);
|
||||
if (ret) {
|
||||
puts ("Can't get entry point property!\n");
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
puts ("Could not find kernel entry point!\n");
|
||||
goto error;
|
||||
}
|
||||
theKernel = (void (*)(int, int, uint))ep;
|
||||
|
||||
s = getenv ("machid");
|
||||
if (s) {
|
||||
@ -93,134 +100,10 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||
printf ("Using machid 0x%x from environment\n", machid);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if there is an initrd image
|
||||
*/
|
||||
if (argc >= 3) {
|
||||
show_boot_progress (9);
|
||||
|
||||
addr = simple_strtoul (argv[2], NULL, 16);
|
||||
|
||||
printf ("## Loading Ramdisk Image at %08lx ...\n", addr);
|
||||
|
||||
/* Copy header so we can blank CRC field for re-calculation */
|
||||
#ifdef CONFIG_HAS_DATAFLASH
|
||||
if (addr_dataflash (addr)) {
|
||||
read_dataflash (addr, sizeof (image_header_t),
|
||||
(char *) &header);
|
||||
} else
|
||||
#endif
|
||||
memcpy (&header, (char *) addr,
|
||||
sizeof (image_header_t));
|
||||
|
||||
if (ntohl (hdr->ih_magic) != IH_MAGIC) {
|
||||
printf ("Bad Magic Number\n");
|
||||
show_boot_progress (-10);
|
||||
do_reset (cmdtp, flag, argc, argv);
|
||||
}
|
||||
|
||||
data = (ulong) & header;
|
||||
len = sizeof (image_header_t);
|
||||
|
||||
checksum = ntohl (hdr->ih_hcrc);
|
||||
hdr->ih_hcrc = 0;
|
||||
|
||||
if (crc32 (0, (unsigned char *) data, len) != checksum) {
|
||||
printf ("Bad Header Checksum\n");
|
||||
show_boot_progress (-11);
|
||||
do_reset (cmdtp, flag, argc, argv);
|
||||
}
|
||||
|
||||
show_boot_progress (10);
|
||||
|
||||
print_image_hdr (hdr);
|
||||
|
||||
data = addr + sizeof (image_header_t);
|
||||
len = ntohl (hdr->ih_size);
|
||||
|
||||
#ifdef CONFIG_HAS_DATAFLASH
|
||||
if (addr_dataflash (addr)) {
|
||||
read_dataflash (data, len, (char *) CFG_LOAD_ADDR);
|
||||
data = CFG_LOAD_ADDR;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (verify) {
|
||||
ulong csum = 0;
|
||||
|
||||
printf (" Verifying Checksum ... ");
|
||||
csum = crc32 (0, (unsigned char *) data, len);
|
||||
if (csum != ntohl (hdr->ih_dcrc)) {
|
||||
printf ("Bad Data CRC\n");
|
||||
show_boot_progress (-12);
|
||||
do_reset (cmdtp, flag, argc, argv);
|
||||
}
|
||||
printf ("OK\n");
|
||||
}
|
||||
|
||||
show_boot_progress (11);
|
||||
|
||||
if ((hdr->ih_os != IH_OS_LINUX) ||
|
||||
(hdr->ih_arch != IH_CPU_ARM) ||
|
||||
(hdr->ih_type != IH_TYPE_RAMDISK)) {
|
||||
printf ("No Linux ARM Ramdisk Image\n");
|
||||
show_boot_progress (-13);
|
||||
do_reset (cmdtp, flag, argc, argv);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_B2) || defined(CONFIG_EVB4510) || \
|
||||
defined(CONFIG_ARMADILLO) || defined(CONFIG_M501SK)
|
||||
/*
|
||||
*we need to copy the ramdisk to SRAM to let Linux boot
|
||||
*/
|
||||
memmove ((void *) ntohl(hdr->ih_load), (uchar *)data, len);
|
||||
data = ntohl(hdr->ih_load);
|
||||
#endif /* CONFIG_B2 || CONFIG_EVB4510 */
|
||||
|
||||
/*
|
||||
* Now check if we have a multifile image
|
||||
*/
|
||||
} else if ((hdr->ih_type == IH_TYPE_MULTI) && (len_ptr[1])) {
|
||||
ulong tail = ntohl (len_ptr[0]) % 4;
|
||||
int i;
|
||||
|
||||
show_boot_progress (13);
|
||||
|
||||
/* skip kernel length and terminator */
|
||||
data = (ulong) (&len_ptr[2]);
|
||||
/* skip any additional image length fields */
|
||||
for (i = 1; len_ptr[i]; ++i)
|
||||
data += 4;
|
||||
/* add kernel length, and align */
|
||||
data += ntohl (len_ptr[0]);
|
||||
if (tail) {
|
||||
data += 4 - tail;
|
||||
}
|
||||
|
||||
len = ntohl (len_ptr[1]);
|
||||
|
||||
} else {
|
||||
/*
|
||||
* no initrd image
|
||||
*/
|
||||
show_boot_progress (14);
|
||||
|
||||
len = data = 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (!data) {
|
||||
printf ("No initrd\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (data) {
|
||||
initrd_start = data;
|
||||
initrd_end = initrd_start + len;
|
||||
} else {
|
||||
initrd_start = 0;
|
||||
initrd_end = 0;
|
||||
}
|
||||
ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_ARM,
|
||||
&initrd_start, &initrd_end);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
show_boot_progress (15);
|
||||
|
||||
@ -257,6 +140,9 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||
setup_end_tag (bd);
|
||||
#endif
|
||||
|
||||
if (!images->autostart)
|
||||
return ;
|
||||
|
||||
/* we assume that the kernel is in place */
|
||||
printf ("\nStarting kernel ...\n\n");
|
||||
|
||||
@ -270,6 +156,13 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||
cleanup_before_linux ();
|
||||
|
||||
theKernel (0, machid, bd->bi_boot_params);
|
||||
/* does not return */
|
||||
return;
|
||||
|
||||
error:
|
||||
if (images->autostart)
|
||||
do_reset (cmdtp, flag, argc, argv);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -27,12 +27,14 @@ include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = $(obj)lib$(ARCH).a
|
||||
|
||||
SOBJS = memset.o
|
||||
SOBJS-y += memset.o
|
||||
|
||||
COBJS = board.o interrupts.o avr32_linux.o
|
||||
COBJS-y += board.o
|
||||
COBJS-y += bootm.o
|
||||
COBJS-y += interrupts.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
|
||||
SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS)
|
||||
$(AR) $(ARFLAGS) $@ $(OBJS)
|
||||
|
@ -31,12 +31,10 @@
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
extern int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
|
||||
|
||||
/* CPU-specific hook to allow flushing of caches, etc. */
|
||||
extern void prepare_to_boot(void);
|
||||
|
||||
extern image_header_t header; /* from cmd_bootm.c */
|
||||
extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
|
||||
|
||||
static struct tag *setup_start_tag(struct tag *params)
|
||||
{
|
||||
@ -176,113 +174,37 @@ static void setup_end_tag(struct tag *params)
|
||||
}
|
||||
|
||||
void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||
unsigned long addr, unsigned long *len_ptr, int verify)
|
||||
bootm_headers_t *images)
|
||||
{
|
||||
unsigned long data, len = 0;
|
||||
unsigned long initrd_start, initrd_end;
|
||||
unsigned long image_start, image_end;
|
||||
unsigned long checksum;
|
||||
void (*theKernel)(int magic, void *tagtable);
|
||||
image_header_t *hdr;
|
||||
struct tag *params, *params_start;
|
||||
char *commandline = getenv("bootargs");
|
||||
ulong initrd_start, initrd_end;
|
||||
ulong ep = 0;
|
||||
void (*theKernel)(int magic, void *tagtable);
|
||||
struct tag *params, *params_start;
|
||||
char *commandline = getenv("bootargs");
|
||||
int ret;
|
||||
|
||||
hdr = (image_header_t *)addr;
|
||||
image_start = addr;
|
||||
image_end = addr + hdr->ih_size;
|
||||
|
||||
theKernel = (void *)ntohl(hdr->ih_ep);
|
||||
|
||||
/*
|
||||
* Check if there is an initrd image
|
||||
*/
|
||||
if (argc >= 3) {
|
||||
show_boot_progress (9);
|
||||
|
||||
addr = simple_strtoul(argv[2], NULL, 16);
|
||||
|
||||
printf("## Loading RAMDISK image at %08lx ...\n", addr);
|
||||
|
||||
memcpy(&header, (char *)addr, sizeof(header));
|
||||
hdr = &header;
|
||||
|
||||
if (ntohl(hdr->ih_magic) != IH_MAGIC) {
|
||||
puts("Bad Magic Number\n");
|
||||
show_boot_progress (-10);
|
||||
do_reset(cmdtp, flag, argc, argv);
|
||||
/* find kernel entry point */
|
||||
if (images->legacy_hdr_valid) {
|
||||
ep = image_get_ep (images->legacy_hdr_os);
|
||||
#if defined(CONFIG_FIT)
|
||||
} else if (images->fit_uname_os) {
|
||||
ret = fit_image_get_entry (images->fit_hdr_os,
|
||||
images->fit_noffset_os, &ep);
|
||||
if (ret) {
|
||||
puts ("Can't get entry point property!\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
data = (unsigned long)hdr;
|
||||
len = sizeof(*hdr);
|
||||
checksum = ntohl(hdr->ih_hcrc);
|
||||
hdr->ih_hcrc = 0;
|
||||
|
||||
if (crc32(0, (unsigned char *)data, len) != checksum) {
|
||||
puts("Bad Header Checksum\n");
|
||||
show_boot_progress (-11);
|
||||
do_reset(cmdtp, flag, argc, argv);
|
||||
}
|
||||
|
||||
show_boot_progress (10);
|
||||
|
||||
print_image_hdr(hdr);
|
||||
|
||||
data = addr + sizeof(header);
|
||||
len = ntohl(hdr->ih_size);
|
||||
|
||||
if (verify) {
|
||||
unsigned long csum = 0;
|
||||
|
||||
puts(" Verifying Checksum ... ");
|
||||
csum = crc32(0, (unsigned char *)data, len);
|
||||
if (csum != ntohl(hdr->ih_dcrc)) {
|
||||
puts("Bad Data CRC\n");
|
||||
show_boot_progress (-12);
|
||||
do_reset(cmdtp, flag, argc, argv);
|
||||
}
|
||||
puts("OK\n");
|
||||
}
|
||||
|
||||
show_boot_progress (11);
|
||||
|
||||
if ((hdr->ih_os != IH_OS_LINUX) ||
|
||||
(hdr->ih_arch != IH_CPU_AVR32) ||
|
||||
(hdr->ih_type != IH_TYPE_RAMDISK)) {
|
||||
puts("Not a Linux/AVR32 RAMDISK image\n");
|
||||
show_boot_progress (-13);
|
||||
do_reset(cmdtp, flag, argc, argv);
|
||||
}
|
||||
} else if ((hdr->ih_type == IH_TYPE_MULTI) && (len_ptr[1])) {
|
||||
ulong tail = ntohl (len_ptr[0]) % 4;
|
||||
int i;
|
||||
|
||||
show_boot_progress (13);
|
||||
|
||||
/* skip kernel length and terminator */
|
||||
data = (ulong) (&len_ptr[2]);
|
||||
/* skip any additional image length fields */
|
||||
for (i = 1; len_ptr[i]; ++i)
|
||||
data += 4;
|
||||
/* add kernel length, and align */
|
||||
data += ntohl (len_ptr[0]);
|
||||
if (tail) {
|
||||
data += 4 - tail;
|
||||
}
|
||||
|
||||
len = ntohl (len_ptr[1]);
|
||||
#endif
|
||||
} else {
|
||||
/* no initrd image */
|
||||
show_boot_progress (14);
|
||||
len = data = 0;
|
||||
puts ("Could not find kernel entry point!\n");
|
||||
goto error;
|
||||
}
|
||||
theKernel = (void *)ep;
|
||||
|
||||
if (data) {
|
||||
initrd_start = data;
|
||||
initrd_end = initrd_start + len;
|
||||
} else {
|
||||
initrd_start = 0;
|
||||
initrd_end = 0;
|
||||
}
|
||||
ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_AVR32,
|
||||
&initrd_start, &initrd_end);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
show_boot_progress (15);
|
||||
|
||||
@ -299,10 +221,20 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||
params = setup_ethernet_tags(params);
|
||||
setup_end_tag(params);
|
||||
|
||||
if (!images->autostart)
|
||||
return ;
|
||||
|
||||
printf("\nStarting kernel at %p (params at %p)...\n\n",
|
||||
theKernel, params_start);
|
||||
|
||||
prepare_to_boot();
|
||||
|
||||
theKernel(ATAG_MAGIC, params_start);
|
||||
/* does not return */
|
||||
return;
|
||||
|
||||
error:
|
||||
if (images->autostart)
|
||||
do_reset (cmdtp, flag, argc, argv);
|
||||
return;
|
||||
}
|
@ -29,12 +29,21 @@ include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = $(obj)lib$(ARCH).a
|
||||
|
||||
SOBJS = memcpy.o memcmp.o memset.o memmove.o
|
||||
SOBJS-y += memcmp.o
|
||||
SOBJS-y += memcpy.o
|
||||
SOBJS-y += memmove.o
|
||||
SOBJS-y += memset.o
|
||||
|
||||
COBJS = post.o tests.o board.o bf533_linux.o bf533_string.o cache.o muldi3.o
|
||||
COBJS-y += bf533_string.o
|
||||
COBJS-y += board.o
|
||||
COBJS-y += bootm.o
|
||||
COBJS-y += cache.o
|
||||
COBJS-y += muldi3.o
|
||||
COBJS-y += post.o
|
||||
COBJS-y += tests.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
|
||||
SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS)
|
||||
$(AR) $(ARFLAGS) $@ $(OBJS)
|
||||
|
@ -42,22 +42,42 @@
|
||||
extern void swap_to(int device_id);
|
||||
#endif
|
||||
|
||||
extern image_header_t header;
|
||||
extern void flush_instruction_cache(void);
|
||||
extern void flush_data_cache(void);
|
||||
static char *make_command_line(void);
|
||||
|
||||
void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[],
|
||||
ulong addr, ulong * len_ptr, int verify)
|
||||
bootm_headers_t *images)
|
||||
{
|
||||
int (*appl) (char *cmdline);
|
||||
char *cmdline;
|
||||
int (*appl) (char *cmdline);
|
||||
char *cmdline;
|
||||
ulong ep = 0;
|
||||
|
||||
if (!images->autostart)
|
||||
return ;
|
||||
|
||||
#ifdef SHARED_RESOURCES
|
||||
swap_to(FLASH);
|
||||
#endif
|
||||
|
||||
appl = (int (*)(char *))ntohl(header.ih_ep);
|
||||
/* find kernel entry point */
|
||||
if (images->legacy_hdr_valid) {
|
||||
ep = image_get_ep (images->legacy_hdr_os);
|
||||
#if defined(CONFIG_FIT)
|
||||
} else if (images->fit_uname_os) {
|
||||
int ret = fit_image_get_entry (images->fit_hdr_os,
|
||||
images->fit_noffset_os, &ep);
|
||||
if (ret) {
|
||||
puts ("Can't get entry point property!\n");
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
puts ("Could not find kernel entry point!\n");
|
||||
goto error;
|
||||
}
|
||||
appl = (int (*)(char *))ep;
|
||||
|
||||
printf("Starting Kernel at = %x\n", appl);
|
||||
cmdline = make_command_line();
|
||||
if (icache_status()) {
|
||||
@ -69,6 +89,13 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[],
|
||||
dcache_disable();
|
||||
}
|
||||
(*appl) (cmdline);
|
||||
/* does not return */
|
||||
return;
|
||||
|
||||
error:
|
||||
if (images->autostart)
|
||||
do_reset (cmdtp, flag, argc, argv);
|
||||
return;
|
||||
}
|
||||
|
||||
char *make_command_line(void)
|
@ -34,7 +34,9 @@ COBJS-y += crc32.o
|
||||
COBJS-y += ctype.o
|
||||
COBJS-y += display_options.o
|
||||
COBJS-y += div64.o
|
||||
COBJS-y += lmb.o
|
||||
COBJS-y += ldiv.o
|
||||
COBJS-$(CONFIG_MD5) += md5.o
|
||||
COBJS-y += sha1.o
|
||||
COBJS-y += string.o
|
||||
COBJS-y += vsprintf.o
|
||||
|
@ -1592,6 +1592,10 @@ const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum)
|
||||
}
|
||||
#endif
|
||||
|
||||
void bz_internal_error(int errcode)
|
||||
{
|
||||
printf ("BZIP2 internal error %d\n", errcode);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end bzlib.c ---*/
|
||||
|
280
lib_generic/lmb.c
Normal file
280
lib_generic/lmb.c
Normal file
@ -0,0 +1,280 @@
|
||||
/*
|
||||
* Procedures for maintaining information about logical memory blocks.
|
||||
*
|
||||
* Peter Bergner, IBM Corp. June 2001.
|
||||
* Copyright (C) 2001 Peter Bergner.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <lmb.h>
|
||||
|
||||
#define LMB_ALLOC_ANYWHERE 0
|
||||
|
||||
void lmb_dump_all(struct lmb *lmb)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
unsigned long i;
|
||||
|
||||
debug("lmb_dump_all:\n");
|
||||
debug(" memory.cnt = 0x%lx\n", lmb->memory.cnt);
|
||||
debug(" memory.size = 0x%08x\n", lmb->memory.size);
|
||||
for (i=0; i < lmb->memory.cnt ;i++) {
|
||||
debug(" memory.reg[0x%x].base = 0x%08x\n", i,
|
||||
lmb->memory.region[i].base);
|
||||
debug(" .size = 0x%08x\n",
|
||||
lmb->memory.region[i].size);
|
||||
}
|
||||
|
||||
debug("\n reserved.cnt = 0x%lx\n", lmb->reserved.cnt);
|
||||
debug(" reserved.size = 0x%08x\n", lmb->reserved.size);
|
||||
for (i=0; i < lmb->reserved.cnt ;i++) {
|
||||
debug(" reserved.reg[0x%x].base = 0x%08x\n", i,
|
||||
lmb->reserved.region[i].base);
|
||||
debug(" .size = 0x%08x\n",
|
||||
lmb->reserved.region[i].size);
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
}
|
||||
|
||||
static unsigned long lmb_addrs_overlap(ulong base1,
|
||||
ulong size1, ulong base2, ulong size2)
|
||||
{
|
||||
return ((base1 < (base2+size2)) && (base2 < (base1+size1)));
|
||||
}
|
||||
|
||||
static long lmb_addrs_adjacent(ulong base1, ulong size1,
|
||||
ulong base2, ulong size2)
|
||||
{
|
||||
if (base2 == base1 + size1)
|
||||
return 1;
|
||||
else if (base1 == base2 + size2)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long lmb_regions_adjacent(struct lmb_region *rgn,
|
||||
unsigned long r1, unsigned long r2)
|
||||
{
|
||||
ulong base1 = rgn->region[r1].base;
|
||||
ulong size1 = rgn->region[r1].size;
|
||||
ulong base2 = rgn->region[r2].base;
|
||||
ulong size2 = rgn->region[r2].size;
|
||||
|
||||
return lmb_addrs_adjacent(base1, size1, base2, size2);
|
||||
}
|
||||
|
||||
static void lmb_remove_region(struct lmb_region *rgn, unsigned long r)
|
||||
{
|
||||
unsigned long i;
|
||||
|
||||
for (i = r; i < rgn->cnt - 1; i++) {
|
||||
rgn->region[i].base = rgn->region[i + 1].base;
|
||||
rgn->region[i].size = rgn->region[i + 1].size;
|
||||
}
|
||||
rgn->cnt--;
|
||||
}
|
||||
|
||||
/* Assumption: base addr of region 1 < base addr of region 2 */
|
||||
static void lmb_coalesce_regions(struct lmb_region *rgn,
|
||||
unsigned long r1, unsigned long r2)
|
||||
{
|
||||
rgn->region[r1].size += rgn->region[r2].size;
|
||||
lmb_remove_region(rgn, r2);
|
||||
}
|
||||
|
||||
void lmb_init(struct lmb *lmb)
|
||||
{
|
||||
/* Create a dummy zero size LMB which will get coalesced away later.
|
||||
* This simplifies the lmb_add() code below...
|
||||
*/
|
||||
lmb->memory.region[0].base = 0;
|
||||
lmb->memory.region[0].size = 0;
|
||||
lmb->memory.cnt = 1;
|
||||
lmb->memory.size = 0;
|
||||
|
||||
/* Ditto. */
|
||||
lmb->reserved.region[0].base = 0;
|
||||
lmb->reserved.region[0].size = 0;
|
||||
lmb->reserved.cnt = 1;
|
||||
lmb->reserved.size = 0;
|
||||
}
|
||||
|
||||
/* This routine called with relocation disabled. */
|
||||
static long lmb_add_region(struct lmb_region *rgn, ulong base, ulong size)
|
||||
{
|
||||
unsigned long coalesced = 0;
|
||||
long adjacent, i;
|
||||
|
||||
if ((rgn->cnt == 1) && (rgn->region[0].size == 0)) {
|
||||
rgn->region[0].base = base;
|
||||
rgn->region[0].size = size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* First try and coalesce this LMB with another. */
|
||||
for (i=0; i < rgn->cnt; i++) {
|
||||
ulong rgnbase = rgn->region[i].base;
|
||||
ulong rgnsize = rgn->region[i].size;
|
||||
|
||||
if ((rgnbase == base) && (rgnsize == size))
|
||||
/* Already have this region, so we're done */
|
||||
return 0;
|
||||
|
||||
adjacent = lmb_addrs_adjacent(base,size,rgnbase,rgnsize);
|
||||
if ( adjacent > 0 ) {
|
||||
rgn->region[i].base -= size;
|
||||
rgn->region[i].size += size;
|
||||
coalesced++;
|
||||
break;
|
||||
}
|
||||
else if ( adjacent < 0 ) {
|
||||
rgn->region[i].size += size;
|
||||
coalesced++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((i < rgn->cnt-1) && lmb_regions_adjacent(rgn, i, i+1) ) {
|
||||
lmb_coalesce_regions(rgn, i, i+1);
|
||||
coalesced++;
|
||||
}
|
||||
|
||||
if (coalesced)
|
||||
return coalesced;
|
||||
if (rgn->cnt >= MAX_LMB_REGIONS)
|
||||
return -1;
|
||||
|
||||
/* Couldn't coalesce the LMB, so add it to the sorted table. */
|
||||
for (i = rgn->cnt-1; i >= 0; i--) {
|
||||
if (base < rgn->region[i].base) {
|
||||
rgn->region[i+1].base = rgn->region[i].base;
|
||||
rgn->region[i+1].size = rgn->region[i].size;
|
||||
} else {
|
||||
rgn->region[i+1].base = base;
|
||||
rgn->region[i+1].size = size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (base < rgn->region[0].base) {
|
||||
rgn->region[0].base = base;
|
||||
rgn->region[0].size = size;
|
||||
}
|
||||
|
||||
rgn->cnt++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This routine may be called with relocation disabled. */
|
||||
long lmb_add(struct lmb *lmb, ulong base, ulong size)
|
||||
{
|
||||
struct lmb_region *_rgn = &(lmb->memory);
|
||||
|
||||
return lmb_add_region(_rgn, base, size);
|
||||
}
|
||||
|
||||
long lmb_reserve(struct lmb *lmb, ulong base, ulong size)
|
||||
{
|
||||
struct lmb_region *_rgn = &(lmb->reserved);
|
||||
|
||||
return lmb_add_region(_rgn, base, size);
|
||||
}
|
||||
|
||||
long lmb_overlaps_region(struct lmb_region *rgn, ulong base,
|
||||
ulong size)
|
||||
{
|
||||
unsigned long i;
|
||||
|
||||
for (i=0; i < rgn->cnt; i++) {
|
||||
ulong rgnbase = rgn->region[i].base;
|
||||
ulong rgnsize = rgn->region[i].size;
|
||||
if ( lmb_addrs_overlap(base,size,rgnbase,rgnsize) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (i < rgn->cnt) ? i : -1;
|
||||
}
|
||||
|
||||
ulong lmb_alloc(struct lmb *lmb, ulong size, ulong align)
|
||||
{
|
||||
return lmb_alloc_base(lmb, size, align, LMB_ALLOC_ANYWHERE);
|
||||
}
|
||||
|
||||
ulong lmb_alloc_base(struct lmb *lmb, ulong size, ulong align, ulong max_addr)
|
||||
{
|
||||
ulong alloc;
|
||||
|
||||
alloc = __lmb_alloc_base(lmb, size, align, max_addr);
|
||||
|
||||
if (alloc == 0)
|
||||
printf("ERROR: Failed to allocate 0x%lx bytes below 0x%lx.\n",
|
||||
size, max_addr);
|
||||
|
||||
return alloc;
|
||||
}
|
||||
|
||||
static ulong lmb_align_down(ulong addr, ulong size)
|
||||
{
|
||||
return addr & ~(size - 1);
|
||||
}
|
||||
|
||||
static ulong lmb_align_up(ulong addr, ulong size)
|
||||
{
|
||||
return (addr + (size - 1)) & ~(size - 1);
|
||||
}
|
||||
|
||||
ulong __lmb_alloc_base(struct lmb *lmb, ulong size, ulong align, ulong max_addr)
|
||||
{
|
||||
long i, j;
|
||||
ulong base = 0;
|
||||
|
||||
for (i = lmb->memory.cnt-1; i >= 0; i--) {
|
||||
ulong lmbbase = lmb->memory.region[i].base;
|
||||
ulong lmbsize = lmb->memory.region[i].size;
|
||||
|
||||
if (max_addr == LMB_ALLOC_ANYWHERE)
|
||||
base = lmb_align_down(lmbbase + lmbsize - size, align);
|
||||
else if (lmbbase < max_addr) {
|
||||
base = min(lmbbase + lmbsize, max_addr);
|
||||
base = lmb_align_down(base - size, align);
|
||||
} else
|
||||
continue;
|
||||
|
||||
while ((lmbbase <= base) &&
|
||||
((j = lmb_overlaps_region(&(lmb->reserved), base, size)) >= 0) )
|
||||
base = lmb_align_down(lmb->reserved.region[j].base - size,
|
||||
align);
|
||||
|
||||
if ((base != 0) && (lmbbase <= base))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < 0)
|
||||
return 0;
|
||||
|
||||
if (lmb_add_region(&(lmb->reserved), base, lmb_align_up(size, align)) < 0)
|
||||
return 0;
|
||||
|
||||
return base;
|
||||
}
|
||||
|
||||
int lmb_is_reserved(struct lmb *lmb, ulong addr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < lmb->reserved.cnt; i++) {
|
||||
ulong upper = lmb->reserved.region[i].base +
|
||||
lmb->reserved.region[i].size - 1;
|
||||
if ((addr >= lmb->reserved.region[i].base) && (addr <= upper))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
274
lib_generic/md5.c
Normal file
274
lib_generic/md5.c
Normal file
@ -0,0 +1,274 @@
|
||||
/*
|
||||
* This file was transplanted with slight modifications from Linux sources
|
||||
* (fs/cifs/md5.c) into U-Boot by Bartlomiej Sieka <tur@semihalf.com>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code implements the MD5 message-digest algorithm.
|
||||
* The algorithm is due to Ron Rivest. This code was
|
||||
* written by Colin Plumb in 1993, no copyright is claimed.
|
||||
* This code is in the public domain; do with it what you wish.
|
||||
*
|
||||
* Equivalent code is available from RSA Data Security, Inc.
|
||||
* This code has been tested against that, and is equivalent,
|
||||
* except that you don't need to include two pages of legalese
|
||||
* with every copy.
|
||||
*
|
||||
* To compute the message digest of a chunk of bytes, declare an
|
||||
* MD5Context structure, pass it to MD5Init, call MD5Update as
|
||||
* needed on buffers full of bytes, and then call MD5Final, which
|
||||
* will fill a supplied 16-byte array with the digest.
|
||||
*/
|
||||
|
||||
/* This code slightly modified to fit into Samba by
|
||||
abartlet@samba.org Jun 2001
|
||||
and to fit the cifs vfs by
|
||||
Steve French sfrench@us.ibm.com */
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/string.h>
|
||||
#include <md5.h>
|
||||
|
||||
static void
|
||||
MD5Transform(__u32 buf[4], __u32 const in[16]);
|
||||
|
||||
/*
|
||||
* Note: this code is harmless on little-endian machines.
|
||||
*/
|
||||
static void
|
||||
byteReverse(unsigned char *buf, unsigned longs)
|
||||
{
|
||||
__u32 t;
|
||||
do {
|
||||
t = (__u32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
|
||||
((unsigned) buf[1] << 8 | buf[0]);
|
||||
*(__u32 *) buf = t;
|
||||
buf += 4;
|
||||
} while (--longs);
|
||||
}
|
||||
|
||||
/*
|
||||
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
|
||||
* initialization constants.
|
||||
*/
|
||||
static void
|
||||
MD5Init(struct MD5Context *ctx)
|
||||
{
|
||||
ctx->buf[0] = 0x67452301;
|
||||
ctx->buf[1] = 0xefcdab89;
|
||||
ctx->buf[2] = 0x98badcfe;
|
||||
ctx->buf[3] = 0x10325476;
|
||||
|
||||
ctx->bits[0] = 0;
|
||||
ctx->bits[1] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update context to reflect the concatenation of another buffer full
|
||||
* of bytes.
|
||||
*/
|
||||
static void
|
||||
MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len)
|
||||
{
|
||||
register __u32 t;
|
||||
|
||||
/* Update bitcount */
|
||||
|
||||
t = ctx->bits[0];
|
||||
if ((ctx->bits[0] = t + ((__u32) len << 3)) < t)
|
||||
ctx->bits[1]++; /* Carry from low to high */
|
||||
ctx->bits[1] += len >> 29;
|
||||
|
||||
t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
|
||||
|
||||
/* Handle any leading odd-sized chunks */
|
||||
|
||||
if (t) {
|
||||
unsigned char *p = (unsigned char *) ctx->in + t;
|
||||
|
||||
t = 64 - t;
|
||||
if (len < t) {
|
||||
memmove(p, buf, len);
|
||||
return;
|
||||
}
|
||||
memmove(p, buf, t);
|
||||
byteReverse(ctx->in, 16);
|
||||
MD5Transform(ctx->buf, (__u32 *) ctx->in);
|
||||
buf += t;
|
||||
len -= t;
|
||||
}
|
||||
/* Process data in 64-byte chunks */
|
||||
|
||||
while (len >= 64) {
|
||||
memmove(ctx->in, buf, 64);
|
||||
byteReverse(ctx->in, 16);
|
||||
MD5Transform(ctx->buf, (__u32 *) ctx->in);
|
||||
buf += 64;
|
||||
len -= 64;
|
||||
}
|
||||
|
||||
/* Handle any remaining bytes of data. */
|
||||
|
||||
memmove(ctx->in, buf, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Final wrapup - pad to 64-byte boundary with the bit pattern
|
||||
* 1 0* (64-bit count of bits processed, MSB-first)
|
||||
*/
|
||||
static void
|
||||
MD5Final(unsigned char digest[16], struct MD5Context *ctx)
|
||||
{
|
||||
unsigned int count;
|
||||
unsigned char *p;
|
||||
|
||||
/* Compute number of bytes mod 64 */
|
||||
count = (ctx->bits[0] >> 3) & 0x3F;
|
||||
|
||||
/* Set the first char of padding to 0x80. This is safe since there is
|
||||
always at least one byte free */
|
||||
p = ctx->in + count;
|
||||
*p++ = 0x80;
|
||||
|
||||
/* Bytes of padding needed to make 64 bytes */
|
||||
count = 64 - 1 - count;
|
||||
|
||||
/* Pad out to 56 mod 64 */
|
||||
if (count < 8) {
|
||||
/* Two lots of padding: Pad the first block to 64 bytes */
|
||||
memset(p, 0, count);
|
||||
byteReverse(ctx->in, 16);
|
||||
MD5Transform(ctx->buf, (__u32 *) ctx->in);
|
||||
|
||||
/* Now fill the next block with 56 bytes */
|
||||
memset(ctx->in, 0, 56);
|
||||
} else {
|
||||
/* Pad block to 56 bytes */
|
||||
memset(p, 0, count - 8);
|
||||
}
|
||||
byteReverse(ctx->in, 14);
|
||||
|
||||
/* Append length in bits and transform */
|
||||
((__u32 *) ctx->in)[14] = ctx->bits[0];
|
||||
((__u32 *) ctx->in)[15] = ctx->bits[1];
|
||||
|
||||
MD5Transform(ctx->buf, (__u32 *) ctx->in);
|
||||
byteReverse((unsigned char *) ctx->buf, 4);
|
||||
memmove(digest, ctx->buf, 16);
|
||||
memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
|
||||
}
|
||||
|
||||
/* The four core functions - F1 is optimized somewhat */
|
||||
|
||||
/* #define F1(x, y, z) (x & y | ~x & z) */
|
||||
#define F1(x, y, z) (z ^ (x & (y ^ z)))
|
||||
#define F2(x, y, z) F1(z, x, y)
|
||||
#define F3(x, y, z) (x ^ y ^ z)
|
||||
#define F4(x, y, z) (y ^ (x | ~z))
|
||||
|
||||
/* This is the central step in the MD5 algorithm. */
|
||||
#define MD5STEP(f, w, x, y, z, data, s) \
|
||||
( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
|
||||
|
||||
/*
|
||||
* The core of the MD5 algorithm, this alters an existing MD5 hash to
|
||||
* reflect the addition of 16 longwords of new data. MD5Update blocks
|
||||
* the data and converts bytes into longwords for this routine.
|
||||
*/
|
||||
static void
|
||||
MD5Transform(__u32 buf[4], __u32 const in[16])
|
||||
{
|
||||
register __u32 a, b, c, d;
|
||||
|
||||
a = buf[0];
|
||||
b = buf[1];
|
||||
c = buf[2];
|
||||
d = buf[3];
|
||||
|
||||
MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
|
||||
|
||||
MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
|
||||
|
||||
MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
|
||||
|
||||
MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
|
||||
|
||||
buf[0] += a;
|
||||
buf[1] += b;
|
||||
buf[2] += c;
|
||||
buf[3] += d;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate and store in 'output' the MD5 digest of 'len' bytes at
|
||||
* 'input'. 'output' must have enough space to hold 16 bytes.
|
||||
*/
|
||||
void
|
||||
md5 (unsigned char *input, int len, unsigned char output[16])
|
||||
{
|
||||
struct MD5Context context;
|
||||
|
||||
MD5Init(&context);
|
||||
MD5Update(&context, input, len);
|
||||
MD5Final(output, &context);
|
||||
}
|
@ -25,13 +25,22 @@ include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = $(obj)lib$(ARCH).a
|
||||
|
||||
SOBJS = bios.o bios_pci.o realmode_switch.o
|
||||
SOBJS-y += bios.o
|
||||
SOBJS-y += bios_pci.o
|
||||
SOBJS-y += realmode_switch.o
|
||||
|
||||
COBJS = board.o bios_setup.o i386_linux.o zimage.o realmode.o \
|
||||
pci_type1.o pci.o video_bios.o video.o
|
||||
COBJS-y += bios_setup.o
|
||||
COBJS-y += board.o
|
||||
COBJS-y += bootm.o
|
||||
COBJS-y += pci.o
|
||||
COBJS-y += pci_type1.o
|
||||
COBJS-y += realmode.o
|
||||
COBJS-y += video_bios.o
|
||||
COBJS-y += video.o
|
||||
COBJS-y += zimage.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
|
||||
SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS)
|
||||
$(AR) $(ARFLAGS) $@ $(OBJS)
|
||||
|
107
lib_i386/bootm.c
Normal file
107
lib_i386/bootm.c
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* (C) Copyright 2002
|
||||
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
* Marius Groeger <mgroeger@sysgo.de>
|
||||
*
|
||||
* Copyright (C) 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <image.h>
|
||||
#include <zlib.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <asm/zimage.h>
|
||||
|
||||
/*cmd_boot.c*/
|
||||
extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
|
||||
|
||||
void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||
bootm_headers_t *images)
|
||||
{
|
||||
void *base_ptr;
|
||||
ulong os_data, os_len;
|
||||
ulong initrd_start, initrd_end;
|
||||
ulong ep;
|
||||
image_header_t *hdr;
|
||||
int ret;
|
||||
#if defined(CONFIG_FIT)
|
||||
const void *data;
|
||||
size_t len;
|
||||
#endif
|
||||
|
||||
ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_I386,
|
||||
&initrd_start, &initrd_end);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
if (images->legacy_hdr_valid) {
|
||||
hdr = images->legacy_hdr_os;
|
||||
if (image_check_type (hdr, IH_TYPE_MULTI)) {
|
||||
/* if multi-part image, we need to get first subimage */
|
||||
image_multi_getimg (hdr, 0, &os_data, &os_len);
|
||||
} else {
|
||||
/* otherwise get image data */
|
||||
os_data = image_get_data (hdr);
|
||||
os_len = image_get_data_size (hdr);
|
||||
}
|
||||
#if defined(CONFIG_FIT)
|
||||
} else if (images->fit_uname_os) {
|
||||
ret = fit_image_get_data (images->fit_hdr_os,
|
||||
images->fit_noffset_os, &data, &len);
|
||||
if (ret) {
|
||||
puts ("Can't get image data/size!\n");
|
||||
goto error;
|
||||
}
|
||||
os_data = (ulong)data;
|
||||
os_len = (ulong)len;
|
||||
#endif
|
||||
} else {
|
||||
puts ("Could not find kernel image!\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
base_ptr = load_zimage ((void*)os_data, os_len,
|
||||
initrd_start, initrd_end - initrd_start, 0);
|
||||
|
||||
if (NULL == base_ptr) {
|
||||
printf ("## Kernel loading failed ...\n");
|
||||
goto error;
|
||||
|
||||
}
|
||||
|
||||
if (!images->autostart)
|
||||
return ;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("## Transferring control to Linux (at address %08x) ...\n",
|
||||
(u32)base_ptr);
|
||||
#endif
|
||||
|
||||
/* we assume that the kernel is in place */
|
||||
printf("\nStarting kernel ...\n\n");
|
||||
|
||||
boot_zimage(base_ptr);
|
||||
/* does not return */
|
||||
return;
|
||||
|
||||
error:
|
||||
if (images->autostart)
|
||||
do_reset (cmdtp, flag, argc, argv);
|
||||
return;
|
||||
}
|
@ -1,179 +0,0 @@
|
||||
/*
|
||||
* (C) Copyright 2002
|
||||
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
* Marius Groeger <mgroeger@sysgo.de>
|
||||
*
|
||||
* Copyright (C) 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <image.h>
|
||||
#include <zlib.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <asm/zimage.h>
|
||||
|
||||
/*cmd_boot.c*/
|
||||
extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
|
||||
|
||||
extern image_header_t header; /* from cmd_bootm.c */
|
||||
|
||||
|
||||
image_header_t *fake_header(image_header_t *hdr, void *ptr, int size)
|
||||
{
|
||||
/* try each supported image type in order */
|
||||
if (NULL != fake_zimage_header(hdr, ptr, size)) {
|
||||
return hdr;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||
ulong addr, ulong *len_ptr, int verify)
|
||||
{
|
||||
void *base_ptr;
|
||||
|
||||
ulong len = 0, checksum;
|
||||
ulong initrd_start, initrd_end;
|
||||
ulong data;
|
||||
image_header_t *hdr = &header;
|
||||
|
||||
/*
|
||||
* Check if there is an initrd image
|
||||
*/
|
||||
if (argc >= 3) {
|
||||
addr = simple_strtoul(argv[2], NULL, 16);
|
||||
|
||||
printf ("## Loading Ramdisk Image at %08lx ...\n", addr);
|
||||
|
||||
/* Copy header so we can blank CRC field for re-calculation */
|
||||
memcpy (&header, (char *)addr, sizeof(image_header_t));
|
||||
|
||||
if (ntohl(hdr->ih_magic) != IH_MAGIC) {
|
||||
printf ("Bad Magic Number\n");
|
||||
do_reset (cmdtp, flag, argc, argv);
|
||||
}
|
||||
|
||||
data = (ulong)&header;
|
||||
len = sizeof(image_header_t);
|
||||
|
||||
checksum = ntohl(hdr->ih_hcrc);
|
||||
hdr->ih_hcrc = 0;
|
||||
|
||||
if (crc32 (0, (char *)data, len) != checksum) {
|
||||
printf ("Bad Header Checksum\n");
|
||||
do_reset (cmdtp, flag, argc, argv);
|
||||
}
|
||||
|
||||
print_image_hdr (hdr);
|
||||
|
||||
data = addr + sizeof(image_header_t);
|
||||
len = ntohl(hdr->ih_size);
|
||||
|
||||
if (verify) {
|
||||
ulong csum = 0;
|
||||
|
||||
printf (" Verifying Checksum ... ");
|
||||
csum = crc32 (0, (char *)data, len);
|
||||
if (csum != ntohl(hdr->ih_dcrc)) {
|
||||
printf ("Bad Data CRC\n");
|
||||
do_reset (cmdtp, flag, argc, argv);
|
||||
}
|
||||
printf ("OK\n");
|
||||
}
|
||||
|
||||
if ((hdr->ih_os != IH_OS_LINUX) ||
|
||||
(hdr->ih_arch != IH_CPU_I386) ||
|
||||
(hdr->ih_type != IH_TYPE_RAMDISK) ) {
|
||||
printf ("No Linux i386 Ramdisk Image\n");
|
||||
do_reset (cmdtp, flag, argc, argv);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now check if we have a multifile image
|
||||
*/
|
||||
} else if ((hdr->ih_type==IH_TYPE_MULTI) && (len_ptr[1])) {
|
||||
ulong tail = ntohl(len_ptr[0]) % 4;
|
||||
int i;
|
||||
|
||||
/* skip kernel length and terminator */
|
||||
data = (ulong)(&len_ptr[2]);
|
||||
/* skip any additional image length fields */
|
||||
for (i=1; len_ptr[i]; ++i)
|
||||
data += 4;
|
||||
/* add kernel length, and align */
|
||||
data += ntohl(len_ptr[0]);
|
||||
if (tail) {
|
||||
data += 4 - tail;
|
||||
}
|
||||
|
||||
len = ntohl(len_ptr[1]);
|
||||
|
||||
} else {
|
||||
/*
|
||||
* no initrd image
|
||||
*/
|
||||
data = 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (!data) {
|
||||
printf ("No initrd\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (data) {
|
||||
initrd_start = data;
|
||||
initrd_end = initrd_start + len;
|
||||
printf (" Loading Ramdisk to %08lx, end %08lx ... ",
|
||||
initrd_start, initrd_end);
|
||||
memmove ((void *)initrd_start, (void *)data, len);
|
||||
printf ("OK\n");
|
||||
} else {
|
||||
initrd_start = 0;
|
||||
initrd_end = 0;
|
||||
}
|
||||
|
||||
/* if multi-part image, we need to advance base ptr */
|
||||
if ((hdr->ih_type==IH_TYPE_MULTI) && (len_ptr[1])) {
|
||||
int i;
|
||||
for (i=0, addr+=sizeof(int); len_ptr[i++]; addr+=sizeof(int));
|
||||
}
|
||||
|
||||
base_ptr = load_zimage((void*)addr + sizeof(image_header_t), ntohl(hdr->ih_size),
|
||||
initrd_start, initrd_end-initrd_start, 0);
|
||||
|
||||
if (NULL == base_ptr) {
|
||||
printf ("## Kernel loading failed ...\n");
|
||||
do_reset(cmdtp, flag, argc, argv);
|
||||
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("## Transferring control to Linux (at address %08x) ...\n",
|
||||
(u32)base_ptr);
|
||||
#endif
|
||||
|
||||
/* we assume that the kernel is in place */
|
||||
printf("\nStarting kernel ...\n\n");
|
||||
|
||||
boot_zimage(base_ptr);
|
||||
|
||||
}
|
@ -212,7 +212,6 @@ void *load_zimage(char *image, unsigned long kernel_size,
|
||||
return setup_base;
|
||||
}
|
||||
|
||||
|
||||
void boot_zimage(void *setup_base)
|
||||
{
|
||||
struct pt_regs regs;
|
||||
@ -224,52 +223,3 @@ void boot_zimage(void *setup_base)
|
||||
regs.eflags = 0;
|
||||
enter_realmode(((u32)setup_base+SETUP_START_OFFSET)>>4, 0, ®s, ®s);
|
||||
}
|
||||
|
||||
|
||||
image_header_t *fake_zimage_header(image_header_t *hdr, void *ptr, int size)
|
||||
{
|
||||
/* There is no way to know the size of a zImage ... *
|
||||
* so we assume that 2MB will be enough for now */
|
||||
#define ZIMAGE_SIZE 0x200000
|
||||
|
||||
/* load a 1MB, the loaded will have to be moved to its final
|
||||
* position again later... */
|
||||
#define ZIMAGE_LOAD 0x100000
|
||||
|
||||
ulong checksum;
|
||||
|
||||
if (KERNEL_MAGIC != *(u16*)(ptr + BOOT_FLAG_OFF)) {
|
||||
/* not a zImage or bzImage */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (-1 == size) {
|
||||
size = ZIMAGE_SIZE;
|
||||
}
|
||||
#if 0
|
||||
checksum = crc32 (0, ptr, size);
|
||||
#else
|
||||
checksum = 0;
|
||||
#endif
|
||||
memset(hdr, 0, sizeof(image_header_t));
|
||||
|
||||
/* Build new header */
|
||||
hdr->ih_magic = htonl(IH_MAGIC);
|
||||
hdr->ih_time = 0;
|
||||
hdr->ih_size = htonl(size);
|
||||
hdr->ih_load = htonl(ZIMAGE_LOAD);
|
||||
hdr->ih_ep = 0;
|
||||
hdr->ih_dcrc = htonl(checksum);
|
||||
hdr->ih_os = IH_OS_LINUX;
|
||||
hdr->ih_arch = IH_CPU_I386;
|
||||
hdr->ih_type = IH_TYPE_KERNEL;
|
||||
hdr->ih_comp = IH_COMP_NONE;
|
||||
|
||||
strncpy((char *)hdr->ih_name, "(none)", IH_NMLEN);
|
||||
|
||||
checksum = crc32(0,(const char *)hdr,sizeof(image_header_t));
|
||||
|
||||
hdr->ih_hcrc = htonl(checksum);
|
||||
|
||||
return hdr;
|
||||
}
|
||||
|
@ -25,12 +25,17 @@ include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = $(obj)lib$(ARCH).a
|
||||
|
||||
SOBJS =
|
||||
SOBJS-y +=
|
||||
|
||||
COBJS = cache.o traps.o time.o interrupts.o board.o m68k_linux.o
|
||||
COBJS-y += board.o
|
||||
COBJS-y += bootm.o
|
||||
COBJS-y += cache.o
|
||||
COBJS-y += interrupts.o
|
||||
COBJS-y += time.o
|
||||
COBJS-y += traps.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
|
||||
SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS)
|
||||
$(AR) $(ARFLAGS) $@ $(OBJS)
|
||||
|
171
lib_m68k/bootm.c
Normal file
171
lib_m68k/bootm.c
Normal file
@ -0,0 +1,171 @@
|
||||
/*
|
||||
* (C) Copyright 2003
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <image.h>
|
||||
#include <zlib.h>
|
||||
#include <bzlib.h>
|
||||
#include <watchdog.h>
|
||||
#include <environment.h>
|
||||
#include <asm/byteorder.h>
|
||||
#ifdef CONFIG_SHOW_BOOT_PROGRESS
|
||||
# include <status_led.h>
|
||||
#endif
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define PHYSADDR(x) x
|
||||
|
||||
#define LINUX_MAX_ENVS 256
|
||||
#define LINUX_MAX_ARGS 256
|
||||
|
||||
static ulong get_sp (void);
|
||||
static void set_clocks_in_mhz (bd_t *kbd);
|
||||
extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
|
||||
|
||||
void do_bootm_linux(cmd_tbl_t * cmdtp, int flag,
|
||||
int argc, char *argv[],
|
||||
bootm_headers_t *images)
|
||||
{
|
||||
ulong sp;
|
||||
|
||||
ulong rd_data_start, rd_data_end, rd_len;
|
||||
ulong initrd_start, initrd_end;
|
||||
int ret;
|
||||
|
||||
ulong cmd_start, cmd_end;
|
||||
ulong bootmap_base;
|
||||
bd_t *kbd;
|
||||
ulong ep = 0;
|
||||
void (*kernel) (bd_t *, ulong, ulong, ulong, ulong);
|
||||
struct lmb *lmb = images->lmb;
|
||||
|
||||
bootmap_base = getenv_bootm_low();
|
||||
|
||||
/*
|
||||
* Booting a (Linux) kernel image
|
||||
*
|
||||
* Allocate space for command line and board info - the
|
||||
* address should be as high as possible within the reach of
|
||||
* the kernel (see CFG_BOOTMAPSZ settings), but in unused
|
||||
* memory, which means far enough below the current stack
|
||||
* pointer.
|
||||
*/
|
||||
sp = get_sp();
|
||||
debug ("## Current stack ends at 0x%08lx ", sp);
|
||||
|
||||
/* adjust sp by 1K to be safe */
|
||||
sp -= 1024;
|
||||
lmb_reserve(lmb, sp, (CFG_SDRAM_BASE + gd->ram_size - sp));
|
||||
|
||||
/* allocate space and init command line */
|
||||
ret = boot_get_cmdline (lmb, &cmd_start, &cmd_end, bootmap_base);
|
||||
if (ret) {
|
||||
puts("ERROR with allocation of cmdline\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* allocate space for kernel copy of board info */
|
||||
ret = boot_get_kbd (lmb, &kbd, bootmap_base);
|
||||
if (ret) {
|
||||
puts("ERROR with allocation of kernel bd\n");
|
||||
goto error;
|
||||
}
|
||||
set_clocks_in_mhz(kbd);
|
||||
|
||||
/* find kernel entry point */
|
||||
if (images->legacy_hdr_valid) {
|
||||
ep = image_get_ep (images->legacy_hdr_os);
|
||||
#if defined(CONFIG_FIT)
|
||||
} else if (images->fit_uname_os) {
|
||||
ret = fit_image_get_entry (images->fit_hdr_os,
|
||||
images->fit_noffset_os, &ep);
|
||||
if (ret) {
|
||||
puts ("Can't get entry point property!\n");
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
puts ("Could not find kernel entry point!\n");
|
||||
goto error;
|
||||
}
|
||||
kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))ep;
|
||||
|
||||
/* find ramdisk */
|
||||
ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_M68K,
|
||||
&rd_data_start, &rd_data_end);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
rd_len = rd_data_end - rd_data_start;
|
||||
ret = boot_ramdisk_high (lmb, rd_data_start, rd_len,
|
||||
&initrd_start, &initrd_end);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
debug("## Transferring control to Linux (at address %08lx) ...\n",
|
||||
(ulong) kernel);
|
||||
|
||||
show_boot_progress (15);
|
||||
|
||||
if (!images->autostart)
|
||||
return;
|
||||
/*
|
||||
* Linux Kernel Parameters (passing board info data):
|
||||
* r3: ptr to board info data
|
||||
* r4: initrd_start or 0 if no initrd
|
||||
* r5: initrd_end - unused if r4 is 0
|
||||
* r6: Start of command line string
|
||||
* r7: End of command line string
|
||||
*/
|
||||
(*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end);
|
||||
/* does not return */
|
||||
return ;
|
||||
|
||||
error:
|
||||
if (images->autostart)
|
||||
do_reset (cmdtp, flag, argc, argv);
|
||||
return ;
|
||||
}
|
||||
|
||||
static ulong get_sp (void)
|
||||
{
|
||||
ulong sp;
|
||||
|
||||
asm("movel %%a7, %%d0\n"
|
||||
"movel %%d0, %0\n": "=d"(sp): :"%d0");
|
||||
|
||||
return sp;
|
||||
}
|
||||
|
||||
static void set_clocks_in_mhz (bd_t *kbd)
|
||||
{
|
||||
char *s;
|
||||
|
||||
if ((s = getenv("clocks_in_mhz")) != NULL) {
|
||||
/* convert all clock information to MHz */
|
||||
kbd->bi_intfreq /= 1000000L;
|
||||
kbd->bi_busfreq /= 1000000L;
|
||||
}
|
||||
}
|
@ -1,340 +0,0 @@
|
||||
/*
|
||||
* (C) Copyright 2003
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <image.h>
|
||||
#include <zlib.h>
|
||||
#include <bzlib.h>
|
||||
#include <watchdog.h>
|
||||
#include <environment.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define PHYSADDR(x) x
|
||||
|
||||
#define LINUX_MAX_ENVS 256
|
||||
#define LINUX_MAX_ARGS 256
|
||||
|
||||
#define CHUNKSZ (64 * 1024)
|
||||
|
||||
#ifdef CONFIG_SHOW_BOOT_PROGRESS
|
||||
# include <status_led.h>
|
||||
# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg)
|
||||
#else
|
||||
# define SHOW_BOOT_PROGRESS(arg)
|
||||
#endif
|
||||
|
||||
extern image_header_t header;
|
||||
|
||||
void do_bootm_linux(cmd_tbl_t * cmdtp, int flag,
|
||||
int argc, char *argv[],
|
||||
ulong addr, ulong * len_ptr, int verify)
|
||||
{
|
||||
ulong sp;
|
||||
ulong len, checksum;
|
||||
ulong initrd_start, initrd_end;
|
||||
ulong cmd_start, cmd_end;
|
||||
ulong initrd_high;
|
||||
ulong data;
|
||||
int initrd_copy_to_ram = 1;
|
||||
char *cmdline;
|
||||
char *s;
|
||||
bd_t *kbd;
|
||||
void (*kernel) (bd_t *, ulong, ulong, ulong, ulong);
|
||||
image_header_t *hdr = &header;
|
||||
|
||||
if ((s = getenv("initrd_high")) != NULL) {
|
||||
/* a value of "no" or a similar string will act like 0,
|
||||
* turning the "load high" feature off. This is intentional.
|
||||
*/
|
||||
initrd_high = simple_strtoul(s, NULL, 16);
|
||||
if (initrd_high == ~0)
|
||||
initrd_copy_to_ram = 0;
|
||||
} else { /* not set, no restrictions to load high */
|
||||
initrd_high = ~0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_LOGBUFFER
|
||||
kbd = gd->bd;
|
||||
/* Prevent initrd from overwriting logbuffer */
|
||||
if (initrd_high < (kbd->bi_memsize - LOGBUFF_LEN - LOGBUFF_OVERHEAD))
|
||||
initrd_high = kbd->bi_memsize - LOGBUFF_LEN - LOGBUFF_OVERHEAD;
|
||||
debug("## Logbuffer at 0x%08lX ", kbd->bi_memsize - LOGBUFF_LEN);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Booting a (Linux) kernel image
|
||||
*
|
||||
* Allocate space for command line and board info - the
|
||||
* address should be as high as possible within the reach of
|
||||
* the kernel (see CFG_BOOTMAPSZ settings), but in unused
|
||||
* memory, which means far enough below the current stack
|
||||
* pointer.
|
||||
*/
|
||||
asm("movel %%a7, %%d0\n"
|
||||
"movel %%d0, %0\n": "=d"(sp): :"%d0");
|
||||
|
||||
debug("## Current stack ends at 0x%08lX ", sp);
|
||||
|
||||
sp -= 2048; /* just to be sure */
|
||||
if (sp > CFG_BOOTMAPSZ)
|
||||
sp = CFG_BOOTMAPSZ;
|
||||
sp &= ~0xF;
|
||||
|
||||
debug("=> set upper limit to 0x%08lX\n", sp);
|
||||
|
||||
cmdline = (char *)((sp - CFG_BARGSIZE) & ~0xF);
|
||||
kbd = (bd_t *) (((ulong) cmdline - sizeof(bd_t)) & ~0xF);
|
||||
|
||||
if ((s = getenv("bootargs")) == NULL)
|
||||
s = "";
|
||||
|
||||
strcpy(cmdline, s);
|
||||
|
||||
cmd_start = (ulong) & cmdline[0];
|
||||
cmd_end = cmd_start + strlen(cmdline);
|
||||
|
||||
*kbd = *(gd->bd);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("## cmdline at 0x%08lX ... 0x%08lX\n", cmd_start, cmd_end);
|
||||
|
||||
do_bdinfo(NULL, 0, 0, NULL);
|
||||
#endif
|
||||
|
||||
if ((s = getenv("clocks_in_mhz")) != NULL) {
|
||||
/* convert all clock information to MHz */
|
||||
kbd->bi_intfreq /= 1000000L;
|
||||
kbd->bi_busfreq /= 1000000L;
|
||||
}
|
||||
|
||||
kernel =
|
||||
(void (*)(bd_t *, ulong, ulong, ulong, ulong))ntohl(hdr->ih_ep);
|
||||
|
||||
/*
|
||||
* Check if there is an initrd image
|
||||
*/
|
||||
|
||||
if (argc >= 3) {
|
||||
debug("Not skipping initrd\n");
|
||||
SHOW_BOOT_PROGRESS(9);
|
||||
|
||||
addr = simple_strtoul(argv[2], NULL, 16);
|
||||
|
||||
printf("## Loading RAMDisk Image at %08lx ...\n", addr);
|
||||
|
||||
/* Copy header so we can blank CRC field for re-calculation */
|
||||
memmove(&header, (char *)addr, sizeof(image_header_t));
|
||||
|
||||
if (ntohl(hdr->ih_magic) != IH_MAGIC) {
|
||||
puts("Bad Magic Number\n");
|
||||
SHOW_BOOT_PROGRESS(-10);
|
||||
do_reset(cmdtp, flag, argc, argv);
|
||||
}
|
||||
|
||||
data = (ulong) & header;
|
||||
len = sizeof(image_header_t);
|
||||
|
||||
checksum = ntohl(hdr->ih_hcrc);
|
||||
hdr->ih_hcrc = 0;
|
||||
|
||||
if (crc32(0, (uchar *) data, len) != checksum) {
|
||||
puts("Bad Header Checksum\n");
|
||||
SHOW_BOOT_PROGRESS(-11);
|
||||
do_reset(cmdtp, flag, argc, argv);
|
||||
}
|
||||
|
||||
SHOW_BOOT_PROGRESS(10);
|
||||
|
||||
print_image_hdr(hdr);
|
||||
|
||||
data = addr + sizeof(image_header_t);
|
||||
len = ntohl(hdr->ih_size);
|
||||
|
||||
if (verify) {
|
||||
ulong csum = 0;
|
||||
#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
|
||||
ulong cdata = data, edata = cdata + len;
|
||||
#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */
|
||||
|
||||
puts(" Verifying Checksum ... ");
|
||||
|
||||
#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
|
||||
|
||||
while (cdata < edata) {
|
||||
ulong chunk = edata - cdata;
|
||||
|
||||
if (chunk > CHUNKSZ)
|
||||
chunk = CHUNKSZ;
|
||||
csum = crc32(csum, (uchar *) cdata, chunk);
|
||||
cdata += chunk;
|
||||
|
||||
WATCHDOG_RESET();
|
||||
}
|
||||
#else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */
|
||||
csum = crc32(0, (uchar *) data, len);
|
||||
#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */
|
||||
|
||||
if (csum != ntohl(hdr->ih_dcrc)) {
|
||||
puts("Bad Data CRC\n");
|
||||
SHOW_BOOT_PROGRESS(-12);
|
||||
do_reset(cmdtp, flag, argc, argv);
|
||||
}
|
||||
puts("OK\n");
|
||||
}
|
||||
|
||||
SHOW_BOOT_PROGRESS(11);
|
||||
|
||||
if ((hdr->ih_os != IH_OS_LINUX) ||
|
||||
(hdr->ih_arch != IH_CPU_M68K) ||
|
||||
(hdr->ih_type != IH_TYPE_RAMDISK)) {
|
||||
puts("No Linux ColdFire Ramdisk Image\n");
|
||||
SHOW_BOOT_PROGRESS(-13);
|
||||
do_reset(cmdtp, flag, argc, argv);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now check if we have a multifile image
|
||||
*/
|
||||
} else if ((hdr->ih_type == IH_TYPE_MULTI) && (len_ptr[1])) {
|
||||
u_long tail = ntohl(len_ptr[0]) % 4;
|
||||
int i;
|
||||
|
||||
SHOW_BOOT_PROGRESS(13);
|
||||
|
||||
/* skip kernel length and terminator */
|
||||
data = (ulong) (&len_ptr[2]);
|
||||
/* skip any additional image length fields */
|
||||
for (i = 1; len_ptr[i]; ++i)
|
||||
data += 4;
|
||||
/* add kernel length, and align */
|
||||
data += ntohl(len_ptr[0]);
|
||||
if (tail) {
|
||||
data += 4 - tail;
|
||||
}
|
||||
|
||||
len = ntohl(len_ptr[1]);
|
||||
|
||||
} else {
|
||||
/*
|
||||
* no initrd image
|
||||
*/
|
||||
SHOW_BOOT_PROGRESS(14);
|
||||
|
||||
len = data = 0;
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
debug("No initrd\n");
|
||||
}
|
||||
|
||||
if (data) {
|
||||
if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */
|
||||
initrd_start = data;
|
||||
initrd_end = initrd_start + len;
|
||||
} else {
|
||||
initrd_start = (ulong) kbd - len;
|
||||
initrd_start &= ~(4096 - 1); /* align on page */
|
||||
|
||||
if (initrd_high) {
|
||||
ulong nsp;
|
||||
|
||||
/*
|
||||
* the inital ramdisk does not need to be within
|
||||
* CFG_BOOTMAPSZ as it is not accessed until after
|
||||
* the mm system is initialised.
|
||||
*
|
||||
* do the stack bottom calculation again and see if
|
||||
* the initrd will fit just below the monitor stack
|
||||
* bottom without overwriting the area allocated
|
||||
* above for command line args and board info.
|
||||
*/
|
||||
asm("movel %%a7, %%d0\n"
|
||||
"movel %%d0, %0\n": "=d"(nsp): :"%d0");
|
||||
|
||||
nsp -= 2048; /* just to be sure */
|
||||
nsp &= ~0xF;
|
||||
|
||||
if (nsp > initrd_high) /* limit as specified */
|
||||
nsp = initrd_high;
|
||||
|
||||
nsp -= len;
|
||||
nsp &= ~(4096 - 1); /* align on page */
|
||||
|
||||
if (nsp >= sp)
|
||||
initrd_start = nsp;
|
||||
}
|
||||
|
||||
SHOW_BOOT_PROGRESS(12);
|
||||
|
||||
debug
|
||||
("## initrd at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n",
|
||||
data, data + len - 1, len, len);
|
||||
|
||||
initrd_end = initrd_start + len;
|
||||
printf(" Loading Ramdisk to %08lx, end %08lx ... ",
|
||||
initrd_start, initrd_end);
|
||||
#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
|
||||
{
|
||||
size_t l = len;
|
||||
void *to = (void *)initrd_start;
|
||||
void *from = (void *)data;
|
||||
|
||||
while (l > 0) {
|
||||
size_t tail =
|
||||
(l > CHUNKSZ) ? CHUNKSZ : l;
|
||||
WATCHDOG_RESET();
|
||||
memmove(to, from, tail);
|
||||
to += tail;
|
||||
from += tail;
|
||||
l -= tail;
|
||||
}
|
||||
}
|
||||
#else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */
|
||||
memmove((void *)initrd_start, (void *)data, len);
|
||||
#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */
|
||||
puts("OK\n");
|
||||
}
|
||||
} else {
|
||||
initrd_start = 0;
|
||||
initrd_end = 0;
|
||||
}
|
||||
|
||||
debug("## Transferring control to Linux (at address %08lx) ...\n",
|
||||
(ulong) kernel);
|
||||
|
||||
SHOW_BOOT_PROGRESS(15);
|
||||
|
||||
/*
|
||||
* Linux Kernel Parameters (passing board info data):
|
||||
* r3: ptr to board info data
|
||||
* r4: initrd_start or 0 if no initrd
|
||||
* r5: initrd_end - unused if r4 is 0
|
||||
* r6: Start of command line string
|
||||
* r7: End of command line string
|
||||
*/
|
||||
(*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end);
|
||||
/* does not return */
|
||||
}
|
@ -25,12 +25,15 @@ include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = $(obj)lib$(ARCH).a
|
||||
|
||||
SOBJS =
|
||||
SOBJS-y +=
|
||||
|
||||
COBJS = board.o microblaze_linux.o time.o cache.o
|
||||
COBJS-y += board.o
|
||||
COBJS-y += bootm.o
|
||||
COBJS-y += cache.o
|
||||
COBJS-y += time.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
|
||||
SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS)
|
||||
$(AR) $(ARFLAGS) $@ $(OBJS)
|
||||
|
81
lib_microblaze/bootm.c
Normal file
81
lib_microblaze/bootm.c
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* (C) Copyright 2007 Michal Simek
|
||||
* (C) Copyright 2004 Atmark Techno, Inc.
|
||||
*
|
||||
* Michal SIMEK <monstr@monstr.eu>
|
||||
* Yasushi SHOJI <yashi@atmark-techno.com>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <image.h>
|
||||
#include <zlib.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
|
||||
|
||||
void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[],
|
||||
bootm_headers_t *images)
|
||||
{
|
||||
/* First parameter is mapped to $r5 for kernel boot args */
|
||||
void (*theKernel) (char *);
|
||||
char *commandline = getenv ("bootargs");
|
||||
ulong ep = 0;
|
||||
|
||||
/* find kernel entry point */
|
||||
if (images->legacy_hdr_valid) {
|
||||
ep = image_get_ep (images->legacy_hdr_os);
|
||||
#if defined(CONFIG_FIT)
|
||||
} else if (images->fit_uname_os) {
|
||||
int ret = fit_image_get_entry (images->fit_hdr_os,
|
||||
images->fit_noffset_os, &ep);
|
||||
if (ret) {
|
||||
puts ("Can't get entry point property!\n");
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
puts ("Could not find kernel entry point!\n");
|
||||
goto error;
|
||||
}
|
||||
theKernel = (void (*)(char *))ep;
|
||||
|
||||
show_boot_progress (15);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("## Transferring control to Linux (at address %08lx) ...\n",
|
||||
(ulong) theKernel);
|
||||
#endif
|
||||
|
||||
if (!images->autostart)
|
||||
return ;
|
||||
|
||||
theKernel (commandline);
|
||||
/* does not return */
|
||||
return;
|
||||
|
||||
error:
|
||||
if (images->autostart)
|
||||
do_reset (cmdtp, flag, argc, argv);
|
||||
return;
|
||||
}
|
@ -1,164 +0,0 @@
|
||||
/*
|
||||
* (C) Copyright 2007 Michal Simek
|
||||
* (C) Copyright 2004 Atmark Techno, Inc.
|
||||
*
|
||||
* Michal SIMEK <monstr@monstr.eu>
|
||||
* Yasushi SHOJI <yashi@atmark-techno.com>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <image.h>
|
||||
#include <zlib.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
extern image_header_t header; /* from cmd_bootm.c */
|
||||
/*cmd_boot.c*/
|
||||
extern int do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]);
|
||||
|
||||
void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[],
|
||||
ulong addr, ulong * len_ptr, int verify)
|
||||
{
|
||||
ulong len = 0, checksum;
|
||||
ulong initrd_start, initrd_end;
|
||||
ulong data;
|
||||
/* First parameter is mapped to $r5 for kernel boot args */
|
||||
void (*theKernel) (char *);
|
||||
image_header_t *hdr = &header;
|
||||
char *commandline = getenv ("bootargs");
|
||||
int i;
|
||||
|
||||
theKernel = (void (*)(char *))ntohl (hdr->ih_ep);
|
||||
|
||||
/* Check if there is an initrd image */
|
||||
if (argc >= 3) {
|
||||
show_boot_progress (9);
|
||||
|
||||
addr = simple_strtoul (argv[2], NULL, 16);
|
||||
|
||||
printf ("## Loading Ramdisk Image at %08lx ...\n", addr);
|
||||
|
||||
/* Copy header so we can blank CRC field for re-calculation */
|
||||
memcpy (&header, (char *)addr, sizeof (image_header_t));
|
||||
|
||||
if (ntohl (hdr->ih_magic) != IH_MAGIC) {
|
||||
printf ("Bad Magic Number\n");
|
||||
show_boot_progress (-10);
|
||||
do_reset (cmdtp, flag, argc, argv);
|
||||
}
|
||||
|
||||
data = (ulong) & header;
|
||||
len = sizeof (image_header_t);
|
||||
|
||||
checksum = ntohl (hdr->ih_hcrc);
|
||||
hdr->ih_hcrc = 0;
|
||||
|
||||
if (crc32 (0, (char *)data, len) != checksum) {
|
||||
printf ("Bad Header Checksum\n");
|
||||
show_boot_progress (-11);
|
||||
do_reset (cmdtp, flag, argc, argv);
|
||||
}
|
||||
|
||||
show_boot_progress (10);
|
||||
|
||||
print_image_hdr (hdr);
|
||||
|
||||
data = addr + sizeof (image_header_t);
|
||||
len = ntohl (hdr->ih_size);
|
||||
|
||||
if (verify) {
|
||||
ulong csum = 0;
|
||||
|
||||
printf (" Verifying Checksum ... ");
|
||||
csum = crc32 (0, (char *)data, len);
|
||||
if (csum != ntohl (hdr->ih_dcrc)) {
|
||||
printf ("Bad Data CRC\n");
|
||||
show_boot_progress (-12);
|
||||
do_reset (cmdtp, flag, argc, argv);
|
||||
}
|
||||
printf ("OK\n");
|
||||
}
|
||||
|
||||
show_boot_progress (11);
|
||||
|
||||
if ((hdr->ih_os != IH_OS_LINUX) ||
|
||||
(hdr->ih_arch != IH_CPU_MICROBLAZE) ||
|
||||
(hdr->ih_type != IH_TYPE_RAMDISK)) {
|
||||
printf ("No Linux Microblaze Ramdisk Image\n");
|
||||
show_boot_progress (-13);
|
||||
do_reset (cmdtp, flag, argc, argv);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now check if we have a multifile image
|
||||
*/
|
||||
} else if ((hdr->ih_type == IH_TYPE_MULTI) && (len_ptr[1])) {
|
||||
ulong tail = ntohl (len_ptr[0]) % 4;
|
||||
|
||||
show_boot_progress (13);
|
||||
|
||||
/* skip kernel length and terminator */
|
||||
data = (ulong) (&len_ptr[2]);
|
||||
/* skip any additional image length fields */
|
||||
for (i = 1; len_ptr[i]; ++i)
|
||||
data += 4;
|
||||
/* add kernel length, and align */
|
||||
data += ntohl (len_ptr[0]);
|
||||
if (tail) {
|
||||
data += 4 - tail;
|
||||
}
|
||||
|
||||
len = ntohl (len_ptr[1]);
|
||||
|
||||
} else {
|
||||
/*
|
||||
* no initrd image
|
||||
*/
|
||||
show_boot_progress (14);
|
||||
|
||||
data = 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (!data) {
|
||||
printf ("No initrd\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (data) {
|
||||
initrd_start = data;
|
||||
initrd_end = initrd_start + len;
|
||||
} else {
|
||||
initrd_start = 0;
|
||||
initrd_end = 0;
|
||||
}
|
||||
|
||||
show_boot_progress (15);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("## Transferring control to Linux (at address %08lx) ...\n",
|
||||
(ulong) theKernel);
|
||||
#endif
|
||||
|
||||
theKernel (commandline);
|
||||
}
|
@ -25,12 +25,14 @@ include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = $(obj)lib$(ARCH).a
|
||||
|
||||
SOBJS =
|
||||
SOBJS-y +=
|
||||
|
||||
COBJS = board.o time.o mips_linux.o
|
||||
COBJS-y += board.o
|
||||
COBJS-y += bootm.o
|
||||
COBJS-y += time.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
|
||||
SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS)
|
||||
$(AR) $(ARFLAGS) $@ $(OBJS)
|
||||
|
@ -33,10 +33,6 @@ DECLARE_GLOBAL_DATA_PTR;
|
||||
#define LINUX_MAX_ENVS 256
|
||||
#define LINUX_MAX_ARGS 256
|
||||
|
||||
extern image_header_t header; /* from cmd_bootm.c */
|
||||
|
||||
extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
|
||||
|
||||
static int linux_argc;
|
||||
static char ** linux_argv;
|
||||
|
||||
@ -47,126 +43,40 @@ static int linux_env_idx;
|
||||
static void linux_params_init (ulong start, char * commandline);
|
||||
static void linux_env_set (char * env_name, char * env_val);
|
||||
|
||||
extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
|
||||
|
||||
void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[],
|
||||
ulong addr, ulong * len_ptr, int verify)
|
||||
bootm_headers_t *images)
|
||||
{
|
||||
ulong len = 0, checksum;
|
||||
ulong initrd_start, initrd_end;
|
||||
ulong data;
|
||||
void (*theKernel) (int, char **, char **, int *);
|
||||
image_header_t *hdr = &header;
|
||||
char *commandline = getenv ("bootargs");
|
||||
char env_buf[12];
|
||||
ulong initrd_start, initrd_end;
|
||||
ulong ep = 0;
|
||||
void (*theKernel) (int, char **, char **, int *);
|
||||
char *commandline = getenv ("bootargs");
|
||||
char env_buf[12];
|
||||
int ret;
|
||||
|
||||
theKernel =
|
||||
(void (*)(int, char **, char **, int *)) ntohl (hdr->ih_ep);
|
||||
|
||||
/*
|
||||
* Check if there is an initrd image
|
||||
*/
|
||||
if (argc >= 3) {
|
||||
show_boot_progress (9);
|
||||
|
||||
addr = simple_strtoul (argv[2], NULL, 16);
|
||||
|
||||
printf ("## Loading Ramdisk Image at %08lx ...\n", addr);
|
||||
|
||||
/* Copy header so we can blank CRC field for re-calculation */
|
||||
memcpy (&header, (char *) addr, sizeof (image_header_t));
|
||||
|
||||
if (ntohl (hdr->ih_magic) != IH_MAGIC) {
|
||||
printf ("Bad Magic Number\n");
|
||||
show_boot_progress (-10);
|
||||
do_reset (cmdtp, flag, argc, argv);
|
||||
/* find kernel entry point */
|
||||
if (images->legacy_hdr_valid) {
|
||||
ep = image_get_ep (images->legacy_hdr_os);
|
||||
#if defined(CONFIG_FIT)
|
||||
} else if (images->fit_uname_os) {
|
||||
ret = fit_image_get_entry (images->fit_hdr_os,
|
||||
images->fit_noffset_os, &ep);
|
||||
if (ret) {
|
||||
puts ("Can't get entry point property!\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
data = (ulong) & header;
|
||||
len = sizeof (image_header_t);
|
||||
|
||||
checksum = ntohl (hdr->ih_hcrc);
|
||||
hdr->ih_hcrc = 0;
|
||||
|
||||
if (crc32 (0, (uchar *) data, len) != checksum) {
|
||||
printf ("Bad Header Checksum\n");
|
||||
show_boot_progress (-11);
|
||||
do_reset (cmdtp, flag, argc, argv);
|
||||
}
|
||||
|
||||
show_boot_progress (10);
|
||||
|
||||
print_image_hdr (hdr);
|
||||
|
||||
data = addr + sizeof (image_header_t);
|
||||
len = ntohl (hdr->ih_size);
|
||||
|
||||
if (verify) {
|
||||
ulong csum = 0;
|
||||
|
||||
printf (" Verifying Checksum ... ");
|
||||
csum = crc32 (0, (uchar *) data, len);
|
||||
if (csum != ntohl (hdr->ih_dcrc)) {
|
||||
printf ("Bad Data CRC\n");
|
||||
show_boot_progress (-12);
|
||||
do_reset (cmdtp, flag, argc, argv);
|
||||
}
|
||||
printf ("OK\n");
|
||||
}
|
||||
|
||||
show_boot_progress (11);
|
||||
|
||||
if ((hdr->ih_os != IH_OS_LINUX) ||
|
||||
(hdr->ih_arch != IH_CPU_MIPS) ||
|
||||
(hdr->ih_type != IH_TYPE_RAMDISK)) {
|
||||
printf ("No Linux MIPS Ramdisk Image\n");
|
||||
show_boot_progress (-13);
|
||||
do_reset (cmdtp, flag, argc, argv);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now check if we have a multifile image
|
||||
*/
|
||||
} else if ((hdr->ih_type == IH_TYPE_MULTI) && (len_ptr[1])) {
|
||||
ulong tail = ntohl (len_ptr[0]) % 4;
|
||||
int i;
|
||||
|
||||
show_boot_progress (13);
|
||||
|
||||
/* skip kernel length and terminator */
|
||||
data = (ulong) (&len_ptr[2]);
|
||||
/* skip any additional image length fields */
|
||||
for (i = 1; len_ptr[i]; ++i)
|
||||
data += 4;
|
||||
/* add kernel length, and align */
|
||||
data += ntohl (len_ptr[0]);
|
||||
if (tail) {
|
||||
data += 4 - tail;
|
||||
}
|
||||
|
||||
len = ntohl (len_ptr[1]);
|
||||
|
||||
} else {
|
||||
/*
|
||||
* no initrd image
|
||||
*/
|
||||
show_boot_progress (14);
|
||||
|
||||
data = 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (!data) {
|
||||
printf ("No initrd\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (data) {
|
||||
initrd_start = data;
|
||||
initrd_end = initrd_start + len;
|
||||
} else {
|
||||
initrd_start = 0;
|
||||
initrd_end = 0;
|
||||
puts ("Could not find kernel entry point!\n");
|
||||
goto error;
|
||||
}
|
||||
theKernel = (void (*)(int, char **, char **, int *))ep;
|
||||
|
||||
ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_MIPS,
|
||||
&initrd_start, &initrd_end);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
show_boot_progress (15);
|
||||
|
||||
@ -203,10 +113,20 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[],
|
||||
sprintf (env_buf, "0x%X", (uint) (gd->bd->bi_flashsize));
|
||||
linux_env_set ("flash_size", env_buf);
|
||||
|
||||
if (!images->autostart)
|
||||
return ;
|
||||
|
||||
/* we assume that the kernel is in place */
|
||||
printf ("\nStarting kernel ...\n\n");
|
||||
|
||||
theKernel (linux_argc, linux_argv, linux_env, 0);
|
||||
/* does not return */
|
||||
return;
|
||||
|
||||
error:
|
||||
if (images->autostart)
|
||||
do_reset (cmdtp, flag, argc, argv);
|
||||
return;
|
||||
}
|
||||
|
||||
static void linux_params_init (ulong start, char *line)
|
@ -25,12 +25,17 @@ include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = $(obj)lib$(ARCH).a
|
||||
|
||||
SOBJS =
|
||||
SOBJS-y +=
|
||||
|
||||
COBJS = board.o cache.o divmod.o nios_linux.o mult.o time.o
|
||||
COBJS-y += board.o
|
||||
COBJS-y += bootm.o
|
||||
COBJS-y += cache.o
|
||||
COBJS-y += divmod.o
|
||||
COBJS-y += mult.o
|
||||
COBJS-y += time.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
|
||||
SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS)
|
||||
$(AR) $(ARFLAGS) $@ $(OBJS)
|
||||
|
@ -29,6 +29,6 @@
|
||||
*
|
||||
*/
|
||||
void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||
ulong addr, ulong *len_ptr, int verify)
|
||||
bootm_headers_t *images)
|
||||
{
|
||||
}
|
@ -25,12 +25,16 @@ include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = $(obj)lib$(ARCH).a
|
||||
|
||||
SOBJS = cache.o
|
||||
SOBJS-y += cache.o
|
||||
|
||||
COBJS = board.o divmod.o nios_linux.o mult.o time.o
|
||||
COBJS-y += board.o
|
||||
COBJS-y += bootm.o
|
||||
COBJS-y += divmod.o
|
||||
COBJS-y += mult.o
|
||||
COBJS-y += time.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
|
||||
SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS)
|
||||
$(AR) $(ARFLAGS) $@ $(OBJS)
|
||||
|
@ -25,16 +25,43 @@
|
||||
#include <command.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
extern image_header_t header; /* common/cmd_bootm.c */
|
||||
extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
|
||||
|
||||
void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||
ulong addr, ulong *len_ptr, int verify)
|
||||
bootm_headers_t *images)
|
||||
{
|
||||
image_header_t *hdr = &header;
|
||||
void (*kernel)(void) = (void (*)(void))ntohl (hdr->ih_ep);
|
||||
ulong ep = 0;
|
||||
|
||||
/* find kernel entry point */
|
||||
if (images->legacy_hdr_valid) {
|
||||
ep = image_get_ep (images->legacy_hdr_os);
|
||||
#if defined(CONFIG_FIT)
|
||||
} else if (images->fit_uname_os) {
|
||||
int ret = fit_image_get_entry (images->fit_hdr_os,
|
||||
images->fit_noffset_os, &ep);
|
||||
if (ret) {
|
||||
puts ("Can't get entry point property!\n");
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
puts ("Could not find kernel entry point!\n");
|
||||
goto error;
|
||||
}
|
||||
void (*kernel)(void) = (void (*)(void))ep;
|
||||
|
||||
if (!images->autostart)
|
||||
return ;
|
||||
|
||||
/* For now we assume the Microtronix linux ... which only
|
||||
* needs to be called ;-)
|
||||
*/
|
||||
kernel ();
|
||||
/* does not return */
|
||||
return;
|
||||
|
||||
error:
|
||||
if (images->autostart)
|
||||
do_reset (cmdtp, flag, argc, argv);
|
||||
return;
|
||||
}
|
@ -25,13 +25,21 @@ include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = $(obj)lib$(ARCH).a
|
||||
|
||||
SOBJS = ppccache.o ppcstring.o ticks.o
|
||||
SOBJS-y += ppccache.o
|
||||
SOBJS-y += ppcstring.o
|
||||
SOBJS-y += ticks.o
|
||||
|
||||
COBJS = board.o \
|
||||
bat_rw.o cache.o extable.o kgdb.o time.o interrupts.o
|
||||
COBJS-y += bat_rw.o
|
||||
COBJS-y += board.o
|
||||
COBJS-y += bootm.o
|
||||
COBJS-y += cache.o
|
||||
COBJS-y += extable.o
|
||||
COBJS-y += interrupts.o
|
||||
COBJS-y += kgdb.o
|
||||
COBJS-y += time.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
|
||||
SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS)
|
||||
$(AR) $(ARFLAGS) $@ $(OBJS)
|
||||
|
774
lib_ppc/bootm.c
Normal file
774
lib_ppc/bootm.c
Normal file
@ -0,0 +1,774 @@
|
||||
/*
|
||||
* (C) Copyright 2008 Semihalf
|
||||
*
|
||||
* (C) Copyright 2000-2006
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
#include <common.h>
|
||||
#include <watchdog.h>
|
||||
#include <command.h>
|
||||
#include <image.h>
|
||||
#include <malloc.h>
|
||||
#include <zlib.h>
|
||||
#include <bzlib.h>
|
||||
#include <environment.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
#if defined(CONFIG_OF_LIBFDT)
|
||||
#include <fdt.h>
|
||||
#include <libfdt.h>
|
||||
#include <fdt_support.h>
|
||||
|
||||
static void fdt_error (const char *msg);
|
||||
static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||
bootm_headers_t *images, char **of_flat_tree, ulong *of_size);
|
||||
static int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base,
|
||||
cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||
char **of_flat_tree, ulong *of_size);
|
||||
#endif
|
||||
|
||||
#ifdef CFG_INIT_RAM_LOCK
|
||||
#include <asm/cache.h>
|
||||
#endif
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
|
||||
extern ulong get_effective_memsize(void);
|
||||
static ulong get_sp (void);
|
||||
static void set_clocks_in_mhz (bd_t *kbd);
|
||||
|
||||
#ifndef CFG_LINUX_LOWMEM_MAX_SIZE
|
||||
#define CFG_LINUX_LOWMEM_MAX_SIZE (768*1024*1024)
|
||||
#endif
|
||||
|
||||
void __attribute__((noinline))
|
||||
do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||
bootm_headers_t *images)
|
||||
{
|
||||
ulong sp;
|
||||
|
||||
ulong initrd_start, initrd_end;
|
||||
ulong rd_data_start, rd_data_end, rd_len;
|
||||
ulong size;
|
||||
|
||||
ulong cmd_start, cmd_end, bootmap_base;
|
||||
bd_t *kbd;
|
||||
ulong ep = 0;
|
||||
void (*kernel)(bd_t *, ulong, ulong, ulong, ulong);
|
||||
int ret;
|
||||
ulong of_size = 0;
|
||||
struct lmb *lmb = images->lmb;
|
||||
|
||||
#if defined(CONFIG_OF_LIBFDT)
|
||||
char *of_flat_tree = NULL;
|
||||
#endif
|
||||
|
||||
bootmap_base = getenv_bootm_low();
|
||||
size = getenv_bootm_size();
|
||||
|
||||
#ifdef DEBUG
|
||||
if (((u64)bootmap_base + size) > (CFG_SDRAM_BASE + (u64)gd->ram_size))
|
||||
puts("WARNING: bootm_low + bootm_size exceed total memory\n");
|
||||
if ((bootmap_base + size) > get_effective_memsize())
|
||||
puts("WARNING: bootm_low + bootm_size exceed eff. memory\n");
|
||||
#endif
|
||||
|
||||
size = min(size, get_effective_memsize());
|
||||
size = min(size, CFG_LINUX_LOWMEM_MAX_SIZE);
|
||||
|
||||
if (size < getenv_bootm_size()) {
|
||||
ulong base = bootmap_base + size;
|
||||
printf("WARNING: adjusting available memory to %x\n", size);
|
||||
lmb_reserve(lmb, base, getenv_bootm_size() - size);
|
||||
}
|
||||
|
||||
/*
|
||||
* Booting a (Linux) kernel image
|
||||
*
|
||||
* Allocate space for command line and board info - the
|
||||
* address should be as high as possible within the reach of
|
||||
* the kernel (see CFG_BOOTMAPSZ settings), but in unused
|
||||
* memory, which means far enough below the current stack
|
||||
* pointer.
|
||||
*/
|
||||
sp = get_sp();
|
||||
debug ("## Current stack ends at 0x%08lx\n", sp);
|
||||
|
||||
/* adjust sp by 1K to be safe */
|
||||
sp -= 1024;
|
||||
lmb_reserve(lmb, sp, (CFG_SDRAM_BASE + get_effective_memsize() - sp));
|
||||
|
||||
#if defined(CONFIG_OF_LIBFDT)
|
||||
/* find flattened device tree */
|
||||
ret = boot_get_fdt (cmdtp, flag, argc, argv, images, &of_flat_tree, &of_size);
|
||||
|
||||
if (ret)
|
||||
goto error;
|
||||
#endif
|
||||
|
||||
if (!of_size) {
|
||||
/* allocate space and init command line */
|
||||
ret = boot_get_cmdline (lmb, &cmd_start, &cmd_end, bootmap_base);
|
||||
if (ret) {
|
||||
puts("ERROR with allocation of cmdline\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* allocate space for kernel copy of board info */
|
||||
ret = boot_get_kbd (lmb, &kbd, bootmap_base);
|
||||
if (ret) {
|
||||
puts("ERROR with allocation of kernel bd\n");
|
||||
goto error;
|
||||
}
|
||||
set_clocks_in_mhz(kbd);
|
||||
}
|
||||
|
||||
/* find kernel entry point */
|
||||
if (images->legacy_hdr_valid) {
|
||||
ep = image_get_ep (images->legacy_hdr_os);
|
||||
#if defined(CONFIG_FIT)
|
||||
} else if (images->fit_uname_os) {
|
||||
ret = fit_image_get_entry (images->fit_hdr_os,
|
||||
images->fit_noffset_os, &ep);
|
||||
if (ret) {
|
||||
puts ("Can't get entry point property!\n");
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
puts ("Could not find kernel entry point!\n");
|
||||
goto error;
|
||||
}
|
||||
kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))ep;
|
||||
|
||||
/* find ramdisk */
|
||||
ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_PPC,
|
||||
&rd_data_start, &rd_data_end);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
rd_len = rd_data_end - rd_data_start;
|
||||
|
||||
#if defined(CONFIG_OF_LIBFDT)
|
||||
ret = boot_relocate_fdt (lmb, bootmap_base,
|
||||
cmdtp, flag, argc, argv, &of_flat_tree, &of_size);
|
||||
|
||||
/*
|
||||
* Add the chosen node if it doesn't exist, add the env and bd_t
|
||||
* if the user wants it (the logic is in the subroutines).
|
||||
*/
|
||||
if (of_size) {
|
||||
/* pass in dummy initrd info, we'll fix up later */
|
||||
if (fdt_chosen(of_flat_tree, rd_data_start, rd_data_end, 0) < 0) {
|
||||
fdt_error ("/chosen node create failed");
|
||||
goto error;
|
||||
}
|
||||
#ifdef CONFIG_OF_HAS_UBOOT_ENV
|
||||
if (fdt_env(of_flat_tree) < 0) {
|
||||
fdt_error ("/u-boot-env node create failed");
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_OF_HAS_BD_T
|
||||
if (fdt_bd_t(of_flat_tree) < 0) {
|
||||
fdt_error ("/bd_t node create failed");
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_OF_BOARD_SETUP
|
||||
/* Call the board-specific fixup routine */
|
||||
ft_board_setup(of_flat_tree, gd->bd);
|
||||
#endif
|
||||
}
|
||||
#endif /* CONFIG_OF_LIBFDT */
|
||||
|
||||
ret = boot_ramdisk_high (lmb, rd_data_start, rd_len, &initrd_start, &initrd_end);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
#if defined(CONFIG_OF_LIBFDT)
|
||||
/* fixup the initrd now that we know where it should be */
|
||||
if ((of_flat_tree) && (initrd_start && initrd_end)) {
|
||||
uint64_t addr, size;
|
||||
int total = fdt_num_mem_rsv(of_flat_tree);
|
||||
int j;
|
||||
|
||||
/* Look for the dummy entry and delete it */
|
||||
for (j = 0; j < total; j++) {
|
||||
fdt_get_mem_rsv(of_flat_tree, j, &addr, &size);
|
||||
if (addr == rd_data_start) {
|
||||
fdt_del_mem_rsv(of_flat_tree, j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ret = fdt_add_mem_rsv(of_flat_tree, initrd_start,
|
||||
initrd_end - initrd_start + 1);
|
||||
if (ret < 0) {
|
||||
printf("fdt_chosen: %s\n", fdt_strerror(ret));
|
||||
goto error;
|
||||
}
|
||||
|
||||
do_fixup_by_path_u32(of_flat_tree, "/chosen",
|
||||
"linux,initrd-start", initrd_start, 0);
|
||||
do_fixup_by_path_u32(of_flat_tree, "/chosen",
|
||||
"linux,initrd-end", initrd_end, 0);
|
||||
}
|
||||
#endif
|
||||
debug ("## Transferring control to Linux (at address %08lx) ...\n",
|
||||
(ulong)kernel);
|
||||
|
||||
show_boot_progress (15);
|
||||
|
||||
#if defined(CFG_INIT_RAM_LOCK) && !defined(CONFIG_E500)
|
||||
unlock_ram_in_cache();
|
||||
#endif
|
||||
if (!images->autostart)
|
||||
return ;
|
||||
|
||||
#if defined(CONFIG_OF_LIBFDT)
|
||||
if (of_flat_tree) { /* device tree; boot new style */
|
||||
/*
|
||||
* Linux Kernel Parameters (passing device tree):
|
||||
* r3: pointer to the fdt, followed by the board info data
|
||||
* r4: physical pointer to the kernel itself
|
||||
* r5: NULL
|
||||
* r6: NULL
|
||||
* r7: NULL
|
||||
*/
|
||||
debug (" Booting using OF flat tree...\n");
|
||||
(*kernel) ((bd_t *)of_flat_tree, (ulong)kernel, 0, 0, 0);
|
||||
/* does not return */
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
/*
|
||||
* Linux Kernel Parameters (passing board info data):
|
||||
* r3: ptr to board info data
|
||||
* r4: initrd_start or 0 if no initrd
|
||||
* r5: initrd_end - unused if r4 is 0
|
||||
* r6: Start of command line string
|
||||
* r7: End of command line string
|
||||
*/
|
||||
debug (" Booting using board info...\n");
|
||||
(*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end);
|
||||
/* does not return */
|
||||
}
|
||||
return ;
|
||||
|
||||
error:
|
||||
if (images->autostart)
|
||||
do_reset (cmdtp, flag, argc, argv);
|
||||
return ;
|
||||
}
|
||||
|
||||
static ulong get_sp (void)
|
||||
{
|
||||
ulong sp;
|
||||
|
||||
asm( "mr %0,1": "=r"(sp) : );
|
||||
return sp;
|
||||
}
|
||||
|
||||
static void set_clocks_in_mhz (bd_t *kbd)
|
||||
{
|
||||
char *s;
|
||||
|
||||
if ((s = getenv ("clocks_in_mhz")) != NULL) {
|
||||
/* convert all clock information to MHz */
|
||||
kbd->bi_intfreq /= 1000000L;
|
||||
kbd->bi_busfreq /= 1000000L;
|
||||
#if defined(CONFIG_MPC8220)
|
||||
kbd->bi_inpfreq /= 1000000L;
|
||||
kbd->bi_pcifreq /= 1000000L;
|
||||
kbd->bi_pevfreq /= 1000000L;
|
||||
kbd->bi_flbfreq /= 1000000L;
|
||||
kbd->bi_vcofreq /= 1000000L;
|
||||
#endif
|
||||
#if defined(CONFIG_CPM2)
|
||||
kbd->bi_cpmfreq /= 1000000L;
|
||||
kbd->bi_brgfreq /= 1000000L;
|
||||
kbd->bi_sccfreq /= 1000000L;
|
||||
kbd->bi_vco /= 1000000L;
|
||||
#endif
|
||||
#if defined(CONFIG_MPC5xxx)
|
||||
kbd->bi_ipbfreq /= 1000000L;
|
||||
kbd->bi_pcifreq /= 1000000L;
|
||||
#endif /* CONFIG_MPC5xxx */
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(CONFIG_OF_LIBFDT)
|
||||
static void fdt_error (const char *msg)
|
||||
{
|
||||
puts ("ERROR: ");
|
||||
puts (msg);
|
||||
puts (" - must RESET the board to recover.\n");
|
||||
}
|
||||
|
||||
static image_header_t *image_get_fdt (ulong fdt_addr)
|
||||
{
|
||||
image_header_t *fdt_hdr = (image_header_t *)fdt_addr;
|
||||
|
||||
image_print_contents (fdt_hdr);
|
||||
|
||||
puts (" Verifying Checksum ... ");
|
||||
if (!image_check_hcrc (fdt_hdr)) {
|
||||
fdt_error ("fdt header checksum invalid");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!image_check_dcrc (fdt_hdr)) {
|
||||
fdt_error ("fdt checksum invalid");
|
||||
return NULL;
|
||||
}
|
||||
puts ("OK\n");
|
||||
|
||||
if (!image_check_type (fdt_hdr, IH_TYPE_FLATDT)) {
|
||||
fdt_error ("uImage is not a fdt");
|
||||
return NULL;
|
||||
}
|
||||
if (image_get_comp (fdt_hdr) != IH_COMP_NONE) {
|
||||
fdt_error ("uImage is compressed");
|
||||
return NULL;
|
||||
}
|
||||
if (fdt_check_header ((char *)image_get_data (fdt_hdr)) != 0) {
|
||||
fdt_error ("uImage data is not a fdt");
|
||||
return NULL;
|
||||
}
|
||||
return fdt_hdr;
|
||||
}
|
||||
|
||||
/**
|
||||
* fit_check_fdt - verify FIT format FDT subimage
|
||||
* @fit_hdr: pointer to the FIT header
|
||||
* fdt_noffset: FDT subimage node offset within FIT image
|
||||
* @verify: data CRC verification flag
|
||||
*
|
||||
* fit_check_fdt() verifies integrity of the FDT subimage and from
|
||||
* specified FIT image.
|
||||
*
|
||||
* returns:
|
||||
* 1, on success
|
||||
* 0, on failure
|
||||
*/
|
||||
#if defined(CONFIG_FIT)
|
||||
static int fit_check_fdt (const void *fit, int fdt_noffset, int verify)
|
||||
{
|
||||
fit_image_print (fit, fdt_noffset, " ");
|
||||
|
||||
if (verify) {
|
||||
puts (" Verifying Hash Integrity ... ");
|
||||
if (!fit_image_check_hashes (fit, fdt_noffset)) {
|
||||
fdt_error ("Bad Data Hash");
|
||||
return 0;
|
||||
}
|
||||
puts ("OK\n");
|
||||
}
|
||||
|
||||
if (!fit_image_check_type (fit, fdt_noffset, IH_TYPE_FLATDT)) {
|
||||
fdt_error ("Not a FDT image");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!fit_image_check_comp (fit, fdt_noffset, IH_COMP_NONE)) {
|
||||
fdt_error ("FDT image is compressed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif /* CONFIG_FIT */
|
||||
|
||||
static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||
bootm_headers_t *images, char **of_flat_tree, ulong *of_size)
|
||||
{
|
||||
ulong fdt_addr;
|
||||
image_header_t *fdt_hdr;
|
||||
char *fdt_blob = NULL;
|
||||
ulong image_start, image_end;
|
||||
ulong load_start, load_end;
|
||||
#if defined(CONFIG_FIT)
|
||||
void *fit_hdr;
|
||||
const char *fit_uname_config = NULL;
|
||||
const char *fit_uname_fdt = NULL;
|
||||
ulong default_addr;
|
||||
int cfg_noffset;
|
||||
int fdt_noffset;
|
||||
const void *data;
|
||||
size_t size;
|
||||
#endif
|
||||
|
||||
*of_flat_tree = NULL;
|
||||
*of_size = 0;
|
||||
|
||||
if (argc > 3 || genimg_has_config (images)) {
|
||||
#if defined(CONFIG_FIT)
|
||||
if (argc > 3) {
|
||||
/*
|
||||
* If the FDT blob comes from the FIT image and the
|
||||
* FIT image address is omitted in the command line
|
||||
* argument, try to use ramdisk or os FIT image
|
||||
* address or default load address.
|
||||
*/
|
||||
if (images->fit_uname_rd)
|
||||
default_addr = (ulong)images->fit_hdr_rd;
|
||||
else if (images->fit_uname_os)
|
||||
default_addr = (ulong)images->fit_hdr_os;
|
||||
else
|
||||
default_addr = load_addr;
|
||||
|
||||
if (fit_parse_conf (argv[3], default_addr,
|
||||
&fdt_addr, &fit_uname_config)) {
|
||||
debug ("* fdt: config '%s' from image at 0x%08lx\n",
|
||||
fit_uname_config, fdt_addr);
|
||||
} else if (fit_parse_subimage (argv[3], default_addr,
|
||||
&fdt_addr, &fit_uname_fdt)) {
|
||||
debug ("* fdt: subimage '%s' from image at 0x%08lx\n",
|
||||
fit_uname_fdt, fdt_addr);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
fdt_addr = simple_strtoul(argv[3], NULL, 16);
|
||||
debug ("* fdt: cmdline image address = 0x%08lx\n",
|
||||
fdt_addr);
|
||||
}
|
||||
#if defined(CONFIG_FIT)
|
||||
} else {
|
||||
/* use FIT configuration provided in first bootm
|
||||
* command argument
|
||||
*/
|
||||
fdt_addr = (ulong)images->fit_hdr_os;
|
||||
fit_uname_config = images->fit_uname_cfg;
|
||||
debug ("* fdt: using config '%s' from image at 0x%08lx\n",
|
||||
fit_uname_config, fdt_addr);
|
||||
|
||||
/*
|
||||
* Check whether configuration has FDT blob defined,
|
||||
* if not quit silently.
|
||||
*/
|
||||
fit_hdr = (void *)fdt_addr;
|
||||
cfg_noffset = fit_conf_get_node (fit_hdr,
|
||||
fit_uname_config);
|
||||
if (cfg_noffset < 0) {
|
||||
debug ("* fdt: no such config\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
fdt_noffset = fit_conf_get_fdt_node (fit_hdr,
|
||||
cfg_noffset);
|
||||
if (fdt_noffset < 0) {
|
||||
debug ("* fdt: no fdt in config\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
debug ("## Checking for 'FDT'/'FDT Image' at %08lx\n",
|
||||
fdt_addr);
|
||||
|
||||
/* copy from dataflash if needed */
|
||||
fdt_addr = genimg_get_image (fdt_addr);
|
||||
|
||||
/*
|
||||
* Check if there is an FDT image at the
|
||||
* address provided in the second bootm argument
|
||||
* check image type, for FIT images get a FIT node.
|
||||
*/
|
||||
switch (genimg_get_format ((void *)fdt_addr)) {
|
||||
case IMAGE_FORMAT_LEGACY:
|
||||
/* verify fdt_addr points to a valid image header */
|
||||
printf ("## Flattened Device Tree from Legacy Image at %08lx\n",
|
||||
fdt_addr);
|
||||
fdt_hdr = image_get_fdt (fdt_addr);
|
||||
if (!fdt_hdr)
|
||||
goto error;
|
||||
|
||||
/*
|
||||
* move image data to the load address,
|
||||
* make sure we don't overwrite initial image
|
||||
*/
|
||||
image_start = (ulong)fdt_hdr;
|
||||
image_end = image_get_image_end (fdt_hdr);
|
||||
|
||||
load_start = image_get_load (fdt_hdr);
|
||||
load_end = load_start + image_get_data_size (fdt_hdr);
|
||||
|
||||
if ((load_start < image_end) && (load_end > image_start)) {
|
||||
fdt_error ("fdt overwritten");
|
||||
goto error;
|
||||
}
|
||||
|
||||
debug (" Loading FDT from 0x%08lx to 0x%08lx\n",
|
||||
image_get_data (fdt_hdr), load_start);
|
||||
|
||||
memmove ((void *)load_start,
|
||||
(void *)image_get_data (fdt_hdr),
|
||||
image_get_data_size (fdt_hdr));
|
||||
|
||||
fdt_blob = (char *)load_start;
|
||||
break;
|
||||
case IMAGE_FORMAT_FIT:
|
||||
/*
|
||||
* This case will catch both: new uImage format
|
||||
* (libfdt based) and raw FDT blob (also libfdt
|
||||
* based).
|
||||
*/
|
||||
#if defined(CONFIG_FIT)
|
||||
/* check FDT blob vs FIT blob */
|
||||
if (fit_check_format ((const void *)fdt_addr)) {
|
||||
/*
|
||||
* FIT image
|
||||
*/
|
||||
fit_hdr = (void *)fdt_addr;
|
||||
printf ("## Flattened Device Tree from FIT Image at %08lx\n",
|
||||
fdt_addr);
|
||||
|
||||
if (!fit_uname_fdt) {
|
||||
/*
|
||||
* no FDT blob image node unit name,
|
||||
* try to get config node first. If
|
||||
* config unit node name is NULL
|
||||
* fit_conf_get_node() will try to
|
||||
* find default config node
|
||||
*/
|
||||
cfg_noffset = fit_conf_get_node (fit_hdr,
|
||||
fit_uname_config);
|
||||
|
||||
if (cfg_noffset < 0) {
|
||||
fdt_error ("Could not find configuration node\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
fit_uname_config = fdt_get_name (fit_hdr,
|
||||
cfg_noffset, NULL);
|
||||
printf (" Using '%s' configuration\n",
|
||||
fit_uname_config);
|
||||
|
||||
fdt_noffset = fit_conf_get_fdt_node (fit_hdr,
|
||||
cfg_noffset);
|
||||
fit_uname_fdt = fit_get_name (fit_hdr,
|
||||
fdt_noffset, NULL);
|
||||
} else {
|
||||
/* get FDT component image node offset */
|
||||
fdt_noffset = fit_image_get_node (fit_hdr,
|
||||
fit_uname_fdt);
|
||||
}
|
||||
if (fdt_noffset < 0) {
|
||||
fdt_error ("Could not find subimage node\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
printf (" Trying '%s' FDT blob subimage\n",
|
||||
fit_uname_fdt);
|
||||
|
||||
if (!fit_check_fdt (fit_hdr, fdt_noffset,
|
||||
images->verify))
|
||||
goto error;
|
||||
|
||||
/* get ramdisk image data address and length */
|
||||
if (fit_image_get_data (fit_hdr, fdt_noffset,
|
||||
&data, &size)) {
|
||||
fdt_error ("Could not find FDT subimage data");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* verift that image data is a proper FDT blob */
|
||||
if (fdt_check_header ((char *)data) != 0) {
|
||||
fdt_error ("Subimage data is not a FTD");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
* move image data to the load address,
|
||||
* make sure we don't overwrite initial image
|
||||
*/
|
||||
image_start = (ulong)fit_hdr;
|
||||
image_end = fit_get_end (fit_hdr);
|
||||
|
||||
if (fit_image_get_load (fit_hdr, fdt_noffset,
|
||||
&load_start) == 0) {
|
||||
load_end = load_start + size;
|
||||
|
||||
if ((load_start < image_end) &&
|
||||
(load_end > image_start)) {
|
||||
fdt_error ("FDT overwritten");
|
||||
goto error;
|
||||
}
|
||||
|
||||
printf (" Loading FDT from 0x%08lx to 0x%08lx\n",
|
||||
(ulong)data, load_start);
|
||||
|
||||
memmove ((void *)load_start,
|
||||
(void *)data, size);
|
||||
|
||||
fdt_blob = (char *)load_start;
|
||||
} else {
|
||||
fdt_blob = (char *)data;
|
||||
}
|
||||
|
||||
images->fit_hdr_fdt = fit_hdr;
|
||||
images->fit_uname_fdt = fit_uname_fdt;
|
||||
images->fit_noffset_fdt = fdt_noffset;
|
||||
break;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
/*
|
||||
* FDT blob
|
||||
*/
|
||||
debug ("* fdt: raw FDT blob\n");
|
||||
printf ("## Flattened Device Tree blob at %08lx\n", fdt_blob);
|
||||
fdt_blob = (char *)fdt_addr;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fdt_error ("Did not find a cmdline Flattened Device Tree");
|
||||
goto error;
|
||||
}
|
||||
|
||||
printf (" Booting using the fdt blob at 0x%x\n", fdt_blob);
|
||||
|
||||
} else if (images->legacy_hdr_valid &&
|
||||
image_check_type (images->legacy_hdr_os, IH_TYPE_MULTI)) {
|
||||
|
||||
ulong fdt_data, fdt_len;
|
||||
|
||||
/*
|
||||
* Now check if we have a legacy multi-component image,
|
||||
* get second entry data start address and len.
|
||||
*/
|
||||
printf ("## Flattened Device Tree from multi "
|
||||
"component Image at %08lX\n",
|
||||
(ulong)images->legacy_hdr_os);
|
||||
|
||||
image_multi_getimg (images->legacy_hdr_os, 2, &fdt_data, &fdt_len);
|
||||
if (fdt_len) {
|
||||
|
||||
fdt_blob = (char *)fdt_data;
|
||||
printf (" Booting using the fdt at 0x%x\n", fdt_blob);
|
||||
|
||||
if (fdt_check_header (fdt_blob) != 0) {
|
||||
fdt_error ("image is not a fdt");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (be32_to_cpu (fdt_totalsize (fdt_blob)) != fdt_len) {
|
||||
fdt_error ("fdt size != image size");
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
fdt_error ("Did not find a Flattened Device Tree "
|
||||
"in a legacy multi-component image");
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
debug ("## No Flattened Device Tree\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
*of_flat_tree = fdt_blob;
|
||||
*of_size = be32_to_cpu (fdt_totalsize (fdt_blob));
|
||||
debug (" of_flat_tree at 0x%08lx size 0x%08lx\n",
|
||||
*of_flat_tree, *of_size);
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
do_reset (cmdtp, flag, argc, argv);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base,
|
||||
cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||
char **of_flat_tree, ulong *of_size)
|
||||
{
|
||||
char *fdt_blob = *of_flat_tree;
|
||||
ulong relocate = 0;
|
||||
ulong of_len = 0;
|
||||
|
||||
/* nothing to do */
|
||||
if (*of_size == 0)
|
||||
return 0;
|
||||
|
||||
if (fdt_check_header (fdt_blob) != 0) {
|
||||
fdt_error ("image is not a fdt");
|
||||
goto error;
|
||||
}
|
||||
|
||||
#ifndef CFG_NO_FLASH
|
||||
/* move the blob if it is in flash (set relocate) */
|
||||
if (addr2info ((ulong)fdt_blob) != NULL)
|
||||
relocate = 1;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The blob must be within CFG_BOOTMAPSZ,
|
||||
* so we flag it to be copied if it is not.
|
||||
*/
|
||||
if (fdt_blob >= (char *)CFG_BOOTMAPSZ)
|
||||
relocate = 1;
|
||||
|
||||
of_len = be32_to_cpu (fdt_totalsize (fdt_blob));
|
||||
|
||||
/* move flattend device tree if needed */
|
||||
if (relocate) {
|
||||
int err;
|
||||
ulong of_start;
|
||||
|
||||
/* position on a 4K boundary before the alloc_current */
|
||||
of_start = lmb_alloc_base(lmb, of_len, 0x1000,
|
||||
(CFG_BOOTMAPSZ + bootmap_base));
|
||||
|
||||
if (of_start == 0) {
|
||||
puts("device tree - allocation error\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n",
|
||||
(ulong)fdt_blob, (ulong)fdt_blob + of_len - 1,
|
||||
of_len, of_len);
|
||||
|
||||
printf (" Loading Device Tree to %08lx, end %08lx ... ",
|
||||
of_start, of_start + of_len - 1);
|
||||
|
||||
err = fdt_open_into (fdt_blob, (void *)of_start, of_len);
|
||||
if (err != 0) {
|
||||
fdt_error ("fdt move failed");
|
||||
goto error;
|
||||
}
|
||||
puts ("OK\n");
|
||||
|
||||
*of_flat_tree = (char *)of_start;
|
||||
} else {
|
||||
*of_flat_tree = fdt_blob;
|
||||
lmb_reserve(lmb, (ulong)fdt, of_len);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
return 1;
|
||||
}
|
||||
#endif
|
@ -22,12 +22,14 @@ include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = $(obj)lib$(ARCH).a
|
||||
|
||||
SOBJS =
|
||||
SOBJS-y +=
|
||||
|
||||
COBJS = board.o sh_linux.o # time.o
|
||||
COBJS-y += board.o
|
||||
COBJS-y += bootm.o
|
||||
#COBJS-y += time.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
|
||||
SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS)
|
||||
$(AR) $(ARFLAGS) $@ $(OBJS)
|
||||
|
@ -25,8 +25,6 @@
|
||||
#include <command.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
extern image_header_t header; /* common/cmd_bootm.c */
|
||||
|
||||
/* The SH kernel reads arguments from the empty zero page at location
|
||||
* 0 at the start of SDRAM. The following are copied from
|
||||
* arch/sh/kernel/setup.c and may require tweaking if the kernel sources
|
||||
@ -45,6 +43,8 @@ extern image_header_t header; /* common/cmd_bootm.c */
|
||||
|
||||
#define RAMDISK_IMAGE_START_MASK 0x07FF
|
||||
|
||||
extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
|
||||
|
||||
#ifdef CFG_DEBUG
|
||||
static void hexdump (unsigned char *buf, int len)
|
||||
{
|
||||
@ -60,15 +60,42 @@ static void hexdump (unsigned char *buf, int len)
|
||||
#endif
|
||||
|
||||
void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||
ulong addr, ulong *len_ptr, int verify)
|
||||
bootm_headers_t *images)
|
||||
{
|
||||
image_header_t *hdr = &header;
|
||||
char *bootargs = getenv("bootargs");
|
||||
void (*kernel) (void) = (void (*)(void)) ntohl (hdr->ih_ep);
|
||||
ulong ep = 0;
|
||||
char *bootargs = getenv("bootargs");
|
||||
|
||||
/* find kernel entry point */
|
||||
if (images->legacy_hdr_valid) {
|
||||
ep = image_get_ep (images->legacy_hdr_os);
|
||||
#if defined(CONFIG_FIT)
|
||||
} else if (images->fit_uname_os) {
|
||||
int ret = fit_image_get_entry (images->fit_hdr_os,
|
||||
images->fit_noffset_os, &ep);
|
||||
if (ret) {
|
||||
puts ("Can't get entry point property!\n");
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
puts ("Could not find kernel entry point!\n");
|
||||
goto error;
|
||||
}
|
||||
void (*kernel) (void) = (void (*)(void))ep;
|
||||
|
||||
if (!images->autostart)
|
||||
return ;
|
||||
|
||||
/* Setup parameters */
|
||||
memset(PARAM, 0, 0x1000); /* Clear zero page */
|
||||
strcpy(COMMAND_LINE, bootargs);
|
||||
|
||||
kernel();
|
||||
/* does not return */
|
||||
return;
|
||||
|
||||
error:
|
||||
if (images->autostart)
|
||||
do_reset (cmdtp, flag, argc, argv);
|
||||
return;
|
||||
}
|
@ -50,8 +50,12 @@
|
||||
*/
|
||||
#include "libfdt_env.h"
|
||||
|
||||
#ifndef USE_HOSTCC
|
||||
#include <fdt.h>
|
||||
#include <libfdt.h>
|
||||
#else
|
||||
#include "fdt_host.h"
|
||||
#endif
|
||||
|
||||
#include "libfdt_internal.h"
|
||||
|
||||
|
@ -50,8 +50,12 @@
|
||||
*/
|
||||
#include "libfdt_env.h"
|
||||
|
||||
#ifndef USE_HOSTCC
|
||||
#include <fdt.h>
|
||||
#include <libfdt.h>
|
||||
#else
|
||||
#include "fdt_host.h"
|
||||
#endif
|
||||
|
||||
#include "libfdt_internal.h"
|
||||
|
||||
|
@ -50,8 +50,12 @@
|
||||
*/
|
||||
#include "libfdt_env.h"
|
||||
|
||||
#ifndef USE_HOSTCC
|
||||
#include <fdt.h>
|
||||
#include <libfdt.h>
|
||||
#else
|
||||
#include "fdt_host.h"
|
||||
#endif
|
||||
|
||||
#include "libfdt_internal.h"
|
||||
|
||||
|
@ -50,8 +50,12 @@
|
||||
*/
|
||||
#include "libfdt_env.h"
|
||||
|
||||
#ifndef USE_HOSTCC
|
||||
#include <fdt.h>
|
||||
#include <libfdt.h>
|
||||
#else
|
||||
#include "fdt_host.h"
|
||||
#endif
|
||||
|
||||
#include "libfdt_internal.h"
|
||||
|
||||
|
@ -50,8 +50,12 @@
|
||||
*/
|
||||
#include "libfdt_env.h"
|
||||
|
||||
#ifndef USE_HOSTCC
|
||||
#include <fdt.h>
|
||||
#include <libfdt.h>
|
||||
#else
|
||||
#include "fdt_host.h"
|
||||
#endif
|
||||
|
||||
#include "libfdt_internal.h"
|
||||
|
||||
|
8
tools/.gitignore
vendored
8
tools/.gitignore
vendored
@ -4,6 +4,14 @@
|
||||
/environment.c
|
||||
/gen_eth_addr
|
||||
/img2srec
|
||||
/md5.c
|
||||
/mkimage
|
||||
/sha1.c
|
||||
/ubsha1
|
||||
/image.c
|
||||
/fdt.c
|
||||
/fdt_ro.c
|
||||
/fdt_rw.c
|
||||
/fdt_strerror.c
|
||||
/fdt_wip.c
|
||||
/libfdt_internal.h
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
BIN_FILES = img2srec$(SFX) mkimage$(SFX) envcrc$(SFX) ubsha1$(SFX) gen_eth_addr$(SFX) bmp_logo$(SFX)
|
||||
|
||||
OBJ_LINKS = environment.o crc32.o sha1.o
|
||||
OBJ_LINKS = environment.o crc32.o md5.o sha1.o image.o
|
||||
OBJ_FILES = img2srec.o mkimage.o envcrc.o ubsha1.o gen_eth_addr.o bmp_logo.o
|
||||
|
||||
ifeq ($(ARCH),mips)
|
||||
@ -37,6 +37,8 @@ endif
|
||||
#OBJ_FILES += mpc86x_clk.o
|
||||
#endif
|
||||
|
||||
LIBFDT_OBJ_FILES = fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_wip.o
|
||||
|
||||
LOGO_H = $(OBJTREE)/include/bmp_logo.h
|
||||
|
||||
ifeq ($(LOGO_BMP),)
|
||||
@ -120,6 +122,10 @@ CPPFLAGS = -idirafter $(SRCTREE)/include \
|
||||
-idirafter $(OBJTREE)/include \
|
||||
-DTEXT_BASE=$(TEXT_BASE) -DUSE_HOSTCC
|
||||
CFLAGS = $(HOST_CFLAGS) $(CPPFLAGS) -O
|
||||
|
||||
# No -pedantic switch to avoid libfdt compilation warnings
|
||||
FIT_CFLAGS = -Wall $(CPPFLAGS) -O
|
||||
|
||||
AFLAGS = -D__ASSEMBLY__ $(CPPFLAGS)
|
||||
CC = $(HOSTCC)
|
||||
STRIP = $(HOSTSTRIP)
|
||||
@ -137,7 +143,7 @@ $(obj)img2srec$(SFX): $(obj)img2srec.o
|
||||
$(CC) $(CFLAGS) $(HOST_LDFLAGS) -o $@ $^
|
||||
$(STRIP) $@
|
||||
|
||||
$(obj)mkimage$(SFX): $(obj)mkimage.o $(obj)crc32.o
|
||||
$(obj)mkimage$(SFX): $(obj)mkimage.o $(obj)crc32.o $(obj)image.o $(obj)md5.o $(obj)sha1.o $(LIBFDT_OBJ_FILES)
|
||||
$(CC) $(CFLAGS) $(HOST_LDFLAGS) -o $@ $^
|
||||
$(STRIP) $@
|
||||
|
||||
@ -170,11 +176,17 @@ $(obj)ubsha1.o: $(src)ubsha1.c
|
||||
$(obj)crc32.o: $(obj)crc32.c
|
||||
$(CC) -g $(CFLAGS) -c -o $@ $<
|
||||
|
||||
$(obj)md5.o: $(obj)md5.c
|
||||
$(CC) -g $(CFLAGS) -c -o $@ $<
|
||||
|
||||
$(obj)sha1.o: $(obj)sha1.c
|
||||
$(CC) -g $(CFLAGS) -c -o $@ $<
|
||||
|
||||
$(obj)image.o: $(obj)image.c
|
||||
$(CC) -g $(FIT_CFLAGS) -c -o $@ $<
|
||||
|
||||
$(obj)mkimage.o: $(src)mkimage.c
|
||||
$(CC) -g $(CFLAGS) -c -o $@ $<
|
||||
$(CC) -g $(FIT_CFLAGS) -c -o $@ $<
|
||||
|
||||
$(obj)ncb.o: $(src)ncb.c
|
||||
$(CC) -g $(CFLAGS) -c -o $@ $<
|
||||
@ -188,6 +200,21 @@ $(obj)inca-swap-bytes.o: $(src)inca-swap-bytes.c
|
||||
$(obj)mpc86x_clk.o: $(src)mpc86x_clk.c
|
||||
$(CC) -g $(CFLAGS) -c -o $@ $<
|
||||
|
||||
$(obj)fdt.o: $(obj)fdt.c
|
||||
$(CC) -g $(FIT_CFLAGS) -c -o $@ $<
|
||||
|
||||
$(obj)fdt_ro.o: $(obj)fdt_ro.c
|
||||
$(CC) -g $(FIT_CFLAGS) -c -o $@ $<
|
||||
|
||||
$(obj)fdt_rw.o: $(obj)fdt_rw.c
|
||||
$(CC) -g $(FIT_CFLAGS) -c -o $@ $<
|
||||
|
||||
$(obj)fdt_strerror.o: $(obj)fdt_strerror.c
|
||||
$(CC) -g $(FIT_CFLAGS) -c -o $@ $<
|
||||
|
||||
$(obj)fdt_wip.o: $(obj)fdt_wip.c
|
||||
$(CC) -g $(FIT_CFLAGS) -c -o $@ $<
|
||||
|
||||
subdirs:
|
||||
ifeq ($(TOOLSUBDIRS),)
|
||||
@:
|
||||
@ -213,10 +240,42 @@ $(obj)crc32.c:
|
||||
@rm -f $(obj)crc32.c
|
||||
ln -s $(src)../lib_generic/crc32.c $(obj)crc32.c
|
||||
|
||||
$(obj)md5.c:
|
||||
@rm -f $(obj)md5.c
|
||||
ln -s $(src)../lib_generic/md5.c $(obj)md5.c
|
||||
|
||||
$(obj)sha1.c:
|
||||
@rm -f $(obj)sha1.c
|
||||
ln -s $(src)../lib_generic/sha1.c $(obj)sha1.c
|
||||
|
||||
$(obj)image.c:
|
||||
@rm -f $(obj)image.c
|
||||
ln -s $(src)../common/image.c $(obj)image.c
|
||||
|
||||
$(obj)fdt.c: libfdt_internal.h
|
||||
@rm -f $(obj)fdt.c
|
||||
ln -s $(src)../libfdt/fdt.c $(obj)fdt.c
|
||||
|
||||
$(obj)fdt_ro.c: libfdt_internal.h
|
||||
@rm -f $(obj)fdt_ro.c
|
||||
ln -s $(src)../libfdt/fdt_ro.c $(obj)fdt_ro.c
|
||||
|
||||
$(obj)fdt_rw.c: libfdt_internal.h
|
||||
@rm -f $(obj)fdt_rw.c
|
||||
ln -s $(src)../libfdt/fdt_rw.c $(obj)fdt_rw.c
|
||||
|
||||
$(obj)fdt_strerror.c: libfdt_internal.h
|
||||
@rm -f $(obj)fdt_strerror.c
|
||||
ln -s $(src)../libfdt/fdt_strerror.c $(obj)fdt_strerror.c
|
||||
|
||||
$(obj)fdt_wip.c: libfdt_internal.h
|
||||
@rm -f $(obj)fdt_wip.c
|
||||
ln -s $(src)../libfdt/fdt_wip.c $(obj)fdt_wip.c
|
||||
|
||||
$(obj)libfdt_internal.h:
|
||||
@rm -f $(obj)libfdt_internal.h
|
||||
ln -s $(src)../libfdt/libfdt_internal.h $(obj)libfdt_internal.h
|
||||
|
||||
$(LOGO_H): $(obj)bmp_logo $(LOGO_BMP)
|
||||
$(obj)./bmp_logo $(LOGO_BMP) >$@
|
||||
|
||||
|
28
tools/fdt_host.h
Normal file
28
tools/fdt_host.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* (C) Copyright 2008 Semihalf
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __FDT_HOST_H__
|
||||
#define __FDT_HOST_H__
|
||||
|
||||
/* Make sure to include u-boot version of libfdt include files */
|
||||
#include "../include/fdt.h"
|
||||
#include "../include/libfdt.h"
|
||||
#include "../include/fdt_support.h"
|
||||
|
||||
#endif /* __FDT_HOST_H__ */
|
557
tools/mkimage.c
557
tools/mkimage.c
@ -1,4 +1,6 @@
|
||||
/*
|
||||
* (C) Copyright 2008 Semihalf
|
||||
*
|
||||
* (C) Copyright 2000-2004
|
||||
* DENX Software Engineering
|
||||
* Wolfgang Denk, wd@denx.de
|
||||
@ -20,44 +22,7 @@
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifndef __WIN32__
|
||||
#include <netinet/in.h> /* for host / network byte order conversions */
|
||||
#endif
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if defined(__BEOS__) || defined(__NetBSD__) || defined(__APPLE__)
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#ifdef __WIN32__
|
||||
typedef unsigned int __u32;
|
||||
|
||||
#define SWAP_LONG(x) \
|
||||
((__u32)( \
|
||||
(((__u32)(x) & (__u32)0x000000ffUL) << 24) | \
|
||||
(((__u32)(x) & (__u32)0x0000ff00UL) << 8) | \
|
||||
(((__u32)(x) & (__u32)0x00ff0000UL) >> 8) | \
|
||||
(((__u32)(x) & (__u32)0xff000000UL) >> 24) ))
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
|
||||
#define ntohl(a) SWAP_LONG(a)
|
||||
#define htonl(a) SWAP_LONG(a)
|
||||
#endif /* __WIN32__ */
|
||||
|
||||
#ifndef O_BINARY /* should be define'd on __WIN32__ */
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
#include "mkimage.h"
|
||||
#include <image.h>
|
||||
|
||||
extern int errno;
|
||||
@ -66,110 +31,27 @@ extern int errno;
|
||||
#define MAP_FAILED (-1)
|
||||
#endif
|
||||
|
||||
char *cmdname;
|
||||
|
||||
extern unsigned long crc32 (unsigned long crc, const char *buf, unsigned int len);
|
||||
|
||||
typedef struct table_entry {
|
||||
int val; /* as defined in image.h */
|
||||
char *sname; /* short (input) name */
|
||||
char *lname; /* long (output) name */
|
||||
} table_entry_t;
|
||||
|
||||
table_entry_t arch_name[] = {
|
||||
{ IH_CPU_INVALID, NULL, "Invalid CPU", },
|
||||
{ IH_CPU_ALPHA, "alpha", "Alpha", },
|
||||
{ IH_CPU_ARM, "arm", "ARM", },
|
||||
{ IH_CPU_I386, "x86", "Intel x86", },
|
||||
{ IH_CPU_IA64, "ia64", "IA64", },
|
||||
{ IH_CPU_M68K, "m68k", "MC68000", },
|
||||
{ IH_CPU_MICROBLAZE, "microblaze", "MicroBlaze", },
|
||||
{ IH_CPU_MIPS, "mips", "MIPS", },
|
||||
{ IH_CPU_MIPS64, "mips64", "MIPS 64 Bit", },
|
||||
{ IH_CPU_NIOS, "nios", "NIOS", },
|
||||
{ IH_CPU_NIOS2, "nios2", "NIOS II", },
|
||||
{ IH_CPU_PPC, "ppc", "PowerPC", },
|
||||
{ IH_CPU_S390, "s390", "IBM S390", },
|
||||
{ IH_CPU_SH, "sh", "SuperH", },
|
||||
{ IH_CPU_SPARC, "sparc", "SPARC", },
|
||||
{ IH_CPU_SPARC64, "sparc64", "SPARC 64 Bit", },
|
||||
{ IH_CPU_BLACKFIN, "blackfin", "Blackfin", },
|
||||
{ IH_CPU_AVR32, "avr32", "AVR32", },
|
||||
{ -1, "", "", },
|
||||
};
|
||||
|
||||
table_entry_t os_name[] = {
|
||||
{ IH_OS_INVALID, NULL, "Invalid OS", },
|
||||
{ IH_OS_4_4BSD, "4_4bsd", "4_4BSD", },
|
||||
{ IH_OS_ARTOS, "artos", "ARTOS", },
|
||||
{ IH_OS_DELL, "dell", "Dell", },
|
||||
{ IH_OS_ESIX, "esix", "Esix", },
|
||||
{ IH_OS_FREEBSD, "freebsd", "FreeBSD", },
|
||||
{ IH_OS_IRIX, "irix", "Irix", },
|
||||
{ IH_OS_LINUX, "linux", "Linux", },
|
||||
{ IH_OS_LYNXOS, "lynxos", "LynxOS", },
|
||||
{ IH_OS_NCR, "ncr", "NCR", },
|
||||
{ IH_OS_NETBSD, "netbsd", "NetBSD", },
|
||||
{ IH_OS_OPENBSD, "openbsd", "OpenBSD", },
|
||||
{ IH_OS_PSOS, "psos", "pSOS", },
|
||||
{ IH_OS_QNX, "qnx", "QNX", },
|
||||
{ IH_OS_RTEMS, "rtems", "RTEMS", },
|
||||
{ IH_OS_SCO, "sco", "SCO", },
|
||||
{ IH_OS_SOLARIS, "solaris", "Solaris", },
|
||||
{ IH_OS_SVR4, "svr4", "SVR4", },
|
||||
{ IH_OS_U_BOOT, "u-boot", "U-Boot", },
|
||||
{ IH_OS_VXWORKS, "vxworks", "VxWorks", },
|
||||
{ -1, "", "", },
|
||||
};
|
||||
|
||||
table_entry_t type_name[] = {
|
||||
{ IH_TYPE_INVALID, NULL, "Invalid Image", },
|
||||
{ IH_TYPE_FILESYSTEM, "filesystem", "Filesystem Image", },
|
||||
{ IH_TYPE_FIRMWARE, "firmware", "Firmware", },
|
||||
{ IH_TYPE_KERNEL, "kernel", "Kernel Image", },
|
||||
{ IH_TYPE_MULTI, "multi", "Multi-File Image", },
|
||||
{ IH_TYPE_RAMDISK, "ramdisk", "RAMDisk Image", },
|
||||
{ IH_TYPE_SCRIPT, "script", "Script", },
|
||||
{ IH_TYPE_STANDALONE, "standalone", "Standalone Program", },
|
||||
{ IH_TYPE_FLATDT, "flat_dt", "Flat Device Tree", },
|
||||
{ -1, "", "", },
|
||||
};
|
||||
|
||||
table_entry_t comp_name[] = {
|
||||
{ IH_COMP_NONE, "none", "uncompressed", },
|
||||
{ IH_COMP_BZIP2, "bzip2", "bzip2 compressed", },
|
||||
{ IH_COMP_GZIP, "gzip", "gzip compressed", },
|
||||
{ -1, "", "", },
|
||||
};
|
||||
|
||||
static void copy_file (int, const char *, int);
|
||||
static void usage (void);
|
||||
static void print_header (image_header_t *);
|
||||
static void print_type (image_header_t *);
|
||||
static char *put_table_entry (table_entry_t *, char *, int);
|
||||
static char *put_arch (int);
|
||||
static char *put_type (int);
|
||||
static char *put_os (int);
|
||||
static char *put_comp (int);
|
||||
static int get_table_entry (table_entry_t *, char *, char *);
|
||||
static int get_arch(char *);
|
||||
static int get_comp(char *);
|
||||
static int get_os (char *);
|
||||
static int get_type(char *);
|
||||
|
||||
extern unsigned long crc32 (unsigned long crc, const char *buf, unsigned int len);
|
||||
static void copy_file (int, const char *, int);
|
||||
static void usage (void);
|
||||
static void image_verify_header (char *, int);
|
||||
static void fit_handle_file (void);
|
||||
|
||||
char *datafile;
|
||||
char *imagefile;
|
||||
char *cmdname;
|
||||
|
||||
int dflag = 0;
|
||||
int eflag = 0;
|
||||
int fflag = 0;
|
||||
int lflag = 0;
|
||||
int vflag = 0;
|
||||
int xflag = 0;
|
||||
int opt_os = IH_OS_LINUX;
|
||||
int opt_arch = IH_CPU_PPC;
|
||||
int opt_arch = IH_ARCH_PPC;
|
||||
int opt_type = IH_TYPE_KERNEL;
|
||||
int opt_comp = IH_COMP_GZIP;
|
||||
char *opt_dtc = MKIMAGE_DEFAULT_DTC_OPTIONS;
|
||||
|
||||
image_header_t header;
|
||||
image_header_t *hdr = &header;
|
||||
@ -177,7 +59,7 @@ image_header_t *hdr = &header;
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int ifd;
|
||||
int ifd = -1;
|
||||
uint32_t checksum;
|
||||
uint32_t addr;
|
||||
uint32_t ep;
|
||||
@ -197,22 +79,28 @@ main (int argc, char **argv)
|
||||
break;
|
||||
case 'A':
|
||||
if ((--argc <= 0) ||
|
||||
(opt_arch = get_arch(*++argv)) < 0)
|
||||
(opt_arch = genimg_get_arch_id (*++argv)) < 0)
|
||||
usage ();
|
||||
goto NXTARG;
|
||||
case 'C':
|
||||
if ((--argc <= 0) ||
|
||||
(opt_comp = get_comp(*++argv)) < 0)
|
||||
(opt_comp = genimg_get_comp_id (*++argv)) < 0)
|
||||
usage ();
|
||||
goto NXTARG;
|
||||
case 'D':
|
||||
if (--argc <= 0)
|
||||
usage ();
|
||||
opt_dtc = *++argv;
|
||||
goto NXTARG;
|
||||
|
||||
case 'O':
|
||||
if ((--argc <= 0) ||
|
||||
(opt_os = get_os(*++argv)) < 0)
|
||||
(opt_os = genimg_get_os_id (*++argv)) < 0)
|
||||
usage ();
|
||||
goto NXTARG;
|
||||
case 'T':
|
||||
if ((--argc <= 0) ||
|
||||
(opt_type = get_type(*++argv)) < 0)
|
||||
(opt_type = genimg_get_type_id (*++argv)) < 0)
|
||||
usage ();
|
||||
goto NXTARG;
|
||||
|
||||
@ -245,6 +133,12 @@ main (int argc, char **argv)
|
||||
}
|
||||
eflag = 1;
|
||||
goto NXTARG;
|
||||
case 'f':
|
||||
if (--argc <= 0)
|
||||
usage ();
|
||||
datafile = *++argv;
|
||||
fflag = 1;
|
||||
goto NXTARG;
|
||||
case 'n':
|
||||
if (--argc <= 0)
|
||||
usage ();
|
||||
@ -263,14 +157,17 @@ main (int argc, char **argv)
|
||||
NXTARG: ;
|
||||
}
|
||||
|
||||
if ((argc != 1) || ((lflag ^ dflag) == 0))
|
||||
if ((argc != 1) ||
|
||||
(dflag && (fflag || lflag)) ||
|
||||
(fflag && (dflag || lflag)) ||
|
||||
(lflag && (dflag || fflag)))
|
||||
usage();
|
||||
|
||||
if (!eflag) {
|
||||
ep = addr;
|
||||
/* If XIP, entry point must be after the U-Boot header */
|
||||
if (xflag)
|
||||
ep += sizeof(image_header_t);
|
||||
ep += image_get_header_size ();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -278,32 +175,33 @@ NXTARG: ;
|
||||
* the size of the U-Boot header.
|
||||
*/
|
||||
if (xflag) {
|
||||
if (ep != addr + sizeof(image_header_t)) {
|
||||
if (ep != addr + image_get_header_size ()) {
|
||||
fprintf (stderr,
|
||||
"%s: For XIP, the entry point must be the load addr + %lu\n",
|
||||
cmdname,
|
||||
(unsigned long)sizeof(image_header_t));
|
||||
(unsigned long)image_get_header_size ());
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
imagefile = *argv;
|
||||
|
||||
if (lflag) {
|
||||
ifd = open(imagefile, O_RDONLY|O_BINARY);
|
||||
} else {
|
||||
ifd = open(imagefile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0666);
|
||||
}
|
||||
if (!fflag){
|
||||
if (lflag) {
|
||||
ifd = open (imagefile, O_RDONLY|O_BINARY);
|
||||
} else {
|
||||
ifd = open (imagefile,
|
||||
O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0666);
|
||||
}
|
||||
|
||||
if (ifd < 0) {
|
||||
fprintf (stderr, "%s: Can't open %s: %s\n",
|
||||
cmdname, imagefile, strerror(errno));
|
||||
exit (EXIT_FAILURE);
|
||||
if (ifd < 0) {
|
||||
fprintf (stderr, "%s: Can't open %s: %s\n",
|
||||
cmdname, imagefile, strerror(errno));
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (lflag) {
|
||||
int len;
|
||||
char *data;
|
||||
/*
|
||||
* list header information of existing image
|
||||
*/
|
||||
@ -313,7 +211,7 @@ NXTARG: ;
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if ((unsigned)sbuf.st_size < sizeof(image_header_t)) {
|
||||
if ((unsigned)sbuf.st_size < image_get_header_size ()) {
|
||||
fprintf (stderr,
|
||||
"%s: Bad size: \"%s\" is no valid image\n",
|
||||
cmdname, imagefile);
|
||||
@ -328,49 +226,23 @@ NXTARG: ;
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/*
|
||||
* create copy of header so that we can blank out the
|
||||
* checksum field for checking - this can't be done
|
||||
* on the PROT_READ mapped data.
|
||||
*/
|
||||
memcpy (hdr, ptr, sizeof(image_header_t));
|
||||
|
||||
if (ntohl(hdr->ih_magic) != IH_MAGIC) {
|
||||
fprintf (stderr,
|
||||
"%s: Bad Magic Number: \"%s\" is no valid image\n",
|
||||
cmdname, imagefile);
|
||||
exit (EXIT_FAILURE);
|
||||
if (fdt_check_header (ptr)) {
|
||||
/* old-style image */
|
||||
image_verify_header ((char *)ptr, sbuf.st_size);
|
||||
image_print_contents_noindent ((image_header_t *)ptr);
|
||||
} else {
|
||||
/* FIT image */
|
||||
fit_print_contents_noindent (ptr);
|
||||
}
|
||||
|
||||
data = (char *)hdr;
|
||||
len = sizeof(image_header_t);
|
||||
|
||||
checksum = ntohl(hdr->ih_hcrc);
|
||||
hdr->ih_hcrc = htonl(0); /* clear for re-calculation */
|
||||
|
||||
if (crc32 (0, data, len) != checksum) {
|
||||
fprintf (stderr,
|
||||
"%s: ERROR: \"%s\" has bad header checksum!\n",
|
||||
cmdname, imagefile);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
data = (char *)(ptr + sizeof(image_header_t));
|
||||
len = sbuf.st_size - sizeof(image_header_t) ;
|
||||
|
||||
if (crc32 (0, data, len) != ntohl(hdr->ih_dcrc)) {
|
||||
fprintf (stderr,
|
||||
"%s: ERROR: \"%s\" has corrupted data!\n",
|
||||
cmdname, imagefile);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* for multi-file images we need the data part, too */
|
||||
print_header ((image_header_t *)ptr);
|
||||
|
||||
(void) munmap((void *)ptr, sbuf.st_size);
|
||||
(void) close (ifd);
|
||||
|
||||
exit (EXIT_SUCCESS);
|
||||
} else if (fflag) {
|
||||
/* Flattened Image Tree (FIT) format handling */
|
||||
debug ("FIT format handling\n");
|
||||
fit_handle_file ();
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
@ -379,9 +251,9 @@ NXTARG: ;
|
||||
*
|
||||
* write dummy header, to be fixed later
|
||||
*/
|
||||
memset (hdr, 0, sizeof(image_header_t));
|
||||
memset (hdr, 0, image_get_header_size ());
|
||||
|
||||
if (write(ifd, hdr, sizeof(image_header_t)) != sizeof(image_header_t)) {
|
||||
if (write(ifd, hdr, image_get_header_size ()) != image_get_header_size ()) {
|
||||
fprintf (stderr, "%s: Write error on %s: %s\n",
|
||||
cmdname, imagefile, strerror(errno));
|
||||
exit (EXIT_FAILURE);
|
||||
@ -404,7 +276,7 @@ NXTARG: ;
|
||||
cmdname, file, strerror(errno));
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
size = htonl(sbuf.st_size);
|
||||
size = cpu_to_uimage (sbuf.st_size);
|
||||
} else {
|
||||
size = 0;
|
||||
}
|
||||
@ -469,29 +341,29 @@ NXTARG: ;
|
||||
hdr = (image_header_t *)ptr;
|
||||
|
||||
checksum = crc32 (0,
|
||||
(const char *)(ptr + sizeof(image_header_t)),
|
||||
sbuf.st_size - sizeof(image_header_t)
|
||||
(const char *)(ptr + image_get_header_size ()),
|
||||
sbuf.st_size - image_get_header_size ()
|
||||
);
|
||||
|
||||
/* Build new header */
|
||||
hdr->ih_magic = htonl(IH_MAGIC);
|
||||
hdr->ih_time = htonl(sbuf.st_mtime);
|
||||
hdr->ih_size = htonl(sbuf.st_size - sizeof(image_header_t));
|
||||
hdr->ih_load = htonl(addr);
|
||||
hdr->ih_ep = htonl(ep);
|
||||
hdr->ih_dcrc = htonl(checksum);
|
||||
hdr->ih_os = opt_os;
|
||||
hdr->ih_arch = opt_arch;
|
||||
hdr->ih_type = opt_type;
|
||||
hdr->ih_comp = opt_comp;
|
||||
image_set_magic (hdr, IH_MAGIC);
|
||||
image_set_time (hdr, sbuf.st_mtime);
|
||||
image_set_size (hdr, sbuf.st_size - image_get_header_size ());
|
||||
image_set_load (hdr, addr);
|
||||
image_set_ep (hdr, ep);
|
||||
image_set_dcrc (hdr, checksum);
|
||||
image_set_os (hdr, opt_os);
|
||||
image_set_arch (hdr, opt_arch);
|
||||
image_set_type (hdr, opt_type);
|
||||
image_set_comp (hdr, opt_comp);
|
||||
|
||||
strncpy((char *)hdr->ih_name, name, IH_NMLEN);
|
||||
image_set_name (hdr, name);
|
||||
|
||||
checksum = crc32(0,(const char *)hdr,sizeof(image_header_t));
|
||||
checksum = crc32 (0, (const char *)hdr, image_get_header_size ());
|
||||
|
||||
hdr->ih_hcrc = htonl(checksum);
|
||||
image_set_hcrc (hdr, checksum);
|
||||
|
||||
print_header (hdr);
|
||||
image_print_contents_noindent (hdr);
|
||||
|
||||
(void) munmap((void *)ptr, sbuf.st_size);
|
||||
|
||||
@ -554,14 +426,14 @@ copy_file (int ifd, const char *datafile, int pad)
|
||||
* reserved for it.
|
||||
*/
|
||||
|
||||
if ((unsigned)sbuf.st_size < sizeof(image_header_t)) {
|
||||
if ((unsigned)sbuf.st_size < image_get_header_size ()) {
|
||||
fprintf (stderr,
|
||||
"%s: Bad size: \"%s\" is too small for XIP\n",
|
||||
cmdname, datafile);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
for (p=ptr; p < ptr+sizeof(image_header_t); p++) {
|
||||
for (p = ptr; p < ptr + image_get_header_size (); p++) {
|
||||
if ( *p != 0xff ) {
|
||||
fprintf (stderr,
|
||||
"%s: Bad file: \"%s\" has invalid buffer for XIP\n",
|
||||
@ -570,7 +442,7 @@ copy_file (int ifd, const char *datafile, int pad)
|
||||
}
|
||||
}
|
||||
|
||||
offset = sizeof(image_header_t);
|
||||
offset = image_get_header_size ();
|
||||
}
|
||||
|
||||
size = sbuf.st_size - offset;
|
||||
@ -597,11 +469,11 @@ void
|
||||
usage ()
|
||||
{
|
||||
fprintf (stderr, "Usage: %s -l image\n"
|
||||
" -l ==> list image header information\n"
|
||||
" %s [-x] -A arch -O os -T type -C comp "
|
||||
"-a addr -e ep -n name -d data_file[:data_file...] image\n",
|
||||
cmdname, cmdname);
|
||||
fprintf (stderr, " -A ==> set architecture to 'arch'\n"
|
||||
" -l ==> list image header information\n",
|
||||
cmdname);
|
||||
fprintf (stderr, " %s [-x] -A arch -O os -T type -C comp "
|
||||
"-a addr -e ep -n name -d data_file[:data_file...] image\n"
|
||||
" -A ==> set architecture to 'arch'\n"
|
||||
" -O ==> set operating system to 'os'\n"
|
||||
" -T ==> set image type to 'type'\n"
|
||||
" -C ==> set compression type 'comp'\n"
|
||||
@ -609,143 +481,158 @@ usage ()
|
||||
" -e ==> set entry point to 'ep' (hex)\n"
|
||||
" -n ==> set image name to 'name'\n"
|
||||
" -d ==> use image data from 'datafile'\n"
|
||||
" -x ==> set XIP (execute in place)\n"
|
||||
);
|
||||
" -x ==> set XIP (execute in place)\n",
|
||||
cmdname);
|
||||
fprintf (stderr, " %s [-D dtc_options] -f fit-image.its fit-image\n",
|
||||
cmdname);
|
||||
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static void
|
||||
print_header (image_header_t *hdr)
|
||||
image_verify_header (char *ptr, int image_size)
|
||||
{
|
||||
time_t timestamp;
|
||||
uint32_t size;
|
||||
int len;
|
||||
char *data;
|
||||
uint32_t checksum;
|
||||
image_header_t header;
|
||||
image_header_t *hdr = &header;
|
||||
|
||||
timestamp = (time_t)ntohl(hdr->ih_time);
|
||||
size = ntohl(hdr->ih_size);
|
||||
/*
|
||||
* create copy of header so that we can blank out the
|
||||
* checksum field for checking - this can't be done
|
||||
* on the PROT_READ mapped data.
|
||||
*/
|
||||
memcpy (hdr, ptr, sizeof(image_header_t));
|
||||
|
||||
printf ("Image Name: %.*s\n", IH_NMLEN, hdr->ih_name);
|
||||
printf ("Created: %s", ctime(×tamp));
|
||||
printf ("Image Type: "); print_type(hdr);
|
||||
printf ("Data Size: %d Bytes = %.2f kB = %.2f MB\n",
|
||||
size, (double)size / 1.024e3, (double)size / 1.048576e6 );
|
||||
printf ("Load Address: 0x%08X\n", ntohl(hdr->ih_load));
|
||||
printf ("Entry Point: 0x%08X\n", ntohl(hdr->ih_ep));
|
||||
if (ntohl(hdr->ih_magic) != IH_MAGIC) {
|
||||
fprintf (stderr,
|
||||
"%s: Bad Magic Number: \"%s\" is no valid image\n",
|
||||
cmdname, imagefile);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (hdr->ih_type == IH_TYPE_MULTI || hdr->ih_type == IH_TYPE_SCRIPT) {
|
||||
int i, ptrs;
|
||||
uint32_t pos;
|
||||
uint32_t *len_ptr = (uint32_t *) (
|
||||
(unsigned long)hdr + sizeof(image_header_t)
|
||||
);
|
||||
data = (char *)hdr;
|
||||
len = sizeof(image_header_t);
|
||||
|
||||
/* determine number of images first (to calculate image offsets) */
|
||||
for (i=0; len_ptr[i]; ++i) /* null pointer terminates list */
|
||||
;
|
||||
ptrs = i; /* null pointer terminates list */
|
||||
checksum = ntohl(hdr->ih_hcrc);
|
||||
hdr->ih_hcrc = htonl(0); /* clear for re-calculation */
|
||||
|
||||
pos = sizeof(image_header_t) + ptrs * sizeof(long);
|
||||
printf ("Contents:\n");
|
||||
for (i=0; len_ptr[i]; ++i) {
|
||||
size = ntohl(len_ptr[i]);
|
||||
if (crc32 (0, data, len) != checksum) {
|
||||
fprintf (stderr,
|
||||
"%s: ERROR: \"%s\" has bad header checksum!\n",
|
||||
cmdname, imagefile);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
printf (" Image %d: %8d Bytes = %4d kB = %d MB\n",
|
||||
i, size, size>>10, size>>20);
|
||||
if (hdr->ih_type == IH_TYPE_SCRIPT && i > 0) {
|
||||
/*
|
||||
* the user may need to know offsets
|
||||
* if planning to do something with
|
||||
* multiple files
|
||||
*/
|
||||
printf (" Offset = %08X\n", pos);
|
||||
}
|
||||
/* copy_file() will pad the first files to even word align */
|
||||
size += 3;
|
||||
size &= ~3;
|
||||
pos += size;
|
||||
}
|
||||
data = ptr + sizeof(image_header_t);
|
||||
len = image_size - sizeof(image_header_t) ;
|
||||
|
||||
if (crc32 (0, data, len) != ntohl(hdr->ih_dcrc)) {
|
||||
fprintf (stderr,
|
||||
"%s: ERROR: \"%s\" has corrupted data!\n",
|
||||
cmdname, imagefile);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_type (image_header_t *hdr)
|
||||
/**
|
||||
* fit_handle_file - main FIT file processing function
|
||||
*
|
||||
* fit_handle_file() runs dtc to convert .its to .itb, includes
|
||||
* binary data, updates timestamp property and calculates hashes.
|
||||
*
|
||||
* datafile - .its file
|
||||
* imagefile - .itb file
|
||||
*
|
||||
* returns:
|
||||
* only on success, otherwise calls exit (EXIT_FAILURE);
|
||||
*/
|
||||
static void fit_handle_file (void)
|
||||
{
|
||||
printf ("%s %s %s (%s)\n",
|
||||
put_arch (hdr->ih_arch),
|
||||
put_os (hdr->ih_os ),
|
||||
put_type (hdr->ih_type),
|
||||
put_comp (hdr->ih_comp)
|
||||
);
|
||||
}
|
||||
char tmpfile[MKIMAGE_MAX_TMPFILE_LEN];
|
||||
char cmd[MKIMAGE_MAX_DTC_CMDLINE_LEN];
|
||||
int tfd;
|
||||
struct stat sbuf;
|
||||
unsigned char *ptr;
|
||||
|
||||
static char *put_arch (int arch)
|
||||
{
|
||||
return (put_table_entry(arch_name, "Unknown Architecture", arch));
|
||||
}
|
||||
|
||||
static char *put_os (int os)
|
||||
{
|
||||
return (put_table_entry(os_name, "Unknown OS", os));
|
||||
}
|
||||
|
||||
static char *put_type (int type)
|
||||
{
|
||||
return (put_table_entry(type_name, "Unknown Image", type));
|
||||
}
|
||||
|
||||
static char *put_comp (int comp)
|
||||
{
|
||||
return (put_table_entry(comp_name, "Unknown Compression", comp));
|
||||
}
|
||||
|
||||
static char *put_table_entry (table_entry_t *table, char *msg, int type)
|
||||
{
|
||||
for (; table->val>=0; ++table) {
|
||||
if (table->val == type)
|
||||
return (table->lname);
|
||||
/* call dtc to include binary properties into the tmp file */
|
||||
if (strlen (imagefile) + strlen (MKIMAGE_TMPFILE_SUFFIX) + 1 >
|
||||
sizeof (tmpfile)) {
|
||||
fprintf (stderr, "%s: Image file name (%s) too long, "
|
||||
"can't create tmpfile",
|
||||
imagefile, cmdname);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
return (msg);
|
||||
}
|
||||
sprintf (tmpfile, "%s%s", imagefile, MKIMAGE_TMPFILE_SUFFIX);
|
||||
|
||||
static int get_arch(char *name)
|
||||
{
|
||||
return (get_table_entry(arch_name, "CPU", name));
|
||||
}
|
||||
|
||||
|
||||
static int get_comp(char *name)
|
||||
{
|
||||
return (get_table_entry(comp_name, "Compression", name));
|
||||
}
|
||||
|
||||
|
||||
static int get_os (char *name)
|
||||
{
|
||||
return (get_table_entry(os_name, "OS", name));
|
||||
}
|
||||
|
||||
|
||||
static int get_type(char *name)
|
||||
{
|
||||
return (get_table_entry(type_name, "Image", name));
|
||||
}
|
||||
|
||||
static int get_table_entry (table_entry_t *table, char *msg, char *name)
|
||||
{
|
||||
table_entry_t *t;
|
||||
int first = 1;
|
||||
|
||||
for (t=table; t->val>=0; ++t) {
|
||||
if (t->sname && strcasecmp(t->sname, name)==0)
|
||||
return (t->val);
|
||||
/* dtc -I dts -O -p 200 datafile > tmpfile */
|
||||
sprintf (cmd, "%s %s %s > %s",
|
||||
MKIMAGE_DTC, opt_dtc, datafile, tmpfile);
|
||||
debug ("Trying to execute \"%s\"\n", cmd);
|
||||
if (system (cmd) == -1) {
|
||||
fprintf (stderr, "%s: system(%s) failed: %s\n",
|
||||
cmdname, cmd, strerror(errno));
|
||||
unlink (tmpfile);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
fprintf (stderr, "\nInvalid %s Type - valid names are", msg);
|
||||
for (t=table; t->val>=0; ++t) {
|
||||
if (t->sname == NULL)
|
||||
continue;
|
||||
fprintf (stderr, "%c %s", (first) ? ':' : ',', t->sname);
|
||||
first = 0;
|
||||
|
||||
/* load FIT blob into memory */
|
||||
tfd = open (tmpfile, O_RDWR|O_BINARY);
|
||||
|
||||
if (tfd < 0) {
|
||||
fprintf (stderr, "%s: Can't open %s: %s\n",
|
||||
cmdname, tmpfile, strerror(errno));
|
||||
unlink (tmpfile);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (fstat (tfd, &sbuf) < 0) {
|
||||
fprintf (stderr, "%s: Can't stat %s: %s\n",
|
||||
cmdname, tmpfile, strerror(errno));
|
||||
unlink (tmpfile);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ptr = (unsigned char *)mmap (0, sbuf.st_size,
|
||||
PROT_READ|PROT_WRITE, MAP_SHARED, tfd, 0);
|
||||
if ((caddr_t)ptr == (caddr_t)-1) {
|
||||
fprintf (stderr, "%s: Can't read %s: %s\n",
|
||||
cmdname, tmpfile, strerror(errno));
|
||||
unlink (tmpfile);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* check if ptr has a valid blob */
|
||||
if (fdt_check_header (ptr)) {
|
||||
fprintf (stderr, "%s: Invalid FIT blob\n", cmdname);
|
||||
unlink (tmpfile);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* set hashes for images in the blob */
|
||||
if (fit_set_hashes (ptr)) {
|
||||
fprintf (stderr, "%s Can't add hashes to FIT blob", cmdname);
|
||||
unlink (tmpfile);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* add a timestamp at offset 0 i.e., root */
|
||||
if (fit_set_timestamp (ptr, 0, sbuf.st_mtime)) {
|
||||
fprintf (stderr, "%s: Can't add image timestamp\n", cmdname);
|
||||
unlink (tmpfile);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
debug ("Added timestamp successfully\n");
|
||||
|
||||
munmap ((void *)ptr, sbuf.st_size);
|
||||
close (tfd);
|
||||
|
||||
if (rename (tmpfile, imagefile) == -1) {
|
||||
fprintf (stderr, "%s: Can't rename %s to %s: %s\n",
|
||||
cmdname, tmpfile, imagefile, strerror (errno));
|
||||
unlink (tmpfile);
|
||||
unlink (imagefile);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
fprintf (stderr, "\n");
|
||||
return (-1);
|
||||
}
|
||||
|
75
tools/mkimage.h
Normal file
75
tools/mkimage.h
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* (C) Copyright 2000-2004
|
||||
* DENX Software Engineering
|
||||
* Wolfgang Denk, wd@denx.de
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifndef __WIN32__
|
||||
#include <netinet/in.h> /* for host / network byte order conversions */
|
||||
#endif
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <sha1.h>
|
||||
#include "fdt_host.h"
|
||||
|
||||
#define MKIMAGE_DEBUG
|
||||
|
||||
#ifdef MKIMAGE_DEBUG
|
||||
#define debug(fmt,args...) printf (fmt ,##args)
|
||||
#else
|
||||
#define debug(fmt,args...)
|
||||
#endif /* MKIMAGE_DEBUG */
|
||||
|
||||
#define MKIMAGE_TMPFILE_SUFFIX ".tmp"
|
||||
#define MKIMAGE_MAX_TMPFILE_LEN 256
|
||||
#define MKIMAGE_DEFAULT_DTC_OPTIONS "-I dts -O dtb -p 500"
|
||||
#define MKIMAGE_MAX_DTC_CMDLINE_LEN 512
|
||||
#define MKIMAGE_DTC "dtc" /* assume dtc is in $PATH */
|
||||
|
||||
#if defined(__BEOS__) || defined(__NetBSD__) || defined(__APPLE__)
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#ifdef __WIN32__
|
||||
typedef unsigned int __u32;
|
||||
|
||||
#define SWAP_LONG(x) \
|
||||
((__u32)( \
|
||||
(((__u32)(x) & (__u32)0x000000ffUL) << 24) | \
|
||||
(((__u32)(x) & (__u32)0x0000ff00UL) << 8) | \
|
||||
(((__u32)(x) & (__u32)0x00ff0000UL) >> 8) | \
|
||||
(((__u32)(x) & (__u32)0xff000000UL) >> 24) ))
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
|
||||
#define ntohl(a) SWAP_LONG(a)
|
||||
#define htonl(a) SWAP_LONG(a)
|
||||
#endif /* __WIN32__ */
|
||||
|
||||
#ifndef O_BINARY /* should be define'd on __WIN32__ */
|
||||
#define O_BINARY 0
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user