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

📄 boot.c

📁 一个类linux的dos下开发的操作系统.
💻 C
📖 第 1 页 / 共 5 页
字号:
#if 1
#define	PMODE_LOAD_ADR	0x00100000L /* 1 meg (for stand-alone loader) */
#else
#define	PMODE_LOAD_ADR	0x00110000L /* 1 meg+64K (for DOS loader) */
#endif
/*****************************************************************************
DEFS.H
- in file_t, allocate 'name' dynamically, with malloc()
- in fsinfo_t, allocate 'info' dynamically, with malloc()
FAT.C
- in fat_find_root(), get root dir size (may not be possible)
EXT2.C
- finish ext2_find_file()
- finish ext2_read()
- finish ext2_mount()
VFS.C
- in open(), either convert path from relative to absolute
	or handle relative pathnames
- in open(), maybe figure out mount point based on absolute path
	so you don't need global variable _mount
- in open(), fix it so open() doesn't modify the path argument
- in open(), maybe remove superfluous components of path
various
- support LBA
- support partition type 0x0E (FAT16 with LBA)
*****************************************************************************/
#include <stdio.h>
/*////////////////////////////////////////////////////////////////////////////
DEFS.H - DEFINES
////////////////////////////////////////////////////////////////////////////*/
/* no debug messages */
#if 1
#define	DEBUG(X)	/* nothing */
#define	DEBUG1(X)	/* nothing */
/* some debug messages */
#elif 1
#define	DEBUG(X)	X
#define	DEBUG1(X)	/* nothing */
#else
/* many debug messages */
#define	DEBUG(X)	X
#define	DEBUG1(X)	X
#endif

#define	HUGE	huge

/* these assume sizeof(short)==2 and sizeof(long)==4 */
#define	read_le16(X)	*(unsigned short *)(X)
#define	read_le32(X)	*(unsigned long *)(X)

/* some functions return -1 when I don't know what else to return */
#define	EINVAL		2	/* invalid function argument */
#define	EIO		3	/* disk/device read/write error */
#define	ERR_FILE_NAME	4	/* filename not supported by filesystem */
#define	ERR_EOF		5	/* end of file */
#define	ERR_FILE_SYSTEM	6	/* filesystem is invalid/corrupt */
#define	ENOIMP		7	/* function not (yet) implemented */
#define	EMFILE		8	/* too many open files */
#define	EBADF		9	/* bad file handle */
#define	ENOMEM		10	/* not enough memory */
#define	ERR_FILE_FORMAT	11	/* invalid file format */

/* bytes per sector for disks */
#define	BPS		512

#define	SEEK_SET	0
#define	SEEK_CUR	1
#define	SEEK_END	2

#define	O_RDONLY	0x0001
#define	O_WRONLY	0x0002
#define	O_RDWR		0x0004

/* "An inode is an [unique] integer associated with a file on the filesystem."
For FAT, we use the first cluster of the file as the inode */
typedef unsigned long	inode_t;

typedef unsigned long	sector_t;

typedef unsigned long	pos_t;

typedef struct
{
	unsigned char int13_dev;
	unsigned short sects, heads, bytes_per_sector;
} dev_t;

typedef struct
{
	pos_t pos;
	struct _mount *mount;
	inode_t inode;
	unsigned long file_size;
	unsigned is_dir : 1;
	unsigned is_open : 1;
	char name[16]; /* xxx - 16 is arbitrary...maybe use malloc()? */
} file_t;

#define	DIR	file_t

typedef struct
{
	int (*read)(file_t *file, unsigned char HUGE *buf, unsigned len);
	int (*find_root)(struct _mount *mount, file_t *dir);
	int (*find_file)(file_t *file, char *name);
/*	void *info; */
	unsigned char info[64]; /* xxx - use malloc()? */
} fsinfo_t;

typedef struct _mount
{
	dev_t *dev;
	fsinfo_t fsinfo;
	sector_t partition_start;
	inode_t curr_dir;
} mount_t;

#define	MAX_SECT	4

typedef struct
{
	unsigned load : 1;		/* section flags: load from disk? */
	unsigned zero : 1;		/* BSS? */
	unsigned read : 1;		/* readable? */
	unsigned write : 1;		/* writable? */
	unsigned exec : 1;		/* executable? */
	unsigned long off, size, adr;	/* file offset, size, virtual adr */
	char name[12];			/* section name (e.g. ".bss") */
} sect_t;

