Home | History | Annotate | Line # | Download | only in common
      1 /*	$NetBSD: devopen.c,v 1.5 2011/12/25 06:09:09 tsutsui Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2004 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by UCHIYAMA Yasushi.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 #include <lib/libsa/stand.h>
     33 #include <lib/libkern/libkern.h>
     34 
     35 #include <netinet/in.h>
     36 #include <lib/libsa/dev_net.h>
     37 #include <lib/libsa/ufs.h>
     38 #include <lib/libsa/nfs.h>
     39 #include <lib/libsa/dev_net.h>
     40 #include <machine/sbd.h>
     41 
     42 #include "local.h"
     43 
     44 extern uint8_t kernel_binary[];
     45 extern int kernel_binary_size;
     46 
     47 extern struct fs_ops datafs_ops;
     48 extern struct fs_ops bfs_ops;
     49 struct fs_ops ufs_ops = FS_OPS(ufs);
     50 struct fs_ops nfs_ops = FS_OPS(nfs);
     51 
     52 extern struct devsw netdevsw;
     53 extern struct devsw dkdevsw;
     54 char fname[16];
     55 
     56 /* Referenced by libsa/open.c */
     57 struct fs_ops file_system[1];
     58 int nfsys = 1;
     59 struct devsw devsw[1];
     60 int ndevs = 1;
     61 
     62 int
     63 devopen(struct open_file *f, const char *request, char **file)
     64 {
     65 	char *p, *filename;
     66 	int disk, partition;
     67 	void *addr;
     68 	size_t size;
     69 
     70 	strcpy(fname, request);
     71 
     72 	filename = 0;
     73 	for (p = fname; *p; p++) {
     74 		if (*p == ':') {
     75 			filename = p + 1;
     76 			*p = '\0';
     77 			break;
     78 		}
     79 	}
     80 
     81 	if (filename == 0) {	/* not a loader's request. probably ufs_ls() */
     82 		printf("request=%s\n", request);
     83 		f->f_dev = &dkdevsw;
     84 		file_system[0] = ufs_ops;
     85 		devsw[0] = dkdevsw;
     86 		*file = "/";
     87 		return 0;
     88 	}
     89 
     90 	/* Data section */
     91 	if (strcmp(fname, "mem") == 0) {
     92 		data_attach(kernel_binary, kernel_binary_size);
     93 		*file = "noname";
     94 		f->f_flags |= F_NODEV;
     95 		file_system[0] = datafs_ops;
     96 		printf("data(compiled):noname\n");
     97 		return 0;
     98 	}
     99 
    100 	/* NFS boot */
    101 	if (strcmp(fname, "nfs") == 0) {
    102 		if (!DEVICE_CAPABILITY.network_enabled) {
    103 			printf("Network disabled.\n");
    104 			return -1;
    105 		}
    106 		try_bootp = true;
    107 		file_system[0] = nfs_ops;
    108 		f->f_dev = &netdevsw;
    109 		if (*filename == '\0') {
    110 			printf("set kernel filename. ex.) nfs:netbsd\n");
    111 			return 1;
    112 		}
    113 		*--filename = '/';
    114 		*file = filename;
    115 		printf("nfs:/%s\n", filename);
    116 		net_open(f);
    117 		return 0;
    118 	}
    119 
    120 	/* FD boot */
    121 	if (strcmp(fname, "fd") == 0) {
    122 		printf("floppy(boot):/%s (ustarfs)\n", filename);
    123 		f->f_dev = &dkdevsw;
    124 		file_system[0] = datafs_ops;
    125 		devsw[0] = dkdevsw;
    126 		device_attach(NVSRAM_BOOTDEV_FLOPPYDISK, -1, -1);
    127 		if (!ustarfs_load(filename, &addr, &size))
    128 			return -1;
    129 		data_attach(addr, size);
    130 		*file = filename;
    131 		return 0;
    132 	}
    133 
    134 	/* Disk boot */
    135 	if (strncmp(fname, "sd", 2) == 0) {
    136 		enum fstype fs;
    137 		if (!DEVICE_CAPABILITY.disk_enabled) {
    138 			printf("Disk disabled.\n");
    139 			return -1;
    140 		}
    141 
    142 		disk = fname[2] - '0';
    143 		partition = fname[3] - 'a';
    144 		if (disk < 0 || disk > 9 || partition < 0 || partition > 15) {
    145 			fs = FSTYPE_USTARFS;
    146 			printf("disk(boot):%s ", filename);
    147 			device_attach(NVSRAM_BOOTDEV_HARDDISK, -1, -1);
    148 		} else {
    149 			fs = fstype(partition);
    150 			printf("disk(%d,%d):/%s ",
    151 			    disk, partition, filename);
    152 			device_attach(NVSRAM_BOOTDEV_HARDDISK, disk, partition);
    153 		}
    154 
    155 		switch (fs) {
    156 		case FSTYPE_UFS:
    157 			printf(" (ufs)\n");
    158 			f->f_dev = &dkdevsw;
    159 			file_system[0] = ufs_ops;
    160 			devsw[0] = dkdevsw;
    161 			break;
    162 		case FSTYPE_BFS:
    163 			printf(" (bfs)\n");
    164 			f->f_flags |= F_NODEV;
    165 			file_system[0] = bfs_ops;
    166 			break;
    167 		case FSTYPE_USTARFS:
    168 			printf(" (ustarfs)\n");
    169 			f->f_dev = &dkdevsw;
    170 			file_system[0] = datafs_ops;
    171 			devsw[0] = dkdevsw;
    172 			if (!ustarfs_load(filename, &addr, &size))
    173 				return -1;
    174 			data_attach(addr, size);
    175 			break;
    176 		}
    177 		*file = filename;
    178 		return 0;
    179 	}
    180 
    181 	printf("%s invalid.\n", fname);
    182 
    183 	return -1;
    184 }
    185