1 /* $NetBSD: devopen.c,v 1.4 2008/04/28 20:23:18 martin 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 = { 50 ufs_open, ufs_close, ufs_read, ufs_write, ufs_seek, ufs_stat 51 }; 52 struct fs_ops nfs_ops = { 53 nfs_open, nfs_close, nfs_read, nfs_write, nfs_seek, nfs_stat 54 }; 55 56 extern struct devsw netdevsw; 57 extern struct devsw dkdevsw; 58 char fname[16]; 59 60 /* Referenced by libsa/open.c */ 61 struct fs_ops file_system[1]; 62 int nfsys = 1; 63 struct devsw devsw[1]; 64 int ndevs = 1; 65 66 int 67 devopen(struct open_file *f, const char *request, char **file) 68 { 69 char *p, *filename; 70 int disk, partition; 71 void *addr; 72 size_t size; 73 74 strcpy(fname, request); 75 76 filename = 0; 77 for (p = fname; *p; p++) { 78 if (*p == ':') { 79 filename = p + 1; 80 *p = '\0'; 81 break; 82 } 83 } 84 85 if (filename == 0) { /* not a loader's request. probably ufs_ls() */ 86 printf("request=%s\n", request); 87 f->f_dev = &dkdevsw; 88 file_system[0] = ufs_ops; 89 devsw[0] = dkdevsw; 90 *file = "/"; 91 return 0; 92 } 93 94 /* Data section */ 95 if (strcmp(fname, "mem") == 0) { 96 data_attach(kernel_binary, kernel_binary_size); 97 *file = "noname"; 98 f->f_flags |= F_NODEV; 99 file_system[0] = datafs_ops; 100 printf("data(compiled):noname\n"); 101 return 0; 102 } 103 104 /* NFS boot */ 105 if (strcmp(fname, "nfs") == 0) { 106 if (!DEVICE_CAPABILITY.network_enabled) { 107 printf("Network disabled.\n"); 108 return -1; 109 } 110 try_bootp = true; 111 file_system[0] = nfs_ops; 112 f->f_dev = &netdevsw; 113 if (*filename == '\0') { 114 printf("set kernel filename. ex.) nfs:netbsd\n"); 115 return 1; 116 } 117 *--filename = '/'; 118 *file = filename; 119 printf("nfs:/%s\n", filename); 120 net_open(f); 121 return 0; 122 } 123 124 /* FD boot */ 125 if (strcmp(fname, "fd") == 0) { 126 printf("floppy(boot):/%s (ustarfs)\n", filename); 127 f->f_dev = &dkdevsw; 128 file_system[0] = datafs_ops; 129 devsw[0] = dkdevsw; 130 device_attach(NVSRAM_BOOTDEV_FLOPPYDISK, -1, -1); 131 if (!ustarfs_load(filename, &addr, &size)) 132 return -1; 133 data_attach(addr, size); 134 *file = filename; 135 return 0; 136 } 137 138 /* Disk boot */ 139 if (strncmp(fname, "sd", 2) == 0) { 140 enum fstype fs; 141 if (!DEVICE_CAPABILITY.disk_enabled) { 142 printf("Disk disabled.\n"); 143 return -1; 144 } 145 146 disk = fname[2] - '0'; 147 partition = fname[3] - 'a'; 148 if (disk < 0 || disk > 9 || partition < 0 || partition > 15) { 149 fs = FSTYPE_USTARFS; 150 printf("disk(boot):%s ", filename); 151 device_attach(NVSRAM_BOOTDEV_HARDDISK, -1, -1); 152 } else { 153 fs = fstype(partition); 154 printf("disk(%d,%d):/%s ", 155 disk, partition, filename); 156 device_attach(NVSRAM_BOOTDEV_HARDDISK, disk, partition); 157 } 158 159 switch (fs) { 160 case FSTYPE_UFS: 161 printf(" (ufs)\n"); 162 f->f_dev = &dkdevsw; 163 file_system[0] = ufs_ops; 164 devsw[0] = dkdevsw; 165 break; 166 case FSTYPE_BFS: 167 printf(" (bfs)\n"); 168 f->f_flags |= F_NODEV; 169 file_system[0] = bfs_ops; 170 break; 171 case FSTYPE_USTARFS: 172 printf(" (ustarfs)\n"); 173 f->f_dev = &dkdevsw; 174 file_system[0] = datafs_ops; 175 devsw[0] = dkdevsw; 176 if (!ustarfs_load(filename, &addr, &size)) 177 return -1; 178 data_attach(addr, size); 179 break; 180 } 181 *file = filename; 182 return 0; 183 } 184 185 printf("%s invalid.\n", fname); 186 187 return -1; 188 } 189