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

📄 ext2fs.c

📁 某个ARM9板子的实际bootloader 对裁剪
💻 C
📖 第 1 页 / 共 2 页
字号:
//==========================================================================////      e2fs.c////      RedBoot support for second extended filesystem////==========================================================================//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.// Copyright (C) 2003 Gary Thomas <gary@mind.be>//// 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):    msalter// Contributors: msalter// Date:         2001-07-14// Purpose:      // Description:  //              // This code is part of RedBoot (tm).////####DESCRIPTIONEND####////==========================================================================#include <define.h>#include <api.h>#include <board_config.h>#include <sl2312.h>#ifdef BOARD_SUPPORT_IDE#include "ide.h"#include "ext2fs.h"#define MAX_FILES			2#define ext2fs_printf// only one open file every timeFILE_T 				file_info[MAX_FILES];static UINT32		blockbuf[EXT2_MAX_BLOCK_SIZE/sizeof(UINT32)];static EXT2_DESC_T	ext2fs_desc;FILE_T				*kernel_fp;FILE_T				*initrd_fp;FILE_T *ext2fs_open(char *filepath);static int ext2fs_mount(IDE_PART_T *part, EXT2_DESC_T *desc);static int ext2fs_get_gdesc(EXT2_DESC_T *ext2fs, UINT32 group_nr, EXT2_GROUP_T *gdesc);static int ext2fs_get_inode(EXT2_DESC_T *ext2fs, int ino, EXT2_INODE_T *ip);static int ext2fs_inode_block(EXT2_DESC_T *ext2fs, EXT2_INODE_T *inode,		 						UINT32 bindex, UINT32 *pblknr);static EXT2_DIR_T *search_dir_block(EXT2_DESC_T *ext2fs, UINT32 *blkbuf,		 							char *name, int namelen, int type);static EXT2_DIR_T * ext2fs_dir_lookup(EXT2_DESC_T *ext2fs, UINT32 dir_ino,										char  *name, int namelen, int type);static int ext2fs_follow_symlink(EXT2_DESC_T *ext2fs, UINT32 dir_ino, UINT32 sym_ino, 								INODE_INFO_T *info);static int ext2fs_inode_lookup(EXT2_DESC_T *ext2fs, UINT32 dir_ino,			     				char *pathname, INODE_INFO_T *info, int type);int ext2fs_read(void *fp, char *buf, UINT32 nbytes);int ext2fs_close(void *fp);#define __READ_BLOCK(n)                                          	\	PARTITION_READ(ext2fs->part, EXT2_BLOCK_TO_SECTOR(ext2fs, (n)),    \                   ext2fs->blocksize/IDE_SECTOR_SIZE, (UINT16 *)blockbuf)/*----------------------------------------------------------------------*  ext2fs_init*----------------------------------------------------------------------*/int ext2fs_init(void){	int			p;	IDE_PART_T	*part;		memset((void *)&file_info, 0, sizeof(file_info));	memset((void *)blockbuf, 0, sizeof(blockbuf));		// looking for zImage.gz	part = (IDE_PART_T *)&ide_partitions[0];	for (p=0; p<ide_part_num; p++, part++)	{		if (!part->present) continue;						if (part->part_id != 0)	// only handle first partition per disk			 continue;				if (ext2fs_mount(part, &ext2fs_desc) != 0)		{			ext2fs_printf(("Failed to mount!\n"));			continue;		}				kernel_fp = NULL;		initrd_fp = NULL;		if ((kernel_fp = ext2fs_open((char *)sys_get_kernel_name())) && 			(initrd_fp = ext2fs_open((char *)sys_get_initrd_name())))		{			ext2fs_close(kernel_fp);			ext2fs_close(initrd_fp);			return 1;		}		if (kernel_fp) ext2fs_close(kernel_fp);		if (initrd_fp) ext2fs_close(initrd_fp);	}		printf("Not found files: %s and %s\n", sys_get_kernel_name(), sys_get_initrd_name());	return 0;		}/*----------------------------------------------------------------------*  ext2fs_open*	open a file in a desired partition*----------------------------------------------------------------------*/FILE_T *ext2fs_open(char *filepath){	int		i;	FILE_T	*file;		// get a new file handler	// currently only support one file at the same time	file = (FILE_T *)&file_info;	for (i=0; i<MAX_FILES; i++, file++)	{		if (!file->opened)			break;	}	if (i == MAX_FILES)		return NULL;		memset((void *)file, 0, sizeof(FILE_T));	file->opened = 1;	    // find file inode    if (!ext2fs_inode_lookup(&ext2fs_desc, EXT2_ROOT_INO, filepath, &file->inode_info, 0))    {		ext2fs_printf(("ext2fs_inode_lookup failed\n"));		return NULL;    }    // read inode    if (!ext2fs_get_inode(&ext2fs_desc, file->inode_info.ino, &file->inode))    {		ext2fs_printf(("ext2fs_get_inode failed for ino[%d]\n", file->inode_info.ino));		return NULL;    }	file->ext2fs_desc = &ext2fs_desc;    file->file_size = SWAB_LE32(file->inode.size);    file->file_pos  = 0;    return file;}/*----------------------------------------------------------------------*  ext2fs_mount*----------------------------------------------------------------------*/static int ext2fs_mount(IDE_PART_T *part, EXT2_DESC_T *desc){    int			sb_block = 1;    UINT32		sb_buf[EXT2_MIN_BLOCK_SIZE/sizeof(UINT32)];    EXT2_SB_T	*sb = (EXT2_SB_T *)sb_buf;    UINT16		magic;    desc->part = part;	// Read super block. Super Block is the 2nd block    if (!PARTITION_READ(part,    					sb_block*(EXT2_MIN_BLOCK_SIZE/IDE_SECTOR_SIZE),						EXT2_MIN_BLOCK_SIZE/IDE_SECTOR_SIZE,						(UINT16 *)sb))	{		return -1;	}    if (SWAB_LE16(sb->magic) != EXT2_SUPER_MAGIC)    {		ext2fs_printf(("Bad magic 0x%x\n", SWAB_LE16(magic)));		return -1;    }    // save some stuff for easy access    desc->blocksize = EXT2_BLOCK_SIZE(sb);    desc->nr_ind_blocks = (desc)->blocksize / sizeof(UINT32);    desc->nr_dind_blocks = desc->nr_ind_blocks * ((desc)->blocksize / sizeof(UINT32));    desc->nr_tind_blocks = desc->nr_dind_blocks * ((desc)->blocksize / sizeof(UINT32));    desc->blocks_per_group = SWAB_LE32(sb->blocks_per_group);    desc->ngroups = (SWAB_LE32(sb->blocks_count) + desc->blocks_per_group - 1) /	             desc->blocks_per_group;    desc->inodes_per_group = SWAB_LE32(sb->inodes_per_group);    // Find the group descriptors which follow superblock    desc->gdesc_block = ((sb_block * EXT2_MIN_BLOCK_SIZE) / desc->blocksize) + 1;    desc->gdesc_first = 0; // cache group 0 initially    if (!PARTITION_READ(part, EXT2_BLOCK_TO_SECTOR(desc, desc->gdesc_block), 1,			(UINT16 *)desc->gdesc_cache))	{		return -1;	}    return 0;}/*----------------------------------------------------------------------*  ext2fs_get_gdesc*----------------------------------------------------------------------*/static int ext2fs_get_gdesc(EXT2_DESC_T *ext2fs, UINT32 group_nr, EXT2_GROUP_T *gdesc){    UINT32 sec_nr;    if (group_nr < ext2fs->gdesc_first ||		group_nr >= (ext2fs->gdesc_first + EXT2_GDESC_CACHE_SIZE))	{		// cache miss		sec_nr = EXT2_BLOCK_TO_SECTOR(ext2fs, ext2fs->gdesc_block);		sec_nr += (group_nr / EXT2_GDESC_PER_SECTOR);		if (!PARTITION_READ(ext2fs->part, sec_nr,			    sizeof(ext2fs->gdesc_cache)/IDE_SECTOR_SIZE, (UINT16 *)ext2fs->gdesc_cache))			return 0;		ext2fs->gdesc_first = (group_nr / EXT2_GDESC_CACHE_SIZE) * EXT2_GDESC_CACHE_SIZE;    }		memcpy((void *)gdesc, (void *)&ext2fs->gdesc_cache[group_nr - ext2fs->gdesc_first], sizeof(EXT2_GROUP_T));	return 1;}/*----------------------------------------------------------------------*  ext2fs_get_inode*----------------------------------------------------------------------*/static int ext2fs_get_inode(EXT2_DESC_T *ext2fs, int ino, EXT2_INODE_T *ip){	UINT32 offset, sec_nr, buf[IDE_SECTOR_SIZE/sizeof(UINT32)];	EXT2_GROUP_T gdesc;		// get descriptor for group which this inode belongs to	if (!ext2fs_get_gdesc(ext2fs, (ino - 1) / ext2fs->inodes_per_group, &gdesc))		return 0;		if (gdesc.inode_table == 0)		return 0;		// byte offset within group inode table	offset = ((ino - 1) % ext2fs->inodes_per_group) * sizeof(EXT2_INODE_T);		// figure out which sector holds the inode	sec_nr = EXT2_BLOCK_TO_SECTOR(ext2fs, SWAB_LE32(gdesc.inode_table));	sec_nr += offset / IDE_SECTOR_SIZE;		// and the offset within that sector.	offset %= IDE_SECTOR_SIZE;		if (!PARTITION_READ(ext2fs->part, sec_nr, 1, (UINT16 *)buf))		return 0;		memcpy((void *)ip, (char *)buf + offset, sizeof(EXT2_INODE_T));		return 1;}/*----------------------------------------------------------------------*  ext2fs_inode_block*	Convert a block index into inode data into a block_nr.*	If successful, store block number in pblknr and return non-zero.**	NB: This needs some block/sector caching to be speedier. But*		that takes memory and speed is not too bad now for files*		small enough to avoid double and triple indirection.**----------------------------------------------------------------------*/static int ext2fs_inode_block(EXT2_DESC_T *ext2fs, EXT2_INODE_T *inode,		 						UINT32 bindex, UINT32 *pblknr){    if (bindex < EXT2_NR_DIR_BLOCKS)    {		*pblknr = SWAB_LE32(inode->block[bindex]);		return 1;    }    bindex -= EXT2_NR_DIR_BLOCKS;    if (bindex < ext2fs->nr_ind_blocks)    {		// Indirect block		if (!__READ_BLOCK(SWAB_LE32(inode->block[EXT2_IND_BLOCK])))			return 0;		*pblknr = SWAB_LE32(blockbuf[bindex]);		return 1;	}	bindex -= ext2fs->nr_ind_blocks;	if (bindex < ext2fs->nr_dind_blocks)	{		// Double indirect block		if (!__READ_BLOCK(SWAB_LE32(inode->block[EXT2_DIND_BLOCK])))			return 0;		if (!__READ_BLOCK(SWAB_LE32(blockbuf[bindex / ext2fs->nr_ind_blocks])))			return 0;		*pblknr  = SWAB_LE32(blockbuf[bindex % ext2fs->nr_ind_blocks]);		return 1;	}	bindex -= ext2fs->nr_dind_blocks;	// Triple indirect block	if (!__READ_BLOCK(SWAB_LE32(inode->block[EXT2_TIND_BLOCK])))		return 0;		if (!__READ_BLOCK(SWAB_LE32(blockbuf[bindex / ext2fs->nr_dind_blocks])))		return 0;		bindex %= ext2fs->nr_dind_blocks;		if (!__READ_BLOCK(SWAB_LE32(blockbuf[bindex / ext2fs->nr_ind_blocks])))		return 0;		*pblknr = SWAB_LE32(blockbuf[bindex % ext2fs->nr_ind_blocks]);        return 1;}

⌨️ 快捷键说明

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