5 * David Laight. All rights reserved
6 * Copyright (c) 1996, 1997, 1999
7 * Matthias Drochner. All rights reserved.
8 * Copyright (c) 1996, 1997
9 * Perry E. Metzger. All rights reserved.
11 * Jason R. Thorpe. All rights reserved
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 * 3. All advertising materials mentioning features or use of this software
22 * must display the following acknowledgements:
23 * This product includes software developed for the NetBSD Project
24 * by Matthias Drochner.
25 * This product includes software developed for the NetBSD Project
26 * by Perry E. Metzger.
27 * 4. The names of the authors may not be used to endorse or promote products
28 * derived from this software without specific prior written permission.
30 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
31 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
32 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
33 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
34 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
35 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
39 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 /* Based on stand/biosboot/main.c */
44 #include <sys/types.h>
45 #include <sys/reboot.h>
46 #include <sys/bootblock.h>
47 #include <sys/boot_flag.h>
49 #include <lib/libsa/stand.h>
50 #include <lib/libsa/loadfile.h>
51 #include <lib/libsa/ufs.h>
52 #include <lib/libkern/libkern.h>
62 extern struct landisk_boot_params boot_params
;
64 static const char * const names
[][2] = {
65 { "netbsd", "netbsd.gz" },
66 { "netbsd.old", "netbsd.old.gz", },
67 { "onetbsd", "onetbsd.gz" },
70 #define NUMNAMES (sizeof(names) / sizeof(names[0]))
71 #define DEFFILENAME names[0][0]
75 static char *default_devname
;
76 static uint default_unit
, default_partition
;
77 static const char *default_filename
;
79 char *sprint_bootsel(const char *filename
);
80 void bootit(const char *filename
, int howto
, int tell
);
81 void print_banner(void);
82 void boot2(uint32_t boot_biossector
);
84 int exec_netbsd(const char *file
, int howto
);
86 static char *gettrailer(char *arg
);
87 static int parseopts(const char *opts
, int *howto
);
88 static int parseboot(char *arg
, char **filename
, int *howto
);
91 static void bootcmd_help(char *);
92 static void bootcmd_ls(char *);
93 static void bootcmd_quit(char *);
94 static void bootcmd_halt(char *);
95 static void bootcmd_boot(char *);
96 static void bootcmd_monitor(char *);
98 static const struct bootblk_command
{
100 void (*c_fn
)(char *arg
);
102 { "help", bootcmd_help
},
103 { "?", bootcmd_help
},
104 { "ls", bootcmd_ls
},
105 { "quit", bootcmd_quit
},
106 { "halt", bootcmd_halt
},
107 { "boot", bootcmd_boot
},
108 { "!", bootcmd_monitor
},
113 parsebootfile(const char *fname
, char **devname
,
114 uint
*unit
, uint
*partition
, const char **file
)
118 *devname
= default_devname
;
119 *unit
= default_unit
;
120 *partition
= default_partition
;
121 *file
= default_filename
;
126 if((col
= strchr(fname
, ':'))) { /* device given */
127 static char savedevname
[MAXDEVNAME
+1];
129 unsigned int u
= 0, p
= 0;
132 devlen
= col
- fname
;
133 if (devlen
> MAXDEVNAME
)
136 #define isvalidname(c) ((c) >= 'a' && (c) <= 'z')
137 if (!isvalidname(fname
[i
]))
140 savedevname
[i
] = fname
[i
];
142 } while (isvalidname(fname
[i
]));
143 savedevname
[i
] = '\0';
145 #define isnum(c) ((c) >= '0' && (c) <= '9')
147 if (!isnum(fname
[i
]))
151 u
+= fname
[i
++] - '0';
152 } while (isnum(fname
[i
]));
155 #define isvalidpart(c) ((c) >= 'a' && (c) <= 'p')
157 if (!isvalidpart(fname
[i
]))
159 p
= fname
[i
++] - 'a';
165 *devname
= savedevname
;
178 sprint_bootsel(const char *filename
)
182 uint unit
, partition
;
185 if (parsebootfile(filename
, &devname
, &unit
, &partition
, &file
) == 0) {
186 sprintf(buf
, "%s%d%c:%s", devname
, unit
, 'a' + partition
, file
);
189 return ("(invalid)");
193 bootit(const char *filename
, int howto
, int tell
)
197 printf("booting %s", sprint_bootsel(filename
));
199 printf(" (howto 0x%x)", howto
);
203 if (exec_netbsd(filename
, howto
) < 0) {
204 printf("boot: %s: %s\n", sprint_bootsel(filename
),
207 printf("boot returned\n");
214 extern const char bootprog_name
[];
215 extern const char bootprog_rev
[];
216 extern const char bootprog_date
[];
217 extern const char bootprog_maker
[];
220 printf(">> %s, Revision %s\n", bootprog_name
, bootprog_rev
);
221 printf(">> (%s, %s)\n", bootprog_maker
, bootprog_date
);
225 boot2(uint32_t boot_biossector
)
230 /* Initialize hardware */
233 /* Initialize console */
234 cninit(boot_params
.bp_consdev
);
238 /* try to set default device to what BIOS tells us */
239 bios2dev(0x40, &default_devname
, &default_unit
,
240 boot_biossector
, &default_partition
);
242 /* if the user types "boot" without filename */
243 default_filename
= DEFFILENAME
;
245 printf("Press return to boot now, any other key for boot menu\n");
248 printf("booting %s - starting in ",
249 sprint_bootsel(names
[currname
][0]));
251 c
= awaitkey(boot_params
.bp_timeout
, 1);
252 if ((c
!= '\r') && (c
!= '\n') && (c
!= '\0')) {
253 printf("type \"?\" or \"help\" for help.\n");
254 bootmenu(); /* does not return */
258 * try pairs of names[] entries, foo and foo.gz
260 /* don't print "booting..." again */
261 bootit(names
[currname
][0], 0, 0);
262 /* since it failed, try compressed bootfile. */
263 bootit(names
[currname
][1], 0, 1);
264 /* since it failed, try switching bootfile. */
265 currname
= (currname
+ 1) % NUMNAMES
;
270 exec_netbsd(const char *file
, int howto
)
272 static char bibuf
[BOOTINFO_MAXSIZE
];
273 u_long marks
[MARK_MAX
];
276 BI_ALLOC(6); /* XXX */
278 marks
[MARK_START
] = 0; /* loadaddr */
279 if ((fd
= loadfile(file
, marks
, LOAD_KERNEL
)) == -1)
282 printf("Start @ 0x%lx [%ld=0x%lx-0x%lx]...\n", marks
[MARK_ENTRY
],
283 marks
[MARK_NSYM
], marks
[MARK_SYM
], marks
[MARK_END
]);
286 struct btinfo_common
*help
;
291 memcpy(p
, &bootinfo
->nentries
, sizeof(bootinfo
->nentries
));
292 p
+= sizeof(bootinfo
->nentries
);
293 for (i
= 0; i
< bootinfo
->nentries
; i
++) {
294 help
= (struct btinfo_common
*)(bootinfo
->entry
[i
]);
295 memcpy(p
, help
, help
->len
);
303 (*(void (*)(int, void *))marks
[MARK_ENTRY
])(howto
, bibuf
);
304 panic("exec returned");
317 bootcmd_help(char *arg
)
320 printf("commands are:\n"
321 "boot [xdNx:][filename] [-acdqsv]\n"
322 " (ex. \"hd0a:netbsd.old -s\"\n"
330 bootcmd_ls(char *arg
)
332 const char *save
= default_filename
;
334 default_filename
= "/";
336 default_filename
= save
;
341 bootcmd_quit(char *arg
)
344 printf("Exiting...\n");
347 /* Note: we shouldn't get to this point! */
348 panic("Could not reboot!");
354 bootcmd_halt(char *arg
)
357 printf("Exiting...\n");
360 /* Note: we shouldn't get to this point! */
361 panic("Could not halt!");
366 bootcmd_boot(char *arg
)
371 if (parseboot(arg
, &filename
, &howto
)) {
372 bootit(filename
, howto
, 1);
378 bootcmd_monitor(char *arg
)
386 docommand(const struct bootblk_command
* const cmds
, char *arg
)
391 options
= gettrailer(arg
);
393 for (i
= 0; cmds
[i
].c_name
!= NULL
; i
++) {
394 if (strcmp(arg
, cmds
[i
].c_name
) == 0) {
395 (*cmds
[i
].c_fn
)(options
);
400 printf("unknown command\n");
418 * Skip leading whitespace.
424 docommand(bootcmds
, c
);
430 * from arch/i386/stand/lib/parseutil.c
433 * chops the head from the arguments and returns the arguments if any,
434 * or possibly an empty string.
437 gettrailer(char *arg
)
441 if ((options
= strchr(arg
, ' ')) == NULL
)
446 /* trim leading blanks */
447 while (*options
&& *options
== ' ')
454 parseopts(const char *opts
, int *howto
)
459 while (*opts
&& *opts
!= ' ') {
463 printf("-%c: unknown flag\n", *opts
);
476 parseboot(char *arg
, char **filename
, int *howto
)
483 /* if there were no arguments */
488 /* [[xxNx:]filename] [-adqsv] */
490 /* check for just args */
494 /* there's a file name */
497 opts
= gettrailer(arg
);
500 } else if (*opts
!= '-') {
501 printf("invalid arguments\n");
507 /* at this point, we have dealt with filenames. */
509 /* now, deal with options */
511 if (parseopts(opts
, howto
) == 0) {
519 * for common/lib/libc/arch/sh3/gen/udivsi3.S