/* extipl.c -- * install and testing extended IPL * Auther: takamiti@tsden.org * * CAUTION: * TAKE CARE! * I(WE) HAVE NOT SHARE IN THE TROUBLES, RUNNING BY YOUR OWN RISKS. */ #include #include #include #include #include #include #include #define VERSION "Version 3.00 1997/10/25" #define SECTOR_SIZE 512 #define BOOT_FD 0x00 #define BOOT_HD 0x80 #define WRITE_SECTOR 0x0301 #define READ_SECTOR 0x0201 #define PARTITIONS 4 #define OK 0 #define ERR -1 #define codecpy memcpy typedef unsigned char byte; typedef unsigned long ulong; struct hd_addr { byte head; byte sector; byte cyl; }; typedef struct hd_addr hd_addr; struct partition { byte bootind; hd_addr start; byte systemind; hd_addr end; ulong start_sector; ulong nr_sector; }; typedef struct partition partition; extern int dmaoverrun(char *, int); extern void extendedIPL(); extern void FDtestIPL(); /* extern void codecpy(); */ int fdtest(char *); int install(char *); int restore(char *); int saveipl(char *); int clrboot(char *); int help(char *); int dskrw(int, int); int rdipl(int, char *), wripl(int, char *); int save(char *, char *), load(char *, char *); void tblsort(char *); #if DEBUG int debugout(char *); #endif struct cmdtab { char *command; int (*func)(char *); char *help; } cmdtab[] = { {"install", install, "install 'extended_IPL' on fixed disk #0" }, {"fdtest", fdtest, "testing 'extended_IPL' on diskette" }, {"save", saveipl, "save original-IPL to file" }, {"restore", restore, "restore original-IPL"}, {"clrboot", clrboot, "clear active flag"}, {"help", help, "show this"}, #if DEBUG {"debug", debugout,"for debug mode"}, #endif {"", (int *)NULL, ""} }; char *diskbuf, *sectbuf; char buf1[SECTOR_SIZE], buf2[SECTOR_SIZE]; void main(ac, av) int ac; char *av[]; { int i, r; if (ac < 2) help(av[1]); diskbuf = buf1; sectbuf = buf2; if (dmaoverrun(diskbuf, SECTOR_SIZE)) { diskbuf = buf2; sectbuf = buf1; } for(i = 0; *cmdtab[i].command; i++) { if (strcmp(av[1], cmdtab[i].command) == 0) { r = (*(cmdtab[i].func))(av[2]); fprintf(stderr, "%s.\n", (r == OK) ? "Ok": "Aborted"); exit(r); } } fprintf(stderr, "Unknown command \"%s\"\n", av[1]); exit(ERR); } int help(arg) char *arg; { int i; fprintf(stderr, "\n*** Extended IPL installer %s ***", VERSION); fprintf(stderr, "\nUsage: extIPL command [arg]\nVaild commands are:\n"); for(i=0; *cmdtab[i].command; i++) fprintf(stderr,"\t%s\t- %s\n", cmdtab[i].command, cmdtab[i].help); exit(OK); } int save(file, buf) char *file, *buf; { int fd, i=0; if (*file == '\0') { do { sprintf(file, "fdiskIPL.%03d", i++); if (i > 999) return(ERR); } while (access(file, 0) == 0); } fd = open(file, O_CREAT | O_RDWR | O_TRUNC | O_BINARY, S_IREAD); if (fd < 0 || write(fd, buf, SECTOR_SIZE) != SECTOR_SIZE) { perror(file); return(ERR); } close(fd); return(OK); } int load(file, buf) char *file, *buf; { int fd, r; fd = open(file, O_RDONLY | O_BINARY); if (fd < 0 || (r = read(fd, buf, SECTOR_SIZE)) < 0) { perror(file); return(ERR); } close(fd); return(r); } int dskrw(drive, mode) int drive, mode; { union REGS r; struct SREGS seg; int i, err; for(i = 0; i < 8; i++) { r.x.ax = mode; r.x.bx = (int)diskbuf; r.x.cx = 1; r.x.dx = drive; seg.es = FP_SEG(diskbuf); int86x(0x13, &r, &r, &seg); if ((r.x.flags & 1) == 0) return(OK); err = r.h.ah & 0xff; r.h.ah = 0; r.x.dx = drive; int86(0x13, &r, &r); /* reset */ } fprintf(stderr, "DISK BIOS Error(0x%02X)\n", err); return(ERR); } int rdipl(drive, buf) int drive; char *buf; { if (dskrw(drive, READ_SECTOR) != OK) return(ERR); memcpy(buf, diskbuf, SECTOR_SIZE); return(OK); } int wripl(drive, buf) int drive; char *buf; { if (dskrw(drive, READ_SECTOR) != OK) return(ERR); memcpy(diskbuf, buf, 446); return(dskrw(drive, WRITE_SECTOR)); } int saveipl(arg) char *arg; { if (rdipl(BOOT_HD, sectbuf) != OK) return(ERR); return( save(((arg == NULL) ? "master.ipl": arg), sectbuf) ); } int fdtest(arg) char *arg; { if (arg == NULL) { codecpy(sectbuf, FDtestIPL, SECTOR_SIZE); } else { if (load(arg, sectbuf) < OK) return(ERR); } *(unsigned int *)(sectbuf+510) = 0xaa55; fprintf(stderr, "Please insert blank diskette in drive \"A:\"\n"); fprintf(stderr, "Then hit key. "); while (getchar() != '\n') ; return(wripl(BOOT_FD, sectbuf)); } int install(arg) char *arg; { char name[80]; if (rdipl(BOOT_HD, sectbuf)) return(ERR); fprintf(stderr, "*** Before exchange the master boot program,\n"); fprintf(stderr, "*** You had better keep the original IPL code.\n"); fprintf(stderr, "Enter file name to save: "); gets(name); if (save(name, sectbuf) != OK) return(ERR); fprintf(stderr, "Current IPL saved to '%s'.\n", name); fprintf(stderr, "Hit to install Extended-IPL "); while (getchar() != '\n') ; if (arg == NULL) { codecpy(sectbuf, extendedIPL, 446); } else { if (load(arg, sectbuf) != OK) return(ERR); } return(wripl(BOOT_HD, sectbuf)); } int restore(arg) char *arg; { if (arg == NULL || load(arg, sectbuf) != SECTOR_SIZE) return(ERR); if (*(unsigned int *)(sectbuf+510) != 0xaa55) { fprintf(stderr, "IPL magic != 0xAA55\n"); return(ERR); } fprintf(stderr, "Original IPL(%s) loaded. Hit to restore ", arg); while (getchar() != '\n') ; return(wripl(BOOT_HD, sectbuf)); } int clrboot(arg) char *arg; { char *p; int i; if (dskrw(BOOT_HD, READ_SECTOR) != OK) return(ERR); for(i = 0, p = diskbuf + 0x1be; i < 4; i++, p += 16) { *p &= 0x7f; } return(dskrw(BOOT_HD, WRITE_SECTOR)); } #if DEBUG int debugout(arg) char *arg; { FILE *fp; char tmpbuf[SECTOR_SIZE]; if ((fp = fopen("boot-sec", "wb")) == NULL) { return(ERR); } rdipl(BOOT_HD, sectbuf); if (strcmp(arg, ".0") == 0) { codecpy(sectbuf, extendedIPL, 446); } else if (strcmp(arg, ".1") == 0) { codecpy(sectbuf, FDtestIPL, 446); } else { load(arg, tmpbuf); memcpy(sectbuf, tmpbuf, 446); } fwrite(sectbuf, SECTOR_SIZE, 1, fp); fclose(fp); return(OK); } #endif