Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 27 Jan 1999 14:32:00 +0300 (MSK)
From:      gritsaj@unas.jinr.ru
To:        FreeBSD-gnats-submit@FreeBSD.ORG
Subject:   i386/9721: Patch for FreeBSD netboot (booting via DOS packet driver)
Message-ID:  <199901271132.OAA24311@unas.jinr.ru>

next in thread | raw e-mail | index | archive | help

>Number:         9721
>Category:       i386
>Synopsis:       Patch for FreeBSD netboot (booting via DOS packet driver)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Wed Jan 27 03:40:00 PST 1999
>Closed-Date:
>Last-Modified:
>Originator:     Gritsaj K.
>Release:        FreeBSD 2.2.7-RELEASE i386
>Organization:
JINR
>Environment:

FreeBSD 2.2.7-RELEASE i386

>Description:

This patch intended to provide for the FreeBSD netboot tool the ability 
to work over DOS packet drivers. All previous netboot functionality is 
preserved, new possibilities isolated in new DOS executable nbpkt.com, 
which requires DOS for use of packet driver. 

More details in (revised) netboot man page.

>How-To-Repeat:

>Fix:
	
Apply the following patch to /sys/i386/boot/netboot directory:
	cd /sys/i386/boot/netboot; patch < patch.file
------------------cut here----------------------
*** Makefile.orig	Sun Oct 26 05:18:41 1997
--- Makefile	Sun Jan 24 15:31:53 1999
***************
*** 25,31 ****
  PCI_DEVICE=0x8029
  PCI_CLASS=0x02,0x00,0x00
  
! PROG=	nb8390.com nb3c509.com nb8390.rom nb3c509.rom
  # Order is very important on the SRCS line for this prog
  SRCS=	start2.S main.c misc.c bootmenu.c rpc.c
  
--- 25,31 ----
  PCI_DEVICE=0x8029
  PCI_CLASS=0x02,0x00,0x00
  
! PROG=	nb8390.com nb3c509.com nb8390.rom nb3c509.rom nbpkt.com
  # Order is very important on the SRCS line for this prog
  SRCS=	start2.S main.c misc.c bootmenu.c rpc.c
  
***************
*** 39,45 ****
  NS8390=	-DINCLUDE_NE
  #NS8390+=	-DINCLUDE_3COM -D_3COM_BASE=0x300
  CLEANFILES+=	netboot.com
! CLEANFILES+=	makerom start2.ro 3c509.o ns8390.o
  LDFLAGS+=	-N -T ${RELOCADDR} -e _start -nostdlib
  NOSHARED=	YES
  MAN8=	netboot.8
--- 39,45 ----
  NS8390=	-DINCLUDE_NE
  #NS8390+=	-DINCLUDE_3COM -D_3COM_BASE=0x300
  CLEANFILES+=	netboot.com
! CLEANFILES+=	makerom start2.ro 3c509.o ns8390.o pkt.o pktasm.o
  LDFLAGS+=	-N -T ${RELOCADDR} -e _start -nostdlib
  NOSHARED=	YES
  MAN8=	netboot.8
***************
*** 80,85 ****
--- 80,92 ----
  
  nb3c509.com:	start2.o ${SRCS:N*.h:R:S/$/.o/g} 3c509.o
  	${LD} ${LDFLAGS} -o ${.TARGET}.tmp ${OBJS} 3c509.o
+ 	strip ${.TARGET}.tmp
+ 	size ${.TARGET}.tmp
+ 	dd ibs=32 skip=1 if=${.TARGET}.tmp of=${.TARGET}
+ 	rm -f ${.TARGET}.tmp
+ 
+ nbpkt.com:	start2.o ${SRCS:N*.h:R:S/$/.o/g} pkt.o pktasm.o
+ 	${LD} ${LDFLAGS} -o ${.TARGET}.tmp ${OBJS} pkt.o pktasm.o
  	strip ${.TARGET}.tmp
  	size ${.TARGET}.tmp
  	dd ibs=32 skip=1 if=${.TARGET}.tmp of=${.TARGET}
