[U-Boot-Users] Loading FPGA from an mkimage created image?

Hi there,
I know that
fpga load [device number] [image address] [image size]
can be used to init an FPGA. Now I want to compress and wrap the FPGA data with mkimage.
Is there a way to pass the address of an Image to "fpga load". Or do I have to umcompress it first using "bootm" or something and then pass the address and size to "fpga load"?
Thanks!

In message 41A1CD69.6000708@imc-berlin.de you wrote:
I know that
fpga load [device number] [image address] [image size]
can be used to init an FPGA. Now I want to compress and wrap the FPGA data with mkimage.
Is there a way to pass the address of an Image to "fpga load".
Umm... that's the third parameter in the usage message above: "image address" - isn't it?
Or do I have to umcompress it first using "bootm" or something and then pass the address and size to "fpga load"?
Either this, or extend the fpga command to understand compressed images.
Best regards,
Wolfgang Denk

Wolfgang Denk wrote:
In message 41A1CD69.6000708@imc-berlin.de you wrote:
I know that
fpga load [device number] [image address] [image size]
can be used to init an FPGA. Now I want to compress and wrap the FPGA data with mkimage.
Is there a way to pass the address of an Image to "fpga load".
Umm... that's the third parameter in the usage message above: "image address" - isn't it?
No. IIRC then "image" in "image address" means (raw) data as the FPGA would understand it.
Or do I have to umcompress it first using "bootm" or something and then pass the address and size to "fpga load"?
Either this, or extend the fpga command to understand compressed images.
So checking for valid mkimage header? And then uncompress to $loadaddr? And maybe even introduce a new image type "FPGA data" ?

In message 41A2272D.7050403@imc-berlin.de you wrote:
Umm... that's the third parameter in the usage message above: "image address" - isn't it?
No. IIRC then "image" in "image address" means (raw) data as the FPGA would understand it.
I see. Sorry, I never used this command myself yet.
Or do I have to umcompress it first using "bootm" or something and then pass the address and size to "fpga load"?
Either this, or extend the fpga command to understand compressed images.
So checking for valid mkimage header? And then uncompress to $loadaddr?
Yes - if it's compressed; otherwise just memcpy().
And maybe even introduce a new image type "FPGA data" ?
No. This is what applies (from "include/image.h"):
* "Firmware Images" are binary images containing firmware (like * U-Boot or FPGA images) which usually will be programmed to * flash memory.
Viele Grüße,
Wolfgang Denk

Dear Wolfgang,
I pick up this old thread.
I know that
fpga load [device number] [image address] [image size]
can be used to init an FPGA. Now I want to compress and wrap the FPGA data with mkimage. ... Is there a way to pass the address of an Image to "fpga load". ... Or do I have to umcompress it first using "bootm" or something and then pass the address and size to "fpga load"?
Either this, or extend the fpga command to understand compressed images.
I see that code for checking and uncompressing images is duplicated many times across the U-Boot sources. Are there any plans to provide a generic helper function for this task?
Thanks.
-- Steven

