Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 25 May 2015 01:29:46 +0000 (UTC)
From:      Ian Lepore <ian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r283510 - in stable/10/sys: arm/arm boot/arm/uboot boot/common boot/uboot/lib
Message-ID:  <201505250129.t4P1TkvP073591@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ian
Date: Mon May 25 01:29:45 2015
New Revision: 283510
URL: https://svnweb.freebsd.org/changeset/base/283510

Log:
  MFC r283033, r283062, r283066, r283069:
  
    Do not set preload_addr_relocate for ARM.
  
    Refactor net_getparams() to make it easier to get params from sources other
    than bootp and rarp.
  
    Add a routine to obtain netboot parameters from the U-Boot env vars
  
    Enable the NETIF_OPEN_CLOSE_ONCE option for ubldr.

Modified:
  stable/10/sys/arm/arm/machdep.c
  stable/10/sys/boot/arm/uboot/Makefile
  stable/10/sys/boot/common/dev_net.c
  stable/10/sys/boot/common/dev_net.h
  stable/10/sys/boot/uboot/lib/net.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/arm/arm/machdep.c
==============================================================================
--- stable/10/sys/arm/arm/machdep.c	Mon May 25 01:22:56 2015	(r283509)
+++ stable/10/sys/arm/arm/machdep.c	Mon May 25 01:29:45 2015	(r283510)
@@ -939,7 +939,6 @@ freebsd_parse_boot_param(struct arm_boot
 	ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t);
 	ksym_end = MD_FETCH(kmdp, MODINFOMD_ESYM, uintptr_t);
 #endif
-	preload_addr_relocate = KERNVIRTADDR - abp->abp_physaddr;
 	return lastaddr;
 }
 #endif

Modified: stable/10/sys/boot/arm/uboot/Makefile
==============================================================================
--- stable/10/sys/boot/arm/uboot/Makefile	Mon May 25 01:22:56 2015	(r283509)
+++ stable/10/sys/boot/arm/uboot/Makefile	Mon May 25 01:29:45 2015	(r283510)
@@ -77,6 +77,8 @@ LIBUBOOT_FDT=	${.OBJDIR}/../../uboot/fdt
 LIBFDT=		${.OBJDIR}/../../fdt/libfdt.a
 .endif
 
+CFLAGS+=	-DNETIF_OPEN_CLOSE_ONCE
+
 .if ${MK_FORTH} != "no"
 # Enable BootForth
 BOOT_FORTH=	yes

Modified: stable/10/sys/boot/common/dev_net.c
==============================================================================
--- stable/10/sys/boot/common/dev_net.c	Mon May 25 01:22:56 2015	(r283509)
+++ stable/10/sys/boot/common/dev_net.c	Mon May 25 01:29:45 2015	(r283510)
@@ -111,6 +111,8 @@ net_init(void)
 static int
 net_open(struct open_file *f, ...)
 {
+	char temp[FNAME_SIZE];
+	struct iodesc *d;
 	va_list args;
 	char *devname;		/* Device part of file name (or NULL). */
 	int error = 0;
@@ -140,6 +142,10 @@ net_open(struct open_file *f, ...)
 				printf("net_open: netif_open() succeeded\n");
 #endif
 		}
+		/*
+		 * If network params were not set by netif_open(), try to get
+		 * them via bootp, rarp, etc.
+		 */
 		if (rootip.s_addr == 0) {
 			/* Get root IP address, and path, etc. */
 			error = net_getparams(netdev_sock);
@@ -151,6 +157,20 @@ net_open(struct open_file *f, ...)
 				return (error);
 			}
 		}
+		/*
+		 * Set the variables required by the kernel's nfs_diskless
+		 * mechanism.  This is the minimum set of variables required to
+		 * mount a root filesystem without needing to obtain additional
+		 * info from bootp or other sources.
+		 */
+		d = socktodesc(netdev_sock);
+		sprintf(temp, "%6D", d->myea, ":");
+		setenv("boot.netif.hwaddr", temp, 1);
+		setenv("boot.netif.ip", inet_ntoa(myip), 1);
+		setenv("boot.netif.netmask", intoa(netmask), 1);
+		setenv("boot.netif.gateway", inet_ntoa(gateip), 1);
+		setenv("boot.nfsroot.server", inet_ntoa(rootip), 1);
+		setenv("boot.nfsroot.path", rootpath, 1);
 	}
 	netdev_opens++;
 	f->f_devdata = &netdev_sock;
