]> git.kernelconcepts.de Git - karo-tx-redboot.git/blobdiff - packages/redboot/v2_0/src/flash.c
WinCE redundant image support
[karo-tx-redboot.git] / packages / redboot / v2_0 / src / flash.c
index caefc0c093ca495bd6123f2df15e9aaf73e2e05b..c72621367fb667cdda9e7be16935aa2b10c50bab 100644 (file)
@@ -62,6 +62,7 @@
 
 #ifdef CYGBLD_BUILD_REDBOOT_WITH_WINCE_SUPPORT
 #include <wince.h>
+#include <winceinc.h>
 #endif
 
 #ifdef CYGSEM_REDBOOT_FLASH_COMBINED_FIS_AND_CONFIG
 extern void conf_endian_fixup(void *p);
 #endif
 
+#if defined(CYGBLD_BUILD_REDBOOT_WITH_WINCE_SUPPORT) && defined(CYGSEM_REDBOOT_FLASH_CONFIG)
+#include <flash_config.h>
+
+#if (REDBOOT_IMAGE_SIZE != CYGBLD_REDBOOT_MIN_IMAGE_SIZE)
+#error REDBOOT_IMAGE_SIZE != CYGBLD_REDBOOT_MIN_IMAGE_SIZE
+#endif
+
+RedBoot_config_option("automatic boot partition selection",
+                                       xt0_auto_OS_part_sel,
+                                       ALWAYS_ENABLED, true,
+                                       CONFIG_BOOL,
+                                       false
+       );
+
+RedBoot_config_option("first OS boot partition",
+                                       xt1_first_OS_part,
+                                       "xt0_auto_OS_part_sel", true,
+                                       CONFIG_STRING,
+                                       "osimage1"
+       );
+
+RedBoot_config_option("second OS boot partition",
+                                       xt2_second_OS_part,
+                                       "xt0_auto_OS_part_sel", true,
+                                       CONFIG_STRING,
+                                       "osimage2"
+       );
+
+#endif // CYGBLD_BUILD_REDBOOT_WITH_WINCE_SUPPORT && CYGSEM_REDBOOT_FLASH_CONFIG
+
 // Round a quantity up
 #define _rup(n,s) ((((n)+(s-1))/s)*s)
 
@@ -1237,15 +1268,51 @@ fis_delete(int argc, char *argv[])
        }
 }
 
+#ifdef CYGBLD_BUILD_REDBOOT_WITH_WINCE_SUPPORT
+static bool load_ce_img(struct fis_image_desc *img)
+{
+       bool ret = true;
+
+       FLASH_Enable((void *)img->flash_base, (void *)(img->flash_base + img->size));
+       if (!ce_is_bin_image((void *)img->flash_base, img->size)) {
+               diag_printf("** Error: This does not seem to be a valid Windows CE image\n");
+               ret =  false;
+       }
+       if (ret) {
+               if (!ce_bin_load((void *)img->flash_base, img->size)) {
+                       diag_printf("** Error: Failed to load Windows CE image\n");
+                       ret =  false;
+               }
+       }
+       FLASH_Disable((void *)img->flash_base, (void *)(img->flash_base + img->size));
+       return ret;
+}
+
+static void store_boot_img_name(char *image_name)
+{
+
+       ce_std_driver_globals *std_drv_glb = &_KARO_CECFG_START;
+
+       strncpy(std_drv_glb->chBootPartition, image_name, sizeof(std_drv_glb->chBootPartition));
+
+       std_drv_glb->chBootPartition[15] = '\0';
+}
+#endif
+
 static void
 fis_load(int argc, char *argv[])
 {
-       char *name;
-       struct fis_image_desc *img;
+       char *name = NULL;
+       struct fis_image_desc *img = NULL;
        CYG_ADDRESS mem_addr;
        bool mem_addr_set = false;
        bool show_cksum = false;
+#ifdef CYGBLD_BUILD_REDBOOT_WITH_WINCE_SUPPORT
        bool load_ce = false;
+#else
+#define load_ce                0
+#endif
+       bool auto_part_name = false;
        struct option_info opts[4];
 #if defined(CYGSEM_REDBOOT_FIS_CRC_CHECK)
        unsigned long cksum;
@@ -1269,28 +1336,41 @@ fis_load(int argc, char *argv[])
                        &decompress, 0, "decompress");
 #endif
 
