📄 lilo.c
字号:
/* lilo.c - LILO command-line parameter processing *//*Copyright 1992-1998 Werner Almesberger.Copyright 1999-2005 John Coffman.All rights reserved.Licensed under the terms contained in the file 'COPYING' in the source directory.*/#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 <time.h>#include <limits.h>#include <sys/stat.h>#include <dirent.h>/*#include <asm/page.h>*/#include "config.h"#include "lilo.h"#include "common.h"#include "cfg.h"#if !__MSDOS__#include "raid.h"#include "boot.h"#include "device.h"#include "flags.i"#include "geometry.h"#endif /* !__MSDOS__ */#include "map.h"#if !__MSDOS__#include "bsect.h"#include "identify.h"#include "partition.h"#include "probe.h"#include "temp.h"#include "loader.h"#include "md-int.h"#include "edit.h"#endif /* !__MSDOS__ */char *config_file; /* actual name of the config file */int config_read; /* readable by other than root */FILE *errstd;#if !__MSDOS__static void show_other(int fd){ BOOT_SECTOR buf[SETUPSECS-1]; const unsigned char *drvmap; const unsigned char *prtmap; if (read(fd,buf,sizeof(buf)) != sizeof(buf)) die("Read on map file failed (access conflict ?) 1"); if (!strncmp(buf[0].par_c.signature-4,"LILO",4)) { printf(" Pre-21 signature (0x%02x,0x%02x,0x%02x,0x%02x)\n", buf[0].par_c.signature[0],buf[0].par_c.signature[1], buf[0].par_c.signature[2],buf[0].par_c.signature[3]); return; } if (strncmp(buf[0].par_c.signature,"LILO",4)) { printf(" Bad signature (0x%02x,0x%02x,0x%02x,0x%02x)\n", buf[0].par_c.signature[0],buf[0].par_c.signature[1], buf[0].par_c.signature[2],buf[0].par_c.signature[3]); return; } drvmap = ((unsigned char *) buf+buf[0].par_c.drvmap); prtmap = drvmap+2*(DRVMAP_SIZE+1); while (drvmap[0] && drvmap[1]) { if (drvmap[0]==0xFF && drvmap[1]==0xFF) { if (drvmap[3]==0xFF) printf(" Master-Boot: This BIOS drive will always appear as 0x80 (or 0x00)\n"); else printf(" Boot-As: This BIOS drive will always appear as 0x%02X\n", drvmap[3]); drvmap += 4; } else { printf(" BIOS drive 0x%02X is mapped to 0x%02X\n",drvmap[0], drvmap[1]); drvmap += 2; } } /* fix VERY old bug -- offset of 0 in PT is okay */ while (prtmap[0] /*** && prtmap[1] ***/ ) { printf(" BIOS drive 0x%02x, offset 0x%x: 0x%02x -> 0x%02x\n", prtmap[0],prtmap[1]+PART_TABLE_OFFSET,prtmap[2],prtmap[3]); prtmap += 4; }}#endif /* !__MSDOS__ */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;#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 printf("Installed: %s\n", ctime((time_t*)&boot.par_1.map_stamp)); 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"); 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__ */ fprintf(stdout,"%s%-" S(MAX_IMAGE_NAME) "s %s%s",verbose > 0 ? " " : "",name, image ? "" : "*",#ifdef LCF_VIRTUAL descrs.d.descr[image].flags & FLAG_VMDEFAULT ? "@" :#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 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__ */}static void usage(char *name){ char *here;#if !__MSDOS__ here = strrchr(name,'/');#else /* __MSDOS__ */ here = strrchr(name,'\\');#endif /* __MSDOS__ */ if (here) name = here+1; fprintf(errstd,"usage: %s [ -C config_file ] -q [ -m map_file ] " "[ -v N | -v ... ]\n",name);#if !__MSDOS__ fprintf(errstd,"%7s%s [ -C config_file ] [ -b boot_device ] [ -c ] " "[ -g | -l | -L ]\n","",name); fprintf(errstd,"%12s[ -F ] [ -i boot_loader ] [ -m map_file ] [ -d delay ]\n",""); fprintf(errstd,"%12s[ -v N | -v ... ] [ -t ] [ -s save_file | -S save_file ]\n", ""); fprintf(errstd,"%12s[ -p ][ -P fix | -P ignore ] [ -r root_dir ] [ -w | -w+ ]\n","");#endif /* !__MSDOS__ */ fprintf(errstd,"%7s%s [ -C config_file ] [ -m map_file ] " "-R [ word ... ]\n","",name);#if !__MSDOS__ fprintf(errstd,"%7s%s [ -C config_file ] -I name [ options ]\n","",name); fprintf(errstd,"%7s%s [ -C config_file ] [ -s save_file ] " "-u | -U [ boot_device ]\n","",name); fprintf(errstd,"%7s%s -A /dev/XXX [ N ]\t\tinquire/activate a partition\n","",name); fprintf(errstd,"%7s%s -M /dev/XXX [ mbr | ext ]\tinstall master boot record\n","",name); fprintf(errstd,"%7s%s -T help \t\t\tlist additional options\n", "", name); fprintf(errstd,"%7s%s -X\t\t\t\tinternal compile-time options\n", "", name);#endif /* !__MSDOS__ */ fprintf(errstd,"%7s%s -V [ -v ]\t\t\tversion information\n\n","",name); exit(1);}int main(int argc,char **argv){ char *name,*reboot_arg,*ident_opt,*new_root; char *tell_param, *uninst_dev, *param, *act1, *act2, ch;static char *bitmap_file; int more,version,uninstall,validate,activate,instmbr,geom; int fd, temp=0, tell_early=0; int raid_offset;#if !__MSDOS__ struct stat st;#endif /* !__MSDOS__ */ errstd = stderr;#if VERSION_MINOR>=50 if (sizeof(MENUTABLE)!=256) die("MENUTABLE is not 256 bytes (common.h)");#if !__MSDOS__ cfg_alpha_check();#endif /* !__MSDOS__ */#endif config_file = DFL_CONFIG; act1 = act2 = tell_param = reboot_arg = identify = ident_opt = new_root = uninst_dev = NULL; do_md_install = zflag = version = uninstall = validate = activate = instmbr = 0; verbose = -1;#if !__MSDOS__ name = *argv;#else /* __MSDOS__ */ name = "lilo";#endif /* __MSDOS__ */ argc--;#if !__MSDOS__ if (atexit( (void(*)(void)) sync)) die("atexit(sync)"); if (atexit( (void(*)(void)) purge)) die("atexit(purge)");#endif /* !__MSDOS__ */ cfg_init(cf_options); while (argc && **++argv == '-') { argc--; /* first those options with a mandatory parameter */ /* Notably absent are "RuUvw" */ if (strchr("AbBCdDEfiImMPrsSTxZ", ch=(*argv)[1])) { if ((*argv)[2]) param = (*argv)+2; else { param = *++argv; if(argc-- <= 0) usage(name); } } else { param = NULL; if (strchr("cFglLpqtVXz", ch) /* those with no args */ && (*argv)[2]) usage(name); }#if 0fprintf(errstd,"argc=%d, *argv=%s, ch=%c param=%s\n", argc, *argv, ch, param);#endif switch (ch) {#if !__MSDOS__ case 'A': activate = 1; act1 = param; if (argc && argv[1][0] != '-') { act2 = *++argv; argc--; } break; case 'b': cfg_set(cf_options,"boot",param,NULL); break; case 'B': cfg_set(cf_options,"bitmap",param,NULL); break; case 'c': cfg_set(cf_options,"compact",NULL,NULL); compact = 1; break;#endif /* !__MSDOS */ case 'C': config_file = param; break;#if !__MSDOS__ case 'd': cfg_set(cf_options,"delay",param,NULL); break; case 'D': cfg_set(cf_options,"default",param,NULL); break; case 'E': eflag=1; bitmap_file = param; break; case 'f': cfg_set(cf_options,"disktab",param,NULL); break; case 'F': force_fs=1; break; case 'g': geometric |= AD_GEOMETRIC;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -