svn commit: r246526 - in user/sbruno/pxe_http_head/sys/boot/i386: . libi386 loader pxe_http

Sean Bruno sbruno at FreeBSD.org
Fri Feb 8 01:28:32 UTC 2013


Author: sbruno
Date: Fri Feb  8 01:28:30 2013
New Revision: 246526
URL: http://svnweb.freebsd.org/changeset/base/246526

Log:
  Bring pxe_http all the way to the modern era in a functional state.
  
  LOADER_HTTP_SUPPORT works in this branch at this time by compiling:
  
  make -DLOADER_HTTP_SUPPOT -DLOADER_NO_GPT_SUPPORT.  This will boot
  and attempt to fetch a kernel/ramdisk from a web server.

Added:
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/Makefile
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/README
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/httpfs.c
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/httpfs.h
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_arp.c
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_arp.h
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_await.c
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_await.h
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_buffer.c
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_buffer.h
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_connection.c
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_connection.h
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_core.c
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_core.h
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_dhcp.c
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_dhcp.h
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_dns.c
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_dns.h
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_filter.c
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_filter.h
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_http.c
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_http.h
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_icmp.c
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_icmp.h
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_ip.c
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_ip.h
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_isr.S
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_isr.h
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_mem.c
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_mem.h
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_segment.c
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_segment.h
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_sock.c
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_sock.h
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_tcp.c
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_tcp.h
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_udp.c
  user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_udp.h
Modified:
  user/sbruno/pxe_http_head/sys/boot/i386/Makefile
  user/sbruno/pxe_http_head/sys/boot/i386/libi386/Makefile
  user/sbruno/pxe_http_head/sys/boot/i386/libi386/pxe.c
  user/sbruno/pxe_http_head/sys/boot/i386/libi386/pxe.h
  user/sbruno/pxe_http_head/sys/boot/i386/loader/Makefile
  user/sbruno/pxe_http_head/sys/boot/i386/loader/conf.c
  user/sbruno/pxe_http_head/sys/boot/i386/loader/main.c

Modified: user/sbruno/pxe_http_head/sys/boot/i386/Makefile
==============================================================================
--- user/sbruno/pxe_http_head/sys/boot/i386/Makefile	Fri Feb  8 00:40:10 2013	(r246525)
+++ user/sbruno/pxe_http_head/sys/boot/i386/Makefile	Fri Feb  8 01:28:30 2013	(r246526)
@@ -3,7 +3,7 @@
 .include <bsd.own.mk>
 
 SUBDIR=		mbr pmbr boot0 boot0sio btx boot2 cdboot gptboot kgzldr \
-		libi386 libfirewire loader
+		libi386 libfirewire pxe_http loader
 
 # special boot programs, 'self-extracting boot2+loader'
 SUBDIR+=	pxeldr

Modified: user/sbruno/pxe_http_head/sys/boot/i386/libi386/Makefile
==============================================================================
--- user/sbruno/pxe_http_head/sys/boot/i386/libi386/Makefile	Fri Feb  8 00:40:10 2013	(r246525)
+++ user/sbruno/pxe_http_head/sys/boot/i386/libi386/Makefile	Fri Feb  8 01:28:30 2013	(r246526)
@@ -7,17 +7,19 @@ SRCS=	biosacpi.c bioscd.c biosdisk.c bio
 	biospci.c biossmap.c bootinfo.c bootinfo32.c bootinfo64.c \
 	comconsole.c devicename.c elf32_freebsd.c \
 	elf64_freebsd.c \
-	i386_copy.c i386_module.c nullconsole.c pxe.c pxetramp.s \
+	i386_copy.c i386_module.c nullconsole.c pxe.c \
 	smbios.c time.c vidconsole.c amd64_tramp.S spinconsole.c
 .PATH:	${.CURDIR}/../../zfs
 SRCS+=	devicename_stubs.c
 
-# Enable PXE TFTP or NFS support, not both.
+# Enable PXE to fetch things via HTTP, TFTP or NFS.
+.if !defined(LOADER_HTTP_SUPPORT)
 .if defined(LOADER_TFTP_SUPPORT)
 CFLAGS+=	-DLOADER_TFTP_SUPPORT
 .else
 CFLAGS+=	-DLOADER_NFS_SUPPORT
 .endif
+.endif
 
 BOOT_COMCONSOLE_PORT?= 0x3f8
 CFLAGS+=	-DCOMPORT=${BOOT_COMCONSOLE_PORT}
@@ -42,13 +44,19 @@ CFLAGS+= -DSMBIOS_LITTLE_ENDIAN_UUID
 # Include simple terminal emulation (cons25-compatible)
 CFLAGS+= -DTERM_EMU
 
+# allow pxe_http perform udpread/udpwrite
+CFLAGS+= -DPXEHTTP_UDP_FOR_LIBSTAND
+
+# enable debug of pxe_http
+CDLAGS+= -DPXE_DEBUG
+
 # XXX: make alloca() useable
 CFLAGS+= -Dalloca=__builtin_alloca
 
 CFLAGS+=	-I${.CURDIR}/../../common -I${.CURDIR}/../common \
 		-I${.CURDIR}/../btx/lib \
 		-I${.CURDIR}/../../../contrib/dev/acpica/include \
