svn commit: r293045 - in head/sys: amd64/amd64 arm/arm arm/xscale/ixp425 arm64/arm64 boot i386/i386 kern mips/beri powerpc/powerpc sparc64/sparc64 x86/xen

Ian Lepore ian at FreeBSD.org
Sat Jan 2 02:53:51 UTC 2016


Author: ian
Date: Sat Jan  2 02:53:48 2016
New Revision: 293045
URL: https://svnweb.freebsd.org/changeset/base/293045

Log:
  Make the 'env' directive described in config(5) work on all architectures,
  providing compiled-in static environment data that is used instead of any
  data passed in from a boot loader.
  
  Previously 'env' worked only on i386 and arm xscale systems, because it
  required the MD startup code to examine the global envmode variable and
  decide whether to use static_env or an environment obtained from the boot
  loader, and set the global kern_envp accordingly.  Most startup code wasn't
  doing so.  Making things even more complex, some mips startup code uses an
  alternate scheme that involves calling init_static_kenv() to pass an empty
  buffer and its size, then uses a series of kern_setenv() calls to populate
  that buffer.
  
  Now all MD startup code calls init_static_kenv(), and that routine provides
  a single point where envmode is checked and the decision is made whether to
  use the compiled-in static_kenv or the values provided by the MD code.
  
  The routine also continues to serve its original purpose for mips; if a
  non-zero buffer size is passed the routine installs the empty buffer ready
  to accept kern_setenv() values.  Now if the size is zero, the provided buffer
  full of existing env data is installed.  A NULL pointer can be passed if the
  boot loader provides no env data; this allows the static env to be installed
  if envmode is set to do so.
  
  Most of the work here is a near-mechanical change to call the init function
  instead of directly setting kern_envp.  A notable exception is in xen/pv.c;
  that code was originally installing a buffer full of preformatted env data
  along with its non-zero size (like mips code does), which would have allowed
  kern_setenv() calls to wipe out the preformatted data.  Now it passes a zero
  for the size so that the buffer of data it installs is treated as
  non-writeable.

Modified:
  head/sys/amd64/amd64/machdep.c
  head/sys/arm/arm/machdep.c
  head/sys/arm/xscale/ixp425/avila_machdep.c
  head/sys/arm64/arm64/machdep.c
  head/sys/boot/Makefile.arm
  head/sys/i386/i386/machdep.c
  head/sys/kern/kern_environment.c
  head/sys/mips/beri/beri_machdep.c
  head/sys/powerpc/powerpc/machdep.c
  head/sys/sparc64/sparc64/machdep.c
  head/sys/x86/xen/pv.c

Modified: head/sys/amd64/amd64/machdep.c
==============================================================================
--- head/sys/amd64/amd64/machdep.c	Fri Jan  1 17:56:52 2016	(r293044)
+++ head/sys/amd64/amd64/machdep.c	Sat Jan  2 02:53:48 2016	(r293045)
@@ -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 modu
 	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);

Modified: head/sys/arm/arm/machdep.c
==============================================================================
--- head/sys/arm/arm/machdep.c	Fri Jan  1 17:56:52 2016	(r293044)
+++ head/sys/arm/arm/machdep.c	Sat Jan  2 02:53:48 2016	(r293045)
@@ -1002,6 +1002,8 @@ fake_preload_metadata(struct arm_boot_pa
 	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_p
 	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
 		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);

Modified: head/sys/arm/xscale/ixp425/avila_machdep.c
==============================================================================
--- head/sys/arm/xscale/ixp425/avila_machdep.c	Fri Jan  1 17:56:52 2016	(r293044)
+++ head/sys/arm/xscale/ixp425/avila_machdep.c	Sat Jan  2 02:53:48 2016	(r293045)
@@ -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

Modified: head/sys/arm64/arm64/machdep.c
==============================================================================
--- head/sys/arm64/arm64/machdep.c	Fri Jan  1 17:56:52 2016	(r293044)
+++ head/sys/arm64/arm64/machdep.c	Sat Jan  2 02:53:48 2016	(r293045)
@@ -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);

Modified: head/sys/boot/Makefile.arm
==============================================================================
--- head/sys/boot/Makefile.arm	Fri Jan  1 17:56:52 2016	(r293044)
+++ head/sys/boot/Makefile.arm	Sat Jan  2 02:53:48 2016	(r293045)
@@ -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

Modified: head/sys/i386/i386/machdep.c
==============================================================================
--- head/sys/i386/i386/machdep.c	Fri Jan  1 17:56:52 2016	(r293044)
+++ head/sys/i386/i386/machdep.c	Sat Jan  2 02:53:48 2016	(r293045)
@@ -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();

Modified: head/sys/kern/kern_environment.c
==============================================================================
--- head/sys/kern/kern_environment.c	Fri Jan  1 17:56:52 2016	(r293044)
+++ head/sys/kern/kern_environment.c	Sat Jan  2 02:53:48 2016	(r293045)
@@ -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;
+	}
 }
 
 /*

Modified: head/sys/mips/beri/beri_machdep.c
==============================================================================
--- head/sys/mips/beri/beri_machdep.c	Fri Jan  1 17:56:52 2016	(r293044)
+++ head/sys/mips/beri/beri_machdep.c	Sat Jan  2 02:53:48 2016	(r293045)
@@ -273,7 +273,7 @@ platform_start(__register_t a0, __regist
 	 * 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.

Modified: head/sys/powerpc/powerpc/machdep.c
==============================================================================
--- head/sys/powerpc/powerpc/machdep.c	Fri Jan  1 17:56:52 2016	(r293044)
+++ head/sys/powerpc/powerpc/machdep.c	Sat Jan  2 02:53:48 2016	(r293045)
@@ -261,7 +261,8 @@ powerpc_init(vm_offset_t fdt, vm_offset_
 		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

Modified: head/sys/sparc64/sparc64/machdep.c
==============================================================================
--- head/sys/sparc64/sparc64/machdep.c	Fri Jan  1 17:56:52 2016	(r293044)
+++ head/sys/sparc64/sparc64/machdep.c	Sat Jan  2 02:53:48 2016	(r293045)
@@ -379,7 +379,8 @@ sparc64_init(caddr_t mdp, u_long o1, u_l
 		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);

Modified: head/sys/x86/xen/pv.c
==============================================================================
--- head/sys/x86/xen/pv.c	Fri Jan  1 17:56:52 2016	(r293044)
+++ head/sys/x86/xen/pv.c	Sat Jan  2 02:53:48 2016	(r293045)
@@ -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 modu
 	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 modu
 		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();


More information about the svn-src-head mailing list