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:
Bartlomiej Sieka 2008-03-26 09:38:06 +01:00
commit 27f33e9f45
82 changed files with 8302 additions and 3279 deletions

View File

@ -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
View File

@ -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,

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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;

View File

@ -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;
}

View File

@ -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
);

View File

@ -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 */

View File

@ -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

View File

@ -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;

View File

@ -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)

View File

@ -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;

View File

@ -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;

View File

@ -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
View 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

File diff suppressed because it is too large Load Diff

View File

@ -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"

View File

@ -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;

View File

@ -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;

View 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
View 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
View 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";
};
};
};

View 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
View 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";
};
};
};

View 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.

View File

@ -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>

View File

@ -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)

View File

@ -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

View File

@ -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 */

View File

@ -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
*----------------------------------------------------------------------*/

View File

@ -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__ */

View File

@ -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
View 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
View 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 */

View File

@ -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)

View File

@ -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;
}

View File

@ -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)

View File

@ -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;
}

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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
View 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
View 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);
}

View File

@ -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
View 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;
}

View File

@ -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);
}

View File

@ -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, &regs, &regs);
}
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;
}

View File

@ -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
View 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;
}
}

View File

@ -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 */
}

View File

@ -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
View 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;
}

View File

@ -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);
}

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)
{
}

View File

@ -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)

View File

@ -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;
}

View File

@ -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
View 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

View File

@ -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)

View File

@ -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;
}

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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
View File

@ -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

View File

@ -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
View 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__ */

View File

@ -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(&timestamp));
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
View 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