*** pktasm.S.orig	Sun Jan 24 16:05:49 1999
--- pktasm.S	Sat Oct 17 17:10:48 1998
***************
*** 0 ****
--- 1,189 ----
+ 
+ #define MAX_LEN		1518
+ #define opsize		.byte 0x66
+ #define call_pkt	.byte 0x9c,0xff,0x5e,0x08 /* pushf; call far 8(%bp) */
+ 
+ _receiver:
+ 	.byte 0x9c			/* pushf */
+ 	.byte 0xfa			/* cli */
+ 	.byte 0x1e			/* push %ds */
+ 	.byte 0x68; .word(RELOC>>4)	/* push (RELOC>>4) */
+ 	.byte 0x1f			/* pop %ds */
+ 	.byte 0x0b,0xc0			/* or %ax,%ax */
+ 	.byte 0x74,0x0b			/* jz */
+ 	.byte 0x57			/* push %di */
+ 	.byte 0xbf; .word(_ready)	/* mov (_ready),%di */
+ 	.byte 0xc6,0x05,0x01		/* movb $01,(%di) */
+ 	.byte 0x5f			/* pop %di */
+ 	.byte 0x1f			/* pop %ds */
+ 	.byte 0x9d			/* popf */
+ 	.byte 0xcb			/* retf */
+ 
+ 	.byte 0xbf; .word (_length)	/* mov (_length),%di */
+ 	.byte 0x83,0x3d,0x00		/* cmpw $0000,(%di) */
+ 	.byte 0x75,0x10			/* jnz */
+ 	.byte 0x81,0xf9; .word MAX_LEN	/* cmp MAX_LEN,%cx, */
+ 	.byte 0x77,0x0a			/* ja */
+ 	.byte 0x89,0x0d			/* mov %cx,(%di) */
+ 	.byte 0xbf; .word (_input)	/* mov (_input),%di */
+ 	.byte 0x1e			/* push %ds */
+ 	.byte 0x07			/* pop %es */
+ 	.byte 0x1f			/* pop %ds */
+ 	.byte 0x9d			/* popf */
+ 	.byte 0xcb			/* retf */
+ 
+ 	.byte 0x33,0xff			/* xor %di,%di */
+ 	.byte 0x8e,0xc7			/* mov %di,%es */
+ 	.byte 0x1f			/* pop %ds */
+ 	.byte 0x9d			/* popf */
+ 	.byte 0xcb			/* retf */
+ 
+ 	.globl	_access_type
+ _access_type:
+ 	push	%ebp
+ 	mov	%esp,%ebp
+ 	push	%ebx
+ 	push	%ecx
+ 	push	%edx
+ 	push	%esi
+ 	push	%edi
+ 	mov	$0xffff,%ebx
+ 	xor	%edx,%edx
+ 	mov	12(%ebp),%esi
+ 	mov	16(%ebp),%ecx
+ 	mov	$(_receiver),%edi
+ 	call	_prot_to_real
+ 	movb	$0x01,%al
+ 	movb	$0x02,%ah
+ 	call_pkt
+ 	mov	%eax,%ebx
+ 	opsize
+ 	jc	1f
+ 	xor	%edx,%edx
+ 1:
+ 	opsize
+ 	call	_real_to_prot
+ 	xor	%eax,%eax
+ 	movb	%dh,%al
+ 	mov	20(%ebp),%esi
+ 	mov	%ebx,(%esi)
+ 	pop	%edi
+ 	pop	%esi
+ 	pop	%edx
+ 	pop	%ecx
+ 	pop	%ebx
+ 	pop	%ebp
+ 	ret
+ 
+ 	.globl	_send_pkt
+ _send_pkt:
+ 	push	%ebp
+ 	mov	%esp,%ebp
+ 	push	%ebx
+ 	push	%ecx
+ 	push	%edx
+ 	push	%esi
+ 	push	%edi
+ 	mov	12(%ebp),%esi
+ 	mov	16(%ebp),%ecx
+ 	call	_prot_to_real
+ 	movb	$0x00,%al
+ 	movb	$0x04,%ah
+ 	call_pkt
+ 	opsize
+ 	jc	1f
+ 	xor	%edx,%edx
+ 1:
+ 	opsize
+ 	call	_real_to_prot
+ 	xor	%eax,%eax
+ 	movb	%dh,%al
+ 	pop	%edi
+ 	pop	%esi
+ 	pop	%edx
+ 	pop	%ecx
+ 	pop	%ebx
+ 	pop	%ebp
+ 	ret
+ 
+ 	.globl	_get_address
+ _get_address:
+ 	push	%ebp
+ 	mov	%esp,%ebp
+ 	push	%ebx
+ 	push	%ecx
+ 	push	%edx
+ 	push	%esi
+ 	push	%edi
+ 	mov	12(%ebp),%ebx
+ 	mov	16(%ebp),%edi
+ 	mov	20(%ebp),%ecx
+ 	call	_prot_to_real
+ 	movb	$0x00,%al
+ 	movb	$0x06,%ah
+ 	call_pkt
+ 	opsize
+ 	jc	1f
+ 	xor	%edx,%edx
+ 1:
+ 	opsize
+ 	call	_real_to_prot
+ 	xor	%eax,%eax
+ 	movb	%dh,%al
+ 	pop	%edi
+ 	pop	%esi
+ 	pop	%edx
+ 	pop	%ecx
+ 	pop	%ebx
+ 	pop	%ebp
+ 	ret
+ 
+ 	.globl	_get_handler
+ _get_handler:
+ 	push	%ebp
+ 	mov	%esp,%ebp
+ 	push	%ebx
+ 	mov	8(%ebp),%ebx
+ 	shl	$2,%ebx
+ 	call	_prot_to_real
+ 	xor	%eax,%eax
+ 	mov	%ax,%ds
+ 	.byte 0x66,0x8b,0x1f		/* mov (%bx),%ebx */
+ 	opsize
+ 	call	_real_to_prot
+ 	mov	%ebx,%eax
+ 	pop	%ebx
+ 	pop	%ebp
+ 	ret
+ 
+ 	.globl	_get_string
+ _get_string:
+ 	push	%ebp
+ 	mov	%esp,%ebp
+ 	push	%ecx
+ 	push	%esi
+ 	push	%edi
+ 	mov	12(%ebp),%edi
+ 	mov	16(%ebp),%ecx
+ 	call	_prot_to_real
+ 	cld
+ 	.byte 0xc5,0x76,0x08		/* lds 8(%bp),%si */
+ 	rep
+ 	movsb
+ 	opsize
+ 	call	_real_to_prot
+ 	pop	%edi
+ 	pop	%esi
+ 	pop	%ecx
+ 	pop	%ebp
+ 	ret
+ 
+ 	.globl	_allow_input
+ _allow_input:
+ 	call	_prot_to_real
+ 	sti
+ 	nop
+ 	opsize
+ 	call	_real_to_prot
+ 	ret
+ 
*** start2.S.orig	Wed May 14 06:47:46 1997
--- start2.S	Sat Oct 17 16:44:05 1998
***************
*** 118,124 ****
  	push	%eax
  	lret
  #else
