summaryrefslogtreecommitdiffstats
path: root/sys/boot
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2014-07-27 16:12:51 +0000
committermarcel <marcel@FreeBSD.org>2014-07-27 16:12:51 +0000
commit42335f4752fa57cf15318a09d3cfc118bf559b08 (patch)
tree3fdb72c26ee68a70ec6f2ed8fd97f6d03fbeb233 /sys/boot
parent32661c5bec8b8ab836158f7f46314c35aa7e5fd5 (diff)
downloadFreeBSD-src-42335f4752fa57cf15318a09d3cfc118bf559b08.zip
FreeBSD-src-42335f4752fa57cf15318a09d3cfc118bf559b08.tar.gz
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.
Diffstat (limited to 'sys/boot')
-rw-r--r--sys/boot/amd64/efi/main.c2
-rw-r--r--sys/boot/common/bootstrap.h4
-rw-r--r--sys/boot/common/interp.c17
-rw-r--r--sys/boot/common/interp_forth.c17
-rw-r--r--sys/boot/i386/libi386/libi386.h1
-rw-r--r--sys/boot/i386/libi386/pxe.c23
-rw-r--r--sys/boot/i386/loader/main.c7
-rw-r--r--sys/boot/mips/beri/loader/main.c2
-rw-r--r--sys/boot/ofw/common/main.c2
-rw-r--r--sys/boot/pc98/loader/main.c2
-rw-r--r--sys/boot/powerpc/ps3/main.c2
-rw-r--r--sys/boot/sparc64/loader/main.c2
-rw-r--r--sys/boot/uboot/common/main.c2
-rw-r--r--sys/boot/userboot/userboot/main.c2
14 files changed, 62 insertions, 23 deletions
diff --git a/sys/boot/amd64/efi/main.c b/sys/boot/amd64/efi/main.c
index d1ea9c3..2262a1d 100644
--- a/sys/boot/amd64/efi/main.c
+++ b/sys/boot/amd64/efi/main.c
@@ -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 */
}
diff --git a/sys/boot/common/bootstrap.h b/sys/boot/common/bootstrap.h
index c9bcc52..3d76540 100644
--- a/sys/boot/common/bootstrap.h
+++ b/sys/boot/common/bootstrap.h
@@ -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 */
diff --git a/sys/boot/common/interp.c b/sys/boot/common/interp.c
index 61251ba..6866643 100644
--- a/sys/boot/common/interp.c
+++ b/sys/boot/common/interp.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.
*/
diff --git a/sys/boot/common/interp_forth.c b/sys/boot/common/interp_forth.c
index 1c37e2b..37b377b 100644
--- a/sys/boot/common/interp_forth.c
+++ b/sys/boot/common/interp_forth.c
@@ -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");
}
diff --git a/sys/boot/i386/libi386/libi386.h b/sys/boot/i386/libi386/libi386.h
index f7dc379..24d6f56 100644
--- a/sys/boot/i386/libi386/libi386.h
+++ b/sys/boot/i386/libi386/libi386.h
@@ -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);
diff --git a/sys/boot/i386/libi386/pxe.c b/sys/boot/i386/libi386/pxe.c
index 49814dd..93969c2 100644
--- a/sys/boot/i386/libi386/pxe.c
+++ b/sys/boot/i386/libi386/pxe.c
@@ -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);
+}
diff --git a/sys/boot/i386/loader/main.c b/sys/boot/i386/loader/main.c
index 84ae713..13f9335 100644
--- a/sys/boot/i386/loader/main.c
+++ b/sys/boot/i386/loader/main.c
@@ -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);
diff --git a/sys/boot/mips/beri/loader/main.c b/sys/boot/mips/beri/loader/main.c
index a8e3424..8253fb2 100644
--- a/sys/boot/mips/beri/loader/main.c
+++ b/sys/boot/mips/beri/loader/main.c
@@ -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);
}
diff --git a/sys/boot/ofw/common/main.c b/sys/boot/ofw/common/main.c
index 940ca63..eb8ae0c 100644
--- a/sys/boot/ofw/common/main.c
+++ b/sys/boot/ofw/common/main.c
@@ -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();
diff --git a/sys/boot/pc98/loader/main.c b/sys/boot/pc98/loader/main.c
index 75690c7..da9bca5 100644
--- a/sys/boot/pc98/loader/main.c
+++ b/sys/boot/pc98/loader/main.c
@@ -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);
diff --git a/sys/boot/powerpc/ps3/main.c b/sys/boot/powerpc/ps3/main.c
index 64bd7e9..86ce62e 100644
--- a/sys/boot/powerpc/ps3/main.c
+++ b/sys/boot/powerpc/ps3/main.c
@@ -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);
}
diff --git a/sys/boot/sparc64/loader/main.c b/sys/boot/sparc64/loader/main.c
index 1cdcaee..44c4d21 100644
--- a/sys/boot/sparc64/loader/main.c
+++ b/sys/boot/sparc64/loader/main.c
@@ -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);
}
diff --git a/sys/boot/uboot/common/main.c b/sys/boot/uboot/common/main.c
index 16cea23..288a02d 100644
--- a/sys/boot/uboot/common/main.c
+++ b/sys/boot/uboot/common/main.c
@@ -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);
}
diff --git a/sys/boot/userboot/userboot/main.c b/sys/boot/userboot/userboot/main.c
index c9353ab..d4cefff 100644
--- a/sys/boot/userboot/userboot/main.c
+++ b/sys/boot/userboot/userboot/main.c
@@ -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);
}
OpenPOWER on IntegriCloud