[ECOS] Re: "fis list" won't display RedBoot FIS directory entry

Grant Edwards grante@visi.com
Sun Nov 19 15:35:00 GMT 2006


On 2006-11-19, Grant Edwards <grante@visi.com> wrote:

> I've enabled the CYGOPT_REDBOOT_FIS_REDBOOT option and verified
> that there is an entry for RedBoot in the FIS directory, but the
> "fis list" command refuses to display it.  This is caused by
> the following bit of code in flash.c:
>
>
>    714	    last_addr = 0;
>    715	    image_indx = 0;
>    716	    do {
>    717	        image_found = false;
>    718	        lowest_addr = 0xFFFFFFFF;
>    719	        img = (struct fis_image_desc *) fis_work_block;
>    720	        for (i = 0;  i < fisdir_size/sizeof(*img);  i++, img++) {
>    721	            if (img->u.name[0] != (unsigned char)0xFF) {
>    722	                if ((img->flash_base > last_addr) && (img->flash_base < lowest_addr)) {
>    723	                    lowest_addr = img->flash_base;
>    724	                    image_found = true;
>    725	                    image_indx = i;
>    726	                }
>    727	            }
>    728	        }
>    729	        if (image_found) {
>                     [print entry]

>     Is this an attempt to print the entries sorted by base_addr?

I've concluded that is the case.  

I've got it fixed in my snapshot.  Unfortunately, the flash
stuff has changed so much since the snapshot I'm using that I
am unable to generate a patch against the current version (and
I don't have any platform on which I can run a current
snapshot).  

If somebody else wants to port the fix, here's my version of
fis_list().  The do-loop and is the only thing that really
changed.  The index/flag/address logic was broken and a bit bit
convoluted in my eye. Using a couple pointers to image
structures for state information looks a lot cleaner to me (and
it works correctly):

----------------------------------------------------------------------
static void
fis_list(int argc, char *argv[])
{
    struct fis_image_desc *img,*next,*prev;
    struct fis_image_desc *dirstart = (struct fis_image_desc *) fis_work_block;
    struct fis_image_desc *dirend   = (struct fis_image_desc *)((char*)fis_work_block+fisdir_size);
    bool show_cksums = false;
    bool show_datalen = false;
    struct option_info opts[2];
    int i;
  
#ifdef CYGHWR_REDBOOT_ARM_FLASH_SIB
    // FIXME: this is somewhat half-baked
    extern void arm_fis_list(void);
    arm_fis_list();
    return;
#endif

    init_opts(&opts[0], 'd', false, OPTION_ARG_TYPE_FLG, 
              (void *)&show_datalen, (bool *)0, "display data length");
#ifdef CYGSEM_REDBOOT_FIS_CRC_CHECK
    init_opts(&opts[1], 'c', false, OPTION_ARG_TYPE_FLG, 
              (void *)&show_cksums, (bool *)0, "display checksums");
    i = 2;
#else
    i = 1;
#endif
    if (!scan_opts(argc, argv, 2, opts, i, 0, 0, "")) {
        return;
    }
    fis_read_directory();

    // Let diag_printf do the formatting in both cases, rather than counting
    // cols by hand....
    diag_printf("%-16s  %-10s  %-10s  %-10s  %-s\n",
                "Name","FLASH addr",
                show_cksums ? "Checksum" : "Mem addr",
                show_datalen ? "Datalen" : "Length",
                "Entry point" );
  
    // print directory entires in order by flash_base field
    // using a sort-of-bubble-sort algorithm.  
    // ASSUMPTION: NULL is never a valid pointer to an entry
    // in fis_work_block

    prev = NULL;
    do {
        next = NULL;
        for (img = dirstart; img < dirend; ++img)
           if ( ((unsigned char)(img->name[0]) != 0xff) &&
                ((next == NULL) || (img->flash_base < next->flash_base)) &&
                ((prev == NULL) || (img->flash_base > prev->flash_base)) )
              next = img;
        if (next)
           diag_printf("%-16s  0x%08lX  0x%08lX  0x%08lX  0x%08lX\n", next->name,
                       next->flash_base, 
#ifdef CYGSEM_REDBOOT_FIS_CRC_CHECK
                       show_cksums ? next->file_cksum : next->mem_base,
                       show_datalen ? next->data_length : next->size, 
#else
                       next->mem_base, 
                       next->size, 
#endif
                       next->entry_point);
        prev = next;
        } while (next);
}
----------------------------------------------------------------------

-- 
Grant



-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss



More information about the Ecos-discuss mailing list