@@ -232,10 +252,7 @@ static int
 net_getparams(int sock)
 {
 	char buf[MAXHOSTNAMELEN];
-	char temp[FNAME_SIZE];
-	struct iodesc *d;
-	int i;
-	n_long smask;
+	n_long rootaddr, smask;
 
 #ifdef	SUPPORT_BOOTP
 	/*
@@ -302,21 +319,9 @@ net_getparams(int sock)
 		return (EIO);
 	}
 exit:
-	/*
-	 * If present, strip the server's address off of the rootpath
-	 * before passing it along.  This allows us to be compatible with
-	 * the kernel's diskless (BOOTP_NFSROOT) booting conventions
-	 */
-	for (i = 0; rootpath[i] != '\0' && i < FNAME_SIZE; i++)
-		if (rootpath[i] == ':')
-			break;
-	if (i && i != FNAME_SIZE && rootpath[i] == ':') {
-		rootpath[i++] = '\0';
-		if (inet_addr(&rootpath[0]) != INADDR_NONE)
-			rootip.s_addr = inet_addr(&rootpath[0]);
-		bcopy(&rootpath[i], &temp[0], strlen(&rootpath[i])+1);
-		bcopy(&temp[0], &rootpath[0], strlen(&rootpath[i])+1);
-	}
+	if ((rootaddr = net_parse_rootpath()) != INADDR_NONE)
+		rootip.s_addr = rootaddr;
+
 #ifdef	NETIF_DEBUG
 	if (debug) {
 		printf("net_open: server addr: %s\n", inet_ntoa(rootip));
@@ -324,15 +329,6 @@ exit:
 	}
 #endif
 
-	d = socktodesc(sock);
-	sprintf(temp, "%6D", d->myea, ":");
-	setenv("boot.netif.ip", inet_ntoa(myip), 1);
-	setenv("boot.netif.netmask", intoa(netmask), 1);
-	setenv("boot.netif.gateway", inet_ntoa(gateip), 1);
-	setenv("boot.netif.hwaddr", temp, 1);
-	setenv("boot.nfsroot.server", inet_ntoa(rootip), 1);
-	setenv("boot.nfsroot.path", rootpath, 1);
-
 	return (0);
 }
 
@@ -354,3 +350,24 @@ net_print(int verbose)
 	}
 	printf("\n");
 }
+
+/*
+ * Strip the server's address off of the rootpath if present and return it in
+ * network byte order, leaving just the pathname part in the global rootpath.
+ */
+uint32_t
+net_parse_rootpath()
+{
+	int i;
+	n_long addr = INADDR_NONE;
+
+	for (i = 0; rootpath[i] != '\0' && i < FNAME_SIZE; i++)
+		if (rootpath[i] == ':')
+			break;
+	if (i && i != FNAME_SIZE && rootpath[i] == ':') {
+		rootpath[i++] = '\0';
+		addr = inet_addr(&rootpath[0]);
+		bcopy(&rootpath[i], rootpath, strlen(&rootpath[i])+1);
+	}
+	return (addr);
+}

Modified: stable/10/sys/boot/common/dev_net.h
==============================================================================
--- stable/10/sys/boot/common/dev_net.h	Mon May 25 01:22:56 2015	(r283509)
+++ stable/10/sys/boot/common/dev_net.h	Mon May 25 01:29:45 2015	(r283510)
@@ -26,5 +26,11 @@
  * $FreeBSD$
  */
 
+#ifndef _BOOT_DEV_NET_H_
+#define _BOOT_DEV_NET_H_
+
 extern struct devsw netdev;
 
+uint32_t net_parse_rootpath(void);
+
+#endif

Modified: stable/10/sys/boot/uboot/lib/net.c
==============================================================================
--- stable/10/sys/boot/uboot/lib/net.c	Mon May 25 01:22:56 2015	(r283509)
+++ stable/10/sys/boot/uboot/lib/net.c	Mon May 25 01:29:45 2015	(r283510)
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
 #include "api_public.h"
 #include "glue.h"
 #include "libuboot.h"
+#include "dev_net.h"
 
 static int	net_probe(struct netif *, void *);
 static int	net_match(struct netif *, void *);