-		-I${.CURDIR}/../../.. -I.
+		-I${.CURDIR}/../../.. -I. -I${.CURDIR}/../pxe_http
 # the location of libstand
 CFLAGS+=	-I${.CURDIR}/../../../../lib/libstand/
 

Modified: user/sbruno/pxe_http_head/sys/boot/i386/libi386/pxe.c
==============================================================================
--- user/sbruno/pxe_http_head/sys/boot/i386/libi386/pxe.c	Fri Feb  8 00:40:10 2013	(r246525)
+++ user/sbruno/pxe_http_head/sys/boot/i386/libi386/pxe.c	Fri Feb  8 01:28:30 2013	(r246526)
@@ -39,7 +39,9 @@ __FBSDID("$FreeBSD$");
 
 #include <net.h>
 #include <netif.h>
+#ifdef LOADER_NFS_SUPPORT
 #include <nfsv2.h>
+#endif
 #include <iodesc.h>
 
 #include <bootp.h>
@@ -47,37 +49,38 @@ __FBSDID("$FreeBSD$");
 #include "btxv86.h"
 #include "pxe.h"
 
-/*
- * Allocate the PXE buffers statically instead of sticking grimy fingers into
- * BTX's private data area.  The scratch buffer is used to send information to
- * the PXE BIOS, and the data buffer is used to receive data from the PXE BIOS.
- */
-#define	PXE_BUFFER_SIZE		0x2000
+#include "pxe_core.h"
+#include "pxe_dhcp.h"
+#include "pxe_isr.h"
+#include "pxe_ip.h"
+#include "pxe_udp.h"
+
+
 #define	PXE_TFTP_BUFFER_SIZE	512
-static char	scratch_buffer[PXE_BUFFER_SIZE];
-static char	data_buffer[PXE_BUFFER_SIZE];
+
+#ifndef PXEHTTP_UDP_FOR_LIBSTAND
+extern uint8_t *scratch_buffer;
+extern uint8_t *data_buffer;
+#endif
 
 static pxenv_t	*pxenv_p = NULL;        /* PXENV+ */
 static pxe_t	*pxe_p   = NULL;	/* !PXE */
-static BOOTPLAYER	bootplayer;	/* PXE Cached information. */
 
-static int 	pxe_debug = 0;
 static int	pxe_sock = -1;
 static int	pxe_opens = 0;
 
 void		pxe_enable(void *pxeinfo);
-static void	(*pxe_call)(int func);
-static void	pxenv_call(int func);
-static void	bangpxe_call(int func);
 
 static int	pxe_init(void);
 static int	pxe_strategy(void *devdata, int flag, daddr_t dblk,
 			     size_t size, char *buf, size_t *rsize);
 static int	pxe_open(struct open_file *f, ...);
 static int	pxe_close(struct open_file *f);
-static void	pxe_print(int verbose);
+static void     pxe_print(int verbose);
 static void	pxe_cleanup(void);
+#ifdef LOADER_NFS_SUPPORT
 static void	pxe_setnfshandle(char *rootpath);
+#endif
 
 static void	pxe_perror(int error);
 static int	pxe_netif_match(struct netif *nif, void *machdep_hint);
