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

📄 boot.c

📁 LINUX lilo-22.7 源代码。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* boot.c  -  Boot image composition *//*Copyright 1992-1997 Werner Almesberger.Copyright 1999-2004 John Coffman.All rights reserved.Licensed under the terms contained in the file 'COPYING' in the source directory.*/#define BIG_CHAIN 5#define _GNU_SOURCE#include <stdlib.h>#include <stdio.h>#include <unistd.h>#include <string.h>#include <ctype.h>#include <fcntl.h>#include <errno.h>#include <sys/stat.h>#include "config.h"#include "lilo.h"#include "common.h"#include "geometry.h"#include "device.h"#include "cfg.h"#include "map.h"#include "partition.h"#include "boot.h"#include "loader.h"/* the number of sectors between the 15M memory hole and 1M   this is the max. for a bzImage kernel + initrd unless "large-memory"   or "mem=XXX" raises the limit  			*/#define HIGH_SECTORS	((15-1)*1024*1024/SECTOR_SIZE) #define HIGH_4M		(3*1024*1024/SECTOR_SIZE)static GEOMETRY geo;static struct stat st;static void check_size(char *name,int setup_secs,int sectors){    if (sectors > setup_secs+MAX_KERNEL_SECS)	die("Kernel %s is too big",name);}void boot_image(char *spec,IMAGE_DESCR *descr){    BOOT_SECTOR buff;    SETUP_HDR hdr;    char *initrd;    int setup,fd,sectors,hi_sectors=MAX_KERNEL_SECS*4;    int modern_kernel;    if (verbose > 0) {	printf("Boot image: %s",spec);	show_link(spec);	/* in common.c */	printf("\n");    }    fd = geo_open(&geo,spec,O_RDONLY);    if (fstat(fd,&st) < 0) die("fstat %s: %s",spec,strerror(errno));    if (read(fd,(char *) &buff,SECTOR_SIZE) != SECTOR_SIZE)	die("read %s: %s",spec,strerror(errno));    setup = buff.sector[VSS_NUM] ? buff.sector[VSS_NUM] : SETUPSECS;    if (read(fd,(char *) &hdr,sizeof(hdr)) != sizeof(hdr))	die("read %s: %s",spec,strerror(errno));    modern_kernel = !strncmp(hdr.signature,NEW_HDR_SIG,4) && hdr.version >=      NEW_HDR_VERSION;    if (modern_kernel) descr->flags |= FLAG_MODKRN;    if (verbose > 1)	printf("Setup length is %d sector%s.\n",setup,setup == 1 ? "" : "s");    if (setup > MAX_SETUPSECS)	die("Setup length exceeds %d maximum; kernel setup will overwrite boot loader", MAX_SETUPSECS);    map_add(&geo,0,(st.st_size+SECTOR_SIZE-1)/SECTOR_SIZE);    sectors = map_end_section(&descr->start,setup+SPECIAL_SECTORS+SPECIAL_BOOTSECT);    if (!modern_kernel || !(hdr.flags & LFLAG_HIGH))	check_size(spec,setup,sectors);    else {	if (hdr.start % PAGE_SIZE)	    die("Can't load kernel at mis-aligned address 0x%08lx\n",hdr.start);	descr->flags |= FLAG_LOADHI;	/* load kernel high */	hi_sectors = sectors - setup;	/* number of sectors loaded high */	hi_sectors *= 3;		/* account for decompression */	if (hi_sectors < HIGH_4M) hi_sectors = HIGH_4M;    }    geo_close(&geo);    if (verbose > 1)	printf("Mapped %d sector%s.\n",sectors,sectors == 1 ? "" : "s");    if ((initrd = cfg_get_strg(cf_kernel,"initrd")) || (initrd = cfg_get_strg(      cf_options,"initrd"))) {	if (!modern_kernel) die("Kernel doesn't support initial RAM disks");	if (verbose > 0) {	    printf("Mapping RAM disk %s",initrd);	    show_link(initrd);	    printf("\n");	}	fd = geo_open(&geo,initrd,O_RDONLY);	if (fstat(fd,&st) < 0) die("fstat %s: %s",initrd,strerror(errno));#if 1	*(unsigned int *) descr->rd_size = st.st_size;#else	descr->rd_size = (st.st_size + SECTOR_SIZE - 1)/SECTOR_SIZE;#endif	map_begin_section();	map_add(&geo,0,(st.st_size+SECTOR_SIZE-1)/SECTOR_SIZE);	sectors = map_end_section(&descr->initrd,0);	if (verbose > 1)	    printf("RAM disk: %d sector%s.\n",sectors,sectors == 1 ?  "" :	      "s");	if (hi_sectors + sectors > HIGH_SECTORS#ifndef LCF_INITRDLOW	    && !cfg_get_flag(cf_options,"large-memory")#endif	    ) {		descr->flags |= FLAG_TOOBIG;		if (!nowarn)		fprintf(errstd, "Warning: The initial RAM disk is too big to fit between %s and\n"				"   the 15M-16M memory hole."#ifndef LCF_INITRDLOW# if 0							"  If your BIOS supports memory moves above 16M,\n"				"   then you may specify \"large-memory\" in the configuration file\n"				"   (/etc/lilo.conf)."# else							"  It will be loaded in the highest memory as\n"				"   though the configuration file specified \"large-memory\" and it will\n"				"   be assumed that the BIOS supports memory moves above 16M."# endif#endif				"\n", hi_sectors ? "the kernel" : "1M");	}	geo_close(&geo);    }}void boot_device(char *spec,char *range,IMAGE_DESCR *descr){    char *here;    int start,secs;    int sectors;    if (verbose > 0) printf("Boot device: %s, range %s\n",spec,range);    (void) geo_open(&geo,spec,O_NOACCESS);    here = strchr(range,'-');    if (here) {	*here++ = 0;	start = to_number(range);	if ((secs = to_number(here)-start+1) < 0) die("Invalid range");    }    else {	here = strchr(range,'+');	if (here) {	    *here++ = 0;	    start = to_number(range);	    secs = to_number(here);	}	else {	    start = to_number(range);	    secs = 1;	}    }    map_add(&geo,start,secs);    check_size(spec,SETUPSECS,sectors = map_end_section(&descr->start,60));				/* this is a crude hack ... ----------^^*/    geo_close(&geo);    if (verbose > 1)	printf("Mapped %d sector%s.\n",sectors,sectors == 1 ? "" : "s");}void do_map_drive(void){    const char *tmp;    char *end;    int from,to;    tmp = cfg_get_strg(cf_other,"map-drive");    from = strtoul(tmp,&end,0);    if (from > 0xff || *end)	cfg_error("Invalid drive specification \"%s\"",tmp);    cfg_init(cf_map_drive);    (void) cfg_parse(cf_map_drive);    tmp = cfg_get_strg(cf_map_drive,"to");    if (!tmp) cfg_error("TO is required");    to = strtoul(tmp,&end,0);    if (to > 0xff || *end)	cfg_error("Invalid drive specification \"%s\"",tmp);    if (from || to) { /* 0 -> 0 is special */	int i;	for (i = 0; i < curr_drv_map; i++) {	    if (drv_map[i] == ((to << 8) | from))		die("Mapping 0x%02x to 0x%02x already exists",from,to);	    if ((drv_map[i] & 0xff) == from)		die("Ambiguous mapping 0x%02x to 0x%02x or 0x%02x",from,		  drv_map[i] >> 8,to);	}	if (curr_drv_map == DRVMAP_SIZE)	    cfg_error("Too many drive mappings (more than %d)",DRVMAP_SIZE);	if (verbose > 1)	    printf("  Mapping BIOS drive 0x%02x to 0x%02x\n",from,to);	drv_map[curr_drv_map++] = (to << 8) | from;    }    cfg_unset(cf_other,"map-drive");}/*  *  Derive the name of the MBR from the partition name *  e.g. *   /dev/scsi/host2/bus0/target1/lun0/part2	=> disc *   /dev/sd/c0b0t0u0p7				=> c0b0t0u0 *   /dev/sda11					=> sda * * If table==0, do no check for primary partition; if table==1, check * that we started from a primary (1-4) partition. * * A NULL return indicates an error * */ char *boot_mbr(const char *boot, int table){#if 0    char *part, *npart, *endptr;    int i, j, k;        npart = stralloc(boot);    part = strrchr(npart, '/');    if (!part++) die ("No '/' in partition/device name.");        i = strlen(part);    endptr = part + i - 1;       /* j is the count of digits at the end of the name */     j = 0;    while (isdigit(*endptr)) { j++; --endptr; }    if (j==0 && !table) die ("Not a partition name; no digits at the end.");        k = !table || (j==1 && endptr[1]>='1' && endptr[1]<='4');       /* test for devfs  partNN */    if (strncmp(part, "part", 4)==0) {    	strcpy(part, "disc");    }    /* test for ..NpNN */    else if (*endptr=='p' && isdigit(endptr[-1])) {        *endptr = 0;  /* truncate the pNN part */    }   /* test for old /dev/hda3 or /dev/sda11 */    else if (endptr[-1]=='d' && endptr[-3]=='/' &&    		(endptr[-2]=='h' || endptr[-2]=='s')#if 0		&& strstr(npart, "/dev/")#endif	    ) {        endptr[1] = 0;  /* truncate the NN part */    }    else 	k = 0;#else    struct stat st;    dev_t dev;    DEVICE d;    int mask, k;    char *npart = NULL;        k = 0;    if (stat(boot,&st) < 0) die("stat %s: %s",boot,strerror(errno));

⌨️ 快捷键说明

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