Hi Folks Ascom has recently required that Redboot run on a target board which can be manufactured with two different FLASH devices which are pin compatible and with two banks of flash in disjoint locations. We also needed to support two jffs2 file systems simultaneously so allowing fallback if one was corrupt. The client also wants one image to run on both boards. The current flash infrastructure cannot support this. Due to time pressures we have used Ian Campbells patches to get something going quickly. However in the background i took a step back and overhauled the whole flash infrastructure in what i hope is a clean and consistent API with all the features required: Multiple device drivers at the same time Multiple instantiations of the same driver Probing to detect what is actually on the board Support for boot block devices which have different size blocks Thread safe when used with the kernel Does not pollute the name space Optional backward compatible with old drivers Optional backward compatible with old API Able to support multiple JFFS2 filesystems Redboot to be able to access multiple devices Documentation! Attached are the change. There are two .epk's. One is the new io/flash code which uses v2 instead of current so you can have it in the repository at the same time as the current code. The second is a flash driver which uses the new API for the synthetic target. This installs parallel the current synth flash driver which allows testing of legacy and new drivers in the same system. There is also a patch to the rest of eCos for redboot and jffs2. Some screen shots.... RedBoot(tm) bootstrap and debug environment [ROM] Non-certified release, version UNKNOWN - built 14:27:08, Jul 15 2004 Copyright (C) 2000, 2001, 2002, Red Hat, Inc. RAM: 0x02000000-0x02800000, [0x02006fd0-0x027e1000] available FLASH: 0x40000000 - 0x400fffff 8 x 0x2000 blocks 15 x 0x10000 blocks FLASH: 0x40100000 - 0x401fffff 16 x 0x10000 blocks Here you can see two flash devices, the first one with boot blocks. In this setup the first device is the new synthetic driver and the second one is the legacy driver. RedBoot> fis create -b 0x02000000 -l 0x10000 -f 0x40100000 junk RedBoot> fis list Name FLASH addr Mem addr Length Entry point RedBoot 0x40000000 0x40000000 0x00020000 0x00000000 FIS directory 0x400EFFFF 0x400EFFFF 0x0000F000 0x00000000 RedBoot config 0x400FEFFF 0x400FEFFF 0x00001000 0x00000000 junk 0x40100000 0x40100000 0x00010000 0xFFFFFFFF RedBoot> This creates an entry in the second flash device. There are still some limitations. The FIS directory and RedBoot config have to be in the lower device. Also they cannot yet make use of the boot blocks, but that should be easy to add. The fileio1 test in the jffs2 package has been extended. If the flash block io layer has been configured for two devices the second one is also mounted: : mounting second JFFS2 filesystem on /mnt : reading directory / : entry . [mode 016f0001 ino 00000001 nlink 1 size 0] : entry .. [mode 016f0001 ino 00000001 nlink 1 size 0] : entry etc [mode 016f0001 ino 00000002 nlink 1 size 0] : entry dev: stat() returned -1 No such entity : entry mnt [mode 016f0001 ino 00000001 nlink 1 size 0] : entry var [mode 016f0001 ino 00000008 nlink 1 size 0] : entry tmp [mode 016f0001 ino 00000007 nlink 1 size 0] : entry jffs2.img [mode 004b0008 ino 00000009 nlink 1 size 2013] : reading directory /mnt : entry . [mode 016f0001 ino 00000001 nlink 1 size 0] : entry .. [mode 016f0001 ino 00000001 nlink 1 size 0] : entry etc [mode 016f0001 ino 00000002 nlink 1 size 0] : entry dev [mode 016f0001 ino 00000005 nlink 1 size 0] : entry mnt [mode 016f0001 ino 00000006 nlink 1 size 0] : entry var [mode 016f0001 ino 00000008 nlink 1 size 0] : entry tmp [mode 016f0001 ino 00000007 nlink 1 size 0] : entry jffs2.img [mode 004b0008 ino 00000009 nlink 1 size 2013] : umount /mnt : umount / In this case the two filesystems are identical so its not the best of tests. I also need to look into the /dev failure, but i don't think that is related to the flashiodev code. There is documentaion in SGML format which describes both the new application and device API. Note that it might not be 100% correct. I wrote the documentation first to get my ideas sorted out and then did the implementation. There was some minor changes along the way which might not of made it back into the documentation. The new API is: typedef int cyg_flash_printf(const char *fmt, ...); __externC int cyg_flash_init( cyg_flash_printf *pf ); __externC int cyg_flash_get_info(cyg_uint32 devno, cyg_flash_info_t * info); __externC int cyg_flash_get_info_addr(cyg_flashaddr_t flash_base, cyg_flash_info_t * info); __externC int cyg_flash_verify_addr(const cyg_flashaddr_t address); __externC bool cyg_flash_code_overlaps(const cyg_flashaddr_t start, const cyg_flashaddr_t end); __externC int cyg_flash_get_block_info(size_t *block_size, cyg_uint32 *blocks); __externC int cyg_flash_get_limits(cyg_flashaddr_t *start, cyg_flashaddr_t *end); __externC size_t cyg_flash_block_size(const cyg_flashaddr_t flash_base); __externC int cyg_flash_read(cyg_flashaddr_t flash_base, const void *ram_base, const size_t len, cyg_flashaddr_t *err_address); __externC int cyg_flash_erase(const cyg_flashaddr_t flash_base, const size_t len, cyg_flashaddr_t *err_address); __externC int cyg_flash_program(const cyg_flashaddr_t flash_base, void *ram_base, const size_t len, cyg_flashaddr_t *err_address); __externC int cyg_flash_lock(const cyg_flashaddr_t flash_base, const size_t len, cyg_flashaddr_t *err_address); __externC int cyg_flash_unlock(const cyg_flashaddr_t flash_base, const size_t len, cyg_flashaddr_t *err_address); __externC const char *cyg_flash_errmsg(const int err); #ifdef CYGPKG_KERNEL __externC int cyg_flash_mutex_lock(const cyg_flashaddr_t from, const size_t len); __externC int cyg_flash_mutex_unlock(const cyg_flashaddr_t from, #endif and the device API is // Structure of pointers to functions in the device driver struct cyg_flash_dev_funs { int (*flash_init) (struct cyg_flash_dev *dev); size_t (*flash_query) (struct cyg_flash_dev *dev, void * data, const size_t len); int (*flash_erase_block) (struct cyg_flash_dev *dev, const cyg_flashaddr_t block_base); int (*flash_program) (struct cyg_flash_dev *dev, cyg_flashaddr_t base, const void* data, const size_t len); int (*flash_read) (struct cyg_flash_dev *dev, const cyg_flashaddr_t base, void* data, const size_t len); int (*flash_hwr_map_error) (struct cyg_flash_dev *dev, int err); int (*flash_block_lock) (struct cyg_flash_dev *dev, const cyg_flashaddr_t block_base); int (*flash_block_unlock) (struct cyg_flash_dev *dev, const cyg_flashaddr_t block_base); }; // Structure each device places in the HAL table struct cyg_flash_dev { struct cyg_flash_dev_funs *funs; // Function pointers cyg_flashaddr_t start; // First address cyg_flashaddr_t end; // Last address cyg_uint32 num_block_infos; // Number of entries cyg_block_info_t *block_info; // Info about one block size void *priv; // Devices private data void *config; // Configuration info // The following are only written to by the FLASH IO layer. cyg_flash_printf *pf; // Pointer to diagnostic printf bool init; // Device has been initialised #ifdef CYGPKG_KERNEL cyg_mutex_t mutex; // Mutex for thread safeness #endif struct cyg_flash_dev *next; // Pointer to next device } CYG_HAL_TABLE_TYPE; See the documentation for explanations of each function. It needs some more device drivers. I plan to modify both the SST and the Strata drivers to use the new API, but that work will not start for another two weeks. What i would like now is some feedback. Are there any missing features? Does the APIs make sense. Reading the code do you see obvious problems? Im on Holiday for the next two weeks so it would be nice to come back to a few email of suggestions, improvements and bug fixes. Thanks Andrew