@@ -88,19 +91,15 @@ static int	pxe_netif_get(struct iodesc *
 static int	pxe_netif_put(struct iodesc *desc, void *pkt, size_t len);
 static void	pxe_netif_end(struct netif *nif);
 
+#ifdef LOADER_NFS_SUPPORT
 #ifdef OLD_NFSV2
 int nfs_getrootfh(struct iodesc*, char*, u_char*);
 #else
 int nfs_getrootfh(struct iodesc*, char*, uint32_t*, u_char*);
 #endif
+#endif
 
 extern struct netif_stats	pxe_st[];
-extern u_int16_t		__bangpxeseg;
-extern u_int16_t		__bangpxeoff;
-extern void			__bangpxeentry(void);
-extern u_int16_t		__pxenvseg;
-extern u_int16_t		__pxenvoff;
-extern void			__pxenventry(void);
 
 struct netif_dif pxe_ifs[] = {
 /*      dif_unit        dif_nsel        dif_stats       dif_private     */
@@ -149,7 +148,6 @@ pxe_enable(void *pxeinfo)
 	pxenv_p  = (pxenv_t *)pxeinfo;
 	pxe_p    = (pxe_t *)PTOV(pxenv_p->PXEPtr.segment * 16 +
 				 pxenv_p->PXEPtr.offset);
-	pxe_call = NULL;
 }
 
 /* 
@@ -159,90 +157,9 @@ pxe_enable(void *pxeinfo)
 static int
 pxe_init(void)
 {
-	t_PXENV_GET_CACHED_INFO	*gci_p;
-	int	counter;
-	uint8_t checksum;
-	uint8_t *checkptr;
-	
-	if(pxenv_p == NULL)
-		return (0);
-
-	/*  look for "PXENV+" */
-	if (bcmp((void *)pxenv_p->Signature, S_SIZE("PXENV+"))) {
-		pxenv_p = NULL;
-		return (0);
-	}
-
-	/* make sure the size is something we can handle */
-	if (pxenv_p->Length > sizeof(*pxenv_p)) {
-	  	printf("PXENV+ structure too large, ignoring\n");
-		pxenv_p = NULL;
-		return (0);
-	}
-	    
-	/* 
-	 * do byte checksum:
-	 * add up each byte in the structure, the total should be 0
-	 */
-	checksum = 0;	
-	checkptr = (uint8_t *) pxenv_p;
-	for (counter = 0; counter < pxenv_p->Length; counter++)
-		checksum += *checkptr++;
-	if (checksum != 0) {
-		printf("PXENV+ structure failed checksum, ignoring\n");
-		pxenv_p = NULL;
-		return (0);
-	}
-
-	
-	/*
-	 * PXENV+ passed, so use that if !PXE is not available or
-	 * the checksum fails.
-	 */
-	pxe_call = pxenv_call;
-	if (pxenv_p->Version >= 0x0200) {
-		for (;;) {
-			if (bcmp((void *)pxe_p->Signature, S_SIZE("!PXE"))) {
-				pxe_p = NULL;
-				break;
-			}
-			checksum = 0;
-			checkptr = (uint8_t *)pxe_p;
-			for (counter = 0; counter < pxe_p->StructLength;
-			     counter++)
-				checksum += *checkptr++;
-			if (checksum != 0) {
-				pxe_p = NULL;
-				break;
-			}
-			pxe_call = bangpxe_call;
-			break;
-		}
-	}
-	
-	printf("\nPXE version %d.%d, real mode entry point ",
-	       (uint8_t) (pxenv_p->Version >> 8),
-	       (uint8_t) (pxenv_p->Version & 0xFF));
-	if (pxe_call == bangpxe_call)
-		printf("@%04x:%04x\n",
-		       pxe_p->EntryPointSP.segment,
-		       pxe_p->EntryPointSP.offset);
-	else
-		printf("@%04x:%04x\n",
-		       pxenv_p->RMEntry.segment, pxenv_p->RMEntry.offset);
-
-	gci_p = (t_PXENV_GET_CACHED_INFO *) scratch_buffer;
-	bzero(gci_p, sizeof(*gci_p));
-	gci_p->PacketType =  PXENV_PACKET_TYPE_BINL_REPLY;
-	pxe_call(PXENV_GET_CACHED_INFO);
-	if (gci_p->Status != 0) {
-		pxe_perror(gci_p->Status);
-		pxe_p = NULL;
-		return (0);
-	}
-	bcopy(PTOV((gci_p->Buffer.segment << 4) + gci_p->Buffer.offset),
-	      &bootplayer, gci_p->BufferSize);
-	return (1);
+        if (__pxe_nic_irq != 0)
+                return (2);
+        return pxe_core_init(pxenv_p, pxe_p);
 }
 
 
