Sat Dec 7 02:29:03 2019 UTC ()
loadfile sets errno, return the correct error, not EIO.


(christos)
diff -r1.74 -r1.75 src/sys/arch/i386/stand/lib/exec.c

cvs diff -r1.74 -r1.75 src/sys/arch/i386/stand/lib/exec.c (switch to unified diff)

--- src/sys/arch/i386/stand/lib/exec.c 2019/09/13 02:19:46 1.74
+++ src/sys/arch/i386/stand/lib/exec.c 2019/12/07 02:29:03 1.75
@@ -1,897 +1,897 @@ @@ -1,897 +1,897 @@
1/* $NetBSD: exec.c,v 1.74 2019/09/13 02:19:46 manu Exp $ */ 1/* $NetBSD: exec.c,v 1.75 2019/12/07 02:29:03 christos Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. 4 * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29/* 29/*
30 * Copyright (c) 1982, 1986, 1990, 1993 30 * Copyright (c) 1982, 1986, 1990, 1993
31 * The Regents of the University of California. All rights reserved. 31 * The Regents of the University of California. All rights reserved.
32 * 32 *
33 * Redistribution and use in source and binary forms, with or without 33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions 34 * modification, are permitted provided that the following conditions
35 * are met: 35 * are met:
36 * 1. Redistributions of source code must retain the above copyright 36 * 1. Redistributions of source code must retain the above copyright
37 * notice, this list of conditions and the following disclaimer. 37 * notice, this list of conditions and the following disclaimer.
38 * 2. Redistributions in binary form must reproduce the above copyright 38 * 2. Redistributions in binary form must reproduce the above copyright
39 * notice, this list of conditions and the following disclaimer in the 39 * notice, this list of conditions and the following disclaimer in the
40 * documentation and/or other materials provided with the distribution. 40 * documentation and/or other materials provided with the distribution.
41 * 3. Neither the name of the University nor the names of its contributors 41 * 3. Neither the name of the University nor the names of its contributors
42 * may be used to endorse or promote products derived from this software 42 * may be used to endorse or promote products derived from this software
43 * without specific prior written permission. 43 * without specific prior written permission.
44 * 44 *
45 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 45 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 48 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55 * SUCH DAMAGE. 55 * SUCH DAMAGE.
56 * 56 *
57 * @(#)boot.c 8.1 (Berkeley) 6/10/93 57 * @(#)boot.c 8.1 (Berkeley) 6/10/93
58 */ 58 */
59 59
60/* 60/*
61 * Copyright (c) 1996 61 * Copyright (c) 1996
62 * Matthias Drochner. All rights reserved. 62 * Matthias Drochner. All rights reserved.
63 * Copyright (c) 1996 63 * Copyright (c) 1996
64 * Perry E. Metzger. All rights reserved. 64 * Perry E. Metzger. All rights reserved.
65 * 65 *
66 * Redistribution and use in source and binary forms, with or without 66 * Redistribution and use in source and binary forms, with or without
67 * modification, are permitted provided that the following conditions 67 * modification, are permitted provided that the following conditions
68 * are met: 68 * are met:
69 * 1. Redistributions of source code must retain the above copyright 69 * 1. Redistributions of source code must retain the above copyright
70 * notice, this list of conditions and the following disclaimer. 70 * notice, this list of conditions and the following disclaimer.
71 * 2. Redistributions in binary form must reproduce the above copyright 71 * 2. Redistributions in binary form must reproduce the above copyright
72 * notice, this list of conditions and the following disclaimer in the 72 * notice, this list of conditions and the following disclaimer in the
73 * documentation and/or other materials provided with the distribution. 73 * documentation and/or other materials provided with the distribution.
74 * 74 *
75 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 75 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
76 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 76 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
77 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 77 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
78 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 78 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
79 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 79 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
80 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 80 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
81 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 81 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
82 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 82 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
83 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 83 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
84 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 84 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
85 * SUCH DAMAGE. 85 * SUCH DAMAGE.
86 * 86 *
87 * @(#)boot.c 8.1 (Berkeley) 6/10/93 87 * @(#)boot.c 8.1 (Berkeley) 6/10/93
88 */ 88 */
89 89
90/* 90/*
91 * Starts a NetBSD ELF kernel. The low level startup is done in startprog.S. 91 * Starts a NetBSD ELF kernel. The low level startup is done in startprog.S.
92 * This is a special version of exec.c to support use of XMS. 92 * This is a special version of exec.c to support use of XMS.
93 */ 93 */
94 94
95#include <sys/param.h> 95#include <sys/param.h>
96#include <sys/reboot.h> 96#include <sys/reboot.h>
97 97
98#include <lib/libsa/stand.h> 98#include <lib/libsa/stand.h>
99#include <lib/libkern/libkern.h> 99#include <lib/libkern/libkern.h>
100 100
101#include "loadfile.h" 101#include "loadfile.h"
102#include "libi386.h" 102#include "libi386.h"
103#include "bootinfo.h" 103#include "bootinfo.h"
104#include "bootmod.h" 104#include "bootmod.h"
105#include "vbe.h" 105#include "vbe.h"
106#ifdef SUPPORT_PS2 106#ifdef SUPPORT_PS2
107#include "biosmca.h" 107#include "biosmca.h"
108#endif 108#endif
109#ifdef EFIBOOT 109#ifdef EFIBOOT
110#include "efiboot.h" 110#include "efiboot.h"
111#undef DEBUG /* XXX */ 111#undef DEBUG /* XXX */
112#endif 112#endif
113 113
114#define BOOT_NARGS 6 114#define BOOT_NARGS 6
115 115
116#ifndef PAGE_SIZE 116#ifndef PAGE_SIZE
117#define PAGE_SIZE 4096 117#define PAGE_SIZE 4096
118#endif 118#endif
119 119
120#define MODULE_WARNING_SEC 5 120#define MODULE_WARNING_SEC 5
121 121
122#define MAXMODNAME 32 /* from <sys/module.h> */ 122#define MAXMODNAME 32 /* from <sys/module.h> */
123 123
124extern struct btinfo_console btinfo_console; 124extern struct btinfo_console btinfo_console;
125 125
126boot_module_t *boot_modules; 126boot_module_t *boot_modules;
127bool boot_modules_enabled = true; 127bool boot_modules_enabled = true;
128bool kernel_loaded; 128bool kernel_loaded;
129 129
130typedef struct userconf_command { 130typedef struct userconf_command {
131 char *uc_text; 131 char *uc_text;
132 size_t uc_len; 132 size_t uc_len;
133 struct userconf_command *uc_next; 133 struct userconf_command *uc_next;
134} userconf_command_t; 134} userconf_command_t;
135userconf_command_t *userconf_commands = NULL; 135userconf_command_t *userconf_commands = NULL;
136 136
137struct btinfo_framebuffer btinfo_framebuffer; 137struct btinfo_framebuffer btinfo_framebuffer;
138 138
139struct btinfo_modulelist *btinfo_modulelist; 139struct btinfo_modulelist *btinfo_modulelist;
140static size_t btinfo_modulelist_size; 140static size_t btinfo_modulelist_size;
141static uint32_t image_end; 141static uint32_t image_end;
142static char module_base[64] = "/"; 142static char module_base[64] = "/";
143static int howto; 143static int howto;
144 144
145static struct btinfo_userconfcommands *btinfo_userconfcommands = NULL; 145static struct btinfo_userconfcommands *btinfo_userconfcommands = NULL;
146static size_t btinfo_userconfcommands_size = 0; 146static size_t btinfo_userconfcommands_size = 0;
147 147
148static void module_init(const char *); 148static void module_init(const char *);
149static void module_add_common(const char *, uint8_t); 149static void module_add_common(const char *, uint8_t);
150 150
151static void userconf_init(void); 151static void userconf_init(void);
152 152
153static void extract_device(const char *, char *, size_t); 153static void extract_device(const char *, char *, size_t);
154static void module_base_path(char *, size_t); 154static void module_base_path(char *, size_t);
155static int module_open(boot_module_t *, int, const char *, const char *, 155static int module_open(boot_module_t *, int, const char *, const char *,
156 bool); 156 bool);
157 157
158void 158void
159framebuffer_configure(struct btinfo_framebuffer *fb) 159framebuffer_configure(struct btinfo_framebuffer *fb)
160{ 160{
161 if (fb) 161 if (fb)
162 btinfo_framebuffer = *fb; 162 btinfo_framebuffer = *fb;
163 else { 163 else {
164 btinfo_framebuffer.physaddr = 0; 164 btinfo_framebuffer.physaddr = 0;
165 btinfo_framebuffer.flags = 0; 165 btinfo_framebuffer.flags = 0;
166 } 166 }
167} 167}
168 168
169void 169void
170module_add(char *name) 170module_add(char *name)
171{ 171{
172 return module_add_common(name, BM_TYPE_KMOD); 172 return module_add_common(name, BM_TYPE_KMOD);
173} 173}
174 174
175void 175void
176splash_add(char *name) 176splash_add(char *name)
177{ 177{
178 return module_add_common(name, BM_TYPE_IMAGE); 178 return module_add_common(name, BM_TYPE_IMAGE);
179} 179}
180 180
181void 181void
182rnd_add(char *name) 182rnd_add(char *name)
183{ 183{
184 return module_add_common(name, BM_TYPE_RND); 184 return module_add_common(name, BM_TYPE_RND);
185} 185}
186 186
187void 187void
188fs_add(char *name) 188fs_add(char *name)
189{ 189{
190 return module_add_common(name, BM_TYPE_FS); 190 return module_add_common(name, BM_TYPE_FS);
191} 191}
192 192
193/* 193/*
194 * Add a /-separated list of module names to the boot list 194 * Add a /-separated list of module names to the boot list
195 */ 195 */
196void 196void
197module_add_split(const char *name, uint8_t type) 197module_add_split(const char *name, uint8_t type)
198{ 198{
199 char mod_name[MAXMODNAME]; 199 char mod_name[MAXMODNAME];
200 int i; 200 int i;
201 const char *mp = name; 201 const char *mp = name;
202 char *ep; 202 char *ep;
203 203
204 while (*mp) { /* scan list of module names */ 204 while (*mp) { /* scan list of module names */
205 i = MAXMODNAME; 205 i = MAXMODNAME;
206 ep = mod_name; 206 ep = mod_name;
207 while (--i) { /* scan for end of first name */ 207 while (--i) { /* scan for end of first name */
208 *ep = *mp; 208 *ep = *mp;
209 if (*ep == '/') /* NUL-terminate the name */ 209 if (*ep == '/') /* NUL-terminate the name */
210 *ep = '\0'; 210 *ep = '\0';
211 211
212 if (*ep == 0 ) { /* add non-empty name */ 212 if (*ep == 0 ) { /* add non-empty name */
213 if (ep != mod_name) 213 if (ep != mod_name)
214 module_add_common(mod_name, type); 214 module_add_common(mod_name, type);
215 break; 215 break;
216 } 216 }
217 ep++; mp++; 217 ep++; mp++;
218 } 218 }
219 if (*ep != 0) { 219 if (*ep != 0) {
220 printf("module name too long\n"); 220 printf("module name too long\n");
221 return; 221 return;
222 } 222 }
223 if (*mp == '/') { /* skip separator if more */ 223 if (*mp == '/') { /* skip separator if more */
224 mp++; 224 mp++;
225 } 225 }
226 } 226 }
227} 227}
228 228
229static void 229static void
230module_add_common(const char *name, uint8_t type) 230module_add_common(const char *name, uint8_t type)
231{ 231{
232 boot_module_t *bm, *bmp; 232 boot_module_t *bm, *bmp;
233 size_t len; 233 size_t len;
234 char *str; 234 char *str;
235 235
236 while (*name == ' ' || *name == '\t') 236 while (*name == ' ' || *name == '\t')
237 ++name; 237 ++name;
238 238
239 for (bm = boot_modules; bm != NULL; bm = bm->bm_next) 239 for (bm = boot_modules; bm != NULL; bm = bm->bm_next)
240 if (bm->bm_type == type && strcmp(bm->bm_path, name) == 0) 240 if (bm->bm_type == type && strcmp(bm->bm_path, name) == 0)
241 return; 241 return;
242 242
243 bm = alloc(sizeof(boot_module_t)); 243 bm = alloc(sizeof(boot_module_t));
244 len = strlen(name) + 1; 244 len = strlen(name) + 1;
245 str = alloc(len); 245 str = alloc(len);
246 if (bm == NULL || str == NULL) { 246 if (bm == NULL || str == NULL) {
247 printf("couldn't allocate module\n"); 247 printf("couldn't allocate module\n");
248 return; 248 return;
249 } 249 }
250 memcpy(str, name, len); 250 memcpy(str, name, len);
251 bm->bm_path = str; 251 bm->bm_path = str;
252 bm->bm_next = NULL; 252 bm->bm_next = NULL;
253 bm->bm_type = type; 253 bm->bm_type = type;
254 if (boot_modules == NULL) 254 if (boot_modules == NULL)
255 boot_modules = bm; 255 boot_modules = bm;
256 else { 256 else {
257 for (bmp = boot_modules; bmp->bm_next; 257 for (bmp = boot_modules; bmp->bm_next;
258 bmp = bmp->bm_next) 258 bmp = bmp->bm_next)
259 ; 259 ;
260 bmp->bm_next = bm; 260 bmp->bm_next = bm;
261 } 261 }
262} 262}
263 263
264void 264void
265userconf_add(char *cmd) 265userconf_add(char *cmd)
266{ 266{
267 userconf_command_t *uc; 267 userconf_command_t *uc;
268 size_t len; 268 size_t len;
269 char *text; 269 char *text;
270 270
271 while (*cmd == ' ' || *cmd == '\t') 271 while (*cmd == ' ' || *cmd == '\t')
272 ++cmd; 272 ++cmd;
273 273
274 uc = alloc(sizeof(*uc)); 274 uc = alloc(sizeof(*uc));
275 if (uc == NULL) { 275 if (uc == NULL) {
276 printf("couldn't allocate command\n"); 276 printf("couldn't allocate command\n");
277 return; 277 return;
278 } 278 }
279 279
280 len = strlen(cmd) + 1; 280 len = strlen(cmd) + 1;
281 text = alloc(len); 281 text = alloc(len);
282 if (text == NULL) { 282 if (text == NULL) {
283 dealloc(uc, sizeof(*uc)); 283 dealloc(uc, sizeof(*uc));
284 printf("couldn't allocate command\n"); 284 printf("couldn't allocate command\n");
285 return; 285 return;
286 } 286 }
287 memcpy(text, cmd, len); 287 memcpy(text, cmd, len);
288 288
289 uc->uc_text = text; 289 uc->uc_text = text;
290 uc->uc_len = len; 290 uc->uc_len = len;
291 uc->uc_next = NULL; 291 uc->uc_next = NULL;
292 292
293 if (userconf_commands == NULL) 293 if (userconf_commands == NULL)
294 userconf_commands = uc; 294 userconf_commands = uc;
295 else { 295 else {
296 userconf_command_t *ucp; 296 userconf_command_t *ucp;
297 for (ucp = userconf_commands; ucp->uc_next != NULL; 297 for (ucp = userconf_commands; ucp->uc_next != NULL;
298 ucp = ucp->uc_next) 298 ucp = ucp->uc_next)
299 ; 299 ;
300 ucp->uc_next = uc; 300 ucp->uc_next = uc;
301 } 301 }
302} 302}
303 303
304struct btinfo_prekern bi_prekern; 304struct btinfo_prekern bi_prekern;
305int has_prekern = 0; 305int has_prekern = 0;
306 306
307static int 307static int
308common_load_prekern(const char *file, u_long *basemem, u_long *extmem, 308common_load_prekern(const char *file, u_long *basemem, u_long *extmem,
309 physaddr_t loadaddr, int floppy, u_long marks[MARK_MAX]) 309 physaddr_t loadaddr, int floppy, u_long marks[MARK_MAX])
310{ 310{
311 paddr_t kernpa_start, kernpa_end; 311 paddr_t kernpa_start, kernpa_end;
312 char prekernpath[] = "/prekern"; 312 char prekernpath[] = "/prekern";
313 u_long prekern_start; 313 u_long prekern_start;
314 int fd, flags; 314 int fd, flags;
315 315
316 *extmem = getextmem(); 316 *extmem = getextmem();
317 *basemem = getbasemem(); 317 *basemem = getbasemem();
318 318
319 marks[MARK_START] = loadaddr; 319 marks[MARK_START] = loadaddr;
320 320
321 /* Load the prekern (static) */ 321 /* Load the prekern (static) */
322 flags = LOAD_KERNEL & ~(LOAD_HDR|LOAD_SYM); 322 flags = LOAD_KERNEL & ~(LOAD_HDR|LOAD_SYM);
323 if ((fd = loadfile(prekernpath, marks, flags)) == -1) 323 if ((fd = loadfile(prekernpath, marks, flags)) == -1)
324 return EIO; 324 return errno;
325 close(fd); 325 close(fd);
326 326
327 prekern_start = marks[MARK_START]; 327 prekern_start = marks[MARK_START];
328 328
329 /* The kernel starts at 2MB. */ 329 /* The kernel starts at 2MB. */
330 marks[MARK_START] = loadaddr; 330 marks[MARK_START] = loadaddr;
331 marks[MARK_END] = loadaddr + (1UL << 21); 331 marks[MARK_END] = loadaddr + (1UL << 21);
332 kernpa_start = (1UL << 21); 332 kernpa_start = (1UL << 21);
333 333
334 /* Load the kernel (dynamic) */ 334 /* Load the kernel (dynamic) */
335 flags = (LOAD_KERNEL | LOAD_DYN) & ~(floppy ? LOAD_BACKWARDS : 0); 335 flags = (LOAD_KERNEL | LOAD_DYN) & ~(floppy ? LOAD_BACKWARDS : 0);
336 if ((fd = loadfile(file, marks, flags)) == -1) 336 if ((fd = loadfile(file, marks, flags)) == -1)
337 return EIO; 337 return errno;
338 close(fd); 338 close(fd);
339 339
340 kernpa_end = marks[MARK_END] - loadaddr; 340 kernpa_end = marks[MARK_END] - loadaddr;
341 341
342 /* If the root fs type is unusual, load its module. */ 342 /* If the root fs type is unusual, load its module. */
343 if (fsmod != NULL) 343 if (fsmod != NULL)
344 module_add_split(fsmod, BM_TYPE_KMOD); 344 module_add_split(fsmod, BM_TYPE_KMOD);
345 345
346 bi_prekern.kernpa_start = kernpa_start; 346 bi_prekern.kernpa_start = kernpa_start;
347 bi_prekern.kernpa_end = kernpa_end; 347 bi_prekern.kernpa_end = kernpa_end;
348 BI_ADD(&bi_prekern, BTINFO_PREKERN, sizeof(struct btinfo_prekern)); 348 BI_ADD(&bi_prekern, BTINFO_PREKERN, sizeof(struct btinfo_prekern));
349 349
350 /* 350 /*
351 * Gather some information for the kernel. Do this after the 351 * Gather some information for the kernel. Do this after the
352 * "point of no return" to avoid memory leaks. 352 * "point of no return" to avoid memory leaks.
353 * (but before DOS might be trashed in the XMS case) 353 * (but before DOS might be trashed in the XMS case)
354 */ 354 */
355#ifdef PASS_BIOSGEOM 355#ifdef PASS_BIOSGEOM
356 bi_getbiosgeom(); 356 bi_getbiosgeom();
357#endif 357#endif
358#ifdef PASS_MEMMAP 358#ifdef PASS_MEMMAP
359 bi_getmemmap(); 359 bi_getmemmap();
360#endif 360#endif
361 361
362 marks[MARK_START] = prekern_start; 362 marks[MARK_START] = prekern_start;
363 marks[MARK_END] = (((u_long)marks[MARK_END] + sizeof(int) - 1)) & 363 marks[MARK_END] = (((u_long)marks[MARK_END] + sizeof(int) - 1)) &
364 (-sizeof(int)); 364 (-sizeof(int));
365 image_end = marks[MARK_END]; 365 image_end = marks[MARK_END];
366 kernel_loaded = true; 366 kernel_loaded = true;
367 367
368 return 0; 368 return 0;
369} 369}
370 370
371static int 371static int
372common_load_kernel(const char *file, u_long *basemem, u_long *extmem, 372common_load_kernel(const char *file, u_long *basemem, u_long *extmem,
373 physaddr_t loadaddr, int floppy, u_long marks[MARK_MAX]) 373 physaddr_t loadaddr, int floppy, u_long marks[MARK_MAX])
374{ 374{
375 int fd; 375 int fd;
376#ifdef XMS 376#ifdef XMS
377 u_long xmsmem; 377 u_long xmsmem;
378 physaddr_t origaddr = loadaddr; 378 physaddr_t origaddr = loadaddr;
379#endif 379#endif
380 380
381 *extmem = getextmem(); 381 *extmem = getextmem();
382 *basemem = getbasemem(); 382 *basemem = getbasemem();
383 383
384#ifdef XMS 384#ifdef XMS
385 if ((getextmem1() == 0) && (xmsmem = checkxms())) { 385 if ((getextmem1() == 0) && (xmsmem = checkxms())) {
386 u_long kernsize; 386 u_long kernsize;
387 387
388 /* 388 /*
389 * With "CONSERVATIVE_MEMDETECT", extmem is 0 because 389 * With "CONSERVATIVE_MEMDETECT", extmem is 0 because
390 * getextmem() is getextmem1(). Without, the "smart" 390 * getextmem() is getextmem1(). Without, the "smart"
391 * methods could fail to report all memory as well. 391 * methods could fail to report all memory as well.
392 * xmsmem is a few kB less than the actual size, but 392 * xmsmem is a few kB less than the actual size, but
393 * better than nothing. 393 * better than nothing.
394 */ 394 */
395 if (xmsmem > *extmem) 395 if (xmsmem > *extmem)
396 *extmem = xmsmem; 396 *extmem = xmsmem;
397 /* 397 /*
398 * Get the size of the kernel 398 * Get the size of the kernel
399 */ 399 */
400 marks[MARK_START] = loadaddr; 400 marks[MARK_START] = loadaddr;
401 if ((fd = loadfile(file, marks, COUNT_KERNEL)) == -1) 401 if ((fd = loadfile(file, marks, COUNT_KERNEL)) == -1)
402 return EIO; 402 return errno;
403 close(fd); 403 close(fd);
404 404
405 kernsize = marks[MARK_END]; 405 kernsize = marks[MARK_END];
406 kernsize = (kernsize + 1023) / 1024; 406 kernsize = (kernsize + 1023) / 1024;
407 407
408 loadaddr = xmsalloc(kernsize); 408 loadaddr = xmsalloc(kernsize);
409 if (!loadaddr) 409 if (!loadaddr)
410 return ENOMEM; 410 return ENOMEM;
411 } 411 }
412#endif 412#endif
413 marks[MARK_START] = loadaddr; 413 marks[MARK_START] = loadaddr;
414 if ((fd = loadfile(file, marks, 414 if ((fd = loadfile(file, marks,
415 LOAD_KERNEL & ~(floppy ? LOAD_BACKWARDS : 0))) == -1) 415 LOAD_KERNEL & ~(floppy ? LOAD_BACKWARDS : 0))) == -1)
416 return EIO; 416 return errno;
417 417
418 close(fd); 418 close(fd);
419 419
420 /* If the root fs type is unusual, load its module. */ 420 /* If the root fs type is unusual, load its module. */
421 if (fsmod != NULL) 421 if (fsmod != NULL)
422 module_add_split(fsmod, BM_TYPE_KMOD); 422 module_add_split(fsmod, BM_TYPE_KMOD);
423 423
424 /* 424 /*
425 * Gather some information for the kernel. Do this after the 425 * Gather some information for the kernel. Do this after the
426 * "point of no return" to avoid memory leaks. 426 * "point of no return" to avoid memory leaks.
427 * (but before DOS might be trashed in the XMS case) 427 * (but before DOS might be trashed in the XMS case)
428 */ 428 */
429#ifdef PASS_BIOSGEOM 429#ifdef PASS_BIOSGEOM
430 bi_getbiosgeom(); 430 bi_getbiosgeom();
431#endif 431#endif
432#ifdef PASS_MEMMAP 432#ifdef PASS_MEMMAP
433 bi_getmemmap(); 433 bi_getmemmap();
434#endif 434#endif
435 435
436#ifdef XMS 436#ifdef XMS
437 if (loadaddr != origaddr) { 437 if (loadaddr != origaddr) {
438 /* 438 /*
439 * We now have done our last DOS IO, so we may 439 * We now have done our last DOS IO, so we may
440 * trash the OS. Copy the data from the temporary 440 * trash the OS. Copy the data from the temporary
441 * buffer to its real address. 441 * buffer to its real address.
442 */ 442 */
443 marks[MARK_START] -= loadaddr; 443 marks[MARK_START] -= loadaddr;
444 marks[MARK_END] -= loadaddr; 444 marks[MARK_END] -= loadaddr;
445 marks[MARK_SYM] -= loadaddr; 445 marks[MARK_SYM] -= loadaddr;
446 marks[MARK_END] -= loadaddr; 446 marks[MARK_END] -= loadaddr;
447 ppbcopy(loadaddr, origaddr, marks[MARK_END]); 447 ppbcopy(loadaddr, origaddr, marks[MARK_END]);
448 } 448 }
449#endif 449#endif
450 marks[MARK_END] = (((u_long) marks[MARK_END] + sizeof(int) - 1)) & 450 marks[MARK_END] = (((u_long) marks[MARK_END] + sizeof(int) - 1)) &
451 (-sizeof(int)); 451 (-sizeof(int));
452 image_end = marks[MARK_END]; 452 image_end = marks[MARK_END];
453 kernel_loaded = true; 453 kernel_loaded = true;
454 454
455 return 0; 455 return 0;
456} 456}
457 457
458int 458int
459exec_netbsd(const char *file, physaddr_t loadaddr, int boothowto, int floppy, 459exec_netbsd(const char *file, physaddr_t loadaddr, int boothowto, int floppy,
460 void (*callback)(void)) 460 void (*callback)(void))
461{ 461{
462 uint32_t boot_argv[BOOT_NARGS]; 462 uint32_t boot_argv[BOOT_NARGS];
463 u_long marks[MARK_MAX]; 463 u_long marks[MARK_MAX];
464 struct btinfo_symtab btinfo_symtab; 464 struct btinfo_symtab btinfo_symtab;
465 u_long extmem; 465 u_long extmem;
466 u_long basemem; 466 u_long basemem;
467 int error; 467 int error;
468#ifdef EFIBOOT 468#ifdef EFIBOOT
469 int i; 469 int i;
470#endif 470#endif
471 471
472#ifdef DEBUG 472#ifdef DEBUG
473 printf("exec: file=%s loadaddr=0x%lx\n", file ? file : "NULL", 473 printf("exec: file=%s loadaddr=0x%lx\n", file ? file : "NULL",
474 loadaddr); 474 loadaddr);
475#endif 475#endif
476 476
477 BI_ALLOC(BTINFO_MAX); 477 BI_ALLOC(BTINFO_MAX);
478 478
479 BI_ADD(&btinfo_console, BTINFO_CONSOLE, sizeof(struct btinfo_console)); 479 BI_ADD(&btinfo_console, BTINFO_CONSOLE, sizeof(struct btinfo_console));
480 480
481 howto = boothowto; 481 howto = boothowto;
482 482
483 memset(marks, 0, sizeof(marks)); 483 memset(marks, 0, sizeof(marks));
484 484
485 if (has_prekern) { 485 if (has_prekern) {
486 error = common_load_prekern(file, &basemem, &extmem, loadaddr, 486 error = common_load_prekern(file, &basemem, &extmem, loadaddr,
487 floppy, marks); 487 floppy, marks);
488 } else { 488 } else {
489 error = common_load_kernel(file, &basemem, &extmem, loadaddr, 489 error = common_load_kernel(file, &basemem, &extmem, loadaddr,
490 floppy, marks); 490 floppy, marks);
491 } 491 }
492 if (error) { 492 if (error) {
493 errno = error; 493 errno = error;
494 goto out; 494 goto out;
495 } 495 }
496#ifdef EFIBOOT 496#ifdef EFIBOOT
497 /* adjust to the real load address */ 497 /* adjust to the real load address */
498 marks[MARK_START] -= efi_loadaddr; 498 marks[MARK_START] -= efi_loadaddr;
499 marks[MARK_ENTRY] -= efi_loadaddr; 499 marks[MARK_ENTRY] -= efi_loadaddr;
500 marks[MARK_DATA] -= efi_loadaddr; 500 marks[MARK_DATA] -= efi_loadaddr;
501 /* MARK_NSYM */ 501 /* MARK_NSYM */
502 marks[MARK_SYM] -= efi_loadaddr; 502 marks[MARK_SYM] -= efi_loadaddr;
503 marks[MARK_END] -= efi_loadaddr; 503 marks[MARK_END] -= efi_loadaddr;
504#endif 504#endif
505 505
506 boot_argv[0] = boothowto; 506 boot_argv[0] = boothowto;
507 boot_argv[1] = 0; 507 boot_argv[1] = 0;
508 boot_argv[2] = vtophys(bootinfo); /* old cyl offset */ 508 boot_argv[2] = vtophys(bootinfo); /* old cyl offset */
509 boot_argv[3] = marks[MARK_END]; 509 boot_argv[3] = marks[MARK_END];
510 boot_argv[4] = extmem; 510 boot_argv[4] = extmem;
511 boot_argv[5] = basemem; 511 boot_argv[5] = basemem;
512 512
513 /* pull in any modules if necessary */ 513 /* pull in any modules if necessary */
514 if (boot_modules_enabled) { 514 if (boot_modules_enabled) {
515 module_init(file); 515 module_init(file);
516 if (btinfo_modulelist) { 516 if (btinfo_modulelist) {
517#ifdef EFIBOOT 517#ifdef EFIBOOT
518 /* convert module loaded address to paddr */ 518 /* convert module loaded address to paddr */
519 struct bi_modulelist_entry *bim; 519 struct bi_modulelist_entry *bim;
520 bim = (void *)(btinfo_modulelist + 1); 520 bim = (void *)(btinfo_modulelist + 1);
521 for (i = 0; i < btinfo_modulelist->num; i++, bim++) 521 for (i = 0; i < btinfo_modulelist->num; i++, bim++)
522 bim->base -= efi_loadaddr; 522 bim->base -= efi_loadaddr;
523 btinfo_modulelist->endpa -= efi_loadaddr; 523 btinfo_modulelist->endpa -= efi_loadaddr;
524#endif 524#endif
525 BI_ADD(btinfo_modulelist, BTINFO_MODULELIST, 525 BI_ADD(btinfo_modulelist, BTINFO_MODULELIST,
526 btinfo_modulelist_size); 526 btinfo_modulelist_size);
527 } 527 }
528 } 528 }
529 529
530 userconf_init(); 530 userconf_init();
531 if (btinfo_userconfcommands != NULL) 531 if (btinfo_userconfcommands != NULL)
532 BI_ADD(btinfo_userconfcommands, BTINFO_USERCONFCOMMANDS, 532 BI_ADD(btinfo_userconfcommands, BTINFO_USERCONFCOMMANDS,
533 btinfo_userconfcommands_size); 533 btinfo_userconfcommands_size);
534 534
535#ifdef DEBUG 535#ifdef DEBUG
536 printf("Start @ 0x%lx [%ld=0x%lx-0x%lx]...\n", marks[MARK_ENTRY], 536 printf("Start @ 0x%lx [%ld=0x%lx-0x%lx]...\n", marks[MARK_ENTRY],
537 marks[MARK_NSYM], marks[MARK_SYM], marks[MARK_END]); 537 marks[MARK_NSYM], marks[MARK_SYM], marks[MARK_END]);
538#endif 538#endif
539 539
540 btinfo_symtab.nsym = marks[MARK_NSYM]; 540 btinfo_symtab.nsym = marks[MARK_NSYM];
541 btinfo_symtab.ssym = marks[MARK_SYM]; 541 btinfo_symtab.ssym = marks[MARK_SYM];
542 btinfo_symtab.esym = marks[MARK_END]; 542 btinfo_symtab.esym = marks[MARK_END];
543 BI_ADD(&btinfo_symtab, BTINFO_SYMTAB, sizeof(struct btinfo_symtab)); 543 BI_ADD(&btinfo_symtab, BTINFO_SYMTAB, sizeof(struct btinfo_symtab));
544 544
545 /* set new video mode if necessary */ 545 /* set new video mode if necessary */
546 vbe_commit(); 546 vbe_commit();
547 BI_ADD(&btinfo_framebuffer, BTINFO_FRAMEBUFFER, 547 BI_ADD(&btinfo_framebuffer, BTINFO_FRAMEBUFFER,
548 sizeof(struct btinfo_framebuffer)); 548 sizeof(struct btinfo_framebuffer));
549 549
550 if (callback != NULL) 550 if (callback != NULL)
551 (*callback)(); 551 (*callback)();
552#ifdef EFIBOOT 552#ifdef EFIBOOT
553 /* Copy bootinfo to safe arena. */ 553 /* Copy bootinfo to safe arena. */
554 for (i = 0; i < bootinfo->nentries; i++) { 554 for (i = 0; i < bootinfo->nentries; i++) {
555 struct btinfo_common *bi = (void *)(u_long)bootinfo->entry[i]; 555 struct btinfo_common *bi = (void *)(u_long)bootinfo->entry[i];
556 char *p = alloc(bi->len); 556 char *p = alloc(bi->len);
557 memcpy(p, bi, bi->len); 557 memcpy(p, bi, bi->len);
558 bootinfo->entry[i] = vtophys(p); 558 bootinfo->entry[i] = vtophys(p);
559 } 559 }
560 560
561 efi_kernel_start = marks[MARK_START]; 561 efi_kernel_start = marks[MARK_START];
562 efi_kernel_size = image_end - (efi_loadaddr + efi_kernel_start); 562 efi_kernel_size = image_end - (efi_loadaddr + efi_kernel_start);
563#endif 563#endif
564 startprog(marks[MARK_ENTRY], BOOT_NARGS, boot_argv, 564 startprog(marks[MARK_ENTRY], BOOT_NARGS, boot_argv,
565 x86_trunc_page(basemem * 1024)); 565 x86_trunc_page(basemem * 1024));
566 panic("exec returned"); 566 panic("exec returned");
567 567
568out: 568out:
569 BI_FREE(); 569 BI_FREE();
570 bootinfo = NULL; 570 bootinfo = NULL;
571 return -1; 571 return -1;
572} 572}
573 573
574static void 574static void
575extract_device(const char *path, char *buf, size_t buflen) 575extract_device(const char *path, char *buf, size_t buflen)
576{ 576{
577 size_t i; 577 size_t i;
578 578
579 if (strchr(path, ':') != NULL) { 579 if (strchr(path, ':') != NULL) {
580 for (i = 0; i < buflen - 2 && path[i] != ':'; i++) 580 for (i = 0; i < buflen - 2 && path[i] != ':'; i++)
581 buf[i] = path[i]; 581 buf[i] = path[i];
582 buf[i++] = ':'; 582 buf[i++] = ':';
583 buf[i] = '\0'; 583 buf[i] = '\0';
584 } else 584 } else
585 buf[0] = '\0'; 585 buf[0] = '\0';
586} 586}
587 587
588static const char * 588static const char *
589module_path(boot_module_t *bm, const char *kdev, const char *base_path) 589module_path(boot_module_t *bm, const char *kdev, const char *base_path)
590{ 590{
591 static char buf[256]; 591 static char buf[256];
592 char name_buf[256], dev_buf[64]; 592 char name_buf[256], dev_buf[64];
593 const char *name, *name2, *p; 593 const char *name, *name2, *p;
594 594
595 name = bm->bm_path; 595 name = bm->bm_path;
596 for (name2 = name; *name2; ++name2) { 596 for (name2 = name; *name2; ++name2) {
597 if (*name2 == ' ' || *name2 == '\t') { 597 if (*name2 == ' ' || *name2 == '\t') {
598 strlcpy(name_buf, name, sizeof(name_buf)); 598 strlcpy(name_buf, name, sizeof(name_buf));
599 if ((uintptr_t)name2 - (uintptr_t)name < sizeof(name_buf)) 599 if ((uintptr_t)name2 - (uintptr_t)name < sizeof(name_buf))
600 name_buf[name2 - name] = '\0'; 600 name_buf[name2 - name] = '\0';
601 name = name_buf; 601 name = name_buf;
602 break; 602 break;
603 } 603 }
604 } 604 }
605 if ((p = strchr(name, ':')) != NULL) { 605 if ((p = strchr(name, ':')) != NULL) {
606 /* device specified, use it */ 606 /* device specified, use it */
607 if (p[1] == '/') 607 if (p[1] == '/')
608 snprintf(buf, sizeof(buf), "%s", name); 608 snprintf(buf, sizeof(buf), "%s", name);
609 else { 609 else {
610 p++; 610 p++;
611 extract_device(name, dev_buf, sizeof(dev_buf)); 611 extract_device(name, dev_buf, sizeof(dev_buf));
612 snprintf(buf, sizeof(buf), "%s%s/%s/%s.kmod", 612 snprintf(buf, sizeof(buf), "%s%s/%s/%s.kmod",
613 dev_buf, base_path, p, p); 613 dev_buf, base_path, p, p);
614 } 614 }
615 } else { 615 } else {
616 /* device not specified; load from kernel device if known */ 616 /* device not specified; load from kernel device if known */
617 if (name[0] == '/') 617 if (name[0] == '/')
618 snprintf(buf, sizeof(buf), "%s%s", kdev, name); 618 snprintf(buf, sizeof(buf), "%s%s", kdev, name);
619 else 619 else
620 snprintf(buf, sizeof(buf), "%s%s/%s/%s.kmod", 620 snprintf(buf, sizeof(buf), "%s%s/%s/%s.kmod",
621 kdev, base_path, name, name); 621 kdev, base_path, name, name);
622 } 622 }
623 623
624 return buf; 624 return buf;
625} 625}
626 626
627static int 627static int
628module_open(boot_module_t *bm, int mode, const char *kdev, 628module_open(boot_module_t *bm, int mode, const char *kdev,
629 const char *base_path, bool doload) 629 const char *base_path, bool doload)
630{ 630{
631 int fd; 631 int fd;
632 const char *path; 632 const char *path;
633 633
634 /* check the expanded path first */ 634 /* check the expanded path first */
635 path = module_path(bm, kdev, base_path); 635 path = module_path(bm, kdev, base_path);
636 fd = open(path, mode); 636 fd = open(path, mode);
637 if (fd != -1) { 637 if (fd != -1) {
638 if ((howto & AB_SILENT) == 0 && doload) 638 if ((howto & AB_SILENT) == 0 && doload)
639 printf("Loading %s ", path); 639 printf("Loading %s ", path);
640 } else { 640 } else {
641 /* now attempt the raw path provided */ 641 /* now attempt the raw path provided */
642 fd = open(bm->bm_path, mode); 642 fd = open(bm->bm_path, mode);
643 if (fd != -1 && (howto & AB_SILENT) == 0 && doload) 643 if (fd != -1 && (howto & AB_SILENT) == 0 && doload)
644 printf("Loading %s ", bm->bm_path); 644 printf("Loading %s ", bm->bm_path);
645 } 645 }
646 if (!doload && fd == -1) { 646 if (!doload && fd == -1) {
647 printf("WARNING: couldn't open %s", bm->bm_path); 647 printf("WARNING: couldn't open %s", bm->bm_path);
648 if (strcmp(bm->bm_path, path) != 0) 648 if (strcmp(bm->bm_path, path) != 0)
649 printf(" (%s)", path); 649 printf(" (%s)", path);
650 printf("\n"); 650 printf("\n");
651 } 651 }
652 return fd; 652 return fd;
653} 653}
654 654
655static void 655static void
656module_base_path(char *buf, size_t bufsize) 656module_base_path(char *buf, size_t bufsize)
657{ 657{
658 const char *machine; 658 const char *machine;
659 659
660 switch (netbsd_elf_class) { 660 switch (netbsd_elf_class) {
661 case ELFCLASS32: 661 case ELFCLASS32:
662 machine = "i386"; 662 machine = "i386";
663 break; 663 break;
664 case ELFCLASS64: 664 case ELFCLASS64:
665 machine = "amd64"; 665 machine = "amd64";
666 break; 666 break;
667 default: 667 default:
668 machine = "generic"; 668 machine = "generic";
669 break; 669 break;
670 } 670 }
671 if (netbsd_version / 1000000 % 100 == 99) { 671 if (netbsd_version / 1000000 % 100 == 99) {
672 /* -current */ 672 /* -current */
673 snprintf(buf, bufsize, 673 snprintf(buf, bufsize,
674 "/stand/%s/%d.%d.%d/modules", machine, 674 "/stand/%s/%d.%d.%d/modules", machine,
675 netbsd_version / 100000000, 675 netbsd_version / 100000000,
676 netbsd_version / 1000000 % 100, 676 netbsd_version / 1000000 % 100,
677 netbsd_version / 100 % 100); 677 netbsd_version / 100 % 100);
678 } else if (netbsd_version != 0) { 678 } else if (netbsd_version != 0) {
679 /* release */ 679 /* release */
680 snprintf(buf, bufsize, 680 snprintf(buf, bufsize,
681 "/stand/%s/%d.%d/modules", machine, 681 "/stand/%s/%d.%d/modules", machine,
682 netbsd_version / 100000000, 682 netbsd_version / 100000000,
683 netbsd_version / 1000000 % 100); 683 netbsd_version / 1000000 % 100);
684 } 684 }
685} 685}
686 686
687static void 687static void
688module_init(const char *kernel_path) 688module_init(const char *kernel_path)
689{ 689{
690 struct bi_modulelist_entry *bi; 690 struct bi_modulelist_entry *bi;
691 struct stat st; 691 struct stat st;
692 char kdev[64]; 692 char kdev[64];
693 char *buf; 693 char *buf;
694 boot_module_t *bm; 694 boot_module_t *bm;
695 ssize_t len; 695 ssize_t len;
696 off_t off; 696 off_t off;
697 int err, fd, nfail = 0; 697 int err, fd, nfail = 0;
698 698
699 extract_device(kernel_path, kdev, sizeof(kdev)); 699 extract_device(kernel_path, kdev, sizeof(kdev));
700 module_base_path(module_base, sizeof(module_base)); 700 module_base_path(module_base, sizeof(module_base));
701 701
702 /* First, see which modules are valid and calculate btinfo size */ 702 /* First, see which modules are valid and calculate btinfo size */
703 len = sizeof(struct btinfo_modulelist); 703 len = sizeof(struct btinfo_modulelist);
704 for (bm = boot_modules; bm; bm = bm->bm_next) { 704 for (bm = boot_modules; bm; bm = bm->bm_next) {
705 fd = module_open(bm, 0, kdev, module_base, false); 705 fd = module_open(bm, 0, kdev, module_base, false);
706 if (fd == -1) { 706 if (fd == -1) {
707 bm->bm_len = -1; 707 bm->bm_len = -1;
708 ++nfail; 708 ++nfail;
709 continue; 709 continue;
710 } 710 }
711 err = fstat(fd, &st); 711 err = fstat(fd, &st);
712 if (err == -1 || st.st_size == -1) { 712 if (err == -1 || st.st_size == -1) {
713 printf("WARNING: couldn't stat %s\n", bm->bm_path); 713 printf("WARNING: couldn't stat %s\n", bm->bm_path);
714 close(fd); 714 close(fd);
715 bm->bm_len = -1; 715 bm->bm_len = -1;
716 ++nfail; 716 ++nfail;
717 continue; 717 continue;
718 } 718 }
719 bm->bm_len = st.st_size; 719 bm->bm_len = st.st_size;
720 close(fd); 720 close(fd);
721 len += sizeof(struct bi_modulelist_entry); 721 len += sizeof(struct bi_modulelist_entry);
722 } 722 }
723 723
724 /* Allocate the module list */ 724 /* Allocate the module list */
725 btinfo_modulelist = alloc(len); 725 btinfo_modulelist = alloc(len);
726 if (btinfo_modulelist == NULL) { 726 if (btinfo_modulelist == NULL) {
727 printf("WARNING: couldn't allocate module list\n"); 727 printf("WARNING: couldn't allocate module list\n");
728 wait_sec(MODULE_WARNING_SEC); 728 wait_sec(MODULE_WARNING_SEC);
729 return; 729 return;
730 } 730 }
731 memset(btinfo_modulelist, 0, len); 731 memset(btinfo_modulelist, 0, len);
732 btinfo_modulelist_size = len; 732 btinfo_modulelist_size = len;
733 733
734 /* Fill in btinfo structure */ 734 /* Fill in btinfo structure */
735 buf = (char *)btinfo_modulelist; 735 buf = (char *)btinfo_modulelist;
736 btinfo_modulelist->num = 0; 736 btinfo_modulelist->num = 0;
737 off = sizeof(struct btinfo_modulelist); 737 off = sizeof(struct btinfo_modulelist);
738 738
739 for (bm = boot_modules; bm; bm = bm->bm_next) { 739 for (bm = boot_modules; bm; bm = bm->bm_next) {
740 if (bm->bm_len == -1) 740 if (bm->bm_len == -1)
741 continue; 741 continue;
742 fd = module_open(bm, 0, kdev, module_base, true); 742 fd = module_open(bm, 0, kdev, module_base, true);
743 if (fd == -1) 743 if (fd == -1)
744 continue; 744 continue;
745 image_end = (image_end + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); 745 image_end = (image_end + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
746 len = pread(fd, (void *)(uintptr_t)image_end, SSIZE_MAX); 746 len = pread(fd, (void *)(uintptr_t)image_end, SSIZE_MAX);
747 if (len < bm->bm_len) { 747 if (len < bm->bm_len) {
748 if ((howto & AB_SILENT) != 0) 748 if ((howto & AB_SILENT) != 0)
749 printf("Loading %s ", bm->bm_path); 749 printf("Loading %s ", bm->bm_path);
750 printf(" FAILED\n"); 750 printf(" FAILED\n");
751 } else { 751 } else {
752 btinfo_modulelist->num++; 752 btinfo_modulelist->num++;
753 bi = (struct bi_modulelist_entry *)(buf + off); 753 bi = (struct bi_modulelist_entry *)(buf + off);
754 off += sizeof(struct bi_modulelist_entry); 754 off += sizeof(struct bi_modulelist_entry);
755 strncpy(bi->path, bm->bm_path, sizeof(bi->path) - 1); 755 strncpy(bi->path, bm->bm_path, sizeof(bi->path) - 1);
756 bi->base = image_end; 756 bi->base = image_end;
757 bi->len = len; 757 bi->len = len;
758 switch (bm->bm_type) { 758 switch (bm->bm_type) {
759 case BM_TYPE_KMOD: 759 case BM_TYPE_KMOD:
760 bi->type = BI_MODULE_ELF; 760 bi->type = BI_MODULE_ELF;
761 break; 761 break;
762 case BM_TYPE_IMAGE: 762 case BM_TYPE_IMAGE:
763 bi->type = BI_MODULE_IMAGE; 763 bi->type = BI_MODULE_IMAGE;
764 break; 764 break;
765 case BM_TYPE_FS: 765 case BM_TYPE_FS:
766 bi->type = BI_MODULE_FS; 766 bi->type = BI_MODULE_FS;
767 break; 767 break;
768 case BM_TYPE_RND: 768 case BM_TYPE_RND:
769 default: 769 default:
770 /* safest -- rnd checks the sha1 */ 770 /* safest -- rnd checks the sha1 */
771 bi->type = BI_MODULE_RND; 771 bi->type = BI_MODULE_RND;
772 break; 772 break;
773 } 773 }
774 if ((howto & AB_SILENT) == 0) 774 if ((howto & AB_SILENT) == 0)
775 printf(" \n"); 775 printf(" \n");
776 } 776 }
777 if (len > 0) 777 if (len > 0)
778 image_end += len; 778 image_end += len;
779 close(fd); 779 close(fd);
780 } 780 }
781 btinfo_modulelist->endpa = image_end; 781 btinfo_modulelist->endpa = image_end;
782 782
783 if (nfail > 0) { 783 if (nfail > 0) {
784 printf("WARNING: %d module%s failed to load\n", 784 printf("WARNING: %d module%s failed to load\n",
785 nfail, nfail == 1 ? "" : "s"); 785 nfail, nfail == 1 ? "" : "s");
786#if notyet 786#if notyet
787 wait_sec(MODULE_WARNING_SEC); 787 wait_sec(MODULE_WARNING_SEC);
788#endif 788#endif
789 } 789 }
790} 790}
791 791
792static void 792static void
793userconf_init(void) 793userconf_init(void)
794{ 794{
795 size_t count, len; 795 size_t count, len;
796 userconf_command_t *uc; 796 userconf_command_t *uc;
797 char *buf; 797 char *buf;
798 off_t off; 798 off_t off;
799 799
800 /* Calculate the userconf commands list size */ 800 /* Calculate the userconf commands list size */
801 count = 0; 801 count = 0;
802 for (uc = userconf_commands; uc != NULL; uc = uc->uc_next) 802 for (uc = userconf_commands; uc != NULL; uc = uc->uc_next)
803 count++; 803 count++;
804 len = sizeof(*btinfo_userconfcommands) + 804 len = sizeof(*btinfo_userconfcommands) +
805 count * sizeof(struct bi_userconfcommand); 805 count * sizeof(struct bi_userconfcommand);
806 806
807 /* Allocate the userconf commands list */ 807 /* Allocate the userconf commands list */
808 btinfo_userconfcommands = alloc(len); 808 btinfo_userconfcommands = alloc(len);
809 if (btinfo_userconfcommands == NULL) { 809 if (btinfo_userconfcommands == NULL) {
810 printf("WARNING: couldn't allocate userconf commands list\n"); 810 printf("WARNING: couldn't allocate userconf commands list\n");
811 return; 811 return;
812 } 812 }
813 memset(btinfo_userconfcommands, 0, len); 813 memset(btinfo_userconfcommands, 0, len);
814 btinfo_userconfcommands_size = len; 814 btinfo_userconfcommands_size = len;
815 815
816 /* Fill in btinfo structure */ 816 /* Fill in btinfo structure */
817 buf = (char *)btinfo_userconfcommands; 817 buf = (char *)btinfo_userconfcommands;
818 off = sizeof(*btinfo_userconfcommands); 818 off = sizeof(*btinfo_userconfcommands);
819 btinfo_userconfcommands->num = 0; 819 btinfo_userconfcommands->num = 0;
820 for (uc = userconf_commands; uc != NULL; uc = uc->uc_next) { 820 for (uc = userconf_commands; uc != NULL; uc = uc->uc_next) {
821 struct bi_userconfcommand *bi; 821 struct bi_userconfcommand *bi;
822 bi = (struct bi_userconfcommand *)(buf + off); 822 bi = (struct bi_userconfcommand *)(buf + off);
823 strncpy(bi->text, uc->uc_text, sizeof(bi->text) - 1); 823 strncpy(bi->text, uc->uc_text, sizeof(bi->text) - 1);
824 824
825 off += sizeof(*bi); 825 off += sizeof(*bi);
826 btinfo_userconfcommands->num++; 826 btinfo_userconfcommands->num++;
827 } 827 }
828} 828}
829 829
830int 830int
831exec_multiboot(const char *file, char *args) 831exec_multiboot(const char *file, char *args)
832{ 832{
833 physaddr_t loadaddr = 0; 833 physaddr_t loadaddr = 0;
834 u_long marks[MARK_MAX]; 834 u_long marks[MARK_MAX];
835 u_long extmem; 835 u_long extmem;
836 u_long basemem; 836 u_long basemem;
837 struct multiboot_package *mbp = NULL; 837 struct multiboot_package *mbp = NULL;
838 838
839#ifndef NO_MULTIBOOT2 839#ifndef NO_MULTIBOOT2
840 if ((mbp = probe_multiboot2(file)) != NULL) 840 if ((mbp = probe_multiboot2(file)) != NULL)
841 goto is_multiboot; 841 goto is_multiboot;
842#endif 842#endif
843 843
844 if ((mbp = probe_multiboot1(file)) != NULL) { 844 if ((mbp = probe_multiboot1(file)) != NULL) {
845#ifdef EFIBOOT 845#ifdef EFIBOOT
846 printf("EFI boot requires multiboot 2 kernel\n"); 846 printf("EFI boot requires multiboot 2 kernel\n");
847 goto out; 847 goto out;
848#else 848#else
849 goto is_multiboot; 849 goto is_multiboot;
850#endif 850#endif
851 } 851 }
852 852
853#ifndef NO_MULTIBOOT2 853#ifndef NO_MULTIBOOT2
854 printf("%s is not a multiboot kernel\n", file); 854 printf("%s is not a multiboot kernel\n", file);
855#else 855#else
856 printf("%s is not a multiboot 1 kernel " 856 printf("%s is not a multiboot 1 kernel "
857 "(multiboot 2 support is not built in)\n", file); 857 "(multiboot 2 support is not built in)\n", file);
858#endif 858#endif
859 goto out; 859 goto out;
860 860
861is_multiboot: 861is_multiboot:
862#ifdef EFIBOOT 862#ifdef EFIBOOT
863 loadaddr = efi_loadaddr; 863 loadaddr = efi_loadaddr;
864#endif 864#endif
865 if (common_load_kernel(file, &basemem, &extmem, loadaddr, 0, marks)) 865 if (common_load_kernel(file, &basemem, &extmem, loadaddr, 0, marks))
866 goto out; 866 goto out;
867 867
868 if (boot_modules_enabled) 868 if (boot_modules_enabled)
869 module_init(file); 869 module_init(file);
870 870
871 mbp->mbp_args = args; 871 mbp->mbp_args = args;
872 mbp->mbp_basemem = basemem; 872 mbp->mbp_basemem = basemem;
873 mbp->mbp_extmem = extmem; 873 mbp->mbp_extmem = extmem;
874 mbp->mbp_loadaddr = loadaddr; 874 mbp->mbp_loadaddr = loadaddr;
875 mbp->mbp_marks = marks; 875 mbp->mbp_marks = marks;
876 876
877 /* Only returns on error */ 877 /* Only returns on error */
878 (void)mbp->mbp_exec(mbp); 878 (void)mbp->mbp_exec(mbp);
879 879
880out: 880out:
881 if (mbp != NULL) 881 if (mbp != NULL)
882 mbp->mbp_cleanup(mbp); 882 mbp->mbp_cleanup(mbp);
883 883
884 return -1; 884 return -1;
885} 885}
886 886
887void 887void
888x86_progress(const char *fmt, ...) 888x86_progress(const char *fmt, ...)
889{ 889{
890 va_list ap; 890 va_list ap;
891 891
892 if ((howto & AB_SILENT) != 0) 892 if ((howto & AB_SILENT) != 0)
893 return; 893 return;
894 va_start(ap, fmt); 894 va_start(ap, fmt);
895 vprintf(fmt, ap); 895 vprintf(fmt, ap);
896 va_end(ap); 896 va_end(ap);
897} 897}