@@ -84,6 +85,109 @@ struct uboot_softc {
 
 static struct uboot_softc uboot_softc;
 
+/*
+ * get_env_net_params()
+ *
+ * Attempt to obtain all the parms we need for netbooting from the U-Boot
+ * environment.  If we fail to obtain the values it may still be possible to
+ * netboot; the net_dev code will attempt to get the values from bootp, rarp,
+ * and other such sources.
+ *
+ * If rootip.s_addr is non-zero net_dev assumes the required global variables
+ * are set and skips the bootp inquiry.  For that reason, we don't set rootip
+ * until we've verified that we have at least the minimum required info.
+ *
+ * This is called from netif_init() which can result in it getting called
+ * multiple times, by design.  The network code at higher layers zeroes out
+ * rootip when it closes a network interface, so if it gets opened again we have
+ * to obtain all this info again.
+ */
+static void
+get_env_net_params()
+{
+	char *envstr;
+	in_addr_t rootaddr, serveraddr;
+
+	/* Silently get out right away if we don't have rootpath. */
+	if (ub_env_get("rootpath") == NULL)
+		return;
+
+	/*
+	 * Our own IP address must be valid.  Silently get out if it's not set,
+	 * but whine if it's there and we can't parse it.
+	 */
+	if ((envstr = ub_env_get("ipaddr")) == NULL)
+		return;
+	if ((myip.s_addr = inet_addr(envstr)) == INADDR_NONE) {
+		printf("Could not parse ipaddr '%s'\n", envstr);
+		return;
+	}
+
+	/*
+	 * Netmask is optional, default to the "natural" netmask for our IP, but
+	 * whine if it was provided and we couldn't parse it.
+	 */
+	if ((envstr = ub_env_get("netmask")) != NULL &&
+	    (netmask = inet_addr(envstr)) == INADDR_NONE) {
+		printf("Could not parse netmask '%s'\n", envstr);
+	}
+	if (netmask == INADDR_NONE) {
+		if (IN_CLASSA(myip.s_addr))
+			netmask = IN_CLASSA_NET;
+		else if (IN_CLASSB(myip.s_addr))
+			netmask = IN_CLASSB_NET;
+		else
+			netmask = IN_CLASSC_NET;
+	}
+
+	/*
+	 * Get optional serverip before rootpath; the latter can override it.
+	 * Whine only if it's present but can't be parsed.
+	 */
+	serveraddr = INADDR_NONE;
+	if ((envstr = ub_env_get("serverip")) != NULL) {
+		if ((serveraddr = inet_addr(envstr)) == INADDR_NONE) 
+			printf("Could not parse serverip '%s'\n", envstr);
+	}
+
+	/*
+	 * There must be a rootpath.  It may be ip:/path or it may be just the
+	 * path in which case the ip needs to be in serverip.
+	 */
+	if ((envstr = ub_env_get("rootpath")) == NULL)
+		return;
+	strncpy(rootpath, envstr, sizeof(rootpath) - 1);
+	rootaddr = net_parse_rootpath();
+	if (rootaddr == INADDR_NONE)
+		rootaddr = serveraddr;
+	if (rootaddr == INADDR_NONE) {
+		printf("No server address for rootpath '%s'\n", envstr);
+		return;
+	}
+	rootip.s_addr = rootaddr;
+
+	/*
+	 * Gateway IP is optional unless rootip is on a different net in which
+	 * case whine if it's missing or we can't parse it, and set rootip addr
+	 * to zero, which signals to other network code that network params
+	 * aren't set (so it will try dhcp, bootp, etc).
+	 */
+	envstr = ub_env_get("gatewayip");
+	if (!SAMENET(myip, rootip, netmask)) {
+		if (envstr == NULL)  {
+			printf("Need gatewayip for a root server on a "
+			    "different network.\n");
+			rootip.s_addr = 0;
+			return;
+		}
+		if ((gateip.s_addr = inet_addr(envstr) == INADDR_NONE)) {
+			printf("Could not parse gatewayip '%s'\n", envstr);
+			rootip.s_addr = 0;
+			return;
+		}
+	}
+}
+
 static int
 net_match(struct netif *nif, void *machdep_hint)
 {
@@ -222,6 +326,11 @@ net_init(struct iodesc *desc, void *mach
 		    nif->nif_driver->netif_bname, nif->nif_unit);
 	}
 
+	/* Attempt to get netboot params from the u-boot env. */
+	get_env_net_params();
+	if (myip.s_addr != 0)
+		desc->myip = myip;
+
 #if defined(NETIF_DEBUG)
 	printf("network: %s%d attached to %s\n", nif->nif_driver->netif_bname,
 	    nif->nif_unit, ether_sprintf(desc->myea));



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201505250129.t4P1TkvP073591>