! 	int	$0x19
  #endif
  
  /**************************************************************************
--- 118,130 ----
  	push	%eax
  	lret
  #else
! 	movb	$0xfe,%al
! 	outb	%al, $0x64
! 2:
! 	sti
! 	hlt
! 	opsize
! 	jmp	2b
  #endif
  
  /**************************************************************************
*** bootmenu.c.orig	Wed May 14 06:47:44 1997
--- bootmenu.c	Sat Oct 17 17:01:38 1998
***************
*** 28,37 ****
  	{"help",	cmd_help,	"              this list"},
  	{"ip",		cmd_ip,		"<addr>          set my IP addr"},
  	{"server",	cmd_server,	"<addr>      set TFTP server IP addr"},
! 	{"gateway",	cmd_gateway,	"<addr>      set default router"},
  	{"netmask",	cmd_netmask,	"<addr>     set network mask"},
  	{"hostname",	cmd_hostname,	"<name>    set hostname"},
  	{"kernel",	cmd_kernel,	"<file>      set boot filename"},
  	{"rootfs",	cmd_rootfs,	"ip:/fs      set root filesystem"},
  	{"swapfs",	cmd_swapfs,	"ip:/fs      set swap filesystem"},
  	{"swapsize",	cmd_swapsize,	"<nblks>   set swap size"},
--- 28,38 ----
  	{"help",	cmd_help,	"              this list"},
  	{"ip",		cmd_ip,		"<addr>          set my IP addr"},
  	{"server",	cmd_server,	"<addr>      set TFTP server IP addr"},
! 	{"gateway",	cmd_gateway,	"<addr>     set default router"},
  	{"netmask",	cmd_netmask,	"<addr>     set network mask"},
  	{"hostname",	cmd_hostname,	"<name>    set hostname"},
  	{"kernel",	cmd_kernel,	"<file>      set boot filename"},
+ 	{"interface",	cmd_interface,	"<name>   set default interface"},
  	{"rootfs",	cmd_rootfs,	"ip:/fs      set root filesystem"},
  	{"swapfs",	cmd_swapfs,	"ip:/fs      set swap filesystem"},
  	{"swapsize",	cmd_swapsize,	"<nblks>   set swap size"},
***************
*** 40,46 ****
  	{"diskboot",	exit,		"          boot from disk"},
  	{"autoboot",	NULL,		"          continue"},
          {"trans",       cmd_aui,        "<on|off>     turn transceiver on|off"},
! 	{"flags",       cmd_flags,      "[bcdghsv] set boot flags"},
  	{NULL,		NULL,		NULL}
  };
  
--- 41,47 ----
  	{"diskboot",	exit,		"          boot from disk"},
  	{"autoboot",	NULL,		"          continue"},
          {"trans",       cmd_aui,        "<on|off>     turn transceiver on|off"},
! 	{"flags",       cmd_flags,      "[bcdghsv]    set boot flags"},
  	{NULL,		NULL,		NULL}
  };
  
***************
*** 153,158 ****
--- 154,168 ----
  	printf("Bootfile is: %s\r\n", kernel);
  }
  
+ /**************************************************************************
+ CMD_INTERFACE - set interface name
+ **************************************************************************/
+ cmd_interface(p)
+ 	char *p;
+ {
+ 	if (*p) sprintf(nfsdiskless.myif.ifra_name,"%s",p);
+ 	printf("Interface is: %s\r\n",nfsdiskless.myif.ifra_name);
+ }
  
  /**************************************************************************
  CMD_ROOTFS - Set root filesystem name
*** main.c.orig	Sun Jan 18 23:17:47 1998
--- main.c	Mon Jan 25 12:24:48 1999
***************
*** 66,71 ****
--- 66,72 ----
  		exit(0);
  	}
  	kernel = DEFAULT_BOOTFILE;
+ 	sprintf(&nfsdiskless.myif.ifra_name,eth_driver);
  	while (1) {
  		if (setjmp(jmp_bootmenu))
  			bootmenu();
***************
*** 192,198 ****
  	}
  
  		/* Fill in nfsdiskless.myif */
