📄 boot.c
字号:
"%u sector(s)/cluster\n\r", part, dev->int13_dev,
fat->sectors_per_cluster);)
return 0;
}
/*///////////////////////////////////////////////////////////////////////////
EXT2.C - EXT2 FILESYSTEM
EXPORTS:
int ext2_mount(mount_t *mount, dev_t *dev, unsigned char part);
////////////////////////////////////////////////////////////////////////////*/
#include <string.h> /* strcpy() */
/*#include "defs.h"*/
typedef struct
{
unsigned long super_blk, blks_per_group;
} ext2_t;
/* IMPORTS
from CACHE.C */
int read_sector(dev_t *dev, sector_t sector, unsigned char **blk);
/*****************************************************************************
*****************************************************************************/
static int ext2_find_root(mount_t *mount, file_t *root_dir)
{
unsigned long inode_table_blk;
unsigned char *buf;
fsinfo_t *fsinfo;
ext2_t *ext2;
dev_t *dev;
int err;
fsinfo = &mount->fsinfo;
ext2 = (ext2_t *)fsinfo->info;
dev = mount->dev;
/* LOAD DESCRIPTORS FOR GROUPS #0-15 (32 bytes each == 512 bytes == 1 sector)
Group descriptors start at block #1 within the group == m->super_blk + 1 */
err = read_sector(dev, (ext2->super_blk + 1) * 2, &buf);
if(err != 0)
{
cprintf("ext2_find_root: error reading group descriptors "
"0-15 in group %u\n\r", (ext2->super_blk - 1) /
ext2->blks_per_group);
return -EIO;
}
/* READ FROM GROUP DESCRIPTOR #0: inode_table_blk */
inode_table_blk = read_le32(buf + 8);
/* LOAD INODE TABLE ENTRIES #0-3 (128 bytes each == 512 bytes == 1 sector) */
err = read_sector(dev, inode_table_blk * 2, &buf);
/* no redundancy here ("inode table for this group only")
this error is fatal */
if(err != 0)
{
cprintf("ext2_find_root: error reading inode table "
"for group #0\n\r");
return -EIO;
}
/* READ FROM INODE TABLE ENTRY #0: root_blk and root_size
Root dir is inode #1, so +128 to skip inode #0 */
root_dir->pos = 0;
root_dir->mount = mount;
/* inode = block number xxx - is this right? */
root_dir->inode = read_le32(buf + 128 + 40);
root_dir->file_size = read_le32(buf + 128 + 4);
root_dir->is_dir = 1;
strcpy(root_dir->name, "/");
return 0;
}
/*****************************************************************************
*****************************************************************************/
#pragma argsused
static int ext2_find_file(file_t *dir, char *name)
{
return -1;
}
/*****************************************************************************
*****************************************************************************/
#pragma argsused
static int ext2_read(file_t *file, unsigned char HUGE *buf, unsigned want)
{
return -1;
}
/*****************************************************************************
layout of ext2 disk/partition:
(blocks are almost always 1K in size)
boot block (block #0)
+-superblock for entire disk/partition 1 block
for | group descriptors for entire disk/partition 32 bytes ea.
each----+ block bitmap for this group only
group | inode bitmap for this group only
| inode table for this group only 128 bytes ea.
+-data blocks for this group only
*****************************************************************************/
int ext2_mount(mount_t *mount, dev_t *dev, unsigned char part)
{
unsigned char *blk, *ptab_rec;
unsigned long total_blks;
unsigned short magic;
fsinfo_t *fsinfo;
ext2_t *ext2;
int err;
/* floppy */
if(dev->int13_dev < 0x80)
mount->partition_start = 0;
/* hard disk */
else
{
if(part > 3)
{
cprintf("ext2_mount: partition number must be 0-3\n\r");
return -EINVAL;
}
/* read sector 0 of hard disk == MBR == partition table */
err = read_sector(dev, 0, &blk);
if(err != 0)
return err;
/* point to 16-byte partition table record */
ptab_rec = blk + 446 + 16 * part;
/* check FS type in partition record */
if(ptab_rec[4] != 0x83)
{
NOT: cprintf("ext2_mount: ");
if(dev->int13_dev >= 0x80)
cprintf("partition %u on ", part);
cprintf("drive 0x%02X is not ext2fs\n\r",
dev->int13_dev);
return -ERR_FILE_SYSTEM;
}
mount->partition_start = read_le32(ptab_rec + 8);
}
fsinfo = &mount->fsinfo;
ext2 = (ext2_t *)fsinfo->info;
/* the first superblock MUST be valid,
to get the correct values of total_blks and blks_per_group
xxx - check if Linux works differently */
ext2->blks_per_group = 1;
total_blks = 2;
/* group #0 starts at block #1 on disk/partition */
ext2->super_blk = 1;
do
{
/* LOAD SUPERBLOCK (block #0 within the group; first 512 bytes only) */
while(ext2->super_blk < total_blks)
{
err = read_sector(dev, ext2->super_blk * 2, &blk);
/* make sure it's ext2 */
if(err == 0)
{
magic = read_le16(blk + 56);
if(magic == 0xEF53 || magic == 0xEF51)
break;
}
/* error loading superblock or invalid superblock:
skip to next group on disk/partition and try again */
ext2->super_blk += ext2->blks_per_group;
}
/* did not find a valid superblock, or could not read it */
if(ext2->super_blk >= total_blks)
goto NOT;
/* READ FROM SUPERBLOCK: total_blks and ext2->blks_per_group */
total_blks = read_le32(blk + 4);
ext2->blks_per_group = read_le32(blk + 32);
DEBUG(cprintf("ext2_mount: %lu blocks on disk, "
"%lu blocks/group, %lu group(s)\n\r",
total_blks, ext2->blks_per_group,
ext2->blks_per_group > total_blks ? 1 :
total_blks / ext2->blks_per_group);)
/* LOAD GROUP DESCRIPTORS #0-15 (32 bytes each == 512 bytes == 1 sector)
Group descriptors start at block #1 within the group == super_blk + 1
Do this just to make sure the disk is OK */
err = read_sector(dev, (ext2->super_blk + 1) * 2, &blk);
} while(err != 0);
mount->dev = dev;
/* xxx mount->curr_dir = MAGIC_ROOT_CLUSTER; */
/* init ext2fs-specific info in fsinfo
ext2->super_blk and ext2->blks_per_group were set above */
fsinfo = &mount->fsinfo;
fsinfo->read = ext2_read;
fsinfo->find_root = ext2_find_root;
fsinfo->find_file = ext2_find_file;
return 0;
}
/*////////////////////////////////////////////////////////////////////////////
VFS.C - VFS LAYER
EXPORTS:
int close(int handle);
int read(int handle, void *buf, unsigned len);
long lseek(int handle, long offset, int whence);
int open(char *path, unsigned access);
Filesystem-specific code (such as that in FAT.C) must supply these functions:
static int myfs_read(file_t *file, unsigned char *buf, unsigned want);
static int myfs_find_root(mount_t *mount, file_t *root_dir);
static int myfs_find_file(file_t *dir, char *name);
int myfs_mount(mount_t *mount, dev_t *dev, unsigned char part);
////////////////////////////////////////////////////////////////////////////*/
#include <string.h> /* strcmp(), strchr(), strlen(), memcpy() */
/*#include "defs.h"*/
#define MAX_FILE 20
/* IMPORTS:
from BOOT.C - xxx */
extern mount_t _mount;
file_t _files[MAX_FILE];
/*****************************************************************************
*****************************************************************************/
static int find_free_file(file_t **file_ptr, unsigned *handle_ptr)
{
unsigned handle;
file_t *file;
/* find an unused file_t in _files[] */
file = _files + 0;
for(handle = 0; handle < MAX_FILE; handle++)
{
if(!file->is_open)
break;
file++;
}
if(handle >= MAX_FILE)
return -EMFILE;
/* zero the file_t */
memset(file, 0, sizeof(file_t));
/* ...except for is_open */
file->is_open = 1;
(*file_ptr) = file;
(*handle_ptr) = handle;
return 0;
}
/*****************************************************************************
*****************************************************************************/
int close(unsigned handle)
{
file_t *file;
/* validate handle */
if(handle >= MAX_FILE)
return -EBADF;
file = _files + handle;
/* close it */
file->is_open = 0;
return 0;
}
/*****************************************************************************
*****************************************************************************/
int read(unsigned handle, void HUGE *buf, unsigned len)
{
mount_t *mount;
file_t *file;
/* validate handle */
if(handle >= MAX_FILE)
return -EBADF;
file = _files + handle;
mount = file->mount;
/* call FS-specific read function */
return mount->fsinfo.read(file, buf, len);
}
/*****************************************************************************
*****************************************************************************/
long lseek(unsigned handle, long offset, int whence)
{
file_t *file;
/* validate handle */
if(handle >= MAX_FILE)
return -EBADF;
file = _files + handle;
switch(whence)
{
case SEEK_SET:
/* nothing */
break;
case SEEK_CUR:
offset += file->pos;
break;
case SEEK_END:
offset = (file->file_size - 1) - offset;
break;
default:
return -EINVAL;
}
if(offset < 0)
offset = 0;
else if(offset >= file->file_size - 1)
offset = file->file_size - 1;
file->pos = offset;
return offset;
}
/*****************************************************************************
xxx - convert path from relative to absolute, if necessary?
xxx - remove superfluous components of path (e.g. /./ )?
*****************************************************************************/
int open(char *path, unsigned access)
{
char done, *slash;
unsigned handle;
mount_t *mount;
file_t *file;
int err;
/* xxx - figure out mount point based on absolute path? */
mount = &_mount;
/* allocate a file_t */
err = find_free_file(&file, &handle);
if(err < 0)
return err;
/* absolute pathname */
if(path[0] == '/')
{
/* find root file, get root info to 'file' */
err = mount->fsinfo.find_root(mount, file);
if(err < 0)
{
close(handle);
return err;
}
/* skip first '/' */
path++;
/* done already? */
if(path[0] == '\0')
return handle;
}
/* xxx - relative pathnames are not yet supported */
else
return -1;
done = 0;
do
{
/* pick out one name in path */
slash = strchr(path, '/');
if(slash == NULL)
{
slash = path + strlen(path);
done = 1;
}
/* xxx - this modifies 'path' !!! */
*slash = '\0';
/* find file 'path' in 'file', copy info to 'file' if found */
err = mount->fsinfo.find_file(file, path);
if(err < 0)
{
close(handle);
return err;
}
/* advance to next name+ext pair in pathname
+1 to skip '/' */
path = slash + 1;
} while(!done);
return handle;
}
/*////////////////////////////////////////////////////////////////////////////
EXE.C - REAL MODE (16-BIT) DOS .EXE KERNELS
EXPORTS:
int check_exe_header(exec_t *exec, unsigned handle,
unsigned long rdsk_offset);
////////////////////////////////////////////////////////////////////////////*/
#include <string.h> /* memcmp() */
/*#include "defs.h"*/
/*****************************************************************************
*****************************************************************************/
int check_exe_header(exec_t *exec, unsigned handle,
unsigned long rdsk_offset)
{
static const char *format_name = "DOS .EXE";
/**/
unsigned long new_exe_offset;
char buf[64];
/* seek to start of kernel within RDSK file */
lseek(handle, rdsk_offset, SEEK_SET);
/* read 64-byte old executable (DOS .EXE) header */
if(read(handle, buf, 64) != 64)
/* short file is not EXE */
return -ERR_FILE_FORMAT;
if(memcmp(buf, "MZ", 2) != 0)
return -ERR_FILE_FORMAT;
/* if header is 64 bytes or more, check for New Executable */
if(read_le16(buf + 24) >= 64)
{
new_exe_offset = read_le32(buf + 60);
if(new_exe_offset != 0)
return -ERR_FILE_FORMAT;
}
/* xxx - finish */
exec->num_sections = 0;
exec->format_name = format_name;
exec->pmode = 0;
/* return -1; */
return 0;
}
/*////////////////////////////////////////////////////////////////////////////
ELF.C - PMODE (32-BIT) ELF KERNELS
EXPORTS:
int check_elf_header(exec_t *exec, unsigned handle,
unsigned long rdsk_offset);
////////////////////////////////////////////////////////////////////////////*/
#include <stdio.h> /* sprintf() */
/*#include "defs.h"*/
#define ELF_FILE_MAGIC 0 /* "\x7F""ELF" */
#define ELF_FILE_BITNESS 4 /* 1=32-bit, 2=64-bit */
#define ELF_FILE_ENDIAN 5 /* 1=little endian, 2=big endian */
#define ELF_FILE_VER1 6 /* =1 */
/* bytes 7-15 are reserved */
#define ELF_FILE_TYPE 16 /* 1=.o, 2=executable, 3=DLL */
#define ELF_FILE_MACHINE 18 /* 2=SPARC, 3=i386, 4=68000... */
#define ELF_FILE_VER2 20 /* =1 */
#define ELF_FILE_ENTRY 24 /* initial EIP */
#define ELF_PHTAB_OFFSET 28 /* file offset of Program Header table */
#define ELF_SHTAB_OFFSET 32 /* file offset of Section Header table */
#define ELF_FILE_FLAGS 36 /* (not used for i386?) */
#define ELF_FILE_HDRSIZE 40 /* size of this header, usu. 52 */
#define ELF_PHTAB_ENTSIZE 42 /* size of entries in PH table */
#define ELF_PHTAB_COUNT 44 /* number of entries in PH table */
#define ELF_SHTAB_ENTSIZE 46 /* size of entries in SH table */
#define ELF_SHTAB_COUNT 48 /* number of entries in SH table */
#define ELF_SHSTRTAB_INDEX 50 /* SH table entry for .shstrtab */
/* 52 bytes long */
#define ELF_FILE_HDRLEN 52
#define ELF_PH_TYPE 0
#define ELF_PH_OFFSET 4
#define ELF_PH_VIRT_ADR 8
#define ELF_PH_PADDR 12
#define ELF_PH_SIZE_IN_FILE 16
#define ELF_PH_SIZE_IN_MEM 20
#define ELF_PH_FLAGS 24
#define ELF_PH_ALIGN 28
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -