changeset 1312:08edfb52f9cd

Improve FIS directory handling - should work with small block size devices
author gthomas
date Wed, 15 Oct 2003 15:52:02 +0000
parents e3df0ec06a22
children 68ee1bf08a38
files packages/redboot/current/ChangeLog packages/redboot/current/cdl/redboot.cdl packages/redboot/current/include/redboot.h packages/redboot/current/src/fconfig.c packages/redboot/current/src/flash.c
diffstat 5 files changed, 50 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/packages/redboot/current/ChangeLog
+++ b/packages/redboot/current/ChangeLog
@@ -1,3 +1,18 @@
+2003-10-15  Gary Thomas  <gary@mlbassoc.com>
+
+	* src/flash.c: 
+	* src/fconfig.c: Better handling of layout of fconfig and fis
+	data within the FLASH.  Should work for even flash devices with
+	very smal block sizes.
+
+	* include/redboot.h (RedBoot_INIT_SECOND): 
+	Finer initialization control.
+
+	* cdl/redboot.cdl: Combine FIS directory and FCONFIG database
+	by default.  This results in better FLASH utilization. Also define
+	number of FIS directory slots.  This will allow support for FLASH
+	devices with very small block sizes.
+
 2003-10-12  Gary Thomas  <gary@mlbassoc.com>
 
 	* src/flash.c (fis_create): Verify that any hard FLASH addresses
--- a/packages/redboot/current/cdl/redboot.cdl
+++ b/packages/redboot/current/cdl/redboot.cdl
@@ -657,6 +657,17 @@ cdl_package CYGPKG_REDBOOT {
                       the FIS directory."
                 }
     