-       CYG_ASSERT(num_options <= num_options, "Too many options");
+       CYG_ASSERT(num_options <= NUM_ELEMS(opts), "Too many options");
 
        if (!scan_opts(argc, argv, 2, opts, num_options, &name,
                                        OPTION_ARG_TYPE_STR, "image name")) {
                fis_usage("invalid arguments");
                return;
        }
-       if ((img = fis_lookup(name, NULL)) == NULL) {
-               diag_printf("No image '%s' found\n", name);
-               return;
+
+#ifdef CYGBLD_BUILD_REDBOOT_WITH_WINCE_SUPPORT
+       // check if the name of the OS partition should be chosen automatically
+       if (load_ce) {
+               if (!flash_get_config("xt0_auto_OS_part_sel", &auto_part_name, CONFIG_BOOL)) {
+                       diag_printf("fconfig variable 'xt0_auto_OS_part_sel' not found; use 'fconfig -i' to create it\n");
+                       return;
+               }
        }
-       if (!mem_addr_set || load_ce) {
-               mem_addr = img->mem_base;
+#endif
+       if (name) {
+               if ((img = fis_lookup(name, NULL)) == NULL) {
+                       if (!auto_part_name) {
+                               diag_printf("No image '%s' found\n", name);
+                               return;
+                       }
+               } else {
+                       if (!mem_addr_set && !load_ce) {
+                               mem_addr = img->mem_base;
+                       }
+               }
        }
        // Load image from FLASH into RAM
 #ifdef CYGSEM_REDBOOT_VALIDATE_USER_RAM_LOADS
-       if (!valid_address((void *)mem_addr)) {
-               if (!load_ce) {
-                       diag_printf("Not a loadable image - try using -b ADDRESS option\n");
-               } else {
-                       diag_printf("Not a loadable image\n");
-               }
+       // this does not make sense for WINCE as the load address is stored in the descriptor
+       // inside the image itself. It does not matter what load address is specified in the FIS directory
+       if (!load_ce && !valid_address((void *)mem_addr)) {
+               diag_printf("Not a loadable image - try using -b ADDRESS option\n");
                return;
        }
 #endif
@@ -1299,15 +1379,39 @@ fis_load(int argc, char *argv[])
                if (mem_addr_set) {
                        diag_printf("Warning: -b argument ignored for Windows CE image\n");
                }
-               FLASH_Enable((void *)img->flash_base, (void *)(img->flash_base + img->size));
-               if (!ce_is_bin_image((void *)img->flash_base, img->size)) {
-                       diag_printf("** Error: This does not seem to be a valid Windows CE image\n");
-                       return;
-               }
-               if (!ce_bin_load((void *)img->flash_base, img->size)) {
-                       diag_printf("** Error: Failed to load Windows CE image\n");
+               if (!auto_part_name) {
+                       if (!load_ce_img(img))
+                               return;
+               } else {
+                       if (!img || !load_ce_img(img)) {
+                               // try the first OS image
+                               if (!flash_get_config("xt1_first_OS_part", &name, CONFIG_STRING)) {
+                                       diag_printf("fconfig variable 'xt1_first_OS_part' not found; use 'fconfig -i' to create it\n");
+                               }
+                               if (name) {
+                                       if ((img = fis_lookup(name, NULL)) == NULL) {
+                                               diag_printf("No image '%s' found\n", name);
+                                       } else {
+                                               diag_printf("loading WINCE OS from partition '%s'\n", name);
+                                       }
+                               }
+                               if (!img || !load_ce_img(img)) {
+                                       if (!flash_get_config("xt2_second_OS_part", &name, CONFIG_STRING)) {
+                                               diag_printf("fconfig variable 'xt2_second_OS_part' not found; use 'fconfig -i' to create it\n");
+                                               return;
+                                       }
+                                       if ((img = fis_lookup(name, NULL)) == NULL) {
+                                               diag_printf("No image '%s' found\n", name);
+                                               return;
+                                       } else {
+                                               diag_printf("loading WINCE OS from partition '%s'\n", name);
+                                       }
+                                       if (!load_ce_img(img))
+                                               return;
+                               }
+                       }
+                       store_boot_img_name(name);
                }
-               FLASH_Disable((void *)img->flash_base, (void *)(img->flash_base + img->size));
                // Set load address/top
                load_address = mem_addr;
                load_address_end = mem_addr + img->data_length;