@@ -256,146 +173,94 @@ pxe_strategy(void *devdata, int flag, da
 static int
 pxe_open(struct open_file *f, ...)
 {
-    va_list args;
-    char *devname;		/* Device part of file name (or NULL). */
-    char temp[FNAME_SIZE];
-    int error = 0;
-    int i;
-	
-    va_start(args, f);
-    devname = va_arg(args, char*);
-    va_end(args);
-
-    /* On first open, do netif open, mount, etc. */
-    if (pxe_opens == 0) {
-	/* Find network interface. */
-	if (pxe_sock < 0) {
-	    pxe_sock = netif_open(devname);
-	    if (pxe_sock < 0) {
-		printf("pxe_open: netif_open() failed\n");
-		return (ENXIO);
-	    }
-	    if (pxe_debug)
-		printf("pxe_open: netif_open() succeeded\n");
-	}
-	if (rootip.s_addr == 0) {
-		/*
-		 * Do a bootp/dhcp request to find out where our
-		 * NFS/TFTP server is.  Even if we dont get back
-		 * the proper information, fall back to the server
-		 * which brought us to life and a default rootpath.
-		 */
-		bootp(pxe_sock, BOOTP_PXE);
-		if (rootip.s_addr == 0)
-			rootip.s_addr = bootplayer.sip;
-		if (!rootpath[0])
-			strcpy(rootpath, PXENFSROOTPATH);
-
-		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);
-		}
-		printf("pxe_open: server addr: %s\n", inet_ntoa(rootip));
-		printf("pxe_open: server path: %s\n", rootpath);
-		printf("pxe_open: gateway ip:  %s\n", inet_ntoa(gateip));
-
-		setenv("boot.netif.ip", inet_ntoa(myip), 1);
-		setenv("boot.netif.netmask", intoa(netmask), 1);
-		setenv("boot.netif.gateway", inet_ntoa(gateip), 1);
-		if (bootplayer.Hardware == ETHER_TYPE) {
-		    sprintf(temp, "%6D", bootplayer.CAddr, ":");
-		    setenv("boot.netif.hwaddr", temp, 1);
+	va_list	args;
+	char	*devname = NULL;
+	int	i = 0;
+	
+        va_start(args, f);
+	devname = va_arg(args, char*);
+	va_end(args);
+	
+	if (pxe_opens == 0) {
+		/* Find network interface. */
+		if (pxe_sock < 0) {
+	    		pxe_sock = netif_open(devname);
+	    
+			if (pxe_sock < 0) {
+			        printf("pxe_open: netif_open() failed\n");
+				return (ENXIO);
+			}
+	    
 		}
-		setenv("boot.nfsroot.server", inet_ntoa(rootip), 1);
-		setenv("boot.nfsroot.path", rootpath, 1);
-		setenv("dhcp.host-name", hostname, 1);
+
+#ifdef 	PXE_BOOTP_USE_LIBSTAND
+		const PXE_IPADDR *addr = pxe_get_ip(PXE_IP_ROOT);
+
+		if ( (addr->ip == 0)) {
+			pxe_dhcp_query(0);
+			pxe_core_update_bootp();
+
+#ifdef PXEHTTP_UDP_FOR_LIBSTAND
+			gateip.s_addr = pxe_get_ip(PXE_IP_GATEWAY)->ip;
+			rootip.s_addr = pxe_get_ip(PXE_IP_ROOT)->ip;
+			netmask = pxe_get_ip(PXE_IP_NETMASK)->ip;
+			myip.s_addr = pxe_get_ip(PXE_IP_MY)->ip;
+			nameip.s_addr = pxe_get_ip(PXE_IP_NAMESERVER)->ip;
+#endif
+    		}
+#endif	/* PXE_BOOTP_USE_LIBSTAND */
 	}
-    }
-    pxe_opens++;
-    f->f_devdata = &pxe_sock;
-    return (error);
+	++pxe_opens;
+	f->f_devdata = &pxe_sock;
+	
+	return (0);
 }
 
 static int
 pxe_close(struct open_file *f)
 {
 
-#ifdef	PXE_DEBUG
-    if (pxe_debug)
-	printf("pxe_close: opens=%d\n", pxe_opens);
-#endif
-
-    /* On last close, do netif close, etc. */
-    f->f_devdata = NULL;
-    /* Extra close call? */
-    if (pxe_opens <= 0)
-	return (0);
-    pxe_opens--;
-    /* Not last close? */
-    if (pxe_opens > 0)
-	return(0);
+       	/* On last close, do netif close, etc. */
+	f->f_devdata = NULL;
+    
+	if (pxe_opens)
+		--pxe_opens;
+	    
+	/* Not last close? */
+	if (pxe_opens > 0)
+		return (0);
 
 #ifdef LOADER_NFS_SUPPORT
     /* get an NFS filehandle for our root filesystem */
     pxe_setnfshandle(rootpath);
 #endif
 
-    if (pxe_sock >= 0) {
-
+	if (pxe_sock >= 0) {
 #ifdef PXE_DEBUG
-	if (pxe_debug)
-	    printf("pxe_close: calling netif_close()\n");
+		printf("pxe_close: calling netif_close()\n");
 #endif
-	netif_close(pxe_sock);
-	pxe_sock = -1;
-    }
-    return (0);
+		netif_close(pxe_sock);
+		pxe_sock = -1;
+	}
+    
+	return (0);
 }
 
 static void
 pxe_print(int verbose)
 {
+        printf("    pxenet0:    MAC %6D\n", pxe_get_mymac(), ":");
+        printf("        ISR:    at %x:%x (chained at: %x:%x)\n",
+                __pxe_entry_seg, __pxe_entry_off,
+                __chained_irq_seg, __chained_irq_off);
 
-	if (pxe_call == NULL)
-		return;
-
-	printf("    pxe0:    %s:%s\n", inet_ntoa(rootip), rootpath);
+        return;
 }
 
 static void
 pxe_cleanup(void)
 {
-#ifdef PXE_DEBUG
-	t_PXENV_UNLOAD_STACK *unload_stack_p =
-	    (t_PXENV_UNLOAD_STACK *)scratch_buffer;
-	t_PXENV_UNDI_SHUTDOWN *undi_shutdown_p =
-	    (t_PXENV_UNDI_SHUTDOWN *)scratch_buffer;
-#endif
-
-	if (pxe_call == NULL)
-		return;
-
-	pxe_call(PXENV_UNDI_SHUTDOWN);
-
-#ifdef PXE_DEBUG
-	if (pxe_debug && undi_shutdown_p->Status != 0)
-		printf("pxe_cleanup: UNDI_SHUTDOWN failed %x\n",
-		       undi_shutdown_p->Status);
-#endif
-
-	pxe_call(PXENV_UNLOAD_STACK);
-
-#ifdef PXE_DEBUG	
-	if (pxe_debug && unload_stack_p->Status != 0)
-		printf("pxe_cleanup: UNLOAD_STACK failed %x\n",
-		    unload_stack_p->Status);
-#endif
+        pxe_core_shutdown();
 }
 
 void
@@ -517,61 +382,6 @@ pxe_setnfshandle(char *rootpath)
 #endif	/* OLD_NFSV2 */
 #endif /* LOADER_NFS_SUPPORT */
 
-void
-pxenv_call(int func)
-{
-#ifdef PXE_DEBUG
-	if (pxe_debug)
-		printf("pxenv_call %x\n", func);
-#endif
-	
-	bzero(&v86, sizeof(v86));
-	bzero(data_buffer, sizeof(data_buffer));
-
-	__pxenvseg = pxenv_p->RMEntry.segment;
-	__pxenvoff = pxenv_p->RMEntry.offset;
-	
-	v86.ctl  = V86_ADDR | V86_CALLF | V86_FLAGS;
-	v86.es   = VTOPSEG(scratch_buffer);
-	v86.edi  = VTOPOFF(scratch_buffer);
-	v86.addr = (VTOPSEG(__pxenventry) << 16) | VTOPOFF(__pxenventry);
-	v86.ebx  = func;
-	v86int();
-	v86.ctl  = V86_FLAGS;
-}
-
-void
-bangpxe_call(int func)
-{
-#ifdef PXE_DEBUG
-	if (pxe_debug)
-		printf("bangpxe_call %x\n", func);
-#endif
-	
-	bzero(&v86, sizeof(v86));
-	bzero(data_buffer, sizeof(data_buffer));
-
-	__bangpxeseg = pxe_p->EntryPointSP.segment;
-	__bangpxeoff = pxe_p->EntryPointSP.offset;
-	
-	v86.ctl  = V86_ADDR | V86_CALLF | V86_FLAGS;
-	v86.edx  = VTOPSEG(scratch_buffer);
-	v86.eax  = VTOPOFF(scratch_buffer);
-	v86.addr = (VTOPSEG(__bangpxeentry) << 16) | VTOPOFF(__bangpxeentry);
-	v86.ebx  = func;
-	v86int();
-	v86.ctl  = V86_FLAGS;
-}
-
-
-time_t
-getsecs()
-{
-	time_t n = 0;
-	time(&n);
-	return n;
-}
-
 static int
 pxe_netif_match(struct netif *nif, void *machdep_hint)
 {
@@ -582,54 +392,128 @@ pxe_netif_match(struct netif *nif, void 
 static int
 pxe_netif_probe(struct netif *nif, void *machdep_hint)
 {
-	t_PXENV_UDP_OPEN *udpopen_p = (t_PXENV_UDP_OPEN *)scratch_buffer;
+#ifdef PXE_DEBUG
+        printf("pxe_netif_probe() called.");
+#endif
 
-	if (pxe_call == NULL)
-		return -1;
+#ifdef PXEHTTP_UDP_FOR_LIBSTAND
+        if (__pxe_nic_irq == 0)
+                return (-1);
+#else
+	t_PXENV_UDP_OPEN *udpopen_p = (t_PXENV_UDP_OPEN *)scratch_buffer;
 
 	bzero(udpopen_p, sizeof(*udpopen_p));
-	udpopen_p->src_ip = bootplayer.yip;
+
+        const PXE_IPADDR *my = pxe_get_ip(PXE_IP_MY);
+	udpopen_p->src_ip = my->ip;
 	pxe_call(PXENV_UDP_OPEN);
 
 	if (udpopen_p->status != 0) {
 		printf("pxe_netif_probe: failed %x\n", udpopen_p->status);
 		return -1;
 	}
+#endif
 	return 0;
 }
 
 static void
 pxe_netif_end(struct netif *nif)
 {
-	t_PXENV_UDP_CLOSE *udpclose_p = (t_PXENV_UDP_CLOSE *)scratch_buffer;
-	bzero(udpclose_p, sizeof(*udpclose_p));
+#ifdef PXE_DEBUG
+        printf("pxe_netif_end() called.");
+#endif
+#ifndef PXEHTTP_UDP_FOR_LIBSTAND
+        t_PXENV_UDP_CLOSE *udpclose_p = (t_PXENV_UDP_CLOSE *)scratch_buffer;
+
+        bzero(udpclose_p, sizeof(*udpclose_p));
 
-	pxe_call(PXENV_UDP_CLOSE);
-	if (udpclose_p->status != 0)
-		printf("pxe_end failed %x\n", udpclose_p->status);
+        if (udpclose_p->status != 0)
+                printf("pxe_end failed %x\n", udpclose_p->status);
+#endif
 }
 
 static void
 pxe_netif_init(struct iodesc *desc, void *machdep_hint)
 {
+#ifdef PXE_DEBUG
+        printf("pxe_netif_init(): called.\n");
+#endif
+        uint8_t *mac = (uint8_t *)pxe_get_mymac();
+
 	int i;
 	for (i = 0; i < 6; ++i)
-		desc->myea[i] = bootplayer.CAddr[i];
-	desc->xid = bootplayer.ident;
+		desc->myea[i] = mac[i];
+
+        const PXE_IPADDR *my = pxe_get_ip(PXE_IP_MY);
+	desc->xid = my->ip;
 }
 
 static int
 pxe_netif_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout)
 {
+#ifdef PXE_DEBUG
+        printf("pxe_netif_put(): called.\n");
+#endif
 	return len;
 }
 
 static int
 pxe_netif_put(struct iodesc *desc, void *pkt, size_t len)
 {
+#ifdef PXE_DEBUG
+        printf("pxe_netif_put(): called.\n");
+#endif
 	return len;
 }
 
+#ifdef PXEHTTP_UDP_FOR_LIBSTAND
+/* new versions of udp send/recv functions  */
+ssize_t
+sendudp(struct iodesc *h, void *pkt, size_t len)
+{
+#ifdef PXE_DEBUG_HELL
+        printf("sendudp(): sending %u bytes  from me:%u -> %s:%u\n",
+                len, ntohs(h->myport),
+                inet_ntoa(h->destip), ntohs(h->destport));
+#endif
+        void *ipdata = pkt - sizeof(PXE_UDP_PACKET);
+        PXE_IPADDR      dst;
+        dst.ip = h->destip.s_addr;
+        if (!pxe_udp_send(ipdata, &dst, ntohs(h->destport),
+               ntohs(h->myport), len + sizeof(PXE_UDP_PACKET)))
+        {
+                 printf("sendudp(): failed\n");
+                 return (-1);
+        }
+        return (len);
+}
+
+ssize_t
+readudp(struct iodesc *h, void *pkt, size_t len, time_t timeout)
+{
+        PXE_UDP_DGRAM   dgram;
+        struct udphdr   *uh = (struct udphdr *) pkt - 1;
+
+        /* process any queued incoming packets */
+        pxe_core_recv_packets();
+
+        /* reading from default socket */
+        int recv = pxe_udp_read(NULL, pkt, len, &dgram);
+
+        if (recv == -1) {
+                printf("readudp(): failed\n");
+                return (-1);
+        }
+#ifdef PXE_DEBUG_HELL
+        printf("readudp(): received %d(%u/%u) bytes from %u port\n",
+                recv, len, dgram.size, dgram.src_port);
+#endif
+        uh->uh_sport = htons(dgram.src_port);
+        return (recv);
+}
+
+#else /* !defined(PXEHTTP_UDP_FOR_LIBSTAND) */
+/* old variants of udp send/recv functions */
 ssize_t
 sendudp(struct iodesc *h, void *pkt, size_t len)
 {
@@ -648,7 +532,7 @@ sendudp(struct iodesc *h, void *pkt, siz
 	else
 		udpwrite_p->gw = gateip.s_addr;
 
-	pxe_call(PXENV_UDP_WRITE);
+	pxe_core_call(PXENV_UDP_WRITE);
 
 #if 0
 	/* XXX - I dont know why we need this. */
@@ -678,7 +562,7 @@ readudp(struct iodesc *h, void *pkt, siz
 	udpread_p->buffer.segment = VTOPSEG(data_buffer);
 	udpread_p->buffer.offset  = VTOPOFF(data_buffer);
 
-	pxe_call(PXENV_UDP_READ);
+	pxe_core_call(PXENV_UDP_READ);
 
 #if 0
 	/* XXX - I dont know why we need this. */
@@ -694,3 +578,4 @@ readudp(struct iodesc *h, void *pkt, siz
 	uh->uh_sport = udpread_p->s_port;
 	return udpread_p->buffer_size;
 }
+#endif /* PXEHTTP_UDP_FOR_LIBSTAND */

Modified: user/sbruno/pxe_http_head/sys/boot/i386/libi386/pxe.h
==============================================================================
--- user/sbruno/pxe_http_head/sys/boot/i386/libi386/pxe.h	Fri Feb  8 00:40:10 2013	(r246525)
+++ user/sbruno/pxe_http_head/sys/boot/i386/libi386/pxe.h	Fri Feb  8 01:28:30 2013	(r246526)
@@ -48,6 +48,9 @@
  * structures passed into PXE
  * Question: does this really work for PXE's expected ABI?
  */
+#ifndef __PXE__H__
+#define __PXE__H__
+
 #define	PACKED		__packed
 
 #define	S_SIZE(s)	s, sizeof(s) - 1
@@ -147,7 +150,7 @@ typedef struct {
 	PXENV_STATUS_t	Status;
 	ADDR32_t	ProtocolIni;	/* Phys addr of a copy of the driver module */
 	uint8_t		reserved[8];
-} PACKED t_PXENV_UNDI_INITALIZE;
+} PACKED t_PXENV_UNDI_INITIALIZE;
 
 
 #define	MAXNUM_MCADDR		8
@@ -511,3 +514,5 @@ typedef struct {
 typedef struct {
 	PXENV_STATUS_t	Status;
 } PACKED t_PXENV_STOP_BASE;
+
+#endif

Modified: user/sbruno/pxe_http_head/sys/boot/i386/loader/Makefile
==============================================================================
--- user/sbruno/pxe_http_head/sys/boot/i386/loader/Makefile	Fri Feb  8 00:40:10 2013	(r246525)
+++ user/sbruno/pxe_http_head/sys/boot/i386/loader/Makefile	Fri Feb  8 01:28:30 2013	(r246526)
@@ -23,12 +23,18 @@ CFLAGS+=	-DLOADER_ZFS_SUPPORT
 LIBZFSBOOT=	${.OBJDIR}/../../zfs/libzfsboot.a
 .endif
 
+# Enable HTTP support for PXE
+.if defined(LOADER_HTTP_SUPPORT)
+CFLAGS+=        -DLOADER_HTTP_SUPPORT
+CFLAGS+=        -DPXE_MORE
+.else
 # Enable PXE TFTP or NFS support, not both.
 .if defined(LOADER_TFTP_SUPPORT)
 CFLAGS+=	-DLOADER_TFTP_SUPPORT
 .else
 CFLAGS+=	-DLOADER_NFS_SUPPORT
 .endif
+.endif
 
 # Include bcache code.
 HAVE_BCACHE=	yes
@@ -72,6 +78,10 @@ CFLAGS+=	-I${.CURDIR}/..
 # BTX components
 CFLAGS+=	-I${.CURDIR}/../btx/lib
 
+# pxe_http components
+LIBHTTP=         ${.OBJDIR}/../pxe_http/libpxe_http.a
+CFLAGS+=        -I$(.CURDIR)/../pxe_http
+
 # Debug me!
 #CFLAGS+=	-g
 #LDFLAGS+=	-g
@@ -117,8 +127,8 @@ FILES+= menu.rc
 # XXX crt0.o needs to be first for pxeboot(8) to work
 OBJS=	${BTXCRT}
 
-DPADD=	${LIBFICL} ${LIBFIREWIRE} ${LIBZFSBOOT} ${LIBI386} ${LIBSTAND}
-LDADD=	${LIBFICL} ${LIBFIREWIRE} ${LIBZFSBOOT} ${LIBI386} ${LIBSTAND}
+DPADD=	${LIBFICL} ${LIBFIREWIRE} ${LIBZFSBOOT} ${LIBI386} ${LIBHTTP} ${LIBSTAND}
+LDADD=	${LIBFICL} ${LIBFIREWIRE} ${LIBZFSBOOT} ${LIBI386} ${LIBHTTP} ${LIBSTAND}
 
 .include <bsd.prog.mk>
 

Modified: user/sbruno/pxe_http_head/sys/boot/i386/loader/conf.c
==============================================================================
--- user/sbruno/pxe_http_head/sys/boot/i386/loader/conf.c	Fri Feb  8 00:40:10 2013	(r246525)
+++ user/sbruno/pxe_http_head/sys/boot/i386/loader/conf.c	Fri Feb  8 01:28:30 2013	(r246526)
@@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$");
 #if defined(LOADER_ZFS_SUPPORT)
 #include "../zfs/libzfs.h"
 #endif
+#include "pxe_http/httpfs.h"
 
 /*
  * We could use linker sets for some or all of these, but
@@ -57,7 +58,8 @@ extern struct devsw fwohci;
 struct devsw *devsw[] = {
     &bioscd,
     &biosdisk,
-#if defined(LOADER_NFS_SUPPORT) || defined(LOADER_TFTP_SUPPORT)
+#if defined(LOADER_NFS_SUPPORT) || defined(LOADER_TFTP_SUPPORT) || \
+    defined(LOADER_HTTP_SUPPORT)
     &pxedisk,
 #endif
 #if defined(LOADER_FIREWIRE_SUPPORT)
@@ -73,10 +75,16 @@ struct fs_ops *file_system[] = {
 #if defined(LOADER_ZFS_SUPPORT)
     &zfs_fsops,
 #endif
+/*
+ * Taking these out of HTTP support for now as this makes us too large
+ * to boot.  sbruno 07FEB2013
+ */
+#if !defined(LOADER_HTTP_SUPPORT)
     &ufs_fsops,
     &ext2fs_fsops,
     &dosfs_fsops,
     &cd9660_fsops,
+#endif
 #if defined(LOADER_NANDFS_SUPPORT)
     &nandfs_fsops,
 #endif
@@ -95,6 +103,9 @@ struct fs_ops *file_system[] = {
 #ifdef LOADER_TFTP_SUPPORT
     &tftp_fsops,
 #endif
+#ifdef LOADER_HTTP_SUPPORT
+    &http_fsops,
+#endif
     NULL
 };
 

Modified: user/sbruno/pxe_http_head/sys/boot/i386/loader/main.c
==============================================================================
--- user/sbruno/pxe_http_head/sys/boot/i386/loader/main.c	Fri Feb  8 00:40:10 2013	(r246525)
+++ user/sbruno/pxe_http_head/sys/boot/i386/loader/main.c	Fri Feb  8 01:28:30 2013	(r246526)
@@ -45,6 +45,19 @@ __FBSDID("$FreeBSD$");
 #include "libi386/libi386.h"
 #include "btxv86.h"
 
+#ifdef PXE_MORE
+#include "pxe_arp.h"
+#include "pxe_connection.h"
+#include "pxe_dns.h"
+#include "pxe_filter.h"
+#include "pxe_http.h"
+#include "pxe_icmp.h"
+#include "pxe_ip.h"
+#include "pxe_sock.h"
+#include "pxe_tcp.h"
+#include "pxe_udp.h"
+#endif
+
 #ifdef LOADER_ZFS_SUPPORT
 #include "../zfs/libzfs.h"
 #endif
@@ -353,6 +366,347 @@ command_lszfs(int argc, char *argv[])
 }
 #endif
 
+/* added for pxe_http */
+#ifdef PXE_MORE
+static int
+command_route(int argc, char *argv[])
+{
+    PXE_IPADDR net;
+    PXE_IPADDR gw;
+
+    if (argc < 2) {
+	printf("use: route add|del|print [default|net_addr gw_addr] \n");
+	return (CMD_OK);
+    } 
+
+    if (!strcmp(argv[1], "print")) {
+    	pxe_ip_route_stat();
+	return (CMD_OK);
+    }
+    
+    if (argc < 4) {
+	printf("use: route add|del default|net_addr gw_addr\n");
+	return (CMD_OK);
+    }
+	
+    if ( (strcmp(argv[1], "add") != 0) && (strcmp(argv[1], "del") != 0))
+    	return (CMD_OK);
+    
+    if (!strcmp(argv[2], "default")) {
+	
+	if (!strcmp(argv[1], "del")) {
+	    printf("Cannot delete default gateway.\n");
+	    return (CMD_OK);
+	}
+		
+	gw.ip = pxe_convert_ipstr(argv[3]);
+		
+	pxe_ip_route_default(&gw);
+	    
+	return (CMD_OK);
+    }
+	
+    gw.ip = pxe_convert_ipstr(argv[3]);
+    net.ip = pxe_convert_ipstr(argv[2]);
+	
+    if (!strcmp(argv[1], "add")) {
+	pxe_ip_route_add(&net, pxe_ip_get_netmask(&net), &gw);
+	return (CMD_OK);
+    }
+
+    pxe_ip_route_del(&net, pxe_ip_get_netmask(&net), &gw);
+    
+    return (CMD_OK);
+}
+
+static int
+command_arp(int argc, char *argv[])
+{
+    PXE_IPADDR *ip;
+
+    if (argc > 1) {
+	
+	if (strcmp(argv[1], "stats") != 0)
+	    ip = pxe_gethostbyname(argv[1]);
+	else {
+	    pxe_arp_stats();
+	    return (CMD_OK);
+	}
+
+    } else {
+	printf("use: arp ip4_address|stats\n");
+	return (CMD_OK);
+    }
+    
+    printf("searching ip: %s\n", (ip != NULL) ? inet_ntoa(ip->ip) : "?");
+    
+    const uint8_t* mac = (const uint8_t *)pxe_arp_ip4mac(ip);
+
+    if (mac != NULL)
+           printf("MAC: %6D\n", mac, ":");
+    else
+	   printf("MAC search failed.\n");
+								   
+    return (CMD_OK);
+}
+
+static int
+command_ping(int argc, char *argv[])
+{
+    PXE_IPADDR* ip = NULL;
+
+    pxe_icmp_init();
+
+    if (argc > 1)
+	ip = pxe_gethostbyname(argv[1]);
+    else {
+	printf("use: ping ip4_address\n");
+	return (CMD_OK);
+    }
+
+    pxe_ping(ip, 5, 1);
+								   
+    return (CMD_OK);
+}
+
+static int
+command_await()
+{
+
+    while (1) {
+        if (!pxe_core_recv_packets()) {
+	    twiddle();
+	    delay(10000);
+	}
+    }
+    
+    return (0);
+}
+
+#if 0
+static int
+command_sock(int argc, char *argv[])
+{
+    if (argc < 2) {
+    	printf("use: socket stats|tcptest\n");
+	return (CMD_OK);
+    }
+    
+    if (!strcmp(argv[1], "stats")) {
+	pxe_sock_stats();
+	return (CMD_OK);
+    }
+    
+    if (argc < 3) {
+    	printf("use: socket tcptest ip4.addr\n");
+	return (CMD_OK);
+    }
+    
+    if (!strcmp(argv[1], "tcptest")) {
+	int socket = pxe_socket();
+	PXE_IPADDR	ip;
+	uint32_t	bps = 0;
+	uint32_t	start_time = 0;
+	int		index2 = 0;	
+	    
+	ip.ip = pxe_convert_ipstr(argv[2]);
+	    
+	int res = pxe_connect(socket, &ip, 26, PXE_TCP_PROTOCOL);
+
+	if (res == -1)
+	    printf("tcptest: failed to connect socket.\n");
+	else {
+	    int index = 0;
+	    int recvc = 0;
+	    uint8_t  data;
+	    start_time = pxe_get_secs();
+
+	    index = 0;
+	    recvc = 0;
+		    
+	    data = 1;
+
+	    while ( data != 0) {
+	        recvc = pxe_recv(socket, &data, 1);
+			    
+	        if (recvc == -1) {
+		    printf("tcptest: %d bytes recv, but next failed.\n", index);
+		    pxe_close(socket);
+		    return (CMD_OK);
+		}
+			    
+		if (recvc == 0) {
+		    printf("!");
+		    continue;
+		}
+			    
+		recvc = (index % 149) + 1; 
+
+		if (data == 0) {
+		    printf("tcptest: end of test.\n");
+		    break;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-user mailing list