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

📄 probe.c

📁 LINUX lilo-22.7 源代码。
💻 C
📖 第 1 页 / 共 3 页
字号:
/* probe.c -- BIOS probes *//*Copyright 1999-2004 John Coffman.All rights reserved.Licensed under the terms contained in the file 'COPYING' in the source directory.*//*#define DEBUG*/#define BITMAP 0	/* change to 1 when do_bitmap is filled in */#define VOLID  1	/* change to 1 when do_volid is filled in */#define _GNU_SOURCE#include <stdlib.h>#include <unistd.h>#include <stdio.h>#include <string.h>#include <ctype.h>#include <fcntl.h>#include <errno.h>#include <sys/stat.h>#include <sys/types.h>#include "lilo.h"#include "common.h"#include "device.h"#include "geometry.h"#include "partition.h"#include "bsect.h"#include "bdata.h"#include "probe.h"#ifdef LCF_BDATA#if BD_MAX_FLOPPY > 4#error "too many floppies in  bdata.h"#endif#if BD_MAX_HARD > 16#error "too many hard disks in  bdata.h"#endif#if BD_GET_VIDEO > 3#error "video get level set too high in  bdata.h"#endif#endifstatic union Buf {   unsigned char b[5*SECTOR_SIZE];   struct {      short checksum[2];	/* prevent alignment on *4 boundary */      char signature[4];      short version;      short length;      unsigned char disk;	/* device code of last good disk */      unsigned char vid, mflp, mhrd;      short floppy;		/* byte offset to floppy data    */      short hard;		/* byte offset to hard disk data */      short partitions;		/* byte offset to partition info */      video_t v;      floppy_t f[4];      hard_t d;/*      edd_t edd; */   } s4;   struct {      short checksum[2];	/* prevent alignment on *4 boundary */      char signature[4];      short version;      short length;      unsigned char disk;	/* device code of last good disk */      unsigned char vid, mflp, mhrd;      short floppy;		/* byte offset to floppy data    */      short hard;		/* byte offset to hard disk data */      short partitions;		/* byte offset to partition info *//* version 5 additions	*/      short equipment;		/* byte offset to the equipment information */      short video;		/* byte offset to the video information */   } s5;} buf;static equip_t *eq;static video_t1 *v1;static video_t2 *v2;static video_t25 *v25;	/* extension for PROBE_VERSION 5 */static video_t3 *v3;static int video_36_bug;static int buf_valid = -1;static hard_t *hdp[16+1] =		/* pointers to all the hard disks */	{	NULL, NULL, NULL, NULL, 		NULL, NULL, NULL, NULL, 		NULL, NULL, NULL, NULL, 		NULL, NULL, NULL, NULL,  NULL	};static char warned[16];static void do_ebda(void);static void do_cr_pr(void);static void do_help(void);static void do_geom(char *bios);static void do_geom_all(void);static void do_table(char *part);static void do_video(void);static void do_bios(void);#if BITMAPstatic void do_bitmap(char *file);#endif#if VOLIDstatic void do_volid(void);#endifstatic char dev[] = "<device>";extern CHANGE_RULE *change_rules;	/* defined in partition.c */staticstruct Probes {	char *cmd;	void (*prc)();	char *str;	char *help;	}	list[] = {{ "help",  do_help,  NULL,  "Print list of -T(ell) options"	},{ "bios",  do_bios,  NULL,  "State of DL as passed to boot loader"  },#if BITMAP{ "bitmap=",do_bitmap,"<file>", "Display .bmp file X,Y/color/timer information"},#endif{ "ChRul", do_cr_pr, NULL,  "List partition change-rules"  },{ "EBDA",  do_ebda,  NULL,  "Extended BIOS Data Area information" },{ "geom=", do_geom,  "<bios>", "Geometry CHS data for BIOS code 0x80, etc." },{ "geom" , do_geom_all, NULL, "Geometry for all BIOS drives" },{ "table=", do_table, dev, "Partition table information for /dev/hda, etc."},{ "video", do_video, NULL,  "Graphic mode information" },#if VOLID{ "vol-ID", do_volid, NULL, "Volume ID check for uniqueness"},#endif{ NULL,    NULL,     NULL,   NULL}	};static struct partitions {	char *name;	unsigned char type;	unsigned char hide;	} ptab [] = {		/* Not complete, by any means */    { "DOS12", PART_DOS12, HIDDEN_OFF },    { "DOS16_small", PART_DOS16_SMALL, HIDDEN_OFF },    { "DOS16_big", PART_DOS16_BIG, HIDDEN_OFF },    { "NTFS or OS2_HPFS", PART_NTFS, HIDDEN_OFF },	/* same as HPFS; keep these two together *//*  { "HPFS", PART_HPFS, HIDDEN_OFF },	*/	/* same as NTFS */    { "FAT32", PART_FAT32, HIDDEN_OFF },    { "FAT32_lba", PART_FAT32_LBA, HIDDEN_OFF },    { "FAT16_lba", PART_FAT16_LBA, HIDDEN_OFF },    { "OS/2 BootMgr", PART_OS2_BOOTMGR, 0 },    { "DOS extended", PART_DOS_EXTD, 0 },    { "WIN extended", PART_WIN_EXTD_LBA, 0 },    { "Linux ext'd", PART_LINUX_EXTD, 0 },    { "Linux Swap", PART_LINUX_SWAP, 0 },    { "Linux Native", PART_LINUX_NATIVE, 0 },    { "Minix", PART_LINUX_MINIX, 0 },    { "Linux RAID", 0xfd, 0 },    { NULL, 0, 0 }   };static char phead[] = "\t\t Type  Boot      Start           End      Sector    #sectors";static int dirty = -1;	/* buffer is unread *//* load the low memory bios data area *//*  0 = no error, !0 = error on get */int fetch(void){    int fd;    int got, get;    int at = 0, seek = PROBESEG*16;        if (buf_valid>=0) return buf_valid;        if ((fd=open("/dev/mem", O_RDONLY)) < 0) return buf_valid=1;    at = lseek(fd, seek, SEEK_SET);    if (at != seek) return buf_valid=1;    get = sizeof(buf.b);    if (read(fd, &buf.b, get) != get) return buf_valid=1;    close(fd);    dirty = 0;	/* buffer is unmodified */        if (strncmp(buf.s5.signature, PROBE_SIGNATURE,4)) return buf_valid=2;/*    got = buf.s5.version; */	/* quiet GCC */    if (buf.s5.version < 3 ||        buf.s5.version > (short)(PROBE_VERSION)) return buf_valid=3;    got = buf.s5.length;    if (got > sizeof(buf.b) || got < sizeof(buf.s4)) return buf_valid=4;    if (*(int*)buf.s5.checksum != crc32((char*)&buf.s5 + 4, got-4, CRC_POLY1))    	return buf_valid=5;    if (buf.s5.version == 4) {	eq = (void*)&buf.s4.v.equipment;	v1 = (void*)&buf.s4.v.vid0F;	if (buf.s4.vid > 1) v2 = (void*)&buf.s4.v.vid12;	if (buf.s4.vid > 2) v3 = (void*)&buf.s4.v.vid4F00;    }    if (buf.s5.version >= 5) {	eq = (void*)&buf.b[buf.s5.equipment];	v1 = (void*)&buf.b[buf.s5.video];	if (buf.s5.vid > 1) {	    v2 = (void*)v1 + sizeof(*v1);	    v25 = (void*)v2 + sizeof(*v2);	}	if (buf.s5.vid > 2) v3 = (void*)v25 + sizeof(*v25);    }#if BETA_TEST	if (verbose>=5) printf("fetch: good return\n");#endif        return buf_valid=0;}int purge(void){    int i, fd;    int seek = PROBESEG*16;        if (verbose>=6) printf("purge: called\n");#if 0    if (verbose>=6) {fetch(); dirty=1;}		/* test of checksumming */#endif    if (dirty <= 0) return 0;		/* nothing to purge */        if ((i=fetch())) return i;	/* return error from fetch */        i = buf.s5.length;    *(int*)buf.s5.checksum = crc32((char*)&buf.s5 + 4, i-4, CRC_POLY1);        if ((fd=open("/dev/mem", O_WRONLY)) < 0) pdie("purge: can't open /dev/mem");    if (lseek(fd, seek, SEEK_SET) != seek) pdie("purge: ");    i = sizeof(buf.b);    if (write(fd, &buf.b, i) != i) pdie("purge: ");    close(fd);        if (verbose>=6) printf("purge: successful write\n");        return dirty = 0;			/* buffer is unmodified */}static int notice(int needed){    int f = fetch();        if (f || buf.s5.version < needed) {	printf( f==1 ?  "Only 'root' may do this.\n\n" :#if 0		"This information request requires that you previously booted your system\n"		"using LILO version %s or later.  These versions of the LILO boot\n"		"loader provide the BIOS data check information in low memory.  A boot floppy\n"		"constructed with 'mkrescue' may help.\n\n",#endif		"The information you requested is not available.\n\n"		"Booting your system with LILO version %s or later would provide the re-\n"		"quested information as part of the BIOS data check.  Please install a more\n"		"recent version of LILO on your hard disk, or create a bootable rescue floppy\n"		"with the 'mkrescue' command.\n\n",				needed==4 ? "22.0" :		needed==5 ? "22.5.1" :		needed==6 ? "22.5.7" :		S(VERSION_MAJOR) "." S(VERSION_MINOR) VERSION_EDIT  );	return 1;    }    return 0;}/* print out the help page for -T flag */static void do_help(void){    struct Probes *pr;        printf("usage:");    for (pr=list; pr->cmd; pr++) {    	printf("\tlilo -T %s%s\t%s\n",     			pr->cmd,     			pr->str ? pr->str : "        ",    			pr->help);    }#ifdef DEBUG    printf("    In some cases, the '-v' flag will produce more output.\n");    printf("sizeof(video_t) = %d  sizeof(floppy_t) = %d  sizeof(hard_t) = %d\n"           "sizeof(edd_t) = %d  sizeof(buf.s) = %d\n",            sizeof(video_t),  sizeof(floppy_t), sizeof(hard_t), sizeof(edd_t),            sizeof(buf.s5) );	    printf("fetch returns %d\n", fetch());            #endif}/* diagnostic output */static void show_geom(char *who, int cyl, int head, int sect){   fprintf(errstd, "    %s: %d cylinders, %d heads, %d sectors\n", who, cyl, head, sect);}/* get the old BIOS disk geometry */static int get_geom(unsigned int drive, struct disk_geom *geom){    hard_t *hd;    floppy_t *fd;    int i;    struct partition *pt_base;    unsigned int total;#if 0    if((i=fetch())) {        printf("No drive geometry information is available.\n\n");        exit(0);    }#else    if (notice(4)) exit(0);#endif#ifdef DEBUG	printf("get_geom: drive = 0x%02X\n", drive);	fflush(stdout);#endif    if (drive >= 0 && drive < buf.s5.mflp) {	fd = (floppy_t*)&buf.b[buf.s5.floppy] + drive;	hd = (hard_t*)fd;    }    else if (drive == 0x80) {	hdp[drive-0x80] = hd = (hard_t*)&buf.b[buf.s5.hard];    }        else if (drive >= 0x81 && drive < 0x80+buf.s5.mhrd) {	if (drive > buf.s5.disk) return 1;	if (!hdp[drive-0x80]) {	    i = get_geom(drive-1, geom);#ifdef DEBUG		printf("get_geom recursive return = %d  AH=0x%02X\n", i, i-1);		fflush(stdout);#endif	    if (i) return i;	}	hd = hdp[drive-0x80];    } else return 1;#ifdef DEBUG	printf("get_geom:  hd = %08X\n", (int)hd);	fflush(stdout);#endif        memset(geom, 0, sizeof(*geom));    if (drive >= 0x80)        hdp[drive-0x80 + 1] = (void*)hd + sizeof(hard_t);		/* simplest increment, but may be wrong */        /* regs.eax = 0x1500;           check drive type */    /* regs.edx = drive;			*/#ifdef DEBUG	printf("get_geom: int13, fn=15\n");	fflush(stdout);#endif      if (hd->fn15.flags & 1)   return 1;	/* carry was set */   geom->type = hd->fn15.ah;   if (geom->type == 0) return 1;   if (geom->type == 3)     geom->n_total_blocks = ((int)hd->fn15.cx << 16) + hd->fn15.dx;      /* regs.eax = 0x0800;		*/   /* regs.edx = drive;			*/   #ifdef DEBUG	printf("get_geom: int13, fn=08\n");	fflush(stdout);#endif      if (hd->fn08.flags&1 || hd->fn08.ah || hd->fn08.cx==0)     return 1 + hd->fn08.ah;      i =   geom->n_sect = hd->fn08.cx & 0x3F;   i *=   geom->n_head = ((hd->fn08.dx>>8)&0xFF)+1;   i *=   geom->n_cyl  = (((hd->fn08.cx>>8)&0xFF)|((hd->fn08.cx&0xC0)<<2))+1;   if (i > geom->n_total_blocks) geom->n_total_blocks = i;   geom->n_disks = hd->fn08.dx & 0xFF;   geom->pt = NULL;   if (drive < 4)  return 0;

⌨️ 快捷键说明

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