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

📄 setup.c

📁 Windows上的精简Linux系统
💻 C
📖 第 1 页 / 共 2 页
字号:
#ident "$Id: setup.c,v 1.40 2004/04/27 06:48:59 hpa Exp $"/* ----------------------------------------------------------------------- * *    *   Copyright 2001-2003 H. Peter Anvin - All Rights Reserved * *   This program 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, Inc., 53 Temple Place Ste 330, *   Bostom MA 02111-1307, USA; either version 2 of the License, or *   (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */#include <stdint.h>#include "e820.h"#include "conio.h"#include "version.h"#include "memdisk.h"/* A pointer to this is stored in the header */const char memdisk_version[] ="MEMDISK " VERSION " " DATE;const char copyright[] = "Copyright " FIRSTYEAR "-" COPYYEAR " H. Peter Anvin";extern const char _binary_memdisk_bin_start[], _binary_memdisk_bin_end[];extern const char _binary_memdisk_bin_size[]; /* Weird, I know */struct memdisk_header {  uint16_t int13_offs;  uint16_t int15_offs;  uint16_t patch_offs;  uint16_t total_size;};/* The Disk Parameter Table may be required */typedef union {  struct hd_dpt {    uint16_t max_cyl;		/* Max cylinder */    uint8_t max_head;		/* Max head */    uint8_t junk1[5];		/* Obsolete junk, leave at zero */    uint8_t ctrl;		/* Control byte */    uint8_t junk2[7];		/* More obsolete junk */  } hd;  struct fd_dpt {    uint8_t specify1;		/* "First specify byte" */    uint8_t specify2;		/* "Second specify byte" */    uint8_t delay;		/* Delay until motor turn off */    uint8_t sectors;		/* Sectors/track */    uint8_t bps;		/* Bytes/sector (02h = 512) */    uint8_t isgap;		/* Length of intersector gap */    uint8_t dlen;		/* Data length (0FFh) */    uint8_t fgap;		/* Formatting gap */    uint8_t ffill;		/* Format fill byte */    uint8_t settle;		/* Head settle time (ms) */    uint8_t mstart;		/* Motor start time */    uint8_t _pad1;		/* Padding */    uint32_t old_fd_dpt;	/* Extension: pointer to old INT 1Eh */  } fd;} dpt_t;struct patch_area {  uint32_t diskbuf;  uint32_t disksize;  uint16_t cmdline_off, cmdline_seg;    uint32_t oldint13;  uint32_t oldint15;  uint16_t olddosmem;  uint16_t memint1588;  uint16_t cylinders;  uint16_t heads;  uint32_t sectors;  uint32_t mem1mb;  uint32_t mem16mb;  uint8_t  driveno;  uint8_t  drivetype;  uint8_t  drivecnt;  uint8_t  _pad1;  uint16_t mystack;  uint16_t statusptr;  dpt_t dpt;};/* This is the header in the boot sector/setup area */struct setup_header {  char cmdline[0x1f1];  uint8_t setup_secs;  uint16_t syssize;  uint16_t swap_dev;  uint16_t ram_size;  uint16_t vid_mode;  uint16_t root_dev;  uint16_t boot_flag;  uint16_t jump;  char header[4];  uint16_t version;  uint32_t realmode_swtch;  uint32_t start_sys;  uint8_t type_of_loader;  uint8_t loadflags;  uint16_t setup_move_size;  uint32_t code32_start;  uint32_t ramdisk_image;  uint32_t ramdisk_size;  uint32_t bootsect_kludge;  uint16_t head_end_ptr;  uint16_t pad1;  uint32_t cmd_line_ptr;  uint32_t initrd_addr_max;};const struct setup_header * const shdr = (struct setup_header *)(LOW_SEG << 4);/* Access to high memory *//* Access to objects in the zero page */static inline voidwrz_8(uint32_t addr, uint8_t data){  *((uint8_t *)addr) = data;}static inline voidwrz_16(uint32_t addr, uint16_t data){  *((uint16_t *)addr) = data;}static inline voidwrz_32(uint32_t addr, uint32_t data){  *((uint32_t *)addr) = data;}static inline uint8_trdz_8(uint32_t addr){  return *((uint8_t *)addr);}static inline uint16_trdz_16(uint32_t addr){  return *((uint16_t *)addr);}static inline uint32_trdz_32(uint32_t addr){  return *((uint32_t *)addr);}/* Addresses in the zero page */#define BIOS_INT13	(0x13*4) /* INT 13h vector */#define BIOS_INT15	(0x15*4) /* INT 15h vector */#define BIOS_INT1E      (0x1E*4) /* INT 1Eh vector */#define BIOS_INT40	(0x40*4) /* INT 13h vector */#define BIOS_INT41      (0x41*4) /* INT 41h vector */#define BIOS_INT46      (0x46*4) /* INT 46h vector */#define BIOS_BASEMEM	0x413	 /* Amount of DOS memory */#define BIOS_EQUIP	0x410	 /* BIOS equipment list */#define BIOS_HD_COUNT   0x475	 /* Number of hard drives present *//* * Routine to seek for a command-line item and return a pointer * to the data portion, if present *//* Magic return values */#define CMD_NOTFOUND   ((char *)-1) /* Not found */#define CMD_BOOL       ((char *)-2) /* Found boolean option */#define CMD_HASDATA(X) ((int)(X) >= 0)const char *getcmditem(const char *what){  const char *p;  const char *wp = what;  int match = 0;  for ( p = shdr->cmdline ; *p ; p++ ) {    switch ( match ) {    case 0:			/* Ground state */      if ( *p == ' ' )	break;      wp = what;      match = 1;      /* Fall through */    case 1:			/* Matching */      if ( *wp == '\0' ) {	if ( *p == '=' )	  return p+1;	else if ( *p == ' ' )	  return CMD_BOOL;	else {	  match = 2;	  break;	}      }      if ( *p != *wp++ )	match = 2;      break;    case 2:			/* Mismatch, skip rest of option */      if ( *p == ' ' )	match = 0;		/* Next option */      break;    }  }      /* Check for matching string at end of line */  if ( match == 1 && *wp == '\0' )    return CMD_BOOL;    return CMD_NOTFOUND;}/* * Check to see if this is a gzip image */#define UNZIP_ALIGN 512extern void _end;		/* Symbol signalling end of data */void unzip_if_needed(uint32_t *where_p, uint32_t *size_p){  uint32_t where = *where_p;  uint32_t size = *size_p;  uint32_t zbytes;  uint32_t startrange, endrange;  uint32_t gzdatasize, gzwhere;  uint32_t orig_crc, offset;  uint32_t target = 0;  int i, okmem;  /* Is it a gzip image? */  if (check_zip ((void *)where, size, &zbytes, &gzdatasize,                 &orig_crc, &offset) == 0) {    if (offset + zbytes > size) {      /* Assertion failure; check_zip is supposed to guarantee this         never happens. */      puts("internal error: check_zip returned nonsense\n");      die();    }    /* Find a good place to put it: search memory ranges in descending order       until we find one that is legal and fits */    okmem = 0;    for ( i = nranges-1 ; i >= 0 ; i-- ) {      /* We can't use > 4G memory (32 bits only.)  Truncate to 2^32-1	 so we don't have to deal with funny wraparound issues. */            /* Must be memory */      if ( ranges[i].type != 1 )	continue;      /* Range start */      if ( ranges[i].start >= 0xFFFFFFFF )	continue;      startrange = (uint32_t)ranges[i].start;      /* Range end (0 for end means 2^64) */      endrange = ((ranges[i+1].start >= 0xFFFFFFFF ||		   ranges[i+1].start == 0)		  ? 0xFFFFFFFF : (uint32_t)ranges[i+1].start);      /* Make sure we don't overwrite ourselves */      if ( startrange < (uint32_t)&_end )	startrange = (uint32_t)&_end;      /* Allow for alignment */      startrange = (ranges[i].start + (UNZIP_ALIGN-1)) & ~(UNZIP_ALIGN-1);      /* In case we just killed the whole range... */      if ( startrange >= endrange )	continue;      /* Must be large enough... don't rely on gzwhere for this (wraparound) */      if ( endrange-startrange < gzdatasize )	continue;      /* This is where the gz image should be put if we put it in this range */      gzwhere = (endrange - gzdatasize) & ~(UNZIP_ALIGN-1);      /* Cast to uint64_t just in case we're flush with the top byte */      if ( (uint64_t)where+size >= gzwhere && where < endrange ) {	/* Need to move source data to avoid compressed/uncompressed overlap */	uint32_t newwhere;		if ( gzwhere-startrange < size )	  continue;		/* Can't fit both old and new */		newwhere = (gzwhere - size) & ~(UNZIP_ALIGN-1);	printf("Moving compressed data from 0x%08x to 0x%08x\n",	       where, newwhere);		/* Our memcpy() is OK, because we always move from a higher	   address to a lower one */	memcpy((void *)newwhere, (void *)where, size);	where = newwhere;      }      target = gzwhere;      okmem = 1;      break;    }    if ( !okmem ) {      puts("Not enough memory to decompress image\n");      die();    }    printf("gzip image: decompressed addr 0x%08x, len 0x%08x: ",	   target, gzdatasize);    *size_p  = gzdatasize;    *where_p = (uint32_t)unzip((void *)(where + offset), zbytes,                               gzdatasize, orig_crc, (void *)target);  }}/* * Figure out the "geometry" of the disk in question */struct geometry {  uint32_t sectors;		/* 512-byte sector count */  uint32_t c, h, s;		/* C/H/S geometry */  uint32_t offset;		/* Byte offset for disk */  uint8_t type;		        /* Type byte for INT 13h AH=08h */  uint8_t driveno;		/* Drive no */};static const struct geometry geometries[] ={   {  720, 40,  2,  9, 0, 0x01, 0 }, /*  360 K */  { 1440, 80,  2,  9, 0, 0x03, 0 }, /*  720 K*/  { 2400, 80,  2, 15, 0, 0x02, 0 }, /* 1200 K */  { 2880, 80,  2, 18, 0, 0x04, 0 }, /* 1440 K */  { 1680, 80,  2, 21, 0, 0x04, 0 }, /* 1680 K */  { 1722, 82,  2, 21, 0, 0x04, 0 }, /* 1722 K */  { 5760, 80,  2, 36, 0, 0x06, 0 }, /* 2880 K */};#define known_geometries (sizeof(geometries)/sizeof(struct geometry))/* Format of a DOS partition table entry */struct ptab_entry {  uint8_t active;  uint8_t start_h, start_s, start_c;  uint8_t type;  uint8_t end_h, end_s, end_c;  uint32_t start;  uint32_t size;};/* Format of a DOSEMU header */struct dosemu_header {  uint8_t magic[7];		/* DOSEMU\0 */  uint32_t h;  uint32_t s;  uint32_t c;  uint32_t offset;

⌨️ 快捷键说明

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