- 	sprintf(&nfsdiskless.myif.ifra_name,eth_driver);
          nfsdiskless.myif.ifra_addr.sa_len = sizeof(struct sockaddr);
          nfsdiskless.myif.ifra_addr.sa_family = AF_INET;
  	addr = htonl(arptable[ARP_CLIENT].ipaddr);
--- 193,198 ----
***************
*** 657,662 ****
--- 657,665 ----
  				break;
  			case 131:       /* swap mount options */
  				bootp_string("swapopts", p);
+ 				break;
+ 			case 132:       /* interface name */
+ 				bootp_string("interface", p);
  				break;
  			default:
  				printf("Unknown RFC1048-tag ");
*** pkt.c.orig	Sun Jan 24 16:06:31 1999
--- pkt.c	Sat Oct 17 17:10:48 1998
***************
*** 0 ****
--- 1,158 ----
+ 
+ /**************************************************************************
+ NETBOOT -  BOOTP/TFTP Bootstrap Program
+ 
+ Packet driver interface
+ Written by Gritsaj K. <gritsaj@nu.jinr.ru>
+ Oct/98
+ 
+ **************************************************************************/
+ 
+ #include "netboot.h"
+ 
+ short	aui = 0;
+ char	eth_driver[] = "ed0";		/* default interface name */
+ char	packet[ETHER_MAX_LEN];
+ int 	packetlen;
+ 
+ volatile char	ready = 0;
+ unsigned short	length = 0;
+ char		input[ETHER_MAX_LEN];
+ 
+ static int	handler;
+ static int	handle;
+ static char	addr[6];
+ static char	output[ETHER_MAX_LEN];
+ 
+ /**************************************************************************
+ ETH_PROBE - Look for an adapter
+ **************************************************************************/
+ eth_probe()
+ {
+ 	int vec;
+ 	char str[12];
+ 	int error;
+ 	int i;
+ 
+ 	for (vec = 0x60; vec <= 0x80; vec++) {
+ 		handler = get_handler(vec);
+ 		get_string(handler, str, sizeof(str));
+ 		if (bcompare(&str[3], "PKT DRVR", 9))
+ 			break;
+ 	}
+ 	if (vec > 0x80)
+ 		return (0);
+ 
+ 	if (error = access_type(handler, NULL, 0, &handle)) {
+ 		printf("access_type: %d\n", error);
+ 		return (0);
+ 	}
+ 
+ 	if (error = get_address(handler, handle, addr, sizeof(addr))) {
+ 		printf("get_address: %d\n", error);
+ 		return(0);
+ 	}
+ 
+ 	for (i = 0; i < 6; i++)
+ 		arptable[ARP_CLIENT].node[i] = addr[i];
+ 
+ 	printf("\r\nPacket driver at 0x%b, addr ", vec);
+ 	for (i = 0; i < 6; i++)
+ 		printf("%b%s", addr[i], i < 5 ? ":" : "");
+ 	printf("\n");
+ 
+ 	return (1);
+ }
+ 
+ /**************************************************************************
+ ETH_RESET - Reset adapter
+ **************************************************************************/
+ eth_reset()
+ {
+ 	ready = 0;
+ 	length = 0;
+ 
+ 	return (0);
+ }
+ 
+ /**************************************************************************
+ ETH_TRANSMIT - Transmit a frame
+ **************************************************************************/
+ eth_transmit(d,t,s,p)
+ 	char *d;		/* Destination */
+ 	unsigned short t;	/* Type */
+ 	unsigned short s;	/* Size */
+ 	char *p;		/* Packet */
+ {
+ 	int error;
+ 	int i,j;
+ 
+ 	if (s + 14 > ETHER_MAX_LEN)
+ 		return (0);
+ 
+ 	j = 0;
+ 	for (i = 0; i < 6; i++) output[j++] = d[i];
+ 	for (i = 0; i < 6; i++) output[j++] = addr[i];
+ 	output[j++] = t >> 8;
+ 	output[j++] = t;
+ 	for (i = 0; i < s; i++) output[j++] = p[i];
+ 
+ 	while (j < ETHER_MIN_LEN)
+ 		output[j++] = 0;
+ 
+ 	if (error = send_pkt(handler, output, j))
+ 		printf("send_pkt: %d\n", error);
+ 
+ 	twiddle();
+ 
+ 	return (0);
+ }
+ 
+ /**************************************************************************
+ ETH_POLL - Wait for a frame
+ **************************************************************************/
+ eth_poll()
+ {
+ 	unsigned short type;
+ 
+ 	if (!ready)
+ 		allow_input();
+ 	if (!ready)
+ 		return (0);
+ 
+ 	if (length < ETHER_MIN_LEN) {
+ 		ready = 0;
+ 		length = 0;
+ 		return (0);
+ 	}
+ 
+ 	bcopy(input, packet, length);
+ 	packetlen = length;
+ 	ready = 0;
+ 	length = 0;
+ 
+ 	type = (unsigned)packet[12] << 8 | packet[13];
+ 
+ 	if (type == ARP) {
+ 		struct arprequest *arpreq;
+ 		unsigned long reqip;
+ 
+ 		arpreq = (struct arprequest *)&packet[ETHER_HDR_LEN];
+ 
+ 		convert_ipaddr(&reqip, arpreq->tipaddr);
+ 		if ((ntohs(arpreq->opcode) == ARP_REQUEST) &&
+ 		    (reqip == arptable[ARP_CLIENT].ipaddr)) {
+ 			arpreq->opcode = htons(ARP_REPLY);
+ 			bcopy(arpreq->sipaddr, arpreq->tipaddr, 4);
+ 			bcopy(arpreq->shwaddr, arpreq->thwaddr, 6);
+ 			bcopy(arptable[ARP_CLIENT].node, arpreq->shwaddr, 6);
+ 			convert_ipaddr(arpreq->sipaddr, &reqip);
+ 			eth_transmit(arpreq->thwaddr, ARP, sizeof(struct arprequest),
+ 			    arpreq);
+ 			return(0);
+ 		}
+ 	}
+ 
+ 	return (1);
+ }
+ 
*** netboot.8.orig	Fri Aug 15 17:46:28 1997
--- netboot.8	Tue Jan 26 17:27:01 1999
***************
*** 9,15 ****
  .Nm
  .Bl -tag -width Ds
  is used for booting the operating system over a network card. The
