⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flash.c

📁 基于ecos的redboot
💻 C
📖 第 1 页 / 共 5 页
字号:
//==========================================================================
//
//      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>
#include <cyg/hal/hal_ixdp2400.h>        // Hardware definitions
#include <cyg/hal/hal_platform_ints.h>

externC int qdr_ch_sz_array[MAX_QDR_CHANNEL];

// CLI function
static cmd_fun do_fis;
RedBoot_cmd("fis", 
            "Manage FLASH images", 
            "{cmds}",
            do_fis
    );

#ifdef CYGOPT_REDBOOT_FIS
// Image management functions
local_cmd_entry("init",
                "Initialize FLASH Image System [FIS]",
                "[-f]",
                fis_init,
                FIS_cmds
    );
#ifdef CYGSEM_REDBOOT_FIS_CRC_CHECK
# define FIS_LIST_OPTS "[-c] [-d]"
#else
# define FIS_LIST_OPTS "[-d]"
#endif
local_cmd_entry("list",
                "Display contents of FLASH Image System [FIS]",
                FIS_LIST_OPTS,
                fis_list,
                FIS_cmds
    );
local_cmd_entry("free",
                "Display free [available] locations within FLASH Image System [FIS]",
                "",
                fis_free,
                FIS_cmds
    );
local_cmd_entry("delete",
                "Display an image from FLASH Image System [FIS]",
                "name",
                fis_delete,
                FIS_cmds
    );

static char fis_load_usage[] = 
#ifdef CYGPKG_COMPRESS_ZLIB
                      "[-d] "
#endif
                      "[-b <memory_load_address>] [-c] [-w] name";

local_cmd_entry("load",
                "Load image from FLASH Image System [FIS] into RAM",
                fis_load_usage,
                fis_load,
                FIS_cmds
    );
local_cmd_entry("create",
                "Create an image",
                "-b <mem_base> -l <image_length> [-s <data_length>]\n"
                "      [-f <flash_addr>] [-e <entry_point>] [-r <ram_addr>] [-n] <name>",
                fis_create,
                FIS_cmds
    );
#endif

// Raw flash access functions
local_cmd_entry("erase",
                "Erase FLASH contents",
                "-f <flash_addr> -l <length>",
                fis_erase,
                FIS_cmds
    );
#ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING
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
    );
#endif
local_cmd_entry("write",
                "Write raw data directly to FLASH",
                "-f <flash_addr> -b <mem_base> -l <image_length>",
                fis_write,
                FIS_cmds
    );

// Define table boundaries
CYG_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 routines
static void *flash_start, *flash_end;
static int block_size, blocks;
static void *fis_work_block;
static int fisdir_size;  // Size of FIS directory.  Note: zero if FIS not enabled
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
static void *cfg_base;   // Location in Flash of config data
static int   cfg_size;   // Length of config data - rounded to Flash block size
#endif

static void charcpy(unsigned char *dest, unsigned char *src, int len)
{
	int i;

	for(i = 0; i < len; i++)
		dest[i] = src[i];

	return;
}

static void
fis_usage(char *why)
{
    printf("*** invalid 'fis' command: %s\n", why);
    cmd_usage(__FIS_cmds_TAB__, &__FIS_cmds_TAB_END__, "fis ");
}