+                cdl_option CYGNUM_REDBOOT_FIS_DIRECTORY_ENTRY_COUNT {
+                    display         "Number of FIS directory entries"
+                    flavor	    data
+                    default_value   8
+                    description "
+                      The FIS directory normally occupies a single flash
+                      sector. Adjusting this value can allow for more than
+                      one flash sector to be used, which is useful if your
+                      sectors are very small."
+                }
+    
                 cdl_option CYGBLD_REDBOOT_MIN_IMAGE_SIZE {
                     display       "Minimum image size"
                     flavor        data
@@ -766,7 +777,7 @@ cdl_package CYGPKG_REDBOOT {
                 display       "Merged config data and FIS directory"
                 flavor        bool              
                 active_if     { CYGOPT_REDBOOT_FIS && (CYGHWR_REDBOOT_FLASH_CONFIG_MEDIA == "FLASH") }
-                default_value 0
+                default_value 1
                 description "
                   If this option is set, then the FIS directory and FLASH 
                   configuration database will be stored in the same physical
--- a/packages/redboot/current/include/redboot.h
+++ b/packages/redboot/current/include/redboot.h
@@ -249,7 +249,8 @@ extern _cmd_entry(_s_,_h_,_u_,_f_,_subs_
 static _cmd_entry(_s_,_h_,_u_,_f_,0,0,_n_)
 
 // Initialization functions
-#define RedBoot_INIT_FIRST 0000
+#define RedBoot_INIT_FIRST  0000
+#define RedBoot_INIT_SECOND 0100
 // Specify a 3 digit numeric value for proper prioritizing
 #define RedBoot_INIT_PRIO(_n_) 1##_n_
 #define RedBoot_INIT_LAST  9999
--- a/packages/redboot/current/src/fconfig.c
+++ b/packages/redboot/current/src/fconfig.c
@@ -972,19 +972,20 @@ load_flash_config(void)
     workspace_end = cfg_temp;
 #ifdef CYGHWR_REDBOOT_FLASH_CONFIG_MEDIA_FLASH
     if (!do_flash_init()) return;
-    cfg_size = (flash_block_size > sizeof(struct _config)) ? 
-        sizeof(struct _config) : 
-        _rup(sizeof(struct _config), flash_block_size);
 #ifdef CYGSEM_REDBOOT_FLASH_COMBINED_FIS_AND_CONFIG
-    cfg_size = _rup(cfg_size, sizeof(struct fis_image_desc));
-    if ((flash_block_size-cfg_size) < 8*sizeof(struct fis_image_desc)) {
+    cfg_size = _rup(sizeof(struct _config), sizeof(struct fis_image_desc));
+    if ((fisdir_size-cfg_size) < (CYGNUM_REDBOOT_FIS_DIRECTORY_ENTRY_COUNT *
+                                  CYGNUM_REDBOOT_FIS_DIRECTORY_ENTRY_SIZE)) {
         // Too bad this can't be checked at compile/build time
         diag_printf("Sorry, FLASH config exceeds available space in FIS directory\n");
         return;
     }
-    fisdir_size = flash_block_size - cfg_size;
-    cfg_base = (void *)(((CYG_ADDRESS)fis_addr + flash_block_size) - cfg_size);
+    cfg_base = (void *)(((CYG_ADDRESS)fis_addr + fisdir_size) - cfg_size);
+    fisdir_size -= cfg_size;
 #else
+    cfg_size = (flash_block_size > sizeof(struct _config)) ? 
+        sizeof(struct _config) : 
+        _rup(sizeof(struct _config), flash_block_size);
     if (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK < 0) {
         cfg_base = (void *)((CYG_ADDRESS)flash_end + 1 -
            _rup(_rup((-CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK*flash_block_size), cfg_size), flash_block_size));
@@ -1003,7 +1004,8 @@ load_flash_config(void)
     if ((cyg_crc32((unsigned char *)config, 
                    sizeof(struct _config)-sizeof(config->cksum)) != config->cksum) ||
         (config->key1 != CONFIG_KEY1)|| (config->key2 != CONFIG_KEY2)) {
-        diag_printf("FLASH configuration checksum error or invalid key\n");
+        diag_printf("**Warning** FLASH configuration checksum error or invalid key\n");
+        diag_printf("Use 'fconfig -i' to [re]intialize database\n");
         config_init();
         return;
     }
@@ -1021,6 +1023,6 @@ load_flash_config(void)
 #endif
 }
 
-RedBoot_init(load_flash_config, RedBoot_INIT_FIRST);
+RedBoot_init(load_flash_config, RedBoot_INIT_SECOND);
 
 // EOF fconfig.c
--- a/packages/redboot/current/src/flash.c
+++ b/packages/redboot/current/src/flash.c
@@ -463,8 +463,7 @@ fis_list(int argc, char *argv[])
 #else
     i = 1;
 #endif
-    if (!scan_opts(argc, argv, 2, opts, i, 0, 0, ""))
-    {
+    if (!scan_opts(argc, argv, 2, opts, i, 0, 0, "")) {
         return;
     }
     flash_read(fis_addr, fis_work_block, fisdir_size, (void **)&err_addr);
@@ -1315,6 +1314,7 @@ do_flash_init(void)
     void *err_addr;
 
     if (!__flash_init) {
+        __flash_init = 1;
         if ((stat = flash_init((void *)(workspace_end-FLASH_MIN_WORKSPACE), 
                                FLASH_MIN_WORKSPACE, diag_printf)) != 0) {
             diag_printf("FLASH: driver init failed: %s\n", flash_errmsg(stat));
@@ -1326,18 +1326,19 @@ do_flash_init(void)
         flash_get_block_info(&flash_block_size, &flash_num_blocks);
         workspace_end = (unsigned char *)(workspace_end-FLASH_MIN_WORKSPACE);
 #ifdef CYGOPT_REDBOOT_FIS
+        fisdir_size = CYGNUM_REDBOOT_FIS_DIRECTORY_ENTRY_COUNT * CYGNUM_REDBOOT_FIS_DIRECTORY_ENTRY_SIZE;
+        fisdir_size = ((fisdir_size + flash_block_size - 1) / flash_block_size) * flash_block_size;
 # ifdef CYGOPT_REDBOOT_FIS_ZLIB_COMMON_BUFFER
 	fis_work_block = fis_zlib_common_buffer;
-	if(CYGNUM_REDBOOT_FIS_ZLIB_COMMON_BUFFER_SIZE < flash_block_size) {
+	if(CYGNUM_REDBOOT_FIS_ZLIB_COMMON_BUFFER_SIZE < fisdir_size) {
             diag_printf("FLASH: common buffer too small\n");
 	    workspace_end += FLASH_MIN_WORKSPACE;
             return false;
 	}
 # else
-        workspace_end = (unsigned char *)(workspace_end-flash_block_size);
+        workspace_end = (unsigned char *)(workspace_end-fisdir_size);
         fis_work_block = workspace_end;
 # endif
-        fisdir_size = flash_block_size;
         if (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK < 0) {
             fis_addr = (void *)((CYG_ADDRESS)flash_end + 1 +
                                 (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*flash_block_size));
@@ -1345,9 +1346,12 @@ do_flash_init(void)
             fis_addr = (void *)((CYG_ADDRESS)flash_start + 
                                 (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*flash_block_size));
         }
+        if (((CYG_ADDRESS)fis_addr + fisdir_size - 1) > (CYG_ADDRESS)flash_end) {
+            diag_printf("FIS directory doesn't fit\n");
+            return false;
+        }
         flash_read(fis_addr, fis_work_block, fisdir_size, (void **)&err_addr);
 #endif
-        __flash_init = 1;
     }
     return true;
 }