📄 bsect.c
字号:
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 + -