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

📄 boot.c

📁 一个类linux的dos下开发的操作系统.
💻 C
📖 第 1 页 / 共 5 页
字号:
		"%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 + -