summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/amd64/amd64/machdep.c6
-rw-r--r--sys/arm/arm/machdep.c6
-rw-r--r--sys/arm/xscale/ixp425/avila_machdep.c8
-rw-r--r--sys/arm64/arm64/machdep.c2
-rw-r--r--sys/boot/Makefile.arm7
-rw-r--r--sys/i386/i386/machdep.c9
-rw-r--r--sys/kern/kern_environment.c38
-rw-r--r--sys/mips/beri/beri_machdep.c2
-rw-r--r--sys/powerpc/powerpc/machdep.c3
-rw-r--r--sys/sparc64/sparc64/machdep.c3
-rw-r--r--sys/x86/xen/pv.c9
11 files changed, 71 insertions, 22 deletions
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index 6bf251f..1bf735f 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -1484,6 +1484,7 @@ static caddr_t
native_parse_preload_data(u_int64_t modulep)
{
caddr_t kmdp;
+ char *envp;
#ifdef DDB
vm_offset_t ksym_start;
vm_offset_t ksym_end;
@@ -1495,7 +1496,10 @@ native_parse_preload_data(u_int64_t modulep)
if (kmdp == NULL)
kmdp = preload_search_by_type("elf64 kernel");
boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int);
- kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *) + KERNBASE;
+ envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *);
+ if (envp != NULL)
+ envp += KERNBASE;
+ init_static_kenv(envp, 0);
#ifdef DDB
ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t);
ksym_end = MD_FETCH(kmdp, MODINFOMD_ESYM, uintptr_t);
diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c
index af7ee99..1bd9cec 100644
--- a/sys/arm/arm/machdep.c
+++ b/sys/arm/arm/machdep.c
@@ -1002,6 +1002,8 @@ fake_preload_metadata(struct arm_boot_params *abp __unused)
fake_preload[i] = 0;
preload_metadata = (void *)fake_preload;
+ init_static_kenv(NULL, 0);
+
return (lastaddr);
}
@@ -1074,6 +1076,8 @@ linux_parse_boot_param(struct arm_boot_params *abp)
bcopy(atag_list, atags,
(char *)walker - (char *)atag_list + ATAG_SIZE(walker));
+ init_static_kenv(NULL, 0);
+
return fake_preload_metadata(abp);
}
#endif
@@ -1106,7 +1110,7 @@ freebsd_parse_boot_param(struct arm_boot_params *abp)
return 0;
boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int);
- kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *);
+ init_static_kenv(MD_FETCH(kmdp, MODINFOMD_ENVP, char *), 0);
lastaddr = MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t);
#ifdef DDB
ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t);
diff --git a/sys/arm/xscale/ixp425/avila_machdep.c b/sys/arm/xscale/ixp425/avila_machdep.c
index e48fbb6..e033e13 100644
--- a/sys/arm/xscale/ixp425/avila_machdep.c
+++ b/sys/arm/xscale/ixp425/avila_machdep.c
@@ -225,8 +225,8 @@ initarm(struct arm_boot_params *abp)
pcpu_init(pcpup, 0, sizeof(struct pcpu));
PCPU_SET(curthread, &thread0);
- if (envmode == 1)
- kern_envp = static_env;
+ init_static_kenv(NULL, 0);
+
/* Do basic tuning, hz etc */
init_param1();
@@ -426,10 +426,6 @@ initarm(struct arm_boot_params *abp)
init_param2(physmem);
kdb_init();
- /* use static kernel environment if so configured */
- if (envmode == 1)
- kern_envp = static_env;
-
return ((void *)(kernelstack.pv_va + USPACE_SVC_STACK_TOP -
sizeof(struct pcb)));
#undef next_page
diff --git a/sys/arm64/arm64/machdep.c b/sys/arm64/arm64/machdep.c
index f7e1456..f256260 100644
--- a/sys/arm64/arm64/machdep.c
+++ b/sys/arm64/arm64/machdep.c
@@ -820,7 +820,7 @@ initarm(struct arm64_bootparams *abp)
kmdp = preload_search_by_type("elf64 kernel");
boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int);
- kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *);
+ init_static_kenv(MD_FETCH(kmdp, MODINFOMD_ENVP, char *), 0);
#ifdef FDT
try_load_dtb(kmdp);
diff --git a/sys/boot/Makefile.arm b/sys/boot/Makefile.arm
index bb0e01c..49c4733 100644
--- a/sys/boot/Makefile.arm
+++ b/sys/boot/Makefile.arm
@@ -5,3 +5,10 @@ SUBDIR+= fdt
.endif
SUBDIR+= efi uboot
+
+# Do not generate movt/movw, because the relocation fixup for them does not
+# translate to the -Bsymbolic -pie format required by self_reloc() in loader(8).
+# Also, the fpu is not available in a standalone environment.
+CFLAGS.clang+= -mllvm -arm-use-movt=0
+CFLAGS.clang+= -mfpu=none
+.export: CFLAGS.clang
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index 894244c..67f6ee0 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -2462,10 +2462,11 @@ init386(first)
} else {
metadata_missing = 1;
}
- if (envmode == 1)
- kern_envp = static_env;
- else if (bootinfo.bi_envp)
- kern_envp = (caddr_t)bootinfo.bi_envp + KERNBASE;
+
+ if (bootinfo.bi_envp)
+ init_static_kenv((caddr_t)bootinfo.bi_envp + KERNBASE, 0);
+ else
+ init_static_kenv(NULL, 0);
/* Init basic tunables, hz etc */
init_param1();
diff --git a/sys/kern/kern_environment.c b/sys/kern/kern_environment.c
index 03c7226..cd6930b 100644
--- a/sys/kern/kern_environment.c
+++ b/sys/kern/kern_environment.c
@@ -210,12 +210,44 @@ done:
return (error);
}
+/*
+ * Populate the initial kernel environment.
+ *
+ * This is called very early in MD startup, either to provide a copy of the
+ * environment obtained from a boot loader, or to provide an empty buffer into
+ * which MD code can store an initial environment using kern_setenv() calls.
+ *
+ * If the global envmode is 1, the environment is initialized from the global
+ * static_env[], regardless of the arguments passed. This implements the env
+ * keyword described in config(5). In this case env_pos is set to env_len,
+ * causing kern_setenv() to return -1 (if len > 0) or panic (if len == 0) until
+ * the dynamic environment is available. The envmode and static_env variables
+ * are defined in env.c which is generated by config(8).
+ *
+ * If len is non-zero, the caller is providing an empty buffer. The caller will
+ * subsequently use kern_setenv() to add up to len bytes of initial environment
+ * before the dynamic environment is available.
+ *
+ * If len is zero, the caller is providing a pre-loaded buffer containing
+ * environment strings. Additional strings cannot be added until the dynamic
+ * environment is available. The memory pointed to must remain stable at least
+ * until sysinit runs init_dynamic_kenv(). If no initial environment is
+ * available from the boot loader, passing a NULL pointer allows the static_env
+ * to be installed if it is configured.
+ */
void
init_static_kenv(char *buf, size_t len)
{
- kern_envp = buf;
- env_len = len;
- env_pos = 0;
+
+ if (envmode == 1) {
+ kern_envp = static_env;
+ env_len = len;
+ env_pos = len;
+ } else {
+ kern_envp = buf;
+ env_len = len;
+ env_pos = 0;
+ }
}
/*
diff --git a/sys/mips/beri/beri_machdep.c b/sys/mips/beri/beri_machdep.c
index 758083f..54f61ab 100644
--- a/sys/mips/beri/beri_machdep.c
+++ b/sys/mips/beri/beri_machdep.c
@@ -273,7 +273,7 @@ platform_start(__register_t a0, __register_t a1, __register_t a2,
* Configure more boot-time parameters passed in by loader.
*/
boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int);
- kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *);
+ init_static_kenv(MD_FETCH(kmdp, MODINFOMD_ENVP, char *), 0);
/*
* Get bootargs from FDT if specified.
diff --git a/sys/powerpc/powerpc/machdep.c b/sys/powerpc/powerpc/machdep.c
index dea3461..0913a60 100644
--- a/sys/powerpc/powerpc/machdep.c
+++ b/sys/powerpc/powerpc/machdep.c
@@ -261,7 +261,8 @@ powerpc_init(vm_offset_t fdt, vm_offset_t toc, vm_offset_t ofentry, void *mdp)
kmdp = preload_search_by_type("elf kernel");
if (kmdp != NULL) {
boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int);
- kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *);
+ init_static_kenv(MD_FETCH(kmdp, MODINFOMD_ENVP, char *),
+ 0);
endkernel = ulmax(endkernel, MD_FETCH(kmdp,
MODINFOMD_KERNEND, vm_offset_t));
#ifdef DDB
diff --git a/sys/sparc64/sparc64/machdep.c b/sys/sparc64/sparc64/machdep.c
index 95b10e3..d3cd7a2 100644
--- a/sys/sparc64/sparc64/machdep.c
+++ b/sys/sparc64/sparc64/machdep.c
@@ -379,7 +379,8 @@ sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec)
kmdp = preload_search_by_type("elf kernel");
if (kmdp != NULL) {
boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int);
- kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *);
+ init_static_kenv(MD_FETCH(kmdp, MODINFOMD_ENVP, char *),
+ 0);
end = MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t);
kernel_tlb_slots = MD_FETCH(kmdp, MODINFOMD_DTLB_SLOTS,
int);
diff --git a/sys/x86/xen/pv.c b/sys/x86/xen/pv.c
index 58eb736..1cea294 100644
--- a/sys/x86/xen/pv.c
+++ b/sys/x86/xen/pv.c
@@ -296,7 +296,7 @@ xen_pv_set_env(void)
for (cmd_line_next = cmd_line; strsep(&cmd_line_next, ",") != NULL;)
;
- init_static_kenv(cmd_line, env_size);
+ init_static_kenv(cmd_line, 0);
}
static void
@@ -382,6 +382,7 @@ xen_pv_parse_preload_data(u_int64_t modulep)
caddr_t kmdp;
vm_ooffset_t off;
vm_paddr_t metadata;
+ char *envp;
if (HYPERVISOR_start_info->mod_start != 0) {
preload_metadata = (caddr_t)(HYPERVISOR_start_info->mod_start);
@@ -404,8 +405,10 @@ xen_pv_parse_preload_data(u_int64_t modulep)
preload_bootstrap_relocate(off);
boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int);
- kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *);
- kern_envp += off;
+ envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *);
+ if (envp != NULL)
+ envp += off;
+ init_static_kenv(envp, 0);
} else {
/* Parse the extra boot information given by Xen */
xen_pv_set_env();
OpenPOWER on IntegriCloud