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

📄 boot.c

📁 boot启动监视代码 boot启动监视代码
💻 C
📖 第 1 页 / 共 3 页
字号:
				bootdev.primary= p;			else				bootdev.secondary= p;			break;		}		/* This happens when lightning strikes while booting: */		if (p == NR_PARTITIONS || bootdev.primary >= 0) {			printf("Can't find the partition starting at %lu???\n",				lowsec);			reboot();		}		/* See if the primary partition is subpartitioned. */		bootdev.primary= p;		masterpos= table[p]->lowsec;	}}char null[]= "";void sfree(s) char *s;/* Free a non-null string. */{	if (s != nil && s != null) free((void *) s);}char *copystr(s) char *s;/* Copy a non-null string using malloc. */{	char *c;	if (*s == 0) return null;	c= (char *) malloc((strlen(s) + 1) * sizeof(char));	strcpy(c, s);	return c;}int is_default(e) environment *e;{	return (e->flags & E_SPECIAL) && e->defval == nil;}environment **searchenv(name) char *name;{	environment **aenv= &env;	while (*aenv != nil && strcmp((*aenv)->name, name) != 0)		aenv= &(*aenv)->next;	return aenv;}#define b_getenv(name)	(*searchenv(name))/* Return the environment *structure* belonging to name, or nil if not found. */char *b_value(name) char *name;/* The value of a variable. */{	environment *e= b_getenv(name);	return e == nil || !(e->flags & E_VAR) ? nil : e->value;}char *b_body(name) char *name;/* The value of a function. */{	environment *e= b_getenv(name);	return e == nil || !(e->flags & E_FUNCTION) ? nil : e->value;}//  b_setenv(E_RESERVED|E_FUNCTION, "\1", "=,Start Minix", "boot");int b_setenv(flags, name, arg, value) int flags; char *name, *arg, *value;/* Change the value of an environment variable.  Returns the flags of the * variable if you are not allowed to change it, 0 otherwise. */{	environment **aenv, *e;	if (*(aenv= searchenv(name)) == nil) {		e= (environment *) malloc(sizeof(*e));		e->name= copystr(name);		e->flags= flags;		e->defval= nil;		e->next= nil;		*aenv= e;	} else {		e= *aenv;		/* Don't touch reserved names and don't change special		 * variables to functions or vv.		 */		if (e->flags & E_RESERVED || (e->flags & E_SPECIAL			&& (e->flags & E_FUNCTION) != (flags & E_FUNCTION)		)) return e->flags;		e->flags= (e->flags & E_STICKY) | flags;		if (is_default(e))			e->defval= e->value;		else			sfree(e->value);		sfree(e->arg);	}	e->arg= copystr(arg);	e->value= copystr(value);	return 0;}int b_setvar(flags, name, value) int flags; char *name, *value;/* Set variable or simple function. */{	return b_setenv(flags, name, null, value);}void b_unset(name) char *name;/* Remove a variable from the environment.  A special variable is reset to * its default value. */{	environment **aenv, *e;	if ((e= *(aenv= searchenv(name))) == nil) return;	if (e->flags & E_SPECIAL) {		if (e->defval != nil) {			sfree(e->arg);			e->arg= null;			sfree(e->value);			e->value= e->defval;			e->defval= nil;		}	} else {		sfree(e->name);		sfree(e->arg);		sfree(e->value);		*aenv= e->next;		free((void *) e);	}}#define between(a, c, z)	((unsigned) ((c) - (a)) <= ((z) - (a)))long a2l(a) char *a;/* Cheap atol(). */{	int sign= 1;	long l= 0;	if (*a == '-') { sign= -1; a++; }	while (between('0', *a, '9')) l= l * 10 + (*a++ - '0');	return sign * l;}char *ul2a(n) u32_t n;/* Transform a long number to ascii digits. */{	static char num[3 * sizeof(n)];	char *pn= arraylimit(num) - 1;	do *--pn = (n % 10) + '0'; while ((n/= 10) > 0);	return pn;}char *u2a(n) u16_t n;/* Transform a short number to ascii digits. */{	return ul2a((u32_t) n);}void get_parameters(){	char params[SECTOR_SIZE + 1];	token **acmds;	int vid, r, fundef= 0;	static char *vid_type[] = { "mda", "cga", "ega", "ega", "vga", "vga" };	/* Variables that Minix needs: */	b_setvar(E_SPECIAL|E_VAR|E_DEV, "rootdev", "ram");	b_setvar(E_SPECIAL|E_VAR|E_DEV, "ramimagedev", "bootdev");	b_setvar(E_SPECIAL|E_VAR, "ramsize", "0");	b_setvar(E_SPECIAL|E_VAR, "keyboard", "standard");	b_setvar(E_SPECIAL|E_VAR, "processor", u2a(get_processor()));	b_setvar(E_SPECIAL|E_VAR, "memsize", u2a(get_low_memsize()));	b_setvar(E_SPECIAL|E_VAR, "emssize", u2a(get_ext_memsize()));	vid= get_video();	b_setvar(E_SPECIAL|E_VAR, "chrome", (vid & 1) ? "color" : "mono");	b_setvar(E_SPECIAL|E_VAR, "video", vid_type[vid]);	/* Variables boot needs: */	b_setvar(E_SPECIAL|E_VAR, "image", "minix");	b_setvar(E_SPECIAL|E_FUNCTION, "main", "menu");	/* Default menu functions: */	b_setenv(E_RESERVED|E_FUNCTION, "\1", "=,Start Minix", "boot");	/* Reserved names: */	b_setvar(E_RESERVED, "scancode", null);	b_setvar(E_RESERVED, "boot", null);	b_setvar(E_RESERVED, "menu", null);	b_setvar(E_RESERVED, "set", null);	b_setvar(E_RESERVED, "unset", null);	b_setvar(E_RESERVED, "save", null);	b_setvar(E_RESERVED, "ls", null);	b_setvar(E_RESERVED, "echo", null);	b_setvar(E_RESERVED, "trap", null);	/* Tokenize bootparams sector. */	if ((r= readsectors((u16_t) params, dseg, lowsec+PARAMSEC, 1)) != 0)		readerr(lowsec+PARAMSEC, r);	else {		params[SECTOR_SIZE]= 0;		acmds= tokenize(&cmds, params, &fundef);		/* Reboot code may have new parameters. */		if (device >= 0x80 && boot_part.sysind == NO_PART) {			raw_copy((u16_t) params, dseg,				(u16_t) (boot_part.size & 0x0F),				(u16_t) (boot_part.size >> 4), SECTOR_SIZE);			acmds= tokenize(&cmds, params, &fundef);		}		/* Stuff the default action into the command chain. */		(void) tokenize(acmds, ":;main", &fundef);	}}void addparm(ap, n) char **ap, *n;{	char *p= *ap;	while (*n != 0 && *p != 0) *p++ = *n++;	*ap= p;}void save_parameters()/* Save nondefault environment variables to the bootparams sector. */{	environment *e;	char params[SECTOR_SIZE + 1];	char *p= params;	int r;	/* Default filling: */	memset((void *) params, '\n', (size_t) SECTOR_SIZE);	/* Don't touch the 0! */	params[SECTOR_SIZE]= 0;	for (e= env; e != nil; e= e->next) {		if (e->flags & E_RESERVED || is_default(e)) continue;		addparm(&p, e->name);		if (e->flags & E_FUNCTION) {			addparm(&p, "(");			addparm(&p, e->arg);			addparm(&p, "){");		} else {			addparm(&p, (e->flags & (E_DEV|E_SPECIAL)) != E_DEV							? "=" : "=d ");		}		addparm(&p, e->value);		if (e->flags & E_FUNCTION) addparm(&p, "}");		if (*p == 0) {			printf("The environment is too big\n");			return;		}		*p++= '\n';	}	/* Save the parameters on disk. */	if ((r= writesectors((u16_t) params, dseg, lowsec+PARAMSEC, 1)) != 0) {		writerr(lowsec+PARAMSEC, r);		printf("Can't save environment\n");	}}void show_env()/* Show the environment settings. */{	environment *e;	for (e= env; e != nil; e= e->next) {		if (e->flags & E_RESERVED) continue;		if (e->flags & E_FUNCTION)			printf("%s(%s) {%s}", e->name, e->arg, e->value);		else {			printf("%s = ", e->name);			if (is_default(e)) putchar('(');			printf("%s", e->value);			if (is_default(e)) putchar(')');		}		putchar('\n');	}}int numprefix(s, ps) char *s, **ps;/* True iff s is a string of digits.  *ps will be set to the first nondigit * if non-nil, otherwise the string should end. */{	char *n= s;	while (between('0', *n, '9')) n++;	if (n == s) return 0;	if (ps == nil) return *n == 0;	*ps= n;	return 1;}int numeric(s) char *s;{	return numprefix(s, (char **) nil);}#ifdef MINIX15		/* Now by default Minix 1.6! */#define DEV_PS0		0x21c	/* Major, minor of 1.44M drive 0. */#endif#define DEV_HD1a (DEV_HD0 + 128)	/* First subpartition /dev/hd1a. */dev_t name2dev(name) char *name;/* Translate, say, /dev/hd3 to a device number.  If the name can't be * found on the boot device, then do some guesswork.  The global structure * "tmpdev" will be filled in based on the name, so that "boot hd6" knows * what device to boot without interpreting device numbers. */{	dev_t dev= -1;	ino_t ino;	struct stat st;	char *n, *s;	static char fdN[] = "fdN";	static char hdNX[] = "hdNNX";	static char sub[] = "a";	tmpdev.primary= tmpdev.secondary= -1;	/* "boot *hd3" means: make partition 3 active before you boot it. */	if (activate= (name[0] == '*')) name++;	/* The special name "bootdev" must be translated to the boot device. */	if (strcmp(name, "bootdev") == 0) {		if (device < 0x80) {			/* Floppy disk. */#ifdef MINIX15			/* A Minix 1.5 kernel can't detect a 1.44Mb floppy.  It			 * needs this kluge enabled.			 */			strcpy(fdN, sectors == 18 ? "PS" : "fd");#endif			strcpy(fdN+2, u2a(device));			name= fdN;		} else {			/* Hard disk */			strcpy(hdNX+2, u2a((device - 0x80) * (1 + NR_PARTITIONS)							+ 1 + bootdev.primary));			if (bootdev.secondary >= 0) {				sub[0] = 'a' + bootdev.secondary;				strcat(hdNX, sub);			}			name= hdNX;		}	}	/* Now translate fd0, hd6, etc. the BIOS way. */	n= name;	if (strncmp(n, "/dev/", 5) == 0) n+= 5;	if (n[0] == 'f' && n[1] == 'd' && numeric(n+2))		tmpdev.device= a2l(n+2);	else#ifdef MINIX15	if (n[0] == 'P' && n[1] == 'S' && numeric(n+2))		tmpdev.device= a2l(n+2);	else#endif	if (n[0] == 'h' && n[1] == 'd' && numprefix(n+2, &s)) {		tmpdev.primary= a2l(n+2);		tmpdev.device= 0x80 + tmpdev.primary / (1 + NR_PARTITIONS);		tmpdev.primary= (tmpdev.primary % (1 + NR_PARTITIONS)) - 1;		if (*s == 0)			/* Not a secondary */ ;		else		if (tmpdev.primary >= 0 && between('a', *s, 'd') && s[1] == 0)			tmpdev.secondary= *s - 'a';		else			tmpdev.device= -1;	} else		tmpdev.device= -1;	if (tmpdev.primary < 0) activate= 0;	/* Careful now! */	/* Look the name up on the boot device for the UNIX device number. */	if (fsok) {		/* The current working directory is "/dev". */		ino= r_lookup(r_lookup(ROOT_INO, "dev"), name);		if (ino != 0) {			/* Name has been found, extract the device number. */			r_stat(ino, &st);			if (!S_ISBLK(st.st_mode)) {				printf("%s is not a block device\n");				errno= 0;				return (dev_t) -1;			}			dev= st.st_rdev;		}	}	if (dev == -1 && tmpdev.device >= 0) {		/* The name can't be found on the boot device, do guesswork. */		if (tmpdev.device < 0x80)#ifdef MINIX15			dev= (sectors==18 ? DEV_PS0 : DEV_FD0) + tmpdev.device;#else			dev= DEV_FD0 + tmpdev.device;#endif		else		if (tmpdev.secondary < 0)			dev= DEV_HD0				+ (tmpdev.device - 0x80) * (1 + NR_PARTITIONS)				+ (1 + tmpdev.primary);		else			dev= DEV_HD1a				+ ((tmpdev.device - 0x80) * NR_PARTITIONS					+ tmpdev.primary) * NR_PARTITIONS				+ tmpdev.secondary;	}	/* Don't forget the ram device. */	if (dev == -1 && strcmp(n, "ram") == 0) dev= DEV_RAM;	if (dev == -1) {		printf("Can't recognize %s as a device\n", name);		errno= 0;	}	return dev;}#define B_NODEV		-1#define B_NOSIG		-2int exec_bootstrap()/* Load boot sector from the disk or floppy described by tmpdev and execute it. * The floppy parameters may not be right for the floppy we want to read, but * reading sector 0 seems to be no problem. */{	int r, n, dirty= 0;	char master[SECTOR_SIZE];	struct part_entry *table[NR_PARTITIONS], dummy, *active= &dummy;	u32_t masterpos;

⌨️ 快捷键说明

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