static void
bootpath_build(void)
{
	const char *cp;
	char *pp;
	struct bootpath *bp;
	int fl;

	/*
	 * Grab boot path from PROM and split into `bootpath' components.
	 */
	memset(bootpath, 0, sizeof(bootpath));
	bp = bootpath;
	cp = prom_getbootpath();
	switch (prom_version()) {
	case PROM_OLDMON:
	case PROM_OBP_V0:
		/*
		 * Build fake bootpath.
		 */
		if (cp != NULL)
			bootpath_fake(bp, cp);
		break;
	case PROM_OBP_V2:
	case PROM_OBP_V3:
	case PROM_OPENFIRM:
		while (cp != NULL && *cp == '/') {
			/* Step over '/' */
			++cp;
			/* Extract name */
			pp = bp->name;
			while (*cp != '@' && *cp != '/' && *cp != '\0')
				*pp++ = *cp++;
			*pp = '\0';
#if defined(SUN4M)
			/*
			 * JS1/OF does not have iommu node in the device
			 * tree, so bootpath will start with the sbus entry.
			 * Add entry for iommu to match attachment. See also
			 * mainbus_attach and iommu_attach.
			 */
			if (CPU_ISSUN4M && bp == bootpath
			    && strcmp(bp->name, "sbus") == 0) {
				printf("bootpath_build: inserting iommu entry\n");
				strcpy(bootpath[0].name, "iommu");
				bootpath[0].val[0] = 0;
				bootpath[0].val[1] = 0x10000000;
				bootpath[0].val[2] = 0;
				++nbootpath;

				strcpy(bootpath[1].name, "sbus");
				if (*cp == '/') {
					/* complete sbus entry */
					bootpath[1].val[0] = 0;
					bootpath[1].val[1] = 0x10001000;
					bootpath[1].val[2] = 0;
					++nbootpath;
					bp = &bootpath[2];
					continue;
				} else
					bp = &bootpath[1];
			}
#endif /* SUN4M */
			if (*cp == '@') {
				cp = str2hex(++cp, &bp->val[0]);
				if (*cp == ',')
					cp = str2hex(++cp, &bp->val[1]);
				if (*cp == ':') {
					/* XXX - we handle just one char */
					/*       skip remainder of paths */
					/*       like "ledma@f,400010:tpe" */
					bp->val[2] = *++cp - 'a';
					while (*++cp != '/' && *cp != '\0')
						/*void*/;
				}
			} else {
				bp->val[0] = -1; /* no #'s: assume unit 0, no
							sbus offset/address */
			}
			++bp;
			++nbootpath;
		}
		bp->name[0] = 0;
		break;
	}

	bootpath_print(bootpath);

	/* Setup pointer to boot flags */
	cp = prom_getbootargs();
	if (cp == NULL)
		return;

	/* Skip any whitespace */
	while (*cp != '-')
		if (*cp++ == '\0')
			return;

	for (;*++cp;) {
		fl = 0;
		BOOT_FLAG(*cp, fl);
		if (!fl) {
			printf("unknown option `%c'\n", *cp);
			continue;
		}
		boothowto |= fl;

		/* specialties */
		if (*cp == 'd') {
#if defined(KGDB)
			kgdb_debug_panic = 1;
			kgdb_connect(1);
#elif defined(DDB)
			Debugger();
#else
			printf("kernel has no debugger\n");
#endif
		}
	}
}
示例#2
0
文件: boot.c 项目: ryo/netbsd-src
void
main(void *ofw)
{
	int boothowto, i = 0, isfloppy, kboothowto;

	char kernel[PROM_MAX_PATH];
	char bootline[PROM_MAX_PATH];

	/* Initialize OpenFirmware */
	romp = ofw;
	prom_init();

	printf("\r>> %s, Revision %s\n", bootprog_name, bootprog_rev);

	/* Figure boot arguments */
	strncpy(bootdev, prom_getbootpath(), sizeof(bootdev) - 1);
	kboothowto = boothowto =
	    bootoptions(prom_getbootargs(), bootdev, kernel, bootline);
	isfloppy = bootdev_isfloppy(bootdev);

	for (;; *kernel = '\0') {
		if (boothowto & RB_ASKNAME) {
			char cmdline[PROM_MAX_PATH];

			printf("Boot: ");
			kgets(cmdline, sizeof(cmdline));

			if (!strcmp(cmdline,"exit") ||
			    !strcmp(cmdline,"halt")) {
				prom_halt();
			} else if (!strcmp(cmdline, "?") ||
				   !strcmp(cmdline, "help")) {
				help();
				continue;
			}

			boothowto  = bootoptions(cmdline, bootdev, kernel,
			    bootline);
			boothowto |= RB_ASKNAME;
			i = 0;
		}

		if (*kernel == '\0') {
			if (kernelnames[i] == NULL) {
				boothowto |= RB_ASKNAME;
				continue;
			}
			strncpy(kernel, kernelnames[i++], PROM_MAX_PATH);
		} else if (i == 0) {
			/*
			 * Kernel name was passed via command line -- ask user
			 * again if requested image fails to boot.
			 */
			boothowto |= RB_ASKNAME;
		}

		check_boot_config();
		start_kernel(kernel, bootline, ofw, isfloppy, kboothowto);

		/*
		 * Try next name from kernel name list if not in askname mode,
		 * enter askname on reaching list's end.
		 */
		if ((boothowto & RB_ASKNAME) == 0 && (kernelnames[i] != NULL)) {
			printf(": trying %s...\n", kernelnames[i]);
		} else {
			printf("\n");
			boothowto |= RB_ASKNAME;
		}
	}

	(void)printf("Boot failed! Exiting to the Firmware.\n");
	prom_halt();
}
示例#3
0
int
main(void)
{
	int	error, i;
	char	kernel[MAX_PROM_PATH];
	const char *k;
	u_long	marks[MARK_MAX], bootinfo;
	struct btinfo_symtab bi_sym;
	struct btinfo_boothowto bi_howto;
	void	*arg;

#ifdef HEAP_VARIABLE
	{
		extern char end[];
		setheap((void *)ALIGN(end), (void *)0xffffffff);
	}
#endif
	prom_init();
	mmu_init();

	printf(">> %s, Revision %s\n", bootprog_name, bootprog_rev);

	/* massage machine prom */
	prom_patch();

	/*
	 * get default kernel.
	 */
	k = prom_getbootfile();
	if (k != NULL && *k != '\0') {
		i = -1;	/* not using the kernels */
		strcpy(kernel, k);
	} else {
		i = 0;
		strcpy(kernel, kernels[i]);
	}

	k = prom_getbootpath();
	if (k && *k)
		strcpy(prom_bootdevice, k);
	boothowto = bootoptions(prom_getbootargs());

	for (;;) {
		/*
		 * ask for a kernel first ..
		 */
		if (boothowto & RB_ASKNAME) {
			printf("device[%s] (\"halt\" to halt): ",
					prom_bootdevice);
			gets(dbuf);
			if (strcmp(dbuf, "halt") == 0)
				_rtt();
			if (dbuf[0])
				strcpy(prom_bootdevice, dbuf);
			printf("boot (press RETURN to try default list): ");
			gets(fbuf);
			if (fbuf[0])
				strcpy(kernel, fbuf);
			else {
				boothowto &= ~RB_ASKNAME;
				i = 0;
				strcpy(kernel, kernels[i]);
			}
		}

		printf("Booting %s\n", kernel);
		if ((error = loadk(kernel, marks)) == 0)
			break;

		if (error != ENOENT) {
			printf("Cannot load %s: error=%d\n", kernel, error);
			boothowto |= RB_ASKNAME;
		}

		/*
		 * if we have are not in askname mode, and we aren't using the
		 * prom bootfile, try the next one (if it exits).  otherwise,
		 * go into askname mode.
		 */
		if ((boothowto & RB_ASKNAME) == 0 &&
		    i != -1 && kernels[++i]) {
			strcpy(kernel, kernels[i]);
			printf(": trying %s...\n", kernel);
		} else {
			printf("\n");
			boothowto |= RB_ASKNAME;
		}
	}

	marks[MARK_END] = (((u_long)marks[MARK_END] + sizeof(u_long) - 1)) &
	    (-sizeof(u_long));
	arg = (prom_version() == PROM_OLDMON) ? (void *)PROM_LOADADDR : romp;

	/* Setup boot info structure at the end of the kernel image */
	bootinfo = bi_init(marks[MARK_END] & loadaddrmask);

	/* Add kernel symbols to bootinfo */
	bi_sym.nsym = marks[MARK_NSYM] & loadaddrmask;
	bi_sym.ssym = marks[MARK_SYM] & loadaddrmask;
	bi_sym.esym = marks[MARK_END] & loadaddrmask;
	bi_add(&bi_sym, BTINFO_SYMTAB, sizeof(bi_sym));

	/* Add boothowto */
	bi_howto.boothowto = boothowto;
	bi_add(&bi_howto, BTINFO_BOOTHOWTO, sizeof(bi_howto));

	/* Add kernel path to bootinfo */
	i = sizeof(struct btinfo_common) + strlen(kernel) + 1;
	/* Impose limit (somewhat arbitrary) */
	if (i < BOOTINFO_SIZE / 2) {
		union {
			struct btinfo_kernelfile bi_file;
			char x[i];
		} U;
		strcpy(U.bi_file.name, kernel);
		bi_add(&U.bi_file, BTINFO_KERNELFILE, i);
	}

	(*(entry_t)marks[MARK_ENTRY])(arg, 0, 0, 0, bootinfo, DDB_MAGIC2);
	_rtt();
}