typedef struct
{
	unsigned long entry_pt;		/* initial EIP or CS:IP */
	unsigned short num_sections;	/* sections (.text, .data, .bss) */
	sect_t section[MAX_SECT];
	const char *format_name;	/* name of file format */
	unsigned pmode : 1;		/* 32-bit kernel? */
	unsigned rdsk : 1;		/* RDSK file? */
} exec_t;
/*////////////////////////////////////////////////////////////////////////////
CONSOLE.C - CONSOLE ROUTINES

EXPORTS:
void gotoxy(unsigned char x, unsigned char y);
void textattr(int a);
void cprintf(const char *fmt, ...);
void erase_screen(unsigned char x, unsigned char y,
		unsigned char wd, unsigned char ht);
int getch(void);
////////////////////////////////////////////////////////////////////////////*/
#include <stdarg.h> /* va_list, va_start(), va_end() */
#include <string.h> /* strlen() */
#include <stdio.h> /* vsprintf() */
#include <dos.h> /* struct REGPACK, intr() */

static unsigned char _attrib = 0x07; /* white on black */
/*****************************************************************************
*****************************************************************************/
void gotoxy(unsigned char x, unsigned char y)
{
	struct REGPACK regs;

	regs.r_dx = y;
	regs.r_dx <<= 8;
	regs.r_dx |= x;
	regs.r_bx = 0;		/* BH=video page 0 */
	regs.r_ax = 0x0200;	/* AH=subfunction 2 (move csr) */
	intr(0x10, &regs);
}
/*****************************************************************************
*****************************************************************************/
void textattr(int a)
{
	_attrib = a;
}
/*****************************************************************************
*****************************************************************************/
void cprintf(const char *fmt, ...)
{
	struct REGPACK regs;
	char buf[200];
	va_list args;

	va_start(args, fmt);
	vsprintf(buf, fmt, args);
	va_end(args);

	regs.r_bx = 0;		/* BH=video page 0 */
	regs.r_ax = 0x0300; /* AH=subfunction 3: get cursor pos to DH,DL */
	intr(0x10, &regs);

	regs.r_es = _DS;
	regs.r_bp = (unsigned)buf;
	regs.r_cx = strlen(buf);
	regs.r_bx = _attrib;	/* BH=video page 0, BL=attribute */
	regs.r_ax = 0x1301;	/* AH=subfunction 13h, AL=write mode 1 */
	intr(0x10, &regs);
}
/*****************************************************************************
*****************************************************************************/
void erase_screen(unsigned char x, unsigned char y,
		unsigned char wd, unsigned char ht)
{
	struct REGPACK regs;

	regs.r_ax = 0x0600;	/* AH=subfunction 6 (scroll), AH=0 (erase) */
	regs.r_bx = _attrib;
	regs.r_bx <<= 8;	/* BH=attribute */
	regs.r_cx = y;
	regs.r_cx <<= 8;	/* CH=row */
	regs.r_cx |= x;		/* CL=col */
	regs.r_dx = (y + ht - 1);
	regs.r_dx <<= 8;	/* DH=height */
	regs.r_dx |= (x + wd - 1);/* DL=width */
	intr(0x10, &regs);
}
/*****************************************************************************
*****************************************************************************/
int getch(void)
{
	static short prev = -1;
	struct REGPACK regs;
	int ret_val;

	if(prev != -1)
	{
		ret_val = prev;
		prev = -1;
	}
	else
	{
		regs.r_ax = 0; /* AH=subfunction 0 (get key) */
		intr(0x16, &regs);
		ret_val = regs.r_ax & 0xFF;
		if(ret_val == 0)
		{
			regs.r_ax >>= 8;
			prev = regs.r_ax;
		}
	}
	return ret_val;
}
/*////////////////////////////////////////////////////////////////////////////
CACHE.C - SIMPLE READ-ONLY DISK CACHE

EXPORTS:
int read_sector(dev_t *dev, sector_t sector, unsigned char **blk);
////////////////////////////////////////////////////////////////////////////*/
#include <bios.h> /* biosdisk() */
/*#include "defs.h"*/