#ifdef CYGOPT_REDBOOT_FIS
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);
    charcpy(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 void
fis_init(int argc, char *argv[])
{
    int stat;
    struct fis_image_desc *img;
    void *fis_base, *err_addr, *syslog_base;
    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");

#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;

    // Create a pseudo image for RedBoot
    img = (struct fis_image_desc *)fis_work_block;
#ifdef CYGOPT_REDBOOT_FIS_RESERVED_BASE
    memset(img, 0, sizeof(*img));
    strcpy(img->name, "(reserved)");
    img->flash_base = (unsigned long)flash_start;
    img->mem_base = (unsigned long)flash_start;
    img->size = CYGNUM_REDBOOT_FLASH_RESERVED_BASE;
    img++;
#endif
    redboot_flash_start = (unsigned long)flash_start + CYGBLD_REDBOOT_FLASH_BOOT_OFFSET;
#ifdef CYGOPT_REDBOOT_FIS_REDBOOT
    memset(img, 0, sizeof(*img));
    strcpy(img->name, "RedBoot");
    img->flash_base = redboot_flash_start;
    img->size = redboot_image_size;
    img++;
    redboot_flash_start += redboot_image_size;
#endif
#ifdef CYGOPT_REDBOOT_FIS_REDBOOT_POST
#ifdef CYGNUM_REDBOOT_FIS_REDBOOT_POST_OFFSET
    // Take care to place the POST entry at the right offset:
    redboot_flash_start = (unsigned long)flash_start + CYGNUM_REDBOOT_FIS_REDBOOT_POST_OFFSET;
#endif
    memset(img, 0, sizeof(*img));
    strcpy(img->name, "RedBoot[post]");
    img->flash_base = redboot_flash_start;
    img->mem_base = redboot_flash_start;
    img->size = redboot_image_size;
    img++;
    redboot_flash_start += redboot_image_size;
#endif
#ifdef CYGOPT_REDBOOT_FIS_REDBOOT_BACKUP
    // And a backup image
    memset(img, 0, sizeof(*img));
    strcpy(img->name, "RedBoot[backup]");
    img->flash_base = redboot_flash_start;
    img->mem_base = redboot_flash_start;
    img->size = redboot_image_size;
    img++;
    redboot_flash_start += redboot_image_size;
#endif
	// a descriptor for system logs
	memset(img, 0, sizeof(*img));
    strcpy(img->name, "System Log");
    syslog_base = (void *)((unsigned long)flash_end - (3 * block_size));
    img->flash_base = (unsigned long)syslog_base;
    img->mem_base = (unsigned long)syslog_base;
    img->size = block_size;
    img++;
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
    // And a descriptor for the configuration data
    memset(img, 0, sizeof(*img));
    strcpy(img->name, "RedBoot config");
    img->flash_base = (unsigned long)cfg_base;
    img->mem_base = (unsigned long)cfg_base;
    img->size = cfg_size;
    img++;
#endif
    // And a descriptor for the descriptor table itself
    memset(img, 0, sizeof(*img));
    strcpy(img->name, "FIS directory");
    fis_base = (void *)((unsigned long)flash_end - block_size);
    img->flash_base = (unsigned long)fis_base;
    img->mem_base = (unsigned long)fis_base;
    img->size = block_size;
    img++;

    // Do this after creating the initialized table because that inherently
    // calculates where the high water mark of default RedBoot images is.

    if (full_init) {
        unsigned long erase_start, erase_size;
        // 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.

        // first deal with the possible first part, before RedBoot images:
        erase_start = (unsigned long)flash_start + CYGNUM_REDBOOT_FLASH_RESERVED_BASE;
        erase_size =  (unsigned long)flash_start + CYGBLD_REDBOOT_FLASH_BOOT_OFFSET;
        if ( erase_size > erase_start ) {
            erase_size -= erase_start;
            if ((stat = flash_erase((void *)erase_start, erase_size,
                                    (void **)&err_addr)) != 0) {
                printf("   initialization failed at %p: %s\n",
                       err_addr, flash_errmsg(stat));
            }
        }
        // second deal with the larger part in the main:
        erase_start = redboot_flash_start; // high water of created images
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
        erase_size = (unsigned long)cfg_base - erase_start; // the gap between HWM and config data
#else
        erase_size = (unsigned long)fis_base - erase_start; // the gap between HWM and fis data
#endif
        if ((stat = flash_erase((void *)erase_start, erase_size,
                                (void **)&err_addr)) != 0) {
            printf("   initialization failed at %p: %s\n",
                   err_addr, flash_errmsg(stat));
        }
    } else {
        printf("    Warning: device contents not erased, some blocks may not be usable\n");
    }

#ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL
    // Ensure [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 at %p: %s\n", err_addr, flash_errmsg(stat));
    } else {
        if ((stat = flash_program(fis_base, fis_work_block, 
                                  (unsigned long)img - (unsigned long)fis_work_block,
                                  (void **)&err_addr)) != 0) {
            printf("Error writing image descriptors at %p: %s\n", 
                   err_addr, flash_errmsg(stat));
        }
    }
#ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL
    // Ensure [quietly] that the directory is locked after the update
    flash_lock((void *)fis_base, block_size, (void **)&err_addr);
	// lock BM blocks also
	flash_lock((void *)flash_start, MIN_REDBOOT_IMAGE_SIZE, (void **)&err_addr);
#endif
}

static void
fis_list(int argc, char *argv[])
{
    struct fis_image_desc *img;
    int i;
    bool show_cksums = false;
    bool show_datalen = false;
    struct option_info opts[2];

    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;
    }

    img = (struct fis_image_desc *)((unsigned long)flash_end - block_size);
    // Let printf do the formatting in both cases, rather than cnouting
    // cols by hand....
    printf("%-16s  %-10s  %-10s  %-10s  %-s\n",
           "Name","FLASH addr",
           show_cksums ? "Checksum" : "Mem addr",
           show_datalen ? "Datalen" : "Length",
           "Entry point" );
    for (i = 0;  i < block_size/sizeof(*img);  i++, img++) {
		struct fis_image_desc temp;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -