📄 flashfslib.c
字号:
/* ############################################################################ (c) Copyright Virata Limited 1998## Virata Limited Confidential and Proprietary## The following software source code ("Software") is strictly confidential and# is proprietary to Virata Limited ("Virata"). It may only be read, used,# copied, adapted, modified or otherwise dealt with by you if you have# entered into a confidentiality agreement with Virata and then subject to the# terms of that confidentiality agreement and any other applicable agreement# between you and Virata. If you are in any doubt as to whether you are# entitled to access, read, use, copy, adapt, modify or otherwise deal with# the Software or whether you are entitled to disclose the Software to any# other person you should contact Virata. If you have not entered into a# confidentiality agreement with Virata granting access to this Software you# should forthwith return all media, copies and printed listings containing# the Software to Virata.## Virata reserves the right to take legal action against you should you breach# the above provisions.## If you are unsure, or to report violations, please contact# support@virata.com# ##########################################################################*//*********************************************************************** * * * ATMOS FLASH Filing System library code * * * * FLASHFSLIB.C * * * * * * This source provides a low level API through which an FLASHFS * * format file area may be accessed. * * This library is used, primarly, by the boot code and ATMOS * * flashfs. Do NOT use it directly from ATMOS if flashfs is * * present - use flashfs. * * * ***********************************************************************/#include <stdio.h>#include "config.h"#include "atypes.h"#include "string.h"#include "flash.h"#include "flashfslib.h"/*====================================================================*//* Type and macro definitions *//*====================================================================*//*** May only use one method of specifying an emergency flashfs*/#if defined(NUM_FIXED_FLASH_DEVICES) && defined(EMERGENCY_FLASHFS_SIZE)#error "You may not define both NUM_FIXED_FLASH_DEVICES and EMERGENCY_FLASHFS_SIZE"#endif/*** If NUM_FIXED_FLASH_DEVICES or EMERGENCY_FLASHFS_SIZE are zero then** it is the same as saying no emergency flashfs.*/#if defined (NUM_FIXED_FLASH_DEVICES) && (NUM_FIXED_FLASH_DEVICES == 0)#undef NUM_FIXED_FLASH_DEVICES#endif#if defined(EMERGENCY_FLASHFS_SIZE) && (EMERGENCY_FLASHFS_SIZE == 0)#undef EMERGENCY_FLASHFS_SIZE#endif/*** Sanity check values*/#if defined (NUM_FIXED_FLASH_DEVICES) && (NUM_FIXED_FLASH_DEVICES >= NUM_FLASH_DEVICES)#error "Too many chips specified for emergency FLASHFS"#elif defined (EMERGENCY_FLASHFS_SIZE) && ((EMERGENCY_FLASHFS_SIZE + FLASH_START_OFFSET) >= TOTAL_FLASH_SIZE)#error "Emergency FLASHFS is too large"#endif/*** Set up partition definitions.*/#if defined (NUM_FIXED_FLASH_DEVICES) || defined (EMERGENCY_FLASHFS_SIZE)#define NUM_PARTITIONS (2)#else#define NUM_PARTITIONS (1)#endif#define TOKEN_FIXED_LIST 0x80000000typedef struct PartitionTag{ BOOL isValid; BOOL checked; U32 startOffset; U32 endOffset; /* ** The actual start offset may be modified by what is present in ** memory. */ U32 actualStartOffset;} Partition;/*====================================================================*//* Forward definitions of procedures in this module *//*====================================================================*//*====================================================================*//* Variables *//*====================================================================*/static FLASHFS_ROOT flashfs_root;static BOOL initialised = FALSE;static Partition partitions [NUM_PARTITIONS] ={};/*** Global data*/U32 flashStartOffset;U32 flashfsSize;/*====================================================================*//* Implementation *//*====================================================================*/void flashfslib_initialise (void){ static BOOL libraryInitialised = FALSE; if (!libraryInitialised) { U32 totalSize = flash_total_size (NUM_FLASH_DEVICES); /* ** Set up compile time boundaries for flash partitions. ** Note that partitions are set up such that lower indices represent ** partitions that are higher in logical memory. */#ifdef EMERGENCY_FLASHFS_SIZE U32 boundary = FLASH_START_OFFSET + EMERGENCY_FLASHFS_SIZE; partitions [0].startOffset = boundary; partitions [0].endOffset = totalSize; partitions [1].startOffset = FLASH_START_OFFSET; partitions [1].endOffset = boundary;#elif defined (NUM_FIXED_FLASH_DEVICES) U32 boundary = flash_total_size (NUM_FLASH_DEVICES - NUM_FIXED_FLASH_DEVICES); partitions [0].startOffset = boundary; partitions [0].endOffset = totalSize; partitions [1].startOffset = FLASH_START_OFFSET; partitions [1].endOffset = boundary;#else partitions [0].startOffset = FLASH_START_OFFSET; partitions [0].endOffset = totalSize;#endif /* ** Complete other fields. */ for (totalSize = 0; totalSize < NUM_PARTITIONS; totalSize++) { partitions [totalSize].checked = FALSE; /* Not checked */ partitions [totalSize].isValid = FALSE; /* and not valid until checked */ /* ** Actual offset initially same as that compiled but may be adjusted by what ** is actually _in_ flash memory. */ partitions [totalSize].actualStartOffset = partitions [totalSize].startOffset; } libraryInitialised = TRUE; } return;}/*** Name: flashfs_initialise**** Purpose: Initialise system for filing system located at specific address.**** Checks that there is a filing system located in the region of memory specified.**** Arguments:** startOffset Where the flashfs should start** totalSize Size of the flashfs in bytes****** Result:** 0 Invalid filing system.** 1 Valid filing system.***/U32 flashfs_initialise (U32 startOffset, U32 totalSize){ U32 rc = 1; FLASH_HEADER flashfs_header; flashfslib_initialise (); /* ** Until this routine completes successfully there is no valid flashfs. */ initialised = FALSE; /* ** Set up internal flash table structures. */ flash_initialise (FALSE); /* ** Start offset and flashfs file area size, use compiled literals. */ flashStartOffset = startOffset; flashfsSize = totalSize - flashStartOffset; /* ** Read header from top of flash memory. */ flashfs_read_data (flashfsSize - sizeof flashfs_header, (BYTE *) &flashfs_header, sizeof flashfs_header); /* ** Sanity check start offset value read from flash, ignore big values. */ if (flashfs_header.flash_start_offset < totalSize) { /* ** Recalculate offset & size from value read from flash, it looks good */ flashStartOffset = flashfs_header.flash_start_offset; flashfsSize = totalSize - flashStartOffset; /* ** Check for file system id. */ flashfs_read_data (0, (BYTE *) &flashfs_root, sizeof flashfs_root); if (0 == strncmp (flashfs_root.volser, "ISFSV1", sizeof flashfs_root.volser)) { /* ** Two fields in the header are reserved and 0. Test for this. */ if ((flashfs_header.spare [0] == 0) && (flashfs_header.spare [1] == 0)) { /* ** Checksum validated elsewhere */ initialised = TRUE; rc = 0; } } } return rc;}/*** Name: flashfs_find_validfs**** Purpose: Find a valid filing system in the flash chips**** On systems which have removable and fixed flash chips, there** may be more than one valid filing system. This function allows** iteration through those filing systems.**** Arguments:** token Magic token, see definitions below.** returnCode Whether (this) filing system is valid.**** Result:** 0 No more files or error** <>0 File entry read (next value of token)***/U32 flashfs_find_validfs (U32 token, int *returnCode){ assert(NULL != returnCode); if (NULL == returnCode) { token = 0; } else if (token < NUM_PARTITIONS) { U32 err; *returnCode = flashfslib_PartitionCheck (token, FALSE, &err); if (ESUCCESS == *returnCode) { /* ** Set standard variables */ flashStartOffset = partitions [token].actualStartOffset; flashfsSize = partitions [token].endOffset - partitions [token].actualStartOffset; initialised = TRUE; } token++; if (token == NUM_PARTITIONS) { token = 0; } } else { *returnCode = EINVAL; token = 0; } return token;}/*** Name: flashfs_find_file**** Purpose: Find the specified file in the FLASH filing system**** This function searches the FLASH file system for the required file.** If the file system is empty or corrupt then its contents are not read and** the search fails. If the file is found, the address of the data portion is** returned. Note: this is a logical FLASH filing system address, not an ** absolute memory address. The return value can be passed to the ** 'flashfs_read_data' function to read the contents of the desired file.**** Arguments:** pname Desired filename** plen Pointer to length vairable (set if file found)****** Result:** dataAddr Logical FLASH address of data portion of file (or 0)***/U32 flashfs_find_file(char *name, U32 *len){ FLASHFS_DIRENT entry; U32 max_file_addr, file_addr, entry_addr; /* start by checking the filing system appears sensible, assume NOTHING */ /* this code is a slightly simplified version of 'flashfs_fsck' */ /* with a search for filename appended. */ if (!initialised) { if (flashfs_initialise (FLASH_START_OFFSET, TOTAL_FLASH_SIZE)) { return 0; } } /* read the flash volroot structure from start of file area */ flashfs_read_data(0, (BYTE *)&flashfs_root, sizeof flashfs_root); /* maximum address to be reached by a file */ max_file_addr = flashfsSize - sizeof(FLASH_HEADER); /* leaf down dynamic list checking for the filename we are looking for. */ for (entry_addr=flashfs_root.first.dynamic, file_addr=0; entry_addr && !file_addr; entry_addr=entry.next) { /* check next address is 'sensible' and will fit */ if ((entry_addr + sizeof entry) < max_file_addr) { /* read the file entry */ flashfs_read_data(entry_addr, (BYTE *)&entry, sizeof entry); /* if length field not sensible, error */ if ((entry_addr + sizeof entry + entry.len) > max_file_addr) return 0; /* is it the file we want ? */ if (strncmp(entry.name, name, sizeof entry.name) == 0) file_addr = entry_addr; } /* good link, read next file */ else /* broken link in FLASH dynamic file area */ return 0; } /* walk down dynamic file list */ /* leaf down fixed list checking for the filename we are looking for. */ /* If 'file_addr' is set from above, we've found the file, drop through */ for (entry_addr=flashfs_root.first.fixed; entry_addr && !file_addr; entry_addr=entry.next) { /* check next address is 'sensible' and will fit */ if ((entry_addr + sizeof entry) < max_file_addr) { /* read the file entry */ flashfs_read_data(entry_addr, (BYTE *)&entry, sizeof entry); /* if length field not sensible, error */ if ((entry_addr + sizeof entry + entry.len) > max_file_addr)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -