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

📄 bsect.c

📁 linux 的引导程序源码The Microsoft&reg Windows&reg Software Development Kit (SDK) provides the documentation
💻 C
📖 第 1 页 / 共 3 页
字号:
          text, hilighted text, border, title    */#define color(c) ((int)strchr(khar,(int)(c))-(int)khar)    bg = 0;    at = &(menu->at_text);    for (i=0; i<4 && *scheme; i++) {    	fg = color(*scheme);    	if (fg>=16) die("Invalid menu-scheme color: '%c'", *scheme);    	if (*++scheme) bg = color(*scheme);    	else {	    die("Invalid menu-scheme syntax");    	}    	if (bg>=16) die("Invalid menu-scheme color: '%c'", *scheme);    	if (*++scheme) {    	    if (ispunct(*scheme)) scheme++;    	    else die("Invalid menu-scheme punctuation");    	}    	if (bg>=8 && !nowarn)    	    fprintf(errstd, "Warning: menu-scheme BG color may not be intensified\n");    	*at++ = ((bg<<4) | fg) & 0x7F;    }    /* check on the TEXT color */    if (menu->at_text == 0) {        if (!nowarn)            fprintf(errstd, "Warning: menu-scheme \"black on black\" changed to "        	"\"white on black\"\n");        menu->at_text = 0x07;    }    /* check on the HIGHLIGHT color */    if (menu->at_highlight == 0)  menu->at_highlight = ((menu->at_text<<4)&0x70) | ((menu->at_text>>4)&0x0f);    /* check on the BORDER color */    if (menu->at_border == 0)  menu->at_border = menu->at_text;    /* check on the TITLE color */    if (menu->at_title == 0)  menu->at_title = menu->at_border;        strncpy(menu->menu_sig, "MENU", 4);    if (verbose>=5)       printf("Menu attributes: text %02X  highlight %02X  border %02X  title %02X\n",       		(int)menu->at_text, (int)menu->at_highlight,       		(int)menu->at_border, (int)menu->at_title);#undef color}void bsect_open(char *boot_dev,char *map_file,char *install,int delay,  int timeout, long raid_offset){    static char coms[] = "0123";    static char parity[] = "NnOoEe";    static char bps[] =         "110\000150\000300\000600\0001200\0002400\0004800\0009600\000"        "19200\00038400\00057600\000115200\000?\000?\000?\000?\000"        "56000\000";    GEOMETRY geo;    struct stat st;    int i, speed, bitmap, j;    int m_fd=0,kt_fd,sectors;    char *message,*colon,*serial,*walk,*this,*keytable,*scheme;    MENUTABLE *menu;    BITMAPFILEHEADER fhv;    BITMAPHEADER bmhv;    BITMAPLILOHEADER lhv;    unsigned long timestamp;#ifdef LCF_BUILTIN    BUILTIN_FILE *loader;#else    int i_fd;#endif#if 0printf("sizeof(IMAGE_DESCR) = %d\n", sizeof(IMAGE_DESCR));printf("sizeof(DESCR_SECTORS) = %d\n", sizeof(DESCR_SECTORS));printf("MAX_IMAGES = %d\n", MAX_IMAGES);#endif    image = image_base = i = 0;    if (stat(map_file,&st) >= 0 && !S_ISREG(st.st_mode))	die("Map %s is not a regular file.",map_file);    open_bsect(boot_dev);    part_verify(boot_dev_nr,1);    ireloc = part_nowrite(boot_dev);    if (ireloc>1) {    	die("Filesystem would be destroyed by LILO boot sector: %s", boot_dev);    }    else if (ireloc==1) {	if (!nowarn) printf("Warning: boot record relocation is necessary: %s\n", boot_dev);    }#ifdef EARLY_MAP    if ((colon = strrchr(map_name = map_file,':')) == NULL)	strcat(strcpy(temp_map,map_name),MAP_TMP_APP);    else {	*colon = 0;	strcat(strcat(strcpy(temp_map,map_name),MAP_TMP_APP),colon+1);	*colon = ':';    }    map_create(temp_map);    temp_register(temp_map);#endif    if (!install) {#if !defined(LCF_NOINSTDEF) || defined(LCF_BUILTIN)	install = DFL_BOOT;#else	die("No boot loader specified ('-i' or 'install =')");#endif    } /*  if (install) */ {	timestamp = bsect.par_1.timestamp; /* preserve timestamp */#ifndef LCF_BUILTIN	if (verbose > 0) {	    printf("Merging with %s",install);	    show_link(install);	    printf("\n");	}	i_fd = geo_open(&geo,install,O_RDONLY);	if (read(i_fd, table, MAX_BOOT_SIZE) != MAX_BOOT_SIZE)	    die("read %s: %s",boot_dev ? boot_dev : dev.name,strerror(errno));	check_version ((BOOT_SECTOR*)table, STAGE_FIRST);	memcpy((char*)&bsect, table, MAX_BOOT_SIZE);	if (fstat(i_fd,&st) < 0)	    die("stat %s: %s",boot_dev ? boot_dev : dev.name,strerror(errno));#else/* determine which secondary loader to use */	loader = select_loader();	if (verbose > 0) {	    printf("Using %s secondary loader\n",		loader==&Bitmap ? "BITMAP" :		loader==&Third  ? "MENU" :		"TEXT" );	}	memcpy(&bsect, First.data, MAX_BOOT_SIZE);#endif	bsect.par_1.timestamp = timestamp;	map_begin_section(); /* no access to the (not yet open) map file		required, because this map is built in memory */#if defined(LCF_UNIFY) || defined(LCF_BUILTIN)#ifndef LCF_BUILTIN	(void)map_insert_file (&geo,1,(st.st_size+SECTOR_SIZE-1)/SECTOR_SIZE-1);#else	(void)map_insert_data (loader->data, loader->size);#endif#else	map_add (&geo,1,(st.st_size+SECTOR_SIZE-1)/SECTOR_SIZE-1);#endif	sectors = map_write((SECTOR_ADDR*)secondary_map, (SECTOR_SIZE-4)/sizeof(SECTOR_ADDR)-2, 1);	memcpy(secondary_map+SECTOR_SIZE-4, "LILO", 4);	/* fill in full size of secondary boot loader in paragraphs */	bsect.par_1.dataend = (sectors + 5 + MAX_DESCR_SECS) * (SECTOR_SIZE/16);	if (verbose > 1)	    printf("Secondary loader: %d sector%s (0x%0X dataend).\n",sectors,sectors == 1 ?	      "" : "s", bsect.par_1.dataend*16);#ifndef LCF_BUILTIN	if (lseek(i_fd, SECTOR_SIZE, SEEK_SET)!=SECTOR_SIZE)	    die("lseek %s: %s",boot_dev ? boot_dev : dev.name,strerror(errno));	if (read(i_fd,table,SECTOR_SIZE) != SECTOR_SIZE)	    die("read(2) %s: %s",boot_dev ? boot_dev : dev.name,strerror(errno));	stage_flags = ((BOOT_SECTOR*)table) -> par_2.stage;	geo_close(&geo);#else	stage_flags = ((BOOT_SECTOR*)(loader->data)) -> par_2.stage;#endif	if ((stage_flags & 0xFF) != STAGE_SECOND)	    die("Ill-formed boot loader; no second stage section");	if (verbose>=4) printf("install(2) flags: 0x%04X\n", (int)stage_flags);    }#ifndef EARLY_MAP    if ((colon = strrchr(map_name = map_file,':')) == NULL)	strcat(strcpy(temp_map,map_name),MAP_TMP_APP);    else {	*colon = 0;	strcat(strcat(strcpy(temp_map,map_name),MAP_TMP_APP),colon+1);	*colon = ':';    }    map_create(temp_map);    temp_register(temp_map);#endif#if 1	map_begin_section();	map_add_sector(secondary_map);	(void) map_write(&bsect.par_1.secondary,1,0);#endif        *(unsigned short *) &bsect.sector[BOOT_SIG_OFFSET] = BOOT_SIGNATURE;    message = cfg_get_strg(cf_options,"message");    scheme = cfg_get_strg(cf_options,"bitmap");    if (message && scheme) die("'bitmap' and 'message' are mutually exclusive");    bsect.par_1.msg_len = 0;#ifdef LCF_BUILTIN    bitmap = (loader==&Bitmap);#else    bitmap = scheme ? 1 : 0;#endif    if (bitmap) {	message = scheme;	if (!(stage_flags & STAGE_FLAG_BMP4)) {#ifndef LCF_BUILTIN	    die("Boot loader does not support 'bitmap='");#else	    if (!nowarn) fprintf(errstd,"Warning: Non-bitmap capable boot loader; 'bitmap=' ignored.\n");	    message = NULL;#endif	}    }    j = -1;    if (message) {	if (verbose >= 1) {	    printf("Mapping %s file %s", 			bitmap ? "bitmap" : "message", message);	    show_link(message);	    printf("\n");	}	m_fd = geo_open(&geo,message,O_RDONLY);	if (fstat(m_fd,&st) < 0) die("stat %s: %s",message,strerror(errno));	/* the -2 below is because of GCC's alignment requirements */	i = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPHEADER)+sizeof(RGB)*16+				sizeof(BITMAPLILOHEADER);	if (bitmap || st.st_size>i) {	    j = get_std_headers(m_fd, &fhv, &bmhv, &lhv);	    if (j<0) die("read %s: %s", message, strerror(errno));	    if (j==0 || j>2) { /* definitely a bitmap file */		BITMAPHEADER *bmh = &bmhv;	        if (verbose >= 3) {	            printf("width=%d height=%d planes=%d bits/plane=%d\n",	        	(int)bmh->width, (int)bmh->height,	        	(int)bmh->numBitPlanes, (int)bmh->numBitsPerPlane);	        }	        if (bmh->size == sizeof(BITMAPHEADER) &&	        	bmh->width==640 && bmh->height==480 && 	            	bmh->numBitPlanes * bmh->numBitsPerPlane == 4) {	            if (!bitmap) die("Message specifies a bitmap file");	        }		else if (bitmap) die("Unsupported bitmap");	    } else if (bitmap) die("Not a bitmap file");	}	i = bitmap ? MAX_KERNEL_SECS*SECTOR_SIZE : MAX_MESSAGE;	if (st.st_size > i)	    die("%s is too big (> %d bytes)",message,i);	bsect.par_1.msg_len = bitmap ? (st.st_size+15)/16 : st.st_size;	map_begin_section();#ifndef LCF_UNIFY	map_add(&geo,0,((st.st_size)+SECTOR_SIZE-1)/SECTOR_SIZE);#else	map_insert_file (&geo,0,(st.st_size+SECTOR_SIZE-1)/SECTOR_SIZE);#endif	sectors = map_end_section(&bsect.par_1.msg,0);	if (verbose >= 2)	    printf("%s: %d sector%s.\n",bitmap?"Bitmap":"Message",	    		sectors,sectors == 1 ?  "" : "s");	geo_close(&geo);    }    serial = cfg_get_strg(cf_options,"serial");    if (serial) {    	if (!(stage_flags & STAGE_FLAG_SERIAL))    	    die("Serial line not supported by boot loader");	if (!*serial || !(this = strchr(coms,*serial)))	    die("Invalid serial port in \"%s\" (should be 0-3)",serial);	else bsect.par_1.port = (this-coms)+1;	bsect.par_1.ser_param = SER_DFL_PRM;	if (serial[1]) {	    if (serial[1] != ',')		die("Serial syntax is <port>[,<bps>[<parity>[<bits>]]]");	    walk = bps;	    speed = 0;	    while (*walk && strncmp(serial+2,walk,(i=strlen(walk)))) {	        speed++;	        walk += i+1;	    }	    if (!*walk) die("Unsupported baud rate");	    bsect.par_1.ser_param &= ~0xE4;	    if (speed==16) speed -= 6;  /* convert 56000 to 57600 */	    bsect.par_1.ser_param |= ((speed<<5) | (speed>>1)) & 0xE4;	    serial += i+2;	/* check for parity specified */	    if (*serial) {		if (!(this = strchr(parity,*serial)))		    die("Valid parity values are N, O and E");		i = (int)(this-parity)>>1;		if (i==2) i++; /* N=00, O=01, E=11 */		bsect.par_1.ser_param &= ~(i&1); /* 7 bits if parity specified */		bsect.par_1.ser_param |= i<<3;   /* specify parity */	/* check if number of bits is there */		if (serial[1]) {		    if (serial[1] != '7' && serial[1] != '8')			die("Only 7 or 8 bits supported");		    if (serial[1]=='7')	bsect.par_1.ser_param &= 0xFE;		    else bsect.par_1.ser_param |= 0x01;		    		    if (serial[2]) die("Synax error in SERIAL");		}	    }	    if (verbose>=4) printf("Serial Param = 0x%02X\n", 	                                        (int)bsect.par_1.ser_param);	}	if (delay < 20 && !cfg_get_flag(cf_options,"prompt")) {	    fprintf(errstd,"Setting DELAY to 20 (2 seconds)\n");	    delay = 20;	}    }    bsect.par_1.prompt = cfg_get_flag(cf_options,"prompt") ? FLAG_PROMPT : 0;    if (cfg_get_flag(cf_options,"suppress-boot-time-BIOS-data")) {    	fprintf(errstd,"CAUTION:  boot-time BIOS data will not be saved\n");    	bsect.par_1.prompt |= FLAG_NOBD;    }    if (cfg_get_flag(cf_options,"large-memory")) {#ifndef LCF_INITRDLOW	bsect.par_1.prompt |= FLAG_LARGEMEM;#else	if (!nowarn) fprintf(errstd, "Warning: This LILO compiled with INITRDLOW option, 'large-memory' ignored\n");#endif    }    bsect.par_1.prompt |= raid_flags;    bsect.par_1.raid_offset = raid_offset;  /* to be modified in bsect_raid_update *//* convert timeout in tenths of a second to clock ticks    *//* tick interval is 54.925 ms  *//*   54.925 * 40 -> 2197       *//*  100 * 40 -> 4000	       */#if 0#define	tick(x) ((x)*100/55)#else#define tick(x) ((x)*4000/2197)#endif    if (tick(delay) > 0xffff) die("Maximum delay is 59:59 (3599.5secs).");	else bsect.par_1.delay = tick(delay);    if (timeout == -1) bsect.par_1.timeout = 0xffff;    else if (tick(timeout) >= 0xffff) die("Maximum timeout is 59:59 (3599.5secs).");	else bsect.par_1.timeout = tick(timeout);/* keytable & parameter area setup */    if (!(keytable = cfg_get_strg(cf_options,"keytable"))) {	for (i = 0; i < 256; i++) table[i] = i;    }    else {	if ((kt_fd = open(keytable,O_RDONLY)) < 0)	    die("open %s: %s",keytable,strerror(errno));	if (read(kt_fd,table,256) != 256)	    die("%s: bad keyboard translation table",keytable);	(void) close(kt_fd);    }    menu = (MENUTABLE*)&table[256];    memset(menu, 0, 256);    memcpy(&(menu->row), &(lhv.row), sizeof(lhv) - sizeof(lhv.size) - sizeof(lhv.magic));    if ((scheme = cfg_get_strg(cf_options,"menu-scheme"))) {	if (!(stage_flags & STAGE_FLAG_MENU) && !nowarn)	    fprintf(errstd,"Warning: 'menu-scheme' not supported by boot loader\n");    	menu_do_scheme(scheme, menu);    }    if ((scheme = cfg_get_strg(cf_options,"menu-title"))) {	if (!(stage_flags & STAGE_FLAG_MENU) && !nowarn)	    fprintf(errstd,"Warning: 'menu-title' not supported by boot loader\n");	if (strlen(scheme) > MAX_MENU_TITLE && !nowarn)	    fprintf(errstd,"Warning: menu-title is > %d characters\n", MAX_MENU_TITLE);    	strncpy(menu->title, scheme, MAX_MENU_TITLE);    	menu->len_title = strlen(menu->title);    }    if ((scheme = cfg_get_strg(cf_options,"bmp-table"))) {	if (!(stage_flags & STAGE_FLAG_BMP4) && !nowarn)	    fprintf(errstd,"Warning: 'bmp-table' not supported by boot loader\n");    }    bmp_do_table(scheme, menu);    if (bitmap) {	image_menu_space = menu->ncol * menu->maxcol;	if (verbose>=3) printf("image_menu_space = %d\n", image_menu_space);    }    if ((scheme = cfg_get_strg(cf_options,"bmp-colors"))) {	if (!(stage_flags & STAGE_FLAG_BMP4) && !nowarn)	    fprintf(errstd,"Warning: 'bmp-colors' not supported by boot loader\n");    }    bmp_do_colors(scheme, menu);    if ((scheme = cfg_get_strg(cf_options,"bmp-timer"))) {	if (!(stage_flags & STAGE_FLAG_BMP4) && !nowarn)	    fprintf(errstd,"Warning: 'bmp-timer' not supported by boot loader\n");    }    bmp_do_timer(scheme, menu);#if 0    map_begin_section();    map_add_sector(table);    (void) map_write(&bsect.par_1.keytab,1,0);#endif    memset(&descrs,0,SECTOR_SIZE*MAX_DESCR_SECS);    if (cfg_get_strg(cf_options,"default")) image = image_base = 1;    if (verbose > 0) printf("\n");}static int dev_number(char *dev){    struct stat st;    if (stat(dev,&st) >= 0) return st.st_rdev;    return to_number(dev);}static int get_image(char *name,char *label,IMAGE_DESCR *descr){    char *here,*deflt;    int this_image,other;    unsigned char *uch;    if (!label) {        here = strrchr(label = name,'/');        if (here) label = here+1;    }    if (strchr(label,' ')) die("Image name, label, or alias contains a blank character: '%s'", label);    if (strlen(label) > MAX_IMAGE_NAME) die("Image name, label, or alias is too long: '%s'",label);    for (uch=label; *uch; uch++) {	if (*uch<' ')  die("Image name, label, or alias contains an illegal character: '%s'", label);    }    for (other = image_base; other <= image; other++) {#ifdef LCF_IGNORECASE	if (!strcasecmp(label,descrs.d.descr[other].name))#else	if (!strcmp(label,descrs.d.descr[other].name))#endif	    die("Duplicate label \"%s\"",label);	if ((((descr->flags & FLAG_SINGLE) && strlen(label) == 1) ||          (((descrs.d.descr[other].flags) & FLAG_SINGLE) &&	  strlen(descrs.d.descr[other].name) == 1)) &&#ifdef LCF_IGNORECASE	  toupper(*label) == toupper(*descrs.d.descr[other].name))#else	  *label == *descrs.d.descr[other].name)#endif	    die("Single-key clash: \"%s\" vs. \"%s\"",label,	      descrs.d.descr[other].name);    }    if (image_base && (deflt = cfg_get_strg(cf_options,"default")) &&#ifdef LCF_IGNORECASE      !strcasecmp(deflt,label))#else      !strcmp(deflt,label))#endif	this_image = image_base = 0;    else {	if (image == MAX_IMAGES)	    die("Only %d image names can be defined",MAX_IMAGES);	if (image >= image_menu_space)	    die("Bitmap table has space for only %d images",	    			image_menu_space);	this_image = image++;    }    descrs.d.descr[this_image] = *descr;    strcpy(descrs.d.descr[this_image].name,label);#ifdef LCF_VIRTUAL    if ( (deflt = cfg_get_strg(cf_options,"vmdefault")) &&#ifdef LCF_IGNORECASE		!strcasecmp(deflt,label))#else		!strcmp(deflt,label))#endif	descrs.d.descr[this_image].flags |= FLAG_VMDEFAULT;#endif    return this_image;}static char options[SECTOR_SIZE]; /* this is ugly */static void bsect_common(IMAGE_DESCR *descr, int image){    struct stat st;    char *here,*root,*ram_disk,*vga,*password;    char *literal,*append,*fback;    char fallback_buf[SECTOR_SIZE];    memset(descr, 0, sizeof(IMAGE_DESCR));	/* allocated on stack by caller */    memset(fallback_buf,0,SECTOR_SIZE);    memset(options,0,SECTOR_SIZE);    if (image) { /* long section specific to 'image=' */    if ((cfg_get_flag(cf_kernel,"read-only") && cfg_get_flag(cf_kernel,

⌨️ 快捷键说明

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