Give loaders more control over the Forth initialization process. In
particular, allow loaders to define the name of the RC script the interpreter needs to use. Use this new-found control to have the PXE loader (when compiled with TFTP support and not NFS support) read from ${bootfile}.4th, where ${bootfile} is the name of the file fetched by the PXE firmware. The normal startup process involves reading the following files: 1. /boot/boot.4th 2. /boot/loader.rc or alternatively /boot/boot.conf When these come from a FreeBSD-defined file system, this is all good. But when we boot over the network, subdirectories and fixed file names are often painful to administrators and there's really no way for them to change the behaviour of the loader. Obtained from: Juniper Networks, Inc.
This commit is contained in:
parent
32661c5bec
commit
42335f4752
@ -124,7 +124,7 @@ main(int argc, CHAR16 *argv[])
|
||||
archsw.arch_copyout = x86_efi_copyout;
|
||||
archsw.arch_readin = x86_efi_readin;
|
||||
|
||||
interact(); /* doesn't return */
|
||||
interact(NULL); /* doesn't return */
|
||||
|
||||
return (EFI_SUCCESS); /* keep compiler happy */
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ extern char command_errbuf[]; /* XXX blah, length */
|
||||
#define CMD_ERROR 1
|
||||
|
||||
/* interp.c */
|
||||
void interact(void);
|
||||
void interact(const char *rc);
|
||||
int include(const char *filename);
|
||||
|
||||
/* interp_backslash.c */
|
||||
@ -69,7 +69,7 @@ char *backslash(char *str);
|
||||
int parse(int *argc, char ***argv, char *str);
|
||||
|
||||
/* interp_forth.c */
|
||||
void bf_init(void);
|
||||
void bf_init(const char *rc);
|
||||
int bf_run(char *line);
|
||||
|
||||
/* boot.c */
|
||||
|
@ -90,7 +90,7 @@ perform(int argc, char *argv[])
|
||||
* Interactive mode
|
||||
*/
|
||||
void
|
||||
interact(void)
|
||||
interact(const char *rc)
|
||||
{
|
||||
static char input[256]; /* big enough? */
|
||||
#ifndef BOOT_FORTH
|
||||
@ -99,15 +99,18 @@ interact(void)
|
||||
#endif
|
||||
|
||||
#ifdef BOOT_FORTH
|
||||
bf_init();
|
||||
bf_init((rc) ? "" : NULL);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Read our default configuration
|
||||
*/
|
||||
if (include("/boot/loader.rc") != CMD_OK)
|
||||
include("/boot/boot.conf");
|
||||
if (rc == NULL) {
|
||||
/* Read our default configuration. */
|
||||
if (include("/boot/loader.rc") != CMD_OK)
|
||||
include("/boot/boot.conf");
|
||||
} else if (*rc != '\0')
|
||||
include(rc);
|
||||
|
||||
printf("\n");
|
||||
|
||||
/*
|
||||
* Before interacting, we might want to autoboot.
|
||||
*/
|
||||
|
@ -241,7 +241,7 @@ bf_command(FICL_VM *vm)
|
||||
* Initialise the Forth interpreter, create all our commands as words.
|
||||
*/
|
||||
void
|
||||
bf_init(void)
|
||||
bf_init(const char *rc)
|
||||
{
|
||||
struct bootblk_command **cmdp;
|
||||
char create_buf[41]; /* 31 characters-long builtins */
|
||||
@ -271,13 +271,20 @@ bf_init(void)
|
||||
ficlSetEnv(bf_sys, "loader_version",
|
||||
(bootprog_rev[0] - '0') * 10 + (bootprog_rev[2] - '0'));
|
||||
|
||||
pInterp = ficlLookup(bf_sys, "interpret");
|
||||
|
||||
/* try to load and run init file if present */
|
||||
if ((fd = open("/boot/boot.4th", O_RDONLY)) != -1) {
|
||||
(void)ficlExecFD(bf_vm, fd);
|
||||
close(fd);
|
||||
if (rc == NULL)
|
||||
rc = "/boot/boot.4th";
|
||||
if (*rc != '\0') {
|
||||
fd = open(rc, O_RDONLY);
|
||||
if (fd != -1) {
|
||||
(void)ficlExecFD(bf_vm, fd);
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
/* Do this last, so /boot/boot.4th can change it */
|
||||
/* Do this again, so that interpret can be redefined. */
|
||||
pInterp = ficlLookup(bf_sys, "interpret");
|
||||
}
|
||||
|
||||
|
@ -121,4 +121,5 @@ int bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip,
|
||||
vm_offset_t *modulep, vm_offset_t *kernend);
|
||||
int bi_load64(char *args, vm_offset_t *modulep, vm_offset_t *kernend);
|
||||
|
||||
char *pxe_default_rc(void);
|
||||
void pxe_enable(void *pxeinfo);
|
||||
|
@ -694,3 +694,26 @@ readudp(struct iodesc *h, void *pkt, size_t len, time_t timeout)
|
||||
uh->uh_sport = udpread_p->s_port;
|
||||
return udpread_p->buffer_size;
|
||||
}
|
||||
|
||||
char *
|
||||
pxe_default_rc(void)
|
||||
{
|
||||
char *rc;
|
||||
size_t count, rcsz;
|
||||
|
||||
/* XXX It may not be a good idea to modify the PXE boot file. */
|
||||
rc = (char *)bootplayer.bootfile;
|
||||
rcsz = sizeof(bootplayer.bootfile);
|
||||
|
||||
/* Ignore how we define rc and rcsz above -- it can change. */
|
||||
if (rcsz < 6)
|
||||
return (NULL);
|
||||
if (*rc == '\0') {
|
||||
strncpy(rc, "pxeboot", rcsz);
|
||||
rc[rcsz - 1] = '\0';
|
||||
}
|
||||
count = strlen(rc);
|
||||
strncat(rc, ".4th", rcsz - count - 1);
|
||||
printf("PXE: loading Forth from %s\n", rc);
|
||||
return (rc);
|
||||
}
|
||||
|
@ -192,7 +192,12 @@ main(void)
|
||||
|
||||
bios_getsmap();
|
||||
|
||||
interact(); /* doesn't return */
|
||||
#ifdef LOADER_TFTP_SUPPORT
|
||||
if (kargs->bootflags & KARGS_FLAGS_PXE)
|
||||
interact(pxe_default_rc());
|
||||
else
|
||||
#endif
|
||||
interact(NULL);
|
||||
|
||||
/* if we ever get here, it is an error */
|
||||
return (1);
|
||||
|
@ -151,7 +151,7 @@ main(int argc, char *argv[], char *envv[], struct bootinfo *bootinfop)
|
||||
printf("bootpath=\"%s\"\n", bootpath);
|
||||
#endif
|
||||
|
||||
interact();
|
||||
interact(NULL);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -162,7 +162,7 @@ main(int (*openfirm)(void *))
|
||||
archsw.arch_readin = ofw_readin;
|
||||
archsw.arch_autoload = ofw_autoload;
|
||||
|
||||
interact(); /* doesn't return */
|
||||
interact(NULL); /* doesn't return */
|
||||
|
||||
OF_exit();
|
||||
|
||||
|
@ -193,7 +193,7 @@ main(void)
|
||||
extract_currdev(); /* set $currdev and $loaddev */
|
||||
setenv("LINES", "24", 1); /* optional */
|
||||
|
||||
interact(); /* doesn't return */
|
||||
interact(NULL); /* doesn't return */
|
||||
|
||||
/* if we ever get here, it is an error */
|
||||
return (1);
|
||||
|
@ -145,7 +145,7 @@ main(void)
|
||||
setenv("LINES", "24", 1);
|
||||
setenv("hw.platform", "ps3", 1);
|
||||
|
||||
interact(); /* doesn't return */
|
||||
interact(NULL); /* doesn't return */
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
@ -897,7 +897,7 @@ main(int (*openfirm)(void *))
|
||||
printf("bootpath=\"%s\"\n", bootpath);
|
||||
|
||||
/* Give control to the machine independent loader code. */
|
||||
interact();
|
||||
interact(NULL);
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
@ -492,7 +492,7 @@ main(void)
|
||||
archsw.arch_readin = uboot_readin;
|
||||
archsw.arch_autoload = uboot_autoload;
|
||||
|
||||
interact(); /* doesn't return */
|
||||
interact(NULL); /* doesn't return */
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
@ -141,7 +141,7 @@ loader_main(struct loader_callbacks *cb, void *arg, int version, int ndisks)
|
||||
if (setjmp(jb))
|
||||
return;
|
||||
|
||||
interact(); /* doesn't return */
|
||||
interact(NULL); /* doesn't return */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user