#define	MAX_CACHE	32	/* 32 sectors == 16K */
/*****************************************************************************
*****************************************************************************/
int read_sector(dev_t *dev, sector_t sector, unsigned char **blk)
{
/* this bug was hard to find...
	static unsigned char cached_blk[BPS][MAX_CACHE]; */
	static unsigned char cached_blk[MAX_CACHE][BPS];
	static sector_t cached_sector[MAX_CACHE];
	static unsigned char init, evict;
/**/
	unsigned short c, h, s, temp;
	unsigned char tries;

	if(!init)
	{
		init = 1;
		for(temp = 0; temp < MAX_CACHE; temp++)
			cached_sector[temp] = -1uL;
	}
/* see if this sector is cached */
	for(temp = 0; temp < MAX_CACHE; temp++)
	{
		if(cached_sector[temp] == sector)
		{
			(*blk) = cached_blk[temp];
			return 0;
		}
	}
/* not cached, find a free buffer for it */
	for(temp = 0; temp < MAX_CACHE; temp++)
	{
		if(cached_sector[temp] == -1uL)
			break;
	}
/* no free buffer, kick out someone else */
	if(temp >= MAX_CACHE)
	{
		temp = evict;
		evict++;
		if(evict >= MAX_CACHE)
			evict = 0;
	}
/* load it */
	cached_sector[temp] = sector;
	(*blk) = cached_blk[temp];
/* we can load sector 0 of the disk even if we don't
know the disk geometry. This is good, because we can:
- get floppy geometry from FAT bootsector (in sector 0 of floppy)
- get hard disk geometry from partition table (in sector 0 of hard disk) */
	if(sector == 0)
	{
		s = 1;
		h = 0;
		c = 0;
	}
	else
	{
		s = sector % dev->sects + 1;
		h = (sector / dev->sects) % dev->heads;
		c = (sector / dev->sects) / dev->heads;
	}
/* make 3 attempts */
	for(tries = 3; tries != 0; tries--)
	{
		temp = biosdisk(/* _DISK_READ */2, dev->int13_dev,
			h, c, s, 1, *blk);
/* biosdisk() does not return what the Turbo C online help says.
It returns the AH value from INT 13h, not AX
		temp >>= 8; */
		if(temp == 0 || temp == 0x11)
			return 0;
/* reset FDC if error */
		(void)biosdisk(/* _DISK_RESET */0, dev->int13_dev,
			0, 0, 0, 0, 0);
	}
	cprintf("\n\rread_sector: INT 13h disk error 0x%02X, CHS=%u:%u:%u, "
		"dev=0x%02X, *blk=%p\n\r", temp, c, h, s,
		dev->int13_dev, *blk);
	return -EIO;
}
/*///////////////////////////////////////////////////////////////////////////
FAT.C - FAT12/16 FILESYSTEM

EXPORTS:
int fat_mount(mount_t *mount, dev_t *dev, unsigned char part);
////////////////////////////////////////////////////////////////////////////*/
/* NULL, memset, memcmp, memcpy, _fmemcpy */
#include <string.h> /* strchr, strlen, strcpy, strupr, strchr */
#include <dos.h> /* MK_FP() */
/*#include "defs.h"*/

#define	min(a,b)	(((a) < (b)) ? (a) : (b))

/* bytes per FAT directory entry */
#define	FAT_DIRENT_LEN		32
/* FAT entries 0 and 1 are reserved: */
#define	MAGIC_FAT_CLUSTER	0
#define	MAGIC_ROOT_CLUSTER	1

typedef enum
{
	FAT12, FAT16, FAT32
} fat_type_t;

typedef struct
{
	unsigned short max_cluster;
	unsigned char sectors_per_cluster;
	sector_t fat_start, root_start, data_start;
	fat_type_t fat_type;
} fat_t;

/* IMPORTS:
from VFS.C */
int read(unsigned handle, void HUGE *buf, unsigned len);

extern file_t _files[];

/* from CACHE.C */
int read_sector(dev_t *dev, sector_t sector, unsigned char **blk);
/*****************************************************************************
extend name to 8 characters, extend extension to 3 characters
(both padded on the right with spaces), and capitalize them

e.g. "foo.i" -> "FOO     I  "

'dst' must be >=12 bytes
*****************************************************************************/
static int fat_convert_name_to_fat(char *dst, char *src)
{
	unsigned len;
	char *dot;

/* put dst in FAT format */
	memset(dst, ' ', 11);
	dot = strchr(src, '.');
/* there is an extension */
	if(dot != NULL)
	{
/* long filenames not supported */
		len = dot - src;
		if(len > 8)
			return -ERR_FILE_NAME;
/* copy filename */
		memcpy(dst, src, len);
/* long extension not supported */
		len = strlen(dot) - 1;
		if(len > 3)
			return -ERR_FILE_NAME;
/* copy extension */
		memcpy(dst + 8, dot + 1, len);
	}
/* no extension */
	else
	{
/* long filenames not supported */
		len = strlen(src);
		if(len > 8)
			return -ERR_FILE_NAME;
/* copy filename */
		memcpy(dst, src, len);
	}
/* make it upper case */
	dst[11] = '\0';
	strupr(dst);
	DEBUG(cprintf("fat_convert_name_to_fat:   `%s' -> `%s'\n\r",
		src, dst);)
	return 0;
}
/*****************************************************************************
e.g. "README  TXT" -> "readme.txt"

'dst' must be >=12 bytes
*****************************************************************************/
static void fat_convert_name_from_fat(char *dst, char *src)
{
	unsigned char i;
	char *d = dst;

	for(i = 0; i < 8; i++)
	{
		if(src[i] == ' ')
			break;
		*d = src[i];
		d++;
	}
	if(src[8] != ' ')
	{
		*d = '.';

⌨️ 快捷键说明

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