1
0
Files
irix-657m-src/stand/arcs/lib/libsc/cmd/boot_cmd.c
2022-09-29 17:59:04 +03:00

154 lines
3.3 KiB
C

#ident "lib/libsc/cmd/boot_cmd.c: $Revision: 1.39 $"
/*
* boot -- boot new image
*/
#include <sys/sbd.h>
#include <stringlist.h>
#include <arcs/errno.h>
#include <arcs/restart.h>
#include <arcs/hinv.h>
#include <arcs/io.h>
#include <arcs/pvector.h>
#include <libsc.h>
#include <libsc_internal.h>
extern char * make_bootfile(int);
extern MEMORYDESCRIPTOR *mem_getblock(void);
static void booterr (long, struct string_list *, char *, int);
unsigned long boot_pc; /* shared with go_cmd.c */
char *boot_file; /* shared with go_cmd.c */
/*ARGSUSED*/
int
boot(int argc, char **argv, char **bunk1, struct cmd_table *bunk2)
{
struct string_list newargv;
int nogo = 0;
int nobootfile = 0;
int noreloc = 0;
unsigned long lowaddr;
MEMORYDESCRIPTOR *m;
long err = 0;
/*
* initialize defaults
*/
boot_file = (char *)make_bootfile(1);
init_str(&newargv);
if (new_str1("", &newargv)) /* leave space for boot_file as arg0 */
return(0);
while (--argc > 0) {
argv++;
if (!*argv) /* allow empty argv slots */
continue;
if ((*argv)[0] == '-')
switch ((*argv)[1]) {
case 'a': /* load without relocating */
noreloc = 1;
break;
case 'f': /* file to boot */
if (--argc <= 0)
return(1);
boot_file = *++argv;
nobootfile = 1;
break;
case 'n': /* load but don't go */
nogo = 1;
break;
case '-': /* just pass arg to booted program */
/* skip initial - */
if (new_str1((*argv)+1, &newargv))
return(0);
break;
default:
printf("unknown boot option: %s\n"
"precede option with extra '-' to\n"
"pass to booted program\n",*argv);
return(1);
}
else if (new_str1(*argv, &newargv))
return(0);
}
if (boot_file == NULL) {
printf("No valid boot information found in environment.\n");
return(0);
}
if (set_str(boot_file, 0, &newargv))
return(0);
rbsetbs(BS_BSTARTED); /* boot started */
if (noreloc)
if (nogo)
err = load_abs (newargv.strptrs[0], &boot_pc);
else
err = exec_abs (newargv.strptrs[0],
(LONG)newargv.strcnt,
newargv.strptrs, environ);
else
if (nogo) {
/* If the program is relocatable and is not to be
* executed, then load it at the default address,
* which is the top of the largest continuous memory
* block.
*/
unsigned long top;
if (!(m = mem_getblock()))
return (ENOMEM);
top = PHYS_TO_K0(arcs_ptob(m->BasePage + m->PageCount));
err = Load(newargv.strptrs[0], top, &boot_pc, &lowaddr);
} else {
setenv ("kernname", newargv.strptrs[0]);
err = Execute (newargv.strptrs[0], (LONG)newargv.strcnt,
newargv.strptrs, environ);
}
if (err != ESUCCESS)
booterr (err, &newargv, boot_file, nobootfile);
return(0);
}
static void
booterr (long err, struct string_list *newargv, char *bootfile, int nobootfile)
{
rbclrbs(BS_BSTARTED); /* boot will never finish! */
printf("Unable to load %s: ", newargv->strptrs[0]);
switch(err) {
case EIO:
printf("no such device.\n");
break;
case ENXIO:
printf("no recognizable file system on device.\n");
break;
case ENOCONNECT:
printf("could not connect to remote server.\n");
break;
case EINVAL:
if (nobootfile)
printf("``%s'' is not a valid file to boot.\n",
newargv->strptrs[0]);
else
printf("invalid bootfile %s.\n", bootfile);
break;
default:
perror(err,NULL);
break;
}
}