/*
* This code is based on the ISO filesystem support in MILO (by
* Dave Rusling).
*
* This is a set of functions that provides minimal filesystem
* functionality to the Linux bootstrapper. All we can do is
* open and read files... but that's all we need 8-)
*/
#ifndef TESTING
# include <linux/string.h>
#endif
#include <linux/kernel.h>
#include <linux/config.h>
#include <linux/types.h>
#include <linux/stat.h>
#include <linux/kdev_t.h>
#include <asm/page.h>
#include <iso.h>
#include <isolib.h>
#include <utils.h>
/* iso9660 support code */
#define MAX_OPEN_FILES 5
static struct inode_table_entry {
struct iso_inode inode;
int inumber;
int free;
unsigned short old_mode;
unsigned size;
int nlink;
int mode;
void *start;
} inode_table[MAX_OPEN_FILES];
static unsigned long root_inode = 0;
static struct isofs_super_block sb;
static char data_block[1024];
static char big_data_block[2048];
#ifndef S_IRWXUGO
# define S_IRWXUGO (S_IRWXU|S_IRWXG|S_IRWXO)
# define S_IXUGO (S_IXUSR|S_IXGRP|S_IXOTH)
# define S_IRUGO (S_IRUSR|S_IRGRP|S_IROTH)
#endif
extern long iso_dev_read (void * buf, long offset, long size);
static int parse_rock_ridge_inode(struct iso_directory_record * de,
struct iso_inode * inode);
static char *get_rock_ridge_symlink(struct iso_inode *inode);
static int get_rock_ridge_filename(struct iso_directory_record * de,
char * retname,
struct iso_inode * inode);
int
isonum_711 (char * p)
{
return (*p & 0xff);
}
int
isonum_712 (char * p)
{
int val;
val = *p;
if (val & 0x80)
val |= 0xffffff00;
return val;
}
int
isonum_721 (char * p)
{
return ((p[0] & 0xff) | ((p[1] & 0xff) << 8));
}
int
isonum_722 (char * p)
{
return (((p[0] & 0xff) << 8) | (p[1] & 0xff));
}
int
isonum_723 (char * p)
{
return isonum_721(p);
}
int
isonum_731 (char * p)
{
return ((p[0] & 0xff)
| ((p[1] & 0xff) << 8)
| ((p[2] & 0xff) << 16)
| ((p[3] & 0xff) << 24));
}
int
isonum_732 (char * p)
{
return (((p[0] & 0xff) << 24)
| ((p[1] & 0xff) << 16)
| ((p[2] & 0xff) << 8)
| (p[3] & 0xff));
}
int
isonum_733 (char * p)
{
return isonum_731(p);
}
static int
iso_bmap (struct iso_inode *inode, int block)
{
if (block < 0) {
printf("iso_bmap: block<0");
return 0;
}
return (inode->i_first_extent >> sb.s_blocksize_bits) + block;
}
static int
iso_breadi (struct iso_inode *ip, long blkno, long nblks, char * buffer)
{
long i_size, abs_blkno;
/* do some error checking */
if (!ip || !ip->i_first_extent)
return -1;
i_size = ((struct inode_table_entry *) ip)->size;
/* as in ext2.c - cons_read() doesn't really cope well with
EOF conditions - actually it should be fixed */
if ((blkno+nblks) * sb.s_blocksize > i_size)
nblks = ((i_size + sb.s_blocksize)
/ sb.s_blocksize) - blkno;
/* figure out which iso block number(s) we're being asked for */
abs_blkno = iso_bmap(ip, blkno);
if (!abs_blkno)
return -1;
/* now try and read them (easy since ISO files are continguous) */
return iso_dev_read(buffer, abs_blkno * sb.s_blocksize,
nblks * sb.s_blocksize);
}
/*
* Release our hold on an inode. Since this is a read-only application,
* don't worry about putting back any changes...
*/
static void
iso_iput (struct iso_inode *ip)
{
struct inode_table_entry *itp;
/* Find and free the inode table slot we used... */
itp = (struct inode_table_entry *) ip;
itp->inumber = 0;
itp->free = 1;
}
/*
* Read the specified inode from the disk and return it to the user.
* Returns NULL if the inode can't be read...
*
* Uses data_block
*/
static struct iso_inode *
iso_iget (int ino)
{
int i;
struct iso_inode *inode;
struct inode_table_entry *itp;
struct iso_directory_record * raw_inode;
unsigned char *pnt = NULL;
void *cpnt = NULL;
int high_sierra;
int block;
#ifdef DEBUG_ISO
printf("iso_iget(ino=%d)\n", ino);
#endif
/* find a free inode to play with */
inode = NULL;
itp = NULL;
for (i = 0; i < MAX_OPEN_FILES; i++) {
if (inode_table[i].free) {
itp = &(inode_table[i]);
inode = &(itp->inode);
break;
}
}
if ((inode == NULL) || (itp == NULL)) {
printf("iso9660 (iget): no free inodes\n");
return (NULL);
}
block = ino >> sb.s_blocksize_bits;
if (iso_dev_read(data_block, block * sb.s_blocksize, sb.s_blocksize)
!= sb.s_blocksize) {
printf("iso9660: unable to read i-node block");
return NULL;
}
pnt = ((unsigned char *) data_block + (ino & (sb.s_blocksize - 1)));
raw_inode = ((struct iso_directory_record *) pnt);
high_sierra = sb.s_high_sierra;
if ((ino & (sb.s_blocksize - 1)) + *pnt > sb.s_blocksize){
int frag1, offset;
offset = (ino & (sb.s_blocksize - 1));
frag1 = sb.s_blocksize - offset;
cpnt = big_data_block;
memcpy(cpnt, data_block + offset, frag1);
offset += *pnt - sb.s_blocksize; /* DUH! pnt would get
wiped out by the
iso_dev_read here. */
if (iso_dev_read(data_block, ++block * sb.s_blocksize,
sb.s_blocksize)
!= sb.s_blocksize) {
printf("unable to read i-node block");
return NULL;
}
memcpy((char *)cpnt+frag1, data_block, offset);
pnt = ((unsigned char *) cpnt);
raw_inode = ((struct iso_directory_record *) pnt);
}
if (raw_inode->flags[-high_sierra] & 2) {
itp->mode = S_IRUGO | S_IXUGO | S_IFDIR;
itp->nlink = 1; /* Set to 1. We know there are 2, but
the find utility tries to optimize
if it is 2, and it screws up. It is
easier to give 1 which tells find to
do it the hard way. */
} else {
itp->mode = sb.s_mode; /* Everybody gets to read the file. */
itp->nlink = 1;
itp->mode |= S_IFREG;
/*
* If there are no periods in the name, then set the
* execute permission bit
*/
for(i=0; i< raw_inode->name_len[0]; i++)
if(raw_inode->name[i]=='.' || raw_inode->name[i]==';')
break;
if(i == raw_inode->name_len[0] || raw_inode->name[i] == ';')
itp->mode |= S_IXUGO; /* execute permission */
}
itp->size = isonum_733 (raw_inode->size);
/* There are defective discs out there - we do this to protect
ourselves. A cdrom will never contain more than 700Mb */
if((itp->size < 0 || itp->size > 700000000) &&
sb.s_cruft == 'n')
{
printf("Warning: defective cdrom. "
"Enabling \"cruft\" mount option.\n");
sb.s_cruft = 'y';
}
/*
* Some dipshit decided to store some other bit of information
* in the high byte of the file length. Catch this and
* holler. WARNING: this will make it impossible for a file
* to be > 16Mb on the CDROM!!!
*/
if(sb.s_cruft == 'y' &&
itp->size & 0xff000000)
{
itp->size &= 0x00ffffff;
}
if (raw_inode->interleave[0]) {
printf("Interleaved files not (yet) supported.\n");
itp->size = 0;
}
/* I have no idea what file_unit_size is used for, so
we will flag it for now */
if (raw_inode->file_unit_size[0] != 0){
printf("File unit size != 0 for ISO file (%d).\n", ino);
}
/* I have no idea what other flag bits are used for, so
we will flag it for now */
#ifdef DEBUG_ISO
if ((raw_inode->flags[-high_sierra] & ~2)!= 0){
printf("Unusual flag settings for ISO file (%d %x).\n",
ino, raw_inode->flags[-high_sierra]);
}
#endif
inode->i_first_extent = (isonum_733 (raw_inode->extent) +
isonum_711 (raw_inode->ext_attr_length))
<< sb.s_log_zone_size;
/* Now we check the Rock Ridge extensions for further info */
if (sb.s_rock)
parse_rock_ridge_inode(raw_inode,inode);
/* Will be used for previous directory */
inode->i_backlink = 0xffffffff;
switch (sb.s_conversion) {
case 'a':
inode->i_file_format = ISOFS_FILE_UNKNOWN; /* File type */
break;
case 'b':
inode->i_file_format = ISOFS_FILE_BINARY; /* File type */
break;
case 't':
inode->i_file_format = ISOFS_FILE_TEXT; /* File type */
break;
case 'm':
inode->i_file_format = ISOFS_FILE_TEXT_M; /* File type */
break;
}
/* keep our inode tab
没有合适的资源?快使用搜索试试~ 我知道了~
abootLoader 固件源代码 HP内部珍贵资料!.zip

共84个文件
c:27个
h:14个
html:9个

1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 190 浏览量
2023-03-10
16:24:02
上传
评论
收藏 180KB ZIP 举报
温馨提示
abootLoader 固件源代码 HP内部珍贵资料!.zip
资源推荐
资源详情
资源评论
















收起资源包目录

































































































共 84 条
- 1
资源评论


处处清欢
- 粉丝: 117
- 资源: 2173

下载权益

C知道特权

VIP文章

课程特权

开通VIP
上传资源 快速赚钱
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助


安全验证
文档复制为VIP权益,开通VIP直接复制
