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));
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to