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

📄 romfs.c

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
//==========================================================================
//
//      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 operations
static 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 operations
static 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 operations
static 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 entry

struct 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 ROMFS

struct 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 library

static 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 + -