xref: /onnv-gate/usr/src/psm/stand/boot/sparc/common/inetboot.c (revision 9398:b298f8940380)
15648Ssetje /*
25648Ssetje  * CDDL HEADER START
35648Ssetje  *
45648Ssetje  * The contents of this file are subject to the terms of the
55648Ssetje  * Common Development and Distribution License (the "License").
65648Ssetje  * You may not use this file except in compliance with the License.
75648Ssetje  *
85648Ssetje  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95648Ssetje  * or http://www.opensolaris.org/os/licensing.
105648Ssetje  * See the License for the specific language governing permissions
115648Ssetje  * and limitations under the License.
125648Ssetje  *
135648Ssetje  * When distributing Covered Code, include this CDDL HEADER in each
145648Ssetje  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155648Ssetje  * If applicable, add the following below this CDDL HEADER, with the
165648Ssetje  * fields enclosed by brackets "[]" replaced with your own identifying
175648Ssetje  * information: Portions Copyright [yyyy] [name of copyright owner]
185648Ssetje  *
195648Ssetje  * CDDL HEADER END
205648Ssetje  */
215648Ssetje /*
22*9398SPhaniram.Krishnamurthy@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
235648Ssetje  * Use is subject to license terms.
245648Ssetje  */
255648Ssetje 
265648Ssetje 
275648Ssetje #include <sys/types.h>
285648Ssetje #include <sys/param.h>
295648Ssetje #include <sys/fcntl.h>
305648Ssetje #include <sys/obpdefs.h>
315648Ssetje #include <sys/reboot.h>
325648Ssetje #include <sys/promif.h>
335648Ssetje #include <sys/stat.h>
345648Ssetje #include <sys/bootvfs.h>
355648Ssetje #include <sys/platnames.h>
365648Ssetje #include <sys/salib.h>
375648Ssetje #include <sys/elf.h>
385648Ssetje #include <sys/link.h>
395648Ssetje #include <sys/auxv.h>
405648Ssetje #include <sys/boot_policy.h>
415648Ssetje #include <sys/boot_redirect.h>
425648Ssetje #include <sys/bootconf.h>
435648Ssetje #include <sys/boot.h>
445648Ssetje #include "boot_plat.h"
455648Ssetje #include "ramdisk.h"
465648Ssetje 
475648Ssetje #define	SUCCESS		0
485648Ssetje #define	FAILURE		-1
495648Ssetje 
505648Ssetje #ifdef DEBUG
515648Ssetje extern int debug = 0;
525648Ssetje #else
535648Ssetje static const int debug = 0;
545648Ssetje #endif
555648Ssetje 
565648Ssetje #define	dprintf		if (debug) printf
575648Ssetje 
585648Ssetje char		*def_boot_archive = "boot_archive";
595648Ssetje char		*def_miniroot = "miniroot";
605648Ssetje extern char	cmd_line_boot_archive[];
615648Ssetje 
625648Ssetje extern int	openfile(char *filename);
635648Ssetje 
645648Ssetje static int
read_and_boot_ramdisk(int fd)655648Ssetje read_and_boot_ramdisk(int fd)
665648Ssetje {
675648Ssetje 	struct stat	st;
685648Ssetje 	caddr_t		virt;
695648Ssetje 	size_t		size;
705648Ssetje 	extern		ssize_t xread(int, char *, size_t);
715648Ssetje 
725648Ssetje 	if ((fstat(fd, &st) != 0) ||
735648Ssetje 	    ((virt = create_ramdisk(RD_ROOTFS, st.st_size, NULL)) == NULL))
745648Ssetje 		return (-1);
755648Ssetje 
765648Ssetje 	dprintf("reading boot archive ...\n");
775648Ssetje 	if ((size = xread(fd, (char *)virt, st.st_size)) != st.st_size) {
785648Ssetje 		(void) printf("Error reading boot archive, bytes read = %ld, "
795648Ssetje 		    "filesize = %ld\n", (long)size, (long)st.st_size);
805648Ssetje 		destroy_ramdisk(RD_ROOTFS);
815648Ssetje 		return (-1);
825648Ssetje 	}
835648Ssetje 
845648Ssetje 	boot_ramdisk(RD_ROOTFS);
855648Ssetje 	/* NOT REACHED */
865648Ssetje 	return (0);	/* to make cc happy */
875648Ssetje }
885648Ssetje 
895648Ssetje 
905648Ssetje static void
post_mountroot_nfs(void)915648Ssetje post_mountroot_nfs(void)
925648Ssetje {
935648Ssetje 	int	fd;
945648Ssetje 	char	*fn;
955648Ssetje 	char	tmpname[MAXPATHLEN];
965648Ssetje 
975648Ssetje 	for (;;) {
985648Ssetje 		fn = NULL;
995648Ssetje 		if (boothowto & RB_ASKNAME) {
100*9398SPhaniram.Krishnamurthy@Sun.COM 			char ctmpname[MAXPATHLEN];
101*9398SPhaniram.Krishnamurthy@Sun.COM 
1025648Ssetje 			fn = (cmd_line_boot_archive[0] != '\0') ?
1035648Ssetje 			    cmd_line_boot_archive : def_boot_archive;
104*9398SPhaniram.Krishnamurthy@Sun.COM 
105*9398SPhaniram.Krishnamurthy@Sun.COM 			/* Avoid buffer overrun */
106*9398SPhaniram.Krishnamurthy@Sun.COM 			(void) strncpy(tmpname, fn, strlen(fn)+1);
107*9398SPhaniram.Krishnamurthy@Sun.COM 			fn = tmpname;
108*9398SPhaniram.Krishnamurthy@Sun.COM 
1095648Ssetje 			printf("Enter filename [%s]: ", fn);
110*9398SPhaniram.Krishnamurthy@Sun.COM 			(void) cons_gets(ctmpname, sizeof (ctmpname));
111*9398SPhaniram.Krishnamurthy@Sun.COM 			if (ctmpname[0] != '\0') {
112*9398SPhaniram.Krishnamurthy@Sun.COM 				(void) strncpy(tmpname, ctmpname,
113*9398SPhaniram.Krishnamurthy@Sun.COM 				    strlen(ctmpname)+1);
1145648Ssetje 				fn = tmpname;
115*9398SPhaniram.Krishnamurthy@Sun.COM 			}
1165648Ssetje 		}
1175648Ssetje 
1185648Ssetje 		if (boothowto & RB_HALT) {
1195648Ssetje 			printf("Boot halted.\n");
1205648Ssetje 			prom_enter_mon();
1215648Ssetje 		}
1225648Ssetje 
123*9398SPhaniram.Krishnamurthy@Sun.COM 
124*9398SPhaniram.Krishnamurthy@Sun.COM 		if (fn != NULL) {
1255648Ssetje 			fd = openfile(fn);
126*9398SPhaniram.Krishnamurthy@Sun.COM 		} else if (cmd_line_boot_archive[0] != '\0') {
127*9398SPhaniram.Krishnamurthy@Sun.COM 			(void) strncpy(tmpname, cmd_line_boot_archive,
128*9398SPhaniram.Krishnamurthy@Sun.COM 			    strlen(cmd_line_boot_archive)+1);
129*9398SPhaniram.Krishnamurthy@Sun.COM 			fn = tmpname;
1305648Ssetje 			fd = openfile(fn);
1315648Ssetje 		} else {
132*9398SPhaniram.Krishnamurthy@Sun.COM 			(void) strncpy(tmpname, def_boot_archive,
133*9398SPhaniram.Krishnamurthy@Sun.COM 			    strlen(def_boot_archive)+1);
134*9398SPhaniram.Krishnamurthy@Sun.COM 			fn = tmpname;
1355648Ssetje 			if ((fd = openfile(fn)) == FAILURE) {
136*9398SPhaniram.Krishnamurthy@Sun.COM 				(void) strncpy(tmpname, def_miniroot,
137*9398SPhaniram.Krishnamurthy@Sun.COM 				    strlen(def_miniroot)+1);
138*9398SPhaniram.Krishnamurthy@Sun.COM 				fn = tmpname;
1395648Ssetje 				fd = openfile(fn);
1405648Ssetje 			}
1415648Ssetje 		}
1425648Ssetje 
143*9398SPhaniram.Krishnamurthy@Sun.COM 		if (fn != tmpname || tmpname[0] == '\0') {
144*9398SPhaniram.Krishnamurthy@Sun.COM 			printf("Possible buffer overrun, "
145*9398SPhaniram.Krishnamurthy@Sun.COM 			    "entering boot prompt\n");
146*9398SPhaniram.Krishnamurthy@Sun.COM 			prom_enter_mon();
147*9398SPhaniram.Krishnamurthy@Sun.COM 		}
148*9398SPhaniram.Krishnamurthy@Sun.COM 
149*9398SPhaniram.Krishnamurthy@Sun.COM 
1505648Ssetje 		if (fd == FAILURE) {
151*9398SPhaniram.Krishnamurthy@Sun.COM 			if (strncmp(fn, def_miniroot,
152*9398SPhaniram.Krishnamurthy@Sun.COM 			    strlen(def_miniroot)+1) != 0)
1535648Ssetje 				printf("cannot open %s\n", fn);
1545648Ssetje 			else
1555648Ssetje 				printf("cannot open neither %s nor %s\n",
1565648Ssetje 				    def_boot_archive, def_miniroot);
1575648Ssetje 		} else {
1585648Ssetje 			/*
1595648Ssetje 			 * this function does not return if successful.
1605648Ssetje 			 */
1615648Ssetje 			(void) read_and_boot_ramdisk(fd);
1625648Ssetje 
1635648Ssetje 			printf("boot failed\n");
1645648Ssetje 			(void) close(fd);
1655648Ssetje 		}
1665648Ssetje 		boothowto |= RB_ASKNAME;
1675648Ssetje 	}
1685648Ssetje }
1695648Ssetje 
1705648Ssetje 
1715648Ssetje /*
1725648Ssetje  * bpath is the boot device path buffer.
1735648Ssetje  * bargs is the boot arguments buffer.
1745648Ssetje  */
1755648Ssetje /*ARGSUSED*/
1765648Ssetje int
bootprog(char * bpath,char * bargs,boolean_t user_specified_filename)1775648Ssetje bootprog(char *bpath, char *bargs, boolean_t user_specified_filename)
1785648Ssetje {
1795648Ssetje 	systype = set_fstype(v2path, bpath);
1805648Ssetje 
1815648Ssetje 	if (verbosemode) {
1825648Ssetje 		printf("device path '%s'\n", bpath);
1835648Ssetje 		if (strcmp(bpath, v2path) != 0)
1845648Ssetje 			printf("client path '%s'\n", v2path);
1855648Ssetje 	}
1865648Ssetje 
1875648Ssetje 	if (mountroot(bpath) != SUCCESS)
1885648Ssetje 		prom_panic("Could not mount filesystem.");
1895648Ssetje 
1905648Ssetje 	/*
1915648Ssetje 	 * kernname (default-name) might have changed if mountroot() called
1925648Ssetje 	 * boot_nfs_mountroot(), and it called set_default_filename().
1935648Ssetje 	 */
1945648Ssetje 	if (!user_specified_filename)
1955648Ssetje 		(void) strcpy(filename, kernname);
1965648Ssetje 
1975648Ssetje 	if (verbosemode)
1985648Ssetje 		printf("standalone = `%s', args = `%s'\n", filename, bargs);
1995648Ssetje 
2005648Ssetje 	set_client_bootargs(filename, bargs);
2015648Ssetje 
2025648Ssetje 	post_mountroot_nfs();
2035648Ssetje 
2045648Ssetje 	return (1);
2055648Ssetje }
206