📄 bootconfig.c
字号:
/***************************************** Copyright (c) 2001-2002 Sigma Designs, Inc. All Rights Reserved Proprietary and Confidential *****************************************//* This file is part of the boot loader *//* * bootconfig.c * * first revision by Ho Lee 10/30/2002 * configuration load & save 11/11/2002 */#include "config.h"#include "uart.h"#include "util.h"#include "bootconfig.h"#include "flash.h"//// configuration structure//// configuration is not saved always on the same area. because flash can't be overwritten// and it needs erasing before writing, it is not good idea to overwrite and burn flash // every time. so reserve some flash area for configuration, and write the new configuration// on the next available space, and mark which configuration is the last on the header//// header : (from = BOOTCONFIG_FLASHSTART, size = BOOTCONFIG_HEADSIZE)// signature (4 bytes) : BOOTCONFIG_HEADSIGN// bytes of bit-stream : bit 0 means 'configuration saved' // make use of the fact that : for the flash memory, only changing bit 1 to 0 is possible// 0xff : not saved// 0xfe : 1 saved// 0xfc : 2 saved// body : (from = BOOTCONFIG_FLASHSTART + BOOTCONFIG_HEADSIZE, size = BOOTCONFIG_SIZE)// bootconfig_t////#define BOOTCONFIG_FLASHSTART 0x1ff000#define BOOTCONFIG_FLASHSTART 0x3ff000//#define BOOTCONFIG_FLASHEND 0x200000#define BOOTCONFIG_FLASHEND 0x400000#define BOOTCONFIG_FLASHBUF 0x010000#define BOOTCONFIG_HEADSIZE 0x100#define BOOTCONFIG_SIZE 0x100#define BOOTCONFIG_MAXSAVE ((BOOTCONFIG_FLASHEND - BOOTCONFIG_FLASHSTART - BOOTCONFIG_HEADSIZE) / BOOTCONFIG_SIZE)#define BOOTCONFIG_POS(x) (BOOTCONFIG_FLASHSTART + BOOTCONFIG_HEADSIZE + (x) * BOOTCONFIG_SIZE)//// global variable//bootconfig_t g_bootconfig = { 1, // major 0, // minor BOOTCONFIG_BODYSIGN, // checksum { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 }, // MAC address BOOTNET_NONE, // protocol 0x00000000, // IP address 0x00000000, // netmask 0x00000000, // gateway 0x00000000, // server 0x00000000, // DNS "localdomain.com", // domain DEFAULT_LOADER_FILENAME, // DEFAULT_ROMFS_FILENAME, // DEFAULT_KERNEL_FILENAME, //};//// function prototypes//int bootconfig_load(int index);int bootconfig_save(void);int bootconfig_lastsaved(int *idx);static int bootconfig_format(void);//// Load & Save//// index : // 0 : last saved// > 0 : specified index-th saved configurationint bootconfig_load(int index){ bootconfig_t config; int last; // check if flash exists if (!flash_addr_found(BOOTCONFIG_FLASHSTART)) return 1; // find the last saved configuration if (index > 0) last = index; else if ((last = bootconfig_lastsaved(NULL)) <= 0) return 2;//PrintFormat("bootconfig_load last = %d\n", last); // read configuration flash_read_data(BOOTCONFIG_POS(last - 1), &config, sizeof config); // check if the configuration is valid if (config.checksum != BOOTCONFIG_BODYSIGN) return 3; if (config.major_version > BOOTCONFIG_MAJOR || (config.major_version == BOOTCONFIG_MAJOR && config.minor_version > BOOTCONFIG_MINOR)) return 4; // load configuration to current configuration memcpy(&g_bootconfig, &config, sizeof g_bootconfig); return 0;}int bootconfig_save(void){ int lastidx, last; unsigned int val; int needformat = 0; // check if flash exists if (!flash_addr_found(BOOTCONFIG_FLASHSTART)) return 1; // find the last saved configuration//PrintFormat("lastidx=%d last=%d\n", lastidx, last); if ((last = bootconfig_lastsaved(&lastidx)) <= 0 || last == BOOTCONFIG_MAXSAVE) { needformat = 1;//PrintFormat("step 1 for needformat \n"); } else if (!flash_writable(BOOTCONFIG_POS(last), BOOTCONFIG_SIZE)) { needformat = 1;//PrintFormat("step 2 for needformat \n"); } needformat = 1; // if the configuration are is not formatted, or can't save any more configuration // format the area if (needformat) { bootconfig_format(); lastidx = 4; last = 0; } PrintUart("Writing : ", -1); // write configuration flash_write_data(BOOTCONFIG_POS(last), (unsigned char *) &g_bootconfig, sizeof g_bootconfig); // update header last &= 0x07; val = 0xff; val >>= (last + 1); val <<= (last + 1); flash_write_onebyte(BOOTCONFIG_FLASHSTART + lastidx, val); PrintUart("\r\n", -1); return 0;}// return the last saved configuration index + 1// return < 0 : invalid, needs formatting// return 0 : no configuration saved // return x > 0 : (x - 1) configuration savedint bootconfig_lastsaved(int *idx){ int i, pos, bit; unsigned char head[BOOTCONFIG_HEADSIZE]; flash_read_data(BOOTCONFIG_FLASHSTART, head, BOOTCONFIG_HEADSIZE); if (idx) *idx = 0; if (*(unsigned int *) head != BOOTCONFIG_HEADSIGN) return -1; for (i = 4, pos = 0; i < BOOTCONFIG_HEADSIZE; ++i) if (head[i] != 0x00) { pos = (i - 4) * 8; for (bit = 0; bit < 8; ++bit) { if ((head[i] & (1 << bit)) != 0) break; } pos += bit; break; } if (idx) *idx = i;//PrintFormat("[bootconfig_lastsave] *idx=0x%x, pos=0x%x\n", *idx, pos); return pos;}int bootconfig_format(void){ unsigned int blockstart, blocklen; unsigned char buf[BOOTCONFIG_FLASHBUF]; if ((flash_calcblock(BOOTCONFIG_FLASHSTART, &blockstart, &blocklen)) != 0) return 1; if (BOOTCONFIG_FLASHBUF < blocklen) { PrintUart("Out of buffer memory\r\n", -1); return 2; } // before erasing, preserve the data flash_read_data(blockstart, buf, blocklen); memset(buf + (BOOTCONFIG_FLASHSTART - blockstart), 0xff, BOOTCONFIG_FLASHEND - BOOTCONFIG_FLASHSTART); *(unsigned int *)(buf + BOOTCONFIG_FLASHSTART - blockstart) = BOOTCONFIG_HEADSIGN;PrintFormat("Erase Block Addr = 0x%x Len=%d\n", blockstart, blocklen); PrintUart("Formatting : ", -1); flash_erase_oneblock(blockstart); flash_write_data(blockstart, buf, blocklen); PrintUart("\r\n", -1); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -