1 /* $NetBSD: main.c,v 1.28 2009/03/18 10:22:30 cegger Exp $ */
4 * Copyright (c) 1996, 1997
5 * Matthias Drochner. All rights reserved.
6 * Copyright (c) 1996, 1997
7 * Perry E. Metzger. All rights reserved.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgements:
19 * This product includes software developed for the NetBSD Project
20 * by Matthias Drochner.
21 * This product includes software developed for the NetBSD Project
22 * by Perry E. Metzger.
23 * 4. The names of the authors may not be used to endorse or promote products
24 * derived from this software without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 #include <sys/reboot.h>
41 #include <lib/libkern/libkern.h>
42 #include <lib/libsa/stand.h>
43 #include <lib/libsa/ufs.h>
48 extern int exec_lynx(const char*, int);
53 extern char bootprog_name
[], bootprog_rev
[], bootprog_kernrev
[];
57 static char *current_fsmode
;
58 static char *default_devname
;
59 static int default_unit
, default_partition
;
60 static char *default_filename
;
62 char *sprint_bootsel(const char *);
63 static void bootit(const char *, int, int);
65 int main(int, char **);
67 void command_help(char *);
68 void command_ls(char *);
69 void command_quit(char *);
70 void command_boot(char *);
71 void command_mode(char *);
72 void command_dev(char *);
74 const struct bootblk_command commands
[] = {
75 { "help", command_help
},
76 { "?", command_help
},
78 { "quit", command_quit
},
79 { "boot", command_boot
},
80 { "mode", command_mode
},
81 { "dev", command_dev
},
86 parsebootfile(const char *fname
, char **fsmode
, char **devname
, int *unit
, int *partition
, const char **file
)
89 /* unit, *partition: out */
92 const char *col
, *help
;
94 *fsmode
= current_fsmode
;
95 *devname
= default_devname
;
97 *partition
= default_partition
;
98 *file
= default_filename
;
103 if (strcmp(current_fsmode
, "dos") && (col
= strchr(fname
, ':'))) {
104 /* no DOS, device given */
105 static char savedevname
[MAXDEVNAME
+ 1];
107 unsigned int u
= 0, p
= 0;
110 devlen
= col
- fname
;
111 if (devlen
> MAXDEVNAME
)
114 #define isvalidname(c) ((c) >= 'a' && (c) <= 'z')
115 if (!isvalidname(fname
[i
]))
118 savedevname
[i
] = fname
[i
];
120 } while (isvalidname(fname
[i
]));
121 savedevname
[i
] = '\0';
123 #define isnum(c) ((c) >= '0' && (c) <= '9')
125 if (!isnum(fname
[i
]))
129 u
+= fname
[i
++] - '0';
130 } while (isnum(fname
[i
]));
133 #define isvalidpart(c) ((c) >= 'a' && (c) <= 'z')
135 if (!isvalidpart(fname
[i
]))
137 p
= fname
[i
++] - 'a';
142 *devname
= savedevname
;
156 sprint_bootsel(const char *filename
)
158 char *fsname
, *devname
;
163 if (parsebootfile(filename
, &fsname
, &devname
, &unit
,
164 &partition
, &file
) == 0) {
165 if (!strcmp(fsname
, "dos"))
166 sprintf(buf
, "dos:%s", file
);
167 else if (!strcmp(fsname
, "ufs"))
168 sprintf(buf
, "%s%d%c:%s", devname
, unit
,
169 'a' + partition
, file
);
174 return ("(invalid)");
178 bootit(const char *filename
, int howto
, int tell
)
180 int floppy
= strncmp(default_devname
, "fd", 2) == 0;
182 printf("booting %s", sprint_bootsel(filename
));
184 printf(" (howto 0x%x)", howto
);
188 if(exec_netbsd(filename
, 0, howto
, floppy
, NULL
) < 0)
189 printf("boot netbsd: %s: %s\n", sprint_bootsel(filename
),
192 printf("boot netbsd returned\n");
195 if (exec_lynx(filename
, 0) < 0)
196 printf("boot lynx: %s: %s\n", sprint_bootsel(filename
),
199 printf("boot lynx returned\n");
201 if (exec_netbsd(filename
, 0, howto
, floppy
, NULL
) < 0)
202 printf("boot: %s: %s\n", sprint_bootsel(filename
),
205 printf("boot returned\n");
212 int extmem
= getextmem();
219 if (getextmem1() == 0 && (xmsmem
= checkxms()) != 0) {
221 * With "CONSERVATIVE_MEMDETECT", extmem is 0 because
222 * getextmem() is getextmem1(). Without, the "smart"
223 * methods could fail to report all memory as well.
224 * xmsmem is a few kB less than the actual size, but
225 * better than nothing.
227 if ((int)xmsmem
> extmem
)
234 ">> %s, Revision %s (from NetBSD %s)\n"
235 ">> Memory: %d/%d %sk\n",
236 bootprog_name
, bootprog_rev
, bootprog_kernrev
,
237 getbasemem(), extmem
, s
);
243 printf("dosboot [-u] [-c <commands>] [-i] [filename [-bootopts]]\n");
247 main(int argc
, char **argv
)
255 #ifdef SUPPORT_SERIAL
256 initio(SUPPORT_SERIAL
);
264 current_fsmode
= "dos";
265 default_devname
= "hd";
267 default_partition
= 0;
268 default_filename
= "netbsd";
270 while ((ch
= getopt(argc
, argv
, "c:iu")) != -1) {
280 current_fsmode
= "ufs";
289 printf("type \"?\" or \"help\" for help.\n");
301 if (argc
> 1 && !parseopts(argv
[1], &howto
))
304 bootit((argc
> 0 ? argv
[0] : "netbsd"), howto
, 1);
310 command_help(char *arg
)
312 printf("commands are:\n"
313 "boot [xdNx:][filename] [-acdqsv]\n"
314 " (ex. \"sd0a:netbsd.old -s\"\n"
323 command_ls(char *arg
)
325 char *help
= default_filename
;
326 if (strcmp(current_fsmode
, "ufs")) {
327 printf("UFS only\n");
330 default_filename
= "/";
332 default_filename
= help
;
337 command_quit(char *arg
)
339 printf("Exiting... goodbye...\n");
344 command_boot(char *arg
)
349 if (parseboot(arg
, &filename
, &howto
))
350 bootit(filename
, howto
, 1);
354 command_mode(char *arg
)
356 if (!strcmp("dos", arg
))
357 current_fsmode
= "dos";
358 else if (!strcmp("ufs", arg
))
359 current_fsmode
= "ufs";
361 printf("invalid mode\n");
365 command_dev(char *arg
)
367 static char savedevname
[MAXDEVNAME
+ 1];
368 char *fsname
, *devname
;
369 const char *file
; /* dummy */
371 if (!strcmp(current_fsmode
, "dos")) {
372 printf("not available in DOS mode\n");
377 printf("%s%d%c:\n", default_devname
, default_unit
,
378 'a' + default_partition
);
382 if (!strchr(arg
, ':') ||
383 parsebootfile(arg
, &fsname
, &devname
, &default_unit
,
384 &default_partition
, &file
)) {
389 /* put to own static storage */
390 strncpy(savedevname
, devname
, MAXDEVNAME
+ 1);
391 default_devname
= savedevname
;