Dear Steven,
in message 42A95BF3.5050607@imc-berlin.de you wrote:
I pick up this old thread.
Thanks for it.
I see that code for checking and uncompressing images is duplicated many times across the U-Boot sources.
Yes :-(
Are there any plans to provide a generic helper function for this task?
No. Cleanup and patches welcome.
Best regards,
Wolfgang Denk

Hi,
I see that code for checking and uncompressing images is duplicated many times across the U-Boot sources.
Yes :-(
Are there any plans to provide a generic helper function for this task?
No. Cleanup and patches welcome.
Shell we split out the image code from cmd_bootm.c into cmd_image.c and image.c?

Wolfgang Denk wrote:
In message 41A1CD69.6000708@imc-berlin.de you wrote:
I know that
fpga load [device number] [image address] [image size]
can be used to init an FPGA. Now I want to compress and wrap the FPGA data with mkimage.
Is there a way to pass the address of an Image to "fpga load".
... extend the fpga command to understand compressed images.
Please consider the attached patch. I know it's duplicating some code but that's all I can do for now.
multiIO_2> fpga load 0 $loadaddr Image Name: multiIO TEST FPGA Created: 2005-06-10 14:01:40 UTC Image Type: ARM U-Boot Standalone Program (uncompressed) Data Size: 42431 Bytes = 41.4 kB Load Address: 20008000 Entry Point: deadbeef Verifying Checksum ... OK Loading Firmware/Standalone Image ... OK Loading FPGA Device 0........................................... Done.
----
* Patch by Steven Scholz, 10 Jun 2005: Adding new configuration option CONFIG_FPGA_IMAGE This allows to pass U-Boot images of the types "FIRMWARE" or "STANDALONE" to the fpga command
Thanks.
-- Steven
Index: u-boot/README =================================================================== RCS file: /cvsroot/u-boot/u-boot/README,v retrieving revision 1.126 diff -p -u -r1.126 README --- u-boot/README 3 May 2005 14:12:25 -0000 1.126 +++ u-boot/README 10 Jun 2005 17:24:55 -0000 @@ -1310,6 +1310,12 @@ The following options need to be configu Time to wait after FPGA configuration. The default is 200 mS.
+ CONFIG_FPGA_IMAGE + + Enables checking fpga data for a valid U-Boot image header. + If needed, CRC is checked and data uncompressed before doing + the desired fpga operation like load, loadb, dump (see mkimage) + - Configuration Management: CONFIG_IDENT_STRING
Index: u-boot/common/cmd_fpga.c =================================================================== RCS file: /cvsroot/u-boot/u-boot/common/cmd_fpga.c,v retrieving revision 1.10 diff -p -u -r1.10 cmd_fpga.c --- u-boot/common/cmd_fpga.c 22 Jan 2005 18:13:05 -0000 1.10 +++ u-boot/common/cmd_fpga.c 10 Jun 2005 17:24:55 -0000 @@ -56,6 +56,143 @@ static int fpga_get_op (char *opstr); #define FPGA_LOADB 2 #define FPGA_DUMP 3
+#ifdef CONFIG_FPGA_IMAGE +/* + * 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. + */ +#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) +# define CHUNKSZ (64 * 1024) +#endif + +int gunzip (void *, int, unsigned char *, unsigned long *); + +static image_header_t header; + +/* + * Checking for a valid Firmware/Standalone Image, uncompress/copy data + * and update pointer and size + */ +static int +fpga_check_image(void **fpga_data, size_t *data_size) +{ + unsigned long len, checksum; + uchar *data; + image_header_t *hdr = &header; + int rc = 0; + uint unc_len = 0x400000; + char *name, *s; + int verify; + + /* Copy header so we can blank CRC field for re-calculation */ + memcpy (&header, *fpga_data, sizeof(image_header_t)); + if (ntohl(hdr->ih_magic) != IH_MAGIC) { + /* That's ok. Maybe it's raw data. */ + PRINTF("No Magic Number (%08x != %08x) -> Raw data.\n", ntohl(hdr->ih_magic), IH_MAGIC); + return 0; + } + + print_image_hdr(hdr); + + if (hdr->ih_os != IH_OS_U_BOOT) { + puts("No U-Boot Image\n"); + return 1; + } + + if ((hdr->ih_type != IH_TYPE_FIRMWARE) && (hdr->ih_type != IH_TYPE_STANDALONE)) { + puts("No Firmware/Standalone Image\n"); + return 1; + } + + name = "Firmware/Standalone Image"; + + data = (uchar *)&header; + len = sizeof(image_header_t); + + checksum = ntohl(hdr->ih_hcrc); + hdr->ih_hcrc = 0; + + if (crc32 (0, (char *)data, len) != checksum) { + puts("Bad Header Checksum\n"); + return 1; + } + + data = *fpga_data + sizeof(image_header_t); + len = ntohl(hdr->ih_size); + + s = getenv ("verify"); + verify = (s && (*s == 'n')) ? 0 : 1; + if (verify) { + puts(" Verifying Checksum ... "); + if (crc32 (0, (char *)data, len) != ntohl(hdr->ih_dcrc)) { + puts("Bad Data CRC\n"); + return 1; + } + puts("OK\n"); + } + + switch (hdr->ih_comp) { + case IH_COMP_NONE: + printf (" Loading %s ... ", name); +#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) + size_t l = len; + void *to = (void *)ntohl(hdr->ih_load); + 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 *) ntohl(hdr->ih_load), (uchar *)data, len); +#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ + break; + case IH_COMP_GZIP: + printf (" Uncompressing %s ... ", name); + if (gunzip ((void *)ntohl(hdr->ih_load), unc_len, + (uchar *)data, &len) != 0) { + puts ("GUNZIP ERROR - must RESET board to recover\n"); + return 1; + } + break; +#ifdef CONFIG_BZIP2 + case IH_COMP_BZIP2: + printf (" Uncompressing %s ... ", name); + /* + * If we've got less than 4 MB of malloc() space, + * use slower decompression algorithm which requires + * at most 2300 KB of memory. + */ + i = BZ2_bzBuffToBuffDecompress ((char*)ntohl(hdr->ih_load), + &unc_len, (char *)data, len, + CFG_MALLOC_LEN < (4096 * 1024), 0); + if (i != BZ_OK) { + printf ("BUNZIP2 ERROR %d - must RESET board to recover\n", i); + return 1; + } + break; +#endif /* CONFIG_BZIP2 */ + default: + printf ("Unimplemented compression type %d\n", hdr->ih_comp); + return 1; + } + puts ("OK\n"); + + /* update the value for fpga operations */ + *fpga_data = (void *) data; + *data_size = len; + + return(rc); +} +#else /* ! CONFIG_FPGA_IMAGE */ +#define fpga_check_image(fpga_data, data_size) 0 +#endif /* CONFIG_FPGA_IMAGE */ + /* Convert bitstream data and load into the fpga */ int fpga_loadbitstream(unsigned long dev, char* fpgadata, size_t size) { @@ -229,14 +366,23 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag break;
case FPGA_LOAD: + rc = fpga_check_image(&fpga_data, &data_size); + if (rc) + break; rc = fpga_load (dev, fpga_data, data_size); break;
case FPGA_LOADB: + rc = fpga_check_image(&fpga_data, &data_size); + if (rc) + break; rc = fpga_loadbitstream(dev, fpga_data, data_size); break;
case FPGA_DUMP: + rc = fpga_check_image(&fpga_data, &data_size); + if (rc) + break; rc = fpga_dump (dev, fpga_data, data_size); break;
participants (2)
-
Steven Scholz
-
Wolfgang Denk