void boot_unstripped(char *setup,char *kernel,IMAGE_DESCR *descr) { struct exec exec; int fd,sectors; if (verbose) printf("Unstripped: setup %s, kernel %s\n",setup,kernel); (void) geo_open(&geo,setup,O_RDONLY); map_begin_section(); map_add(&geo,0,SETUPSECS); geo_close(&geo); fd = geo_open(&geo,kernel,O_RDONLY); if (read(fd,(char *) &exec,sizeof(struct exec)) != sizeof(struct exec)) die("read %s: %s",kernel,strerror(errno)); if (exec.a_entry || exec.a_trsize || exec.a_drsize || !exec.a_syms) die("Not an unstripped kernel: %s",kernel); map_add(&geo,2,(exec.a_text+exec.a_data+SECTOR_SIZE-1)/SECTOR_SIZE); if ((exec.a_text+exec.a_data) & 15) fprintf(stderr,"Warning: Unsupported BSS - no initialization.\n"); else { if (verbose > 2) printf("BSS: 0x%X+%d\n",exec.a_text+exec.a_data+DEF_SYSSEG, exec.a_bss); descr->bss_seg = ((exec.a_text+exec.a_data) >> 4)+DEF_SYSSEG; descr->bss_segs = exec.a_bss >> 16; descr->bss_words = ((exec.a_bss & 0xffff)+1) >> 1; } geo_close(&geo); sectors = map_end_section(&descr->start); if (verbose > 1) printf("Mapped %d sector%s.\n",sectors,sectors == 1 ? "" : "s"); }
void boot_device(char *spec,char *range,IMAGE_DESCR *descr) { char *here; int start,secs; int sectors; if (verbose) printf("Boot device: %s, range %s\n",spec,range); (void) geo_open(&geo,spec,O_NOACCESS); map_begin_section(); if (here = strchr(range,'-')) { *here++ = 0; start = to_number(range); if ((secs = to_number(here)-start+1) < 0) die("Invalid range"); } else { if (here = strchr(range,'+')) { *here++ = 0; start = to_number(range); secs = to_number(here); } else { start = to_number(range); secs = 1; } } map_add(&geo,start,secs); sectors = map_end_section(&descr->start); geo_close(&geo); if (verbose > 1) printf("Mapped %d sector%s.\n",sectors,sectors == 1 ? "" : "s"); }
void boot_image(char *spec,IMAGE_DESCR *descr) { BOOT_SECTOR buff; int fd,sectors; if (verbose) printf("Boot image: %s\n",spec); fd = geo_open(&geo,spec,O_RDONLY); map_begin_section(); if (fstat(fd,&st) < 0) die("fstat %s: 5s",spec,strerror(errno)); if (read(fd,(char *) &buff,SECTOR_SIZE) != SECTOR_SIZE) die("read %s: %s",spec,strerror(errno)); if (buff.par_l.root_dev) descr->root_dev = buff.par_l.root_dev; if (buff.par_l.swap_dev) descr->swap_dev = buff.par_l.swap_dev; map_add(&geo,1,(st.st_size+SECTOR_SIZE-1)/SECTOR_SIZE-1); sectors = map_end_section(&descr->start); geo_close(&geo); if (verbose > 1) printf("Mapped %d sector%s.\n",sectors,sectors == 1 ? "" : "s"); }
void boot_other(char *loader,char *boot,char *part,IMAGE_DESCR *descr) { int l_fd,p_fd,walk,found; BOOT_SECTOR buff; if (verbose) printf("Boot other: %s, on %s, loader %s\n",boot,part,loader); (void) geo_open(&geo,boot,O_NOACCESS); if ((l_fd = open(loader,O_RDONLY)) < 0) die("open %s: %s",loader,strerror(errno)); if (!*part) memset(&buff,0,SECTOR_SIZE); else { if ((p_fd = open(part,O_RDONLY)) < 0) die("open %s: %s",part,strerror(errno)); if (read(p_fd,(char *) &buff,SECTOR_SIZE) != SECTOR_SIZE) die("read %s: %s",part,strerror(errno)); } if (read(l_fd,(char *) &buff,PART_TABLE_OFFSET) < 0) die("read %s: %s",loader,strerror(errno)); check_version(&buff,STAGE_CHAIN); if (*part) { found = 0; for (walk = 0; walk < PARTITION_ENTRIES; walk++) if (!PART(buff,walk).sys_ind || PART(buff,walk).start_sect != geo.start) { if (PART(buff,walk).sys_ind != PART_DOS12 && PART(buff,walk). sys_ind != PART_DOS16) PART(buff,walk).sys_ind = PART_INVALID; } else { if (found) die("Duplicate entry in partition table"); buff.par_c.offset = walk*PARTITION_ENTRY; PART(buff,walk).boot_ind = 0x80; found = 1; } if (!found) die("Partition entry not found."); (void) close(p_fd); } (void) close(l_fd); map_begin_section(); map_add_sector(&buff); map_add(&geo,0,1); (void) map_end_section(&descr->start); geo_close(&geo); if (verbose > 1) printf("Mapped 2 (1+1) sectors.\n"); }
static void show_images(char *map_file) { DESCR_SECTORS descrs; BOOT_SECTOR boot; GEOMETRY geo; SECTOR_ADDR addr[4]; char buffer[SECTOR_SIZE]; char *name; int fd,image,i; int tsecs; unsigned short checksum,flags; fd = geo_open(&geo,map_file,O_RDONLY); if (read(fd,buffer,SECTOR_SIZE) != SECTOR_SIZE) die("read %s: %s",map_file,strerror(errno)); if (read(fd,(char *) &descrs,sizeof(descrs)) != sizeof(descrs)) die("read %s: %s",map_file,strerror(errno)); if (verbose > 0) { bsect_read(cfg_get_strg(cf_options,"boot"),&boot); printf("Global settings:\n"); tsecs = (boot.par_1.delay*55+50)/100; printf(" Delay before booting: %d.%d seconds\n",tsecs/10,tsecs % 10); if (boot.par_1.timeout == 0xffff) printf(" No command-line timeout\n"); else { tsecs = (boot.par_1.timeout*55+50)/100; printf(" Command-line timeout: %d.%d seconds\n",tsecs/10, tsecs % 10); } if (boot.par_1.prompt) printf(" Always enter boot prompt\n"); else printf(" Enter boot prompt only on demand\n"); if (!boot.par_1.port) printf(" Serial line access is disabled\n"); else printf(" Boot prompt can be accessed from COM%d\n", boot.par_1.port); if (!boot.par_1.msg_len) printf(" No message for boot prompt\n"); else printf(" Boot prompt message is %d bytes\n",boot.par_1.msg_len); if (*(unsigned short *) buffer != DC_MAGIC || !buffer[2]) printf(" No default boot command line\n"); else printf(" Default boot command line: \"%s\"\n",buffer+2); printf("Images:\n"); } for (image = 0; image < MAX_IMAGES; image++) if (*(name = descrs.d.descr[image].name)) { printf("%s%-" S(MAX_IMAGE_NAME) "s%s",verbose > 0 ? " " : "",name, image ? " " : " *"); if (verbose > 1) { printf(" <dev=0x%02x,hd=%d,cyl=%d,sct=%d>", descrs.d.descr[image].start.device, descrs.d.descr[image].start.head, descrs.d.descr[image].start.track, descrs.d.descr[image].start.sector); } printf("\n"); if (verbose > 0) { flags = descrs.d.descr[image].flags; if (!*descrs.d.descr[image].password) printf(" No password\n"); else printf(" Password is required for %s\n",flags & FLAG_RESTR ? "specifying options" : "booting this image"); printf(" Boot command-line %s be locked\n",flags & FLAG_LOCK ? "WILL" : "won't"); printf(" %single-key activation\n",flags & FLAG_SINGLE ? "S" : "No s"); if (flags & FLAG_KERNEL) { #ifdef NORMAL_VGA if (!(flags & FLAG_VGA)) printf(" VGA mode is taken from boot image\n"); else { printf(" VGA mode: "); switch (descrs.d.descr[image].vga_mode) { case NORMAL_VGA: printf("NORMAL\n"); break; case EXTENDED_VGA: printf("EXTENDED\n"); break; case ASK_VGA: printf("ASK\n"); break; default: printf("%d (0x%04x)\n", descrs.d.descr[image].vga_mode, descrs.d.descr[image].vga_mode); } } #endif if (!descrs.d.descr[image].start_page) printf(" Kernel is loaded \"low\"\n"); else printf(" Kernel is loaded \"high\", at 0x%08lx\n", (unsigned long) descrs.d.descr[image].start_page* getpagesize()); if (!*(unsigned long *) descrs.d.descr[image].rd_size) printf(" No initial RAM disk\n"); else printf(" Initial RAM disk is %ld bytes\n", *(unsigned long *) descrs.d.descr[image].rd_size); } if (!geo_find(&geo,descrs.d.descr[image].start)) { printf(" Map sector not found\n"); continue; } if (read(fd,addr,4*sizeof(SECTOR_ADDR)) != 4*sizeof(SECTOR_ADDR)) die("Read on map file failed (access conflict ?)"); if (!geo_find(&geo,addr[0])) printf(" Fallback sector not found\n"); else { if (read(fd,buffer,SECTOR_SIZE) != SECTOR_SIZE) die("Read on map file failed (access conflict ?)"); if (*(unsigned short *) buffer != DC_MAGIC) printf(" No fallback\n"); else printf(" Fallback: \"%s\"\n",buffer+2); } if (flags & FLAG_KERNEL) if (!geo_find(&geo,addr[1])) printf(" Options sector not found\n"); else { if (read(fd,buffer,SECTOR_SIZE) != SECTOR_SIZE) die("Read on map file failed (access conflict ?)"); printf(" Options: \"%s\"\n",buffer); } else if (geo_find(&geo,addr[3])) show_other(fd); else printf(" Image data not found\n"); } } (void) close(fd); checksum = INIT_CKS; for (i = 0; i < sizeof(descrs)/sizeof(unsigned short); i++) checksum ^= ((unsigned short *) &descrs)[i]; if (!checksum) exit(0); fflush(stdout); fprintf(stderr,"Checksum error\n"); exit(1); }
static void show_images(char *map_file) { #if !__MSDOS__ DESCR_SECTORS descrs; BOOT_SECTOR boot; MENUTABLE menu; BOOT_PARAMS_2 param2; GEOMETRY geo; SECTOR_ADDR addr[4]; char buffer[SECTOR_SIZE]; #else /* __MSDOS */ static DESCR_SECTORS descrs; static char buffer[SECTOR_SIZE]; #endif /*__MSDOS__ */ char *name; int fd,image; int tsecs; int tlinear, tlba32; unsigned short flags; time_t Time; #if !__MSDOS__ fd = geo_open(&geo,map_file,O_RDONLY); #else /* __MSDOS__ */ if ((fd = open(map_file,O_RDONLY))<=0) die("Cannot open map file: %s", map_file); #endif /* __MSDOS__ */ if (read(fd,buffer,SECTOR_SIZE) != SECTOR_SIZE) die("read cmdline %s: %s",map_file,strerror(errno)); if (read(fd,(char*)&descrs,sizeof(descrs)) != sizeof(descrs)) die("read descrs %s: %s",map_file,strerror(errno)); #if !__MSDOS__ if (lseek(fd, SECTOR_SIZE, SEEK_CUR) <= 0) /* skip zero sector */ die("lseek over zero sector %s: %s",map_file,strerror(errno)); if (read(fd,(char*)¶m2,sizeof(param2)) != sizeof(param2)) die("read second params %s: %s",map_file,strerror(errno)); if (lseek(fd, - sizeof(menu), SEEK_END) <= 0) die("lseek keytable %s: %s",map_file,strerror(errno)); if (read(fd,(char*)&menu,sizeof(menu)) != sizeof(menu)) die("read keytable %s: %s",map_file,strerror(errno)); tlba32 = (descrs.d.descr[0].start.device & LBA32_FLAG) != 0; tlinear = !tlba32 && (descrs.d.descr[0].start.device & LINEAR_FLAG); if (tlinear != linear || tlba32 != lba32) { printf("Warning: mapfile created with %s option\n", tlinear?"linear":tlba32?"lba32":"no linear/lba32"); linear = tlinear; lba32 = tlba32; } if (verbose) { bsect_read(cfg_get_strg(cf_options,"boot"),&boot); #if 1 if (boot.par_1.cli != 0xFA) { /* relocation happened */ int len, offset=0; if (boot.sector[0] == 0xEB) /* jmp short */ offset = boot.sector[1]+2; else if (boot.sector[0] == 0xE9) /* jmp near */ offset = *(short*)&boot.sector[1] + 3; else die("Cannot undo boot sector relocation."); len = SECTOR_SIZE - offset; memmove(&boot, &boot.sector[offset], len); if (boot.par_1.cli != 0xFA) die("Cannot recognize boot sector."); } #endif #if 1 Time = boot.par_1.map_stamp; printf("Installed: %s\n", ctime(&Time)); #else printf("Installed: %s\n", ctime((time_t*)&boot.par_1.map_stamp)); #endif printf("Global settings:\n"); tsecs = (param2.delay*2197+3999)/4000; printf(" Delay before booting: %d.%d seconds\n",tsecs/10,tsecs % 10); if (param2.timeout == 0xffff) printf(" No command-line timeout\n"); else { tsecs = (param2.timeout*2197+3999)/4000; printf(" Command-line timeout: %d.%d seconds\n",tsecs/10, tsecs % 10); } printf(" %snattended booting\n", param2.flag2&FLAG2_UNATTENDED ? "U" : "No u"); printf(" %sPC/AT keyboard hardware prescence check\n", param2.flag2&FLAG2_NOKBD ? "" : "No "); if (boot.par_1.prompt & FLAG_PROMPT) printf(" Always enter boot prompt\n"); else printf(" Enter boot prompt only on demand\n"); printf(" Boot-time BIOS data%s saved\n", boot.par_1.prompt & FLAG_NOBD ? " NOT" : ""); printf(" Boot-time BIOS data auto-suppress write%s bypassed\n", boot.par_1.prompt & FLAG_BD_OKAY ? "" : " NOT"); printf(" Large memory (>15M) is%s used to load initial ramdisk\n", boot.par_1.prompt & FLAG_LARGEMEM ? "" : " NOT"); printf(" %sRAID installation\n", boot.par_1.prompt & FLAG_RAID ? "" : "Non-"); printf(" Boot device %s be used for the Map file\n", boot.par_1.prompt & FLAG_MAP_ON_BOOT ? "WILL" : "will not"); if (!param2.port) printf(" Serial line access is disabled\n"); else printf(" Boot prompt can be accessed from COM%d\n", param2.port); if (!param2.msg_len) printf(" No message for boot prompt\n"); else if (!cfg_get_strg(cf_options,"bitmap")) printf(" Boot prompt message is %d bytes\n",param2.msg_len); else printf(" Bitmap file is %d paragraphs (%d bytes)\n", param2.msg_len, 16*param2.msg_len); /* 22.6.2 begin */ if (*(unsigned short *) buffer != DC_MAGIC /* || !buffer[2] */) /* 22.6.2 end */ printf(" No default boot command line\n"); else printf(" Default boot command line: \"%s\"\n",buffer+2); if (verbose>=3) { printf("Serial numbers %08X\n", menu.serial_no[0]); } printf("Images:\n"); } /* 22.7 begin */ else /* verbose==0 */ #endif /* !__MSDOS__ */ { if (*(unsigned short *) buffer == DC_MAGIC) printf("Default boot command line: \"%s\"\n",buffer+2); } /* 22.7 end */ for (image = 0; image < MAX_IMAGES; image++) { if (*(name = descrs.d.descr[image].name)) { #if __MSDOS__ printf("%s\n", name #else /* !__MSDOS__ */ printf("%s%-" SA(MAX_IMAGE_NAME) "s %s%s%s",verbose > 0 ? " " : "",name, image ? "" : "*", #ifdef LCF_VIRTUAL descrs.d.descr[image].flags & FLAG_VMDEFAULT ? "@" : #endif "", #ifdef LCF_NOKEYBOARD descrs.d.descr[image].flags & FLAG_NOKBDEFAULT ? "&" : #endif "" #endif /* !__MSDOS__ */ ); #if !__MSDOS__ if (verbose >= 2) { if (descrs.d.descr[image].start.device & (LINEAR_FLAG|LBA32_FLAG)) { unsigned int sector; sector = (descrs.d.descr[image].start.device & LBA32_FLAG) && (descrs.d.descr[image].start.device & LBA32_NOCOUNT) ? descrs.d.descr[image].start.num_sect : 0; sector = (sector<<8)+descrs.d.descr[image].start.head; sector = (sector<<8)+descrs.d.descr[image].start.track; sector = (sector<<8)+descrs.d.descr[image].start.sector; printf(" <dev=0x%02x,%s=%d>", descrs.d.descr[image].start.device&DEV_MASK, descrs.d.descr[image].start.device&LBA32_FLAG ? "lba32" : "linear", sector); } else { /* CHS addressing */ printf(" <dev=0x%02x,hd=%d,cyl=%d,sct=%d>", descrs.d.descr[image].start.device, descrs.d.descr[image].start.head, descrs.d.descr[image].start.track, descrs.d.descr[image].start.sector); } } printf("\n"); if (verbose >= 1) { flags = descrs.d.descr[image].flags; #ifdef LCF_VIRTUAL if (flags & FLAG_VMDISABLE) printf(" Virtual Boot is disabled\n"); if (flags & FLAG_VMWARN) printf(" Warn on Virtual boot\n"); #endif #ifdef LCF_NOKEYBOARD if (flags & FLAG_NOKBDISABLE) printf(" NoKeyboard Boot is disabled\n"); #endif if ( !(flags & FLAG_PASSWORD) ) printf(" No password\n"); else printf(" Password is required for %s\n",flags & FLAG_RESTR ? "specifying options" : "booting this image"); printf(" Boot command-line %s be locked\n",flags & FLAG_LOCK ? "WILL" : "won't"); printf(" %single-key activation\n",flags & FLAG_SINGLE ? "S" : "No s"); if (flags & FLAG_KERNEL) { #ifdef NORMAL_VGA if (!(flags & FLAG_VGA)) printf(" VGA mode is taken from boot image\n"); else { printf(" VGA mode: "); switch (descrs.d.descr[image].vga_mode) { case NORMAL_VGA: printf("NORMAL\n"); break; case EXTENDED_VGA: printf("EXTENDED\n"); break; case ASK_VGA: printf("ASK\n"); break; default: printf("%d (0x%04x)\n", descrs.d.descr[image].vga_mode, descrs.d.descr[image].vga_mode); } } #endif if (!(flags & FLAG_LOADHI)) printf(" Kernel is loaded \"low\"\n"); else printf(" Kernel is loaded \"high\"\n"); if (!*(unsigned int *) descrs.d.descr[image].rd_size) printf(" No initial RAM disk\n"); else printf(" Initial RAM disk is %d bytes\n", *(unsigned int *) descrs.d.descr[image].rd_size); if (flags & FLAG_TOOBIG) printf(" and is too big to fit between 4M-15M\n"); } if (!geo_find(&geo,descrs.d.descr[image].start)) { printf(" Map sector not found\n"); continue; } if (read(fd,addr,4*sizeof(SECTOR_ADDR)) != 4*sizeof(SECTOR_ADDR)) die("Read on map file failed (access conflict ?) 2"); if (!geo_find(&geo,addr[0])) printf(" Fallback sector not found\n"); else { if (read(fd,buffer,SECTOR_SIZE) != SECTOR_SIZE) die("Read on map file failed (access conflict ?) 3"); if (*(unsigned short *) buffer != DC_MAGIC) printf(" No fallback\n"); else printf(" Fallback: \"%s\"\n",buffer+2); } #define OTHER 0 #if OTHER if (flags & FLAG_KERNEL) #endif if (!geo_find(&geo,addr[1])) printf(" Options sector not found\n"); else { if (read(fd,buffer,SECTOR_SIZE) != SECTOR_SIZE) die("Read on map file failed (access conflict ?) 4"); if (*buffer) printf(" Options: \"%s\"\n",buffer); else printf(" No options\n"); } #if OTHER else { #else if (!(flags & FLAG_KERNEL)) { #endif if (geo_find(&geo,addr[3])) show_other(fd); else printf(" Image data not found\n"); } } #endif /* !__MSDOS__ */ } /* if */ } /* for */ #undef OTHER (void) close(fd); #if !__MSDOS__ if (descrs.l.checksum == crc32(descrs.sector, sizeof(descrs.l.sector), CRC_POLY1) ) #endif /* !__MSDOS__ */ exit(0); #if !__MSDOS__ fflush(stdout); fprintf(errstd,"Checksum error\n"); exit(1); #endif /* !__MSDOS__ */ }