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