! program is either loaded into a ROM, or run from DOS.
  .Pp
  .Sh DESCRIPTION
  .Nm
--- 9,17 ----
  .Nm
  .Bl -tag -width Ds
  is used for booting the operating system over a network card. The
! program is either loaded into a ROM, or run from DOS. The variant 
! of the program with FTP Software Packet Driver interface (nbpkt.com)
! can be run from DOS only and corresponding DOS packet driver must be loaded.
  .Pp
  .Sh DESCRIPTION
  .Nm
***************
*** 31,38 ****
  	:T130="root,mount,options":\\
  	:T131="swap,mount,options":\\
  	:ra=255.255.255.255:
!   client01:bf="kernel.300":ha=00400530d6d9:tc=.default:
!   client02:bf="kernel.280":ha=00400530d6d3:tc=.default:
    ...
  .Ed
  .Pp
--- 33,40 ----
  	:T130="root,mount,options":\\
  	:T131="swap,mount,options":\\
  	:ra=255.255.255.255:
!   client01:bf="kernel.300":ha=00400530d6d9:T132="lnc1":tc=.default:
!   client02:bf="kernel.280":ha=00400530d6d3:T132="tx0":tc=.default:
    ...
  .Ed
  .Pp
***************
*** 75,80 ****
--- 77,87 ----
  .It Cm T131
  specifies swap mount options.
  This argument is optional.
+ .It Cm T132
+ specifies network interface name.
+ This argument is optional, and may be useful only in case of nbpkt.com to 
+ pass name of network driver to kernel.  
+ The default compiled in nbpkt.com is "ed0".
  .It Cm bf
  is the name of the kernel. If not specified, it defaults to
  "kernel".
***************
*** 91,96 ****
--- 98,105 ----
  rom image for 3C509 cards
  .It Pa /usr/mdec/nb3c509.com
  DOS executable for 3C509 cards
+ .It Pa /usr/mdec/nbpkt.com
+ DOS executable with packet driver interface.
  
  .Sh SEE ALSO
  .Xr bootpd 8 ,
------------------cut here----------------------

>Release-Note:
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message



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