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:
marcel 2014-07-27 16:12:51 +00:00
parent 32661c5bec
commit 42335f4752
14 changed files with 62 additions and 23 deletions

View File

@ -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 */
}

View File

@ -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 */

View File

@ -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.
*/

View File

@ -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");
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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();

View File

@ -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);

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}