📄 romfs.c
字号:
//==========================================================================//// romfs.c//// ROM file system////==========================================================================//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.//// eCos is free software; you can redistribute it and/or modify it under// the terms of the GNU General Public License as published by the Free// Software Foundation; either version 2 or (at your option) any later version.//// eCos is distributed in the hope that it will be useful, but WITHOUT ANY// WARRANTY; without even the implied warranty of MERCHANTABILITY or// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License// for more details.//// You should have received a copy of the GNU General Public License along// with eCos; if not, write to the Free Software Foundation, Inc.,// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.//// As a special exception, if other files instantiate templates or use macros// or inline functions from this file, or you compile this file and link it// with other works to produce a work based on this file, this file does not// by itself cause the resulting work to be covered by the GNU General Public// License. However the source code for this file must still be made available// in accordance with section (3) of the GNU General Public License.//// This exception does not invalidate any other reasons why a work based on// this file might be covered by the GNU General Public License.//// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.// at http://sources.redhat.com/ecos/ecos-license/// -------------------------------------------//####ECOSGPLCOPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s): nickg// Contributors: nickg, richard.panton@3glab.com// Date: 2000-07-25// Purpose: ROM file system// Description: This is a ROM filesystem for eCos. It attempts to// provide full POSIX-compatible filesystem behaviour// while at the same time being efficient in terms of// time and space used.// ////####DESCRIPTIONEND####////==========================================================================// // General Description// ===================// // This is an implementation of a ROM filesystem for eCos. Its goal is// to provide a working example of a filesystem that provides most of// the required POSIX functionality. And obviously it may also be// useful in its own right.////// Header// ------//// There is a single header that describes the overall format of the ROMFS// disk. The address of this header is used as the base for all offsets used// in the node and directory structures. It contains the following fields://// label - A human readable label for various purposes// fssize - The size in bytes of the entire ROMFS disk// nodes - A count of the nodes in the disk//// Immediately following thisin memory is the node table, consisting of// 'nodes' repetitions of the node object.//// Nodes// -----//// All files and directories are represented by node objects. Each// romfs_node structure contains the following fields://// mode - Node type, file or directory.// nlink - Number of links to this node. Each directory entry that references// this node is a link. // size - Size of the data in this node in bytes.// ctime - Creation time of the file (NOT the ROMFS)// data - Offset of the first data byte for this node from the header//// Directories// -----------//// A directory is a node whose data is a list of directory entries.// These contain the// following fields://// node - Index of the node in the romfs_disk table that is referenced by// this entry. This is present in every directory entry fragment.// next - Offset of the next name entry.// name - The filename associated with this link to the node.//// Data Storage// ------------//// Each file has its data stored in a single contiguous memory block// referenced by the offset in the node.////==========================================================================#include <pkgconf/system.h>#include <pkgconf/hal.h>#include <pkgconf/kernel.h>#include <pkgconf/io_fileio.h>#include <pkgconf/fs_rom.h>#include <cyg/kernel/ktypes.h> // base kernel types#include <cyg/infra/cyg_trac.h> // tracing macros#include <cyg/infra/cyg_ass.h> // assertion macros#include <unistd.h>#include <sys/types.h>#include <fcntl.h>#include <sys/stat.h>#include <errno.h>#include <dirent.h>#include <stdarg.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <cyg/fileio/fileio.h>#include <cyg/kernel/kapi.h>#include <cyg/infra/diag.h>//==========================================================================// Eventually we want to eXecute In Place from the ROM in a protected// environment, so we'll need executables to be aligned to a boundary// suitable for MMU protection. A suitable boundary would be the 4k// boundary in all the CPU architectures I am currently aware of.// Forward definitions// Filesystem operationsstatic int romfs_mount ( cyg_fstab_entry *fste, cyg_mtab_entry *mte );static int romfs_umount ( cyg_mtab_entry *mte );static int romfs_open ( cyg_mtab_entry *mte, cyg_dir dir, const char *name, int mode, cyg_file *fte );static int romfs_opendir ( cyg_mtab_entry *mte, cyg_dir dir, const char *name, cyg_file *fte );static int romfs_chdir ( cyg_mtab_entry *mte, cyg_dir dir, const char *name, cyg_dir *dir_out );static int romfs_stat ( cyg_mtab_entry *mte, cyg_dir dir, const char *name, struct stat *buf);static int romfs_getinfo ( cyg_mtab_entry *mte, cyg_dir dir, const char *name, int key, void *buf, int len );static int romfs_setinfo ( cyg_mtab_entry *mte, cyg_dir dir, const char *name, int key, void *buf, int len );// File operationsstatic int romfs_fo_read (struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);static int romfs_fo_lseek (struct CYG_FILE_TAG *fp, off_t *pos, int whence );static int romfs_fo_ioctl (struct CYG_FILE_TAG *fp, CYG_ADDRWORD com, CYG_ADDRWORD data);static int romfs_fo_fsync (struct CYG_FILE_TAG *fp, int mode ); static int romfs_fo_close (struct CYG_FILE_TAG *fp);static int romfs_fo_fstat (struct CYG_FILE_TAG *fp, struct stat *buf );static int romfs_fo_getinfo (struct CYG_FILE_TAG *fp, int key, void *buf, int len );static int romfs_fo_setinfo (struct CYG_FILE_TAG *fp, int key, void *buf, int len );// Directory operationsstatic int romfs_fo_dirread (struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);static int romfs_fo_dirlseek (struct CYG_FILE_TAG *fp, off_t *pos, int whence );//==========================================================================// Filesystem table entries// -------------------------------------------------------------------------// Fstab entry.// This defines the entry in the filesystem table.// For simplicity we use _FILESYSTEM synchronization for all accesses since// we should never block in any filesystem operations.FSTAB_ENTRY( romfs_fste, "romfs", 0, CYG_SYNCMODE_FILE_FILESYSTEM|CYG_SYNCMODE_IO_FILESYSTEM, romfs_mount, romfs_umount, romfs_open, (cyg_fsop_unlink *)cyg_fileio_erofs, (cyg_fsop_mkdir *)cyg_fileio_erofs, (cyg_fsop_rmdir *)cyg_fileio_erofs, (cyg_fsop_rename *)cyg_fileio_erofs, (cyg_fsop_link *)cyg_fileio_erofs, romfs_opendir, romfs_chdir, romfs_stat, romfs_getinfo, romfs_setinfo);// -------------------------------------------------------------------------// mtab entry.// This defines a single ROMFS loaded into ROM at the configured address//// MTAB_ENTRY( rom_mte, // structure name// "/rom", // mount point// "romfs", // FIlesystem type// "", // hardware device// (CYG_ADDRWORD) CYGNUM_FS_ROM_BASE_ADDRESS // Address in ROM// );// -------------------------------------------------------------------------// File operations.// This set of file operations are used for normal open files.static cyg_fileops romfs_fileops ={ romfs_fo_read, (cyg_fileop_write *)cyg_fileio_erofs, romfs_fo_lseek, romfs_fo_ioctl, cyg_fileio_seltrue, romfs_fo_fsync, romfs_fo_close, romfs_fo_fstat, romfs_fo_getinfo, romfs_fo_setinfo};// -------------------------------------------------------------------------// Directory file operations.// This set of operations are used for open directories. Most entries// point to error-returning stub functions. Only the read, lseek and// close entries are functional.static cyg_fileops romfs_dirops ={ romfs_fo_dirread, (cyg_fileop_write *)cyg_fileio_enosys, romfs_fo_dirlseek, (cyg_fileop_ioctl *)cyg_fileio_enosys, cyg_fileio_seltrue, (cyg_fileop_fsync *)cyg_fileio_enosys, romfs_fo_close, (cyg_fileop_fstat *)cyg_fileio_enosys, (cyg_fileop_getinfo *)cyg_fileio_enosys, (cyg_fileop_setinfo *)cyg_fileio_enosys};//==========================================================================// Data typedefs// Some forward typedefs for the main data structures.struct romfs_disk;typedef struct romfs_disk romfs_disk;struct romfs_node;typedef struct romfs_node romfs_node;struct romfs_dirent;typedef struct romfs_dirent romfs_dirent;//==========================================================================// File and directory node// This data structure represents a file or directory. struct romfs_node{ cyg_uint32 mode; // 0-3 node type cyg_ucount32 nlink; // 4-7 number of links to this node cyg_uint16 uid; // 8-9 Owner id cyg_uint16 gid; // 10-11 Group id cyg_uint32 size; // 12-15 size of file in bytes cyg_uint32 ctime; // 16-19 creation status time cyg_uint32 offset; // 20-23 offset of data from start of ROMFS cyg_uint32 pad[2]; // 24-31 padding to align to 32byte boundary};//==========================================================================// Directory entry.// Variable sized entry containing the name and node of a directory entrystruct romfs_dirent{ cyg_ucount32 node; // Index of node in romfs_disk structure cyg_uint32 next; // Offset from start of directory of // a) the next entry, or // b) the end of the directory data char name[0]; // The name, NUL terminated};//==========================================================================// ROMFS header// This data structure contains overall information on the ROMFSstruct romfs_disk{ cyg_uint32 magic; // 0-3 Marks a valid ROMFS entry cyg_ucount32 nodecount; // 4-7 Count of nodes in this filesystem cyg_ucount32 disksize; // 8-11 Count of bytes in this filesystem cyg_uint32 dev_id; // 12-15 ID of disk (put into stat.st_dev) char name[16]; // 16-31 Name - pads to 32 bytes romfs_node node[0];};#define ROMFS_MAGIC 0x526f6d2e // The magic signature word for a romfs#define ROMFS_CIGAM 0x2e6d6f52 // The byte sex is wrong if you see this//==========================================================================// Directory search data// Parameters for a directory search. The fields of this structure are// updated as we follow a pathname through the directory tree.struct romfs_dirsearch{ romfs_disk *disk; // disk structure romfs_node *dir; // directory to search const char *path; // path to follow romfs_node *node; // Node found const char *name; // last name used int namelen; // name fragment length cyg_bool last; // last name in path?};typedef struct romfs_dirsearch romfs_dirsearch;//==========================================================================// This seems to be the only string function referenced. Define as static// here to avoid having to load the string librarystatic bool match( const char *a, const char *b, int len ){ for ( ; len > 0 && *a && *b && *a == *b ; a++, b++, len-- ) ; return ( len == 0 );} //==========================================================================// SIMPLE buffer management.// Each node has a data buffer pointer and a size.// -------------------------------------------------------------------------// findbuffer_node()// return a pointer to the data at the indicated file position.static int findbuffer_node( romfs_disk *disk, // header pointer romfs_node *node, // node pointer off_t pos, // data position to get cyg_uint8 **buffer, // returned buffer pointer size_t *size) // returned buffer size{ if ( pos >= node->size || node->size == 0 ) { // Indicate end of data. *size = 0; } else { // Calculate the buffer position *buffer = (cyg_uint8*)disk + node->offset + pos; *size = node->size-pos; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -