📄 probe.c
字号:
struct disk_geom geom; for (hd=0; hd<0x81; hd+=0x80) for (d=0; d<16; d++) { dr = d+hd; if (get_geom(dr, &geom)==0) { if (dr==0x80) printf("\nBIOS reports %d drive%s\n", (int) geom.n_disks, (int)geom.n_disks==1 ? "" : "s"); print_geom(dr, geom); } }}/* print disk drive geometry information for a particular drive */static void do_geom(char *bios){ int dr; struct disk_geom geom;#if 0 dr = my_atoi(bios);#endif dr = to_number(bios); if (get_geom(dr, &geom)==0) print_geom(dr, geom); else printf("Unrecognized BIOS device code 0x%02x\n", dr); }/* print an individual partition table entry */static void print_pt(int index, struct partition pt){ char bt[4], *ty, start[32], end[32], type[8]; char x; int i; for (x=i=0; i<sizeof(pt); i++) x |= ((char*)&pt)[i]; if (!x) { printf("%4d\t\t\t ** empty **\n", index); return; } strcpy(bt," "); sprintf(type, "0x%02x", (int)pt.sys_ind); sprintf(start, "%4d:%d:%d", (int)pt.cyl+((pt.sector&0xC0)<<2), (int)pt.head, (int)pt.sector & 0x3f ); sprintf(end, "%4d:%d:%d", (int)pt.end_cyl+((pt.end_sector&0xC0)<<2), (int)pt.end_head, (int)pt.end_sector & 0x3f ); ty = type; if (pt.boot_ind==0x80) bt[1]='*'; else if (pt.boot_ind==0) ; /* do nothing */ else { sprintf(bt+1,"%02x", (int)pt.boot_ind); } for (i=0; ptab[i].name; i++) { if (ptab[i].type == pt.sys_ind) { ty = ptab[i].name; break; } else if ((ptab[i].type|ptab[i].hide) == pt.sys_ind) { bt[0] = 'H'; ty = ptab[i].name; break; } } printf("%4d%18s%5s%11s%14s%12u%12u\n", index, ty, bt, start, end, pt.start_sect, pt.nr_sects);}/* partition table display */static void do_table(char *part){ int fd, i; struct partition pt [PART_MAX]; unsigned int second, base; unsigned short boot_sig; if (!strncmp(part, "/dev/", 5)) { if (strncmp(part+5, "md", 2) && isdigit(part[strlen(part)-1]) ) die("Not a device: '%s'", part); fd = open(part, O_RDONLY); } else fd = -1; if (fd<0) die("Unable to open '%s'", part); if (lseek(fd, PART_TABLE_OFFSET, SEEK_SET)<0) die("lseek failed"); if (read(fd, pt, sizeof(pt)) != sizeof(pt)) die("read pt failed"); if ( read(fd, &boot_sig, sizeof(boot_sig)) != sizeof(boot_sig) || boot_sig != BOOT_SIGNATURE ) die("read boot signature failed"); { if (lseek(fd, MAX_BOOT_SIZE+2, SEEK_SET)<0) die("lseek s/n failed"); if (read(fd, &second, sizeof(second)) != sizeof(second)) die("read s/n failed"); printf(" S/N = %08X\n", second); } printf("%s\n", phead); second=base=0; for (i=0; i<PART_MAX; i++) { print_pt(i+1, pt[i]); if (is_extd_part(pt[i].sys_ind)) { if (!base) base = pt[i].start_sect; else die("invalid partition table: second extended partition found"); } } i=5; while (verbose>0 && base) { if (llseek(fd, LLSECTORSIZE*(base+second) + PART_TABLE_OFFSET, SEEK_SET) < 0) die("secondary llseek failed"); if (read(fd, pt, sizeof(pt)) != sizeof(pt)) die("secondary read pt failed"); if ( read(fd, &boot_sig, sizeof(boot_sig)) != sizeof(boot_sig) || boot_sig != BOOT_SIGNATURE ) die("read second boot signature failed"); print_pt(i++, pt[0]); if (is_extd_part(pt[1].sys_ind)) second=pt[1].start_sect; else base = 0; } close(fd);}/* list partition change-rules */static void do_cr_pr(void){ CHANGE_RULE *cr; cr = change_rules; printf("\t\tType Normal Hidden\n"); if (!cr) printf("\t **** no change-rules defined ****\n"); while (cr) { printf ("%20s 0x%02x 0x%02x\n", cr->type, (int)cr->normal, (int)cr->hidden); cr = cr->next; }}#if VIDEOstatic int egamem;static int mode, col, row, page;int get_video(void) /* return -1 on error, or adapter type [0..7] */{ int adapter = 0; /* 0=unknown, 1=MDA,HGC, 2=CGA, 3=EGA, 4=MCGA, 5=VGA, 6=VESA (640), 7=VESA (800) */ int okay = 1; int monitor; if(fetch()) return -1; if ((okay=buf.s.vid)) { /* get current video mode */ /* reg.eax = 0x0F00; */ if (verbose >= 2) printf("get video mode\n"); mode = buf.s.v.vid0F.al; col = buf.s.v.vid0F.ah; page = buf.s.v.vid0F.bh; row = buf.s.v.vid0F.bl + 1; if (mode==7) { adapter=1; row = 25; okay = 0; } else if (col<80) { adapter=2; okay=0; } else adapter=2; /* at least CGA */ } if (okay>=2) {#if 1 /* determine video adapter type */ /* reg.eax = 0x1200; call valid on EGA/VGA */ /* reg.ebx = 0xFF10; */ if (verbose >= 2) printf("determine adapter type\n"); if ((unsigned)(monitor = buf.s.v.vid12.bh) <= 1U) { adapter = 3; /* at least EGA */ egamem = buf.s.v.vid12.bl; } else { okay = 0; } }#endif if (okay>=2) { /* check for VGA */ /* reg.eax = 0x1A00; get display combination */ if (verbose >= 2) printf("get display combination\n"); if ( buf.s.v.vid1A.al==0x1A ) { monitor = (buf.s.v.vid1A.bx >> ((verbose>=3)*8) ) & 0xFF; switch (monitor) { case 1: adapter = 1; break; case 2: adapter = 2; break; case 7: case 8: adapter = 5; /* VGA */ break; case 0xA: case 0xB: case 0xC: adapter = 4; /* MCGA */ break; default: okay = 0; break; } } else { okay = 0; } } if (okay>=3 && adapter==5) { /* check for VESA extensions */ if (verbose >= 2) printf("check VESA present\n"); if ((buf.s.v.vid4F00.ax == 0x4f) && strncmp("VESA", buf.s.v.vid4F00.sig, 4)==0) adapter++; if (adapter > 5) { /* reg.eax = 0x4f01; reg.ecx = 0x0101; 640x480x256 */ if ((buf.s.v.vid101.ax == 0x4f) && (buf.s.v.vid101.bits & 0x19) == 0x19) adapter ++; else adapter--; } if (adapter > 6) { /* reg.eax = 0x4f01; reg.ecx = 0x0103; 800x600x256 */ if ((buf.s.v.vid103.ax == 0x4f) && (buf.s.v.vid103.bits & 0x19) == 0x19) ; else adapter--; } } if (verbose>=2) printf ("mode = 0x%02x, columns = %d, rows = %d, page = %d\n\n", mode, col, row, page); return adapter;}/* print VGA/VESA mode information */void do_video(void){static char *display[] = { "unknown", "MDA", "CGA", "EGA", "MCGA", "VGA", "VGA/VESA", "VGA/VESA" }; int adapter; /* 0=unknown, 1=MDA,HGC, 2=CGA, 3=EGA, 4=MCGA, 5=VGA, 6=VESA (640), 7=VESA (800) */ adapter = get_video(); if(adapter<0) { printf("No video mode information is available.\n"); return; } if (verbose>=1) printf ("mode = 0x%02x, columns = %d, rows = %d, page = %d\n\n", mode, col, row, page); printf("%s adapter:\n\n", display[adapter]); if (adapter < 3 || (adapter == 3 && egamem < 1) ) { printf("No graphic modes are supported\n"); } else { if (adapter != 4) printf(" 640x350x16 mode 0x0010\n"); if (adapter >= 5) { printf(" 640x480x16 mode 0x0012\n\n"); printf(" 320x200x256 mode 0x0013\n"); } if (adapter >= 6) printf(" 640x480x256 mode 0x0101\n"); if (adapter >= 7) printf(" 800x600x256 mode 0x0103\n"); }}#endif/* entry from lilo.c for the '-T' (tell) switch */void probe_tell (char *cmd){ struct Probes *pr = list; int n; char *arg; if (!(verbose>0)) printf("\n"); for (; pr->cmd; pr++) { n = strlen(pr->cmd); arg = NULL; if (pr->cmd[n-1] == '=') arg = cmd+n; if (!strncasecmp(cmd, pr->cmd, n)) { pr->prc(arg); printf("\n"); exit(0); } } printf("Unrecognized option to '-T' flag\n"); do_help(); printf("\n"); exit(1);}int bios_max_devs(void){ struct disk_geom geom; int i; if (!fetch() && !get_geom(0x80, &geom)) { i = (buf.s.disk & 0x7f) + 1; if (geom.n_disks == i) return i; } return BIOS_MAX_DEVS; }#ifdef DEBUGstatic void dump_pt(unsigned char *pt){ int i, j; for (j=0; j<4; j++) { for (i=0; i<16; i++) { printf(" %02X", (int)(*pt++)); } printf("\n"); } printf("\n");}#endif/* * return the bios device code of the disk, based on the geometry * match with the probe data * side effect is to place the device code in geo->device * return -1 if indeterminate */int bios_device(GEOMETRY *geo, int device){ int bios1, bios, match, fd; int mbios[BD_MAX_HARD]; struct disk_geom bdata; DEVICE dev; unsigned char part[PART_TABLE_SIZE]; unsigned char extra[8]; int serial; if (fetch()) return -1; if (verbose>=3) printf("bios_dev: device %04X\n", device); match = 0; bios1 = -1; /* signal error */ for (bios=0x80; bios<=buf.s.disk; bios++) { mbios[bios-0x80] = 0; if (get_geom(bios, &bdata)) break; if (geo->cylinders == bdata.n_cyl && geo->heads == bdata.n_head && geo->sectors == bdata.n_sect) { match++; mbios[bios-0x80] = bios1 = bios; } } if (match == 1) { if (verbose>=2) printf("bios_dev: match on geometry alone (0x%02X)\n", bios1); return (geo->device = bios1); } device &= D_MASK(device); /* mask to primary device */ fd = dev_open(&dev,device,O_RDONLY); if (verbose>=3) printf("bios_dev: masked device %04X, which is %s\n", device, dev.name); if (lseek(fd, PART_TABLE_OFFSET-8, SEEK_SET)!=PART_TABLE_OFFSET-8) die("bios_device: seek to partition table - 8"); if (read(fd,extra,sizeof(extra))!= sizeof(extra)) die("bios_device: read partition table - 8"); serial = *(int*)(extra+2); if (lseek(fd, PART_TABLE_OFFSET, SEEK_SET)!=PART_TABLE_OFFSET) die("bios_device: seek to partition table"); if (read(fd,part,sizeof(part))!= sizeof(part)) die("bios_device: read partition table"); dev_close(&dev);#ifdef DEBUG if (verbose>=4) { printf("serial number = %08X\n", serial); dump_pt(part); }#endif if (verbose>=3) printf("bios_dev: geometry check found %d matches\n", match); match = 0; bios1 = -1; while (--bios >= 0x80) { get_geom(bios, &bdata); if (verbose>=4) { printf("bios_dev: (0x%02X) S/N=%08X *PT=%08X\n", bios, bdata.serial_no, (int)bdata.pt);#ifdef DEBUG dump_pt((void*)bdata.pt);#endif } if (!memcmp(part,bdata.pt,sizeof(part)) && !(bdata.serial_no && serial!=bdata.serial_no) ) { match++; bios1 = bios; } } if (verbose>=2) printf("bios_dev: PT match found %d match%s (0x%02X)\n", match, match==1 ? "" : "es", bios1); if (match != 1) bios1 = -1; else { /* match == 1 */ get_geom(bios1, &bdata); if ( (geo->sectors && geo->sectors!=bdata.n_sect) || (geo->heads && geo->heads!=bdata.n_head) ) { unsigned long nblocks = geo->cylinders * geo->heads * geo->sectors; if (!nowarn && !(warned[bios1-0x80]&2) ) { fprintf(errstd,"Warning: Kernel & BIOS return differing head/sector geometries for device 0x%02X\n", bios1); show_geom("Kernel", geo->cylinders, geo->heads, geo->sectors); show_geom(" BIOS", bdata.n_cyl, bdata.n_head, bdata.n_sect); warned[bios1-0x80] |= 2; }#if 1 geo->sectors = bdata.n_sect; geo->heads = bdata.n_head; if (bdata.n_total_blocks > nblocks) nblocks = bdata.n_total_blocks; geo->cylinders = nblocks / (bdata.n_head*bdata.n_sect);#endif } } return (geo->device = bios1);}static void do_bitmap(char *file){ printf("Color, Positioning, and Timer information for file: %s\n", file); printf("...<unimplemented>...\n");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -