📄 flash_junk.c
字号:
//==========================================================================//// flash.c//// RedBoot - FLASH memory support////==========================================================================//####COPYRIGHTBEGIN####// // ------------------------------------------- // The contents of this file are subject to the Red Hat eCos Public License // Version 1.1 (the "License"); you may not use this file except in // compliance with the License. You may obtain a copy of the License at // http://www.redhat.com/ // // Software distributed under the License is distributed on an "AS IS" // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the // License for the specific language governing rights and limitations under // the License. // // The Original Code is eCos - Embedded Configurable Operating System, // released September 30, 1998. // // The Initial Developer of the Original Code is Red Hat. // Portions created by Red Hat are // Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. // All Rights Reserved. // ------------------------------------------- // //####COPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s): gthomas// Contributors: gthomas// Date: 2000-07-28// Purpose: // Description: // // This code is part of RedBoot (tm).////####DESCRIPTIONEND####////==========================================================================#include <redboot.h>#include <cyg/io/flash.h>#include <fis.h>#define flash_end_1 0x02000000// Exported CLI functionsRedBoot_cmd("fis", "Manage FLASH images", "{cmds}", do_fis );#ifdef CYGSEM_REDBOOT_FLASH_CONFIGRedBoot_cmd("fconfig", "Manage configuration kept in FLASH memory", "[-l]", do_flash_config );#endif// Internal commandslocal_cmd_entry("init", "Initialize FLASH Image System [FIS]", "[-f]", fis_init, FIS_cmds );local_cmd_entry("list", "Display contents of FLASH Image System [FIS]", "[-c]", fis_list, FIS_cmds );local_cmd_entry("free", "Display free [available] locations within FLASH Image System [FIS]", "", fis_free, FIS_cmds );local_cmd_entry("erase", "Erase FLASH contents", "-f <flash_addr> -l <length>", fis_erase, FIS_cmds );#if 0 < CYGHWR_IO_FLASH_BLOCK_LOCKING // This is an *interface*local_cmd_entry("lock", "LOCK FLASH contents", "-f <flash_addr> -l <length>", fis_lock, FIS_cmds );local_cmd_entry("unlock", "UNLOCK FLASH contents", "-f <flash_addr> -l <length>", fis_unlock, FIS_cmds );#endiflocal_cmd_entry("delete", "Display an image from FLASH Image System [FIS]", "name", fis_delete, FIS_cmds );local_cmd_entry("load", "Load image from FLASH Image System [FIS] into RAM", "[-b <memory_load_address>] [-c] name", fis_load, FIS_cmds );local_cmd_entry("create", "Create an image", "-b <mem_base> -l <image_length> [-s <data_length>] [-f <flash_addr>] [-e <entry_point>] [-r <ram_addr>] <name>", fis_create, FIS_cmds );// Define table boundariesCYG_HAL_TABLE_BEGIN( __FIS_cmds_TAB__, FIS_cmds);CYG_HAL_TABLE_END( __FIS_cmds_TAB_END__, FIS_cmds);extern struct cmd __FIS_cmds_TAB__[], __FIS_cmds_TAB_END__;// Local data used by these routinesstatic void *flash_start, *flash_end;static int block_size, blocks;static void *fis_work_block;// Simple XOR style checksumstatic unsigned long_cksum(unsigned long *buf, int len){ unsigned long cksum = 0; // Round 'len' up to multiple of longwords len = (len + (sizeof(unsigned long)-1)) / sizeof(unsigned long); while (len-- > 0) { cksum ^= *buf++; } return cksum;}struct fis_image_desc *fis_lookup(char *name){ int i; void *fis_addr; struct fis_image_desc *img; fis_addr = (void *)((unsigned long)flash_end - block_size); memcpy(fis_work_block, fis_addr, block_size); img = (struct fis_image_desc *)fis_work_block; for (i = 0; i < block_size/sizeof(*img); i++, img++) { if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) { return img; } } return (struct fis_image_desc *)0;}static voidfis_usage(char *why){ printf("*** invalid 'fis' command: %s\n", why); cmd_usage(__FIS_cmds_TAB__, &__FIS_cmds_TAB_END__, "fis ");}static voidfis_init(int argc, char *argv[]){ int stat, img_count = 0; struct fis_image_desc *img; void *fis_base, *err_addr;#ifdef CYGSEM_REDBOOT_FLASH_CONFIG void *cfg_base;#endif bool full_init = false; struct option_info opts[1]; unsigned long redboot_image_size, redboot_flash_start; init_opts(&opts[0], 'f', false, OPTION_ARG_TYPE_FLG, (void **)&full_init, (bool *)0, "full initialization, erases all of flash"); if (!scan_opts(argc, argv, 2, opts, 1, 0, 0, "")) { return; } if (!verify_action("About to initialize [format] FLASH image system")) { printf("** Aborted\n"); return; } printf("*** Initialize FLASH Image System\n"); redboot_flash_start = (unsigned long)flash_start + CYGBLD_REDBOOT_FLASH_BOOT_OFFSET;#define MIN_REDBOOT_IMAGE_SIZE CYGBLD_REDBOOT_MIN_IMAGE_SIZE redboot_image_size = block_size > MIN_REDBOOT_IMAGE_SIZE ? block_size : MIN_REDBOOT_IMAGE_SIZE; if (full_init) { // Erase everything except default RedBoot images, fis block, and config block. // FIXME! This still assumes that fis and config blocks can use top of FLASH. if (CYGBLD_REDBOOT_FLASH_BOOT_OFFSET == 0) { if ((stat = flash_erase((void *)((unsigned long)flash_start+(2*redboot_image_size)), ((blocks-2)*block_size) - (2*redboot_image_size), (void **)&err_addr)) != 0) { printf(" initialization failed %p: 0x%x(%s)\n", err_addr, stat, flash_errmsg(stat)); } } else { if ((stat = flash_erase(flash_start, CYGBLD_REDBOOT_FLASH_BOOT_OFFSET, (void **)&err_addr)) != 0) { printf(" initialization failed %p: 0x%x(%s)\n", err_addr, stat, flash_errmsg(stat)); } else { unsigned long erase_start, erase_size; erase_start = redboot_flash_start+(2*redboot_image_size); erase_size = (blocks-2)*block_size; erase_size -= erase_start - (unsigned long)flash_start; if (erase_size && (stat = flash_erase((void *)erase_start, erase_size, (void **)&err_addr)) != 0) { printf(" initialization failed %p: 0x%x(%s)\n", err_addr, stat, flash_errmsg(stat)); } } } } else { printf(" Warning: device contents not erased, some blocks may not be usable\n"); } // Create a pseudo image for RedBoot img = (struct fis_image_desc *)fis_work_block; memset(img, 0, sizeof(*img)); strcpy(img->name, "RedBoot"); img->flash_base = redboot_flash_start; img->mem_base = redboot_flash_start; img->size = redboot_image_size; img++; img_count++; // And a backup image memset(img, 0, sizeof(*img)); strcpy(img->name, "RedBoot[backup]"); img->flash_base = redboot_flash_start+redboot_image_size; img->mem_base = redboot_flash_start+redboot_image_size; img->size = redboot_image_size; img++; img_count++;#ifdef CYGSEM_REDBOOT_FLASH_CONFIG // And a descriptor for the configuration data memset(img, 0, sizeof(*img)); strcpy(img->name, "RedBoot config"); //cfg_base = flash_end_1- (2*block_size); cfg_base = flash_end- (2*block_size); img->flash_base = (unsigned long)cfg_base; img->mem_base = (unsigned long)cfg_base; img->size = block_size; img++; img_count++;#endif // And a descriptor for the descriptor table itself memset(img, 0, sizeof(*img)); strcpy(img->name, "FIS directory"); //fis_base = flash_end_1 - block_size; fis_base = flash_end - block_size; img->flash_base = (unsigned long)fis_base; img->mem_base = (unsigned long)fis_base; img->size = block_size; img++; img_count++;#ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL // Insure [quietly] that the directory is unlocked before trying to update flash_unlock((void *)fis_base, block_size, (void **)&err_addr);#endif if ((stat = flash_erase(fis_base, block_size, (void **)&err_addr)) != 0) { printf(" initialization failed %p: 0x%x(%s)\n", err_addr, stat, flash_errmsg(stat)); } else { if ((stat = flash_program(fis_base, fis_work_block, img_count*sizeof(*img), (void **)&err_addr)) != 0) { printf("Error writing image descriptors at %p: 0x%x(%s)\n", err_addr, stat, flash_errmsg(stat)); } }#ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL // Insure [quietly] that the directory is locked after the update flash_lock((void *)fis_base, block_size, (void **)&err_addr);#endif}static voidfis_list(int argc, char *argv[]){ struct fis_image_desc *img; int i; bool show_cksums = false; struct option_info opts[1]; init_opts(&opts[0], 'c', false, OPTION_ARG_TYPE_FLG, (void **)&show_cksums, (bool *)0, "display checksums"); if (!scan_opts(argc, argv, 2, opts, 1, 0, 0, "")) { return; } img = (struct fis_image_desc *)((unsigned long)flash_end - block_size); printf("Name FLASH addr %s Length Entry point\n", show_cksums ? "Checksum" : "Mem addr"); for (i = 0; i < block_size/sizeof(*img); i++, img++) { if (img->name[0] != (unsigned char)0xFF) { printf("%-16s 0x%08lX 0x%08lX 0x%08lX 0x%08lX\n", img->name, img->flash_base, show_cksums ? img->file_cksum : img->mem_base, img->size, img->entry_point); } }}static voidfis_free(int argc, char *argv[]){ unsigned long *fis_ptr, *fis_end; unsigned long *area_start; fis_ptr = (unsigned long *)((unsigned long)flash_start + 2*block_size); fis_end = (unsigned long *)((unsigned long)flash_end + block_size); fis_end = (unsigned long *)(unsigned long)flash_end; area_start = fis_ptr; while (fis_ptr < fis_end) { if (*fis_ptr != (unsigned long)0xFFFFFFFF) { if (area_start != fis_ptr) { // Assume that this is something printf(" 0x%08lX .. 0x%08lX\n", (unsigned long)area_start, (unsigned long)fis_ptr); } // Find next blank block area_start = fis_ptr; while (area_start < fis_end) { if (*area_start == (unsigned long)0xFFFFFFFF) { break; } area_start += block_size / sizeof(unsigned long); } fis_ptr = area_start; } else { fis_ptr += block_size / sizeof(unsigned long); } } if (area_start != fis_ptr) { printf(" 0x%08lX .. 0x%08lX\n", (unsigned long)area_start, (unsigned long)fis_ptr); }}// Find the first unused area of flash which is long enougnstatic boolfis_find_free(unsigned long *addr, unsigned long length){ unsigned long *fis_ptr, *fis_end; unsigned long *area_start; fis_ptr = (unsigned long *)((unsigned long)flash_start + 2*block_size); fis_end = (unsigned long *)(unsigned long)flash_end; area_start = fis_ptr; while (fis_ptr < fis_end) { if (*fis_ptr != (unsigned long)0xFFFFFFFF) { if (area_start != fis_ptr) { // Assume that this is something if ((fis_ptr-area_start) >= length) { *addr = (unsigned long)area_start; return true; } } // Find next blank block area_start = fis_ptr; while (area_start < fis_end) { if (*area_start == (unsigned long)0xFFFFFFFF) { break; } area_start += block_size / sizeof(unsigned long); } fis_ptr = area_start; } else { fis_ptr += block_size / sizeof(unsigned long); } } if (area_start != fis_ptr) { if ((fis_ptr-area_start) >= length) { *addr = (unsigned long)area_start; return true;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -