summaryrefslogtreecommitdiff
path: root/sys/i386/boot/netboot
diff options
context:
space:
mode:
authorTor Egge <tegge@FreeBSD.org>1997-05-14 02:44:27 +0000
committerTor Egge <tegge@FreeBSD.org>1997-05-14 02:44:27 +0000
commitf811abf08c6441798926ef3cfcd2eb19291d2a14 (patch)
treec4fd99591789e4912ea796d7258bd550793b5fe6 /sys/i386/boot/netboot
parent6e5f0e40e6d662aa04bd73b4548dbc8fad931863 (diff)
Notes
Diffstat (limited to 'sys/i386/boot/netboot')
-rw-r--r--sys/i386/boot/netboot/Makefile1
-rw-r--r--sys/i386/boot/netboot/bootmenu.c110
-rw-r--r--sys/i386/boot/netboot/main.c60
-rw-r--r--sys/i386/boot/netboot/netboot.890
-rw-r--r--sys/i386/boot/netboot/netboot.h14
-rw-r--r--sys/i386/boot/netboot/ns8390.c14
-rw-r--r--sys/i386/boot/netboot/rpc.c5
-rw-r--r--sys/i386/boot/netboot/start2.S6
8 files changed, 213 insertions, 87 deletions
diff --git a/sys/i386/boot/netboot/Makefile b/sys/i386/boot/netboot/Makefile
index c04adc92fe60..b09df450e1f0 100644
--- a/sys/i386/boot/netboot/Makefile
+++ b/sys/i386/boot/netboot/Makefile
@@ -36,7 +36,6 @@ CFLAGS= -O2 -DNFS -DROMSIZE=${ROMSIZE} -DRELOC=${RELOCADDR} # -DASK_BOOT
CFLAGS += -DPCI -DPCI_VENDOR=${PCI_VENDOR} -DPCI_DEVICE=${PCI_DEVICE}
CFLAGS += -DPCI_CLASS=${PCI_CLASS} -DASK_BOOT
#NS8390= -DINCLUDE_WD -DWD_DEFAULT_MEM=0xD0000
-#NS8390= -DINCLUDE_WD -DWD_DEFAULT_MEM=0xD0000
NS8390= -DINCLUDE_NE
#NS8390+= -DINCLUDE_3COM -D_3COM_BASE=0x300
CLEANFILES+= netboot.com
diff --git a/sys/i386/boot/netboot/bootmenu.c b/sys/i386/boot/netboot/bootmenu.c
index 420e8a690ff4..ce1c4164e902 100644
--- a/sys/i386/boot/netboot/bootmenu.c
+++ b/sys/i386/boot/netboot/bootmenu.c
@@ -203,86 +203,64 @@ cmd_hostname(p)
(char*)&nfsdiskless.my_hostnam) + 3) & ~3;
else printf("Hostname is: %s\r\n",nfsdiskless.my_hostnam);
}
-/**************************************************************************
-CMD_ROOTOPTS - Set root mount options
-**************************************************************************/
-cmd_rootopts(p)
- char *p;
-{
- char *tmp;
-
- if (*p) {
- nfsdiskless.root_args.flags = NFSMNT_RSIZE | NFSMNT_WSIZE;
- nfsdiskless.root_args.sotype = SOCK_DGRAM;
- if ((tmp = (char *)substr(p,"rsize=")))
- nfsdiskless.root_args.rsize=getdec(&tmp);
- if ((tmp = (char *)substr(p,"wsize=")))
- nfsdiskless.root_args.wsize=getdec(&tmp);
- if ((tmp = (char *)substr(p,"resvport")))
- nfsdiskless.root_args.flags |= NFSMNT_RESVPORT;
- if ((tmp = (char *)substr(p,"intr")))
- nfsdiskless.root_args.flags |= NFSMNT_INT;
- if ((tmp = (char *)substr(p,"soft")))
- nfsdiskless.root_args.flags |= NFSMNT_SOFT;
- if ((tmp = (char *)substr(p, "tcp")))
- nfsdiskless.root_args.sotype = SOCK_STREAM;
- } else {
- printf("Rootfs mount options: rsize=%d,wsize=%d",
- nfsdiskless.root_args.rsize,
- nfsdiskless.root_args.wsize);
- if (nfsdiskless.root_args.flags & NFSMNT_RESVPORT)
- printf (",resvport");
- if (nfsdiskless.root_args.flags & NFSMNT_SOFT)
- printf (",soft");
- if (nfsdiskless.root_args.flags & NFSMNT_INT)
- printf (",intr");
- if (nfsdiskless.root_args.sotype == SOCK_STREAM)
- printf (",tcp");
- else
- printf (",udp");
- printf ("\r\n");
- }
-}
-/**************************************************************************
-CMD_SWAPOPTS - Set swap mount options
-**************************************************************************/
-cmd_swapopts(p)
- char *p;
+static void mountopts(prefix,args,p)
+ char *prefix;
+ struct onfs_args *args;
+ char *p;
{
- char *tmp;
+ char *tmp;
if (*p) {
- nfsdiskless.swap_args.flags = NFSMNT_RSIZE | NFSMNT_WSIZE;
- nfsdiskless.swap_args.sotype = SOCK_DGRAM;
+ args->flags = NFSMNT_RSIZE | NFSMNT_WSIZE | NFSMNT_RESVPORT;
+ args->sotype = SOCK_DGRAM;
if ((tmp = (char *)substr(p,"rsize=")))
- nfsdiskless.swap_args.rsize=getdec(&tmp);
+ args->rsize=getdec(&tmp);
if ((tmp = (char *)substr(p,"wsize=")))
- nfsdiskless.swap_args.wsize=getdec(&tmp);
- if ((tmp = (char *)substr(p,"resvport")))
- nfsdiskless.swap_args.flags |= NFSMNT_RESVPORT;
+ args->wsize=getdec(&tmp);
if ((tmp = (char *)substr(p,"intr")))
- nfsdiskless.swap_args.flags |= NFSMNT_INT;
+ args->flags |= NFSMNT_INT;
if ((tmp = (char *)substr(p,"soft")))
- nfsdiskless.swap_args.flags |= NFSMNT_SOFT;
+ args->flags |= NFSMNT_SOFT;
+ if ((tmp = (char *)substr(p,"noconn")))
+ args->flags |= NFSMNT_NOCONN;
if ((tmp = (char *)substr(p, "tcp")))
- nfsdiskless.swap_args.sotype = SOCK_STREAM;
- } else {
- printf("Swapfs mount options: rsize=%d,wsize=%d",
- nfsdiskless.swap_args.rsize,
- nfsdiskless.swap_args.wsize);
- if (nfsdiskless.swap_args.flags & NFSMNT_RESVPORT)
- printf (",resvport");
- if (nfsdiskless.swap_args.flags & NFSMNT_SOFT)
- printf (",soft");
- if (nfsdiskless.swap_args.flags & NFSMNT_INT)
+ args->sotype = SOCK_STREAM;
+ } else {
+ printf("%s mount options: rsize=%d,wsize=%d,resvport",
+ prefix,
+ args->rsize,
+ args->wsize);
+ if (args->flags & NFSMNT_INT)
printf (",intr");
- if (nfsdiskless.swap_args.sotype == SOCK_STREAM)
+ if (args->flags & NFSMNT_SOFT)
+ printf (",soft");
+ if (args->flags & NFSMNT_NOCONN)
+ printf (",noconn");
+ if (args->sotype == SOCK_STREAM)
printf (",tcp");
else
printf (",udp");
printf ("\r\n");
- }
+ }
+}
+
+/**************************************************************************
+CMD_ROOTOPTS - Set root mount options
+**************************************************************************/
+cmd_rootopts(p)
+ char *p;
+{
+ mountopts("Rootfs",&nfsdiskless.root_args,p);
+}
+
+/**************************************************************************
+CMD_SWAPOPTS - Set swap mount options
+**************************************************************************/
+cmd_swapopts(p)
+ char *p;
+{
+ mountopts("Swapfs",&nfsdiskless.swap_args,p);
}
/**************************************************************************
diff --git a/sys/i386/boot/netboot/main.c b/sys/i386/boot/netboot/main.c
index fc5943dbb4ce..9a9f0578c209 100644
--- a/sys/i386/boot/netboot/main.c
+++ b/sys/i386/boot/netboot/main.c
@@ -37,12 +37,11 @@ MAIN - Kick off routine
main()
{
int c;
- char *p;
extern char edata[], end[];
- for (p=edata; p<end; p++) *p = 0; /* Zero BSS */
+ bzero(edata,end-edata); /* Zero BSS */
#ifdef ASK_BOOT
while (1) {
- printf("\n\rBoot from Network (Y/N) ? ");
+ printf("\nBoot from Network (Y/N) ? ");
c = getchar();
if ((c >= 'a') && (c <= 'z')) c &= 0x5F;
if (c == '\r') break;
@@ -60,10 +59,10 @@ main()
bootinfo.bi_bios_geom[c] = get_diskinfo(c + 0x80);
gateA20();
- printf("\r\nBOOTP/TFTP/NFS bootstrap loader ESC for menu\n\r");
- printf("\r\nSearching for adapter...");
+ printf("\nBOOTP/TFTP/NFS bootstrap loader ESC for menu\n"
+ "\nSearching for adapter...");
if (!eth_probe()) {
- printf("No adapter found.\r\n");
+ printf("No adapter found.\n");
exit(0);
}
kernel = DEFAULT_BOOTFILE;
@@ -111,8 +110,10 @@ load()
char cmd_line[80];
int err, read_size, i;
long addr, broadcast;
+ int swsize;
unsigned long pad;
+ config_buffer[0]='\0'; /* clear; bootp might fill this up */
/* Initialize this early on */
nfsdiskless.root_args.rsize = 8192;
@@ -120,9 +121,11 @@ load()
nfsdiskless.swap_args.rsize = 8192;
nfsdiskless.swap_args.wsize = 8192;
nfsdiskless.root_args.sotype = SOCK_DGRAM;
- nfsdiskless.root_args.flags = (NFSMNT_WSIZE | NFSMNT_RSIZE);
+ nfsdiskless.root_args.flags = (NFSMNT_WSIZE | NFSMNT_RSIZE |
+ NFSMNT_RESVPORT);
nfsdiskless.swap_args.sotype = SOCK_DGRAM;
- nfsdiskless.swap_args.flags = (NFSMNT_WSIZE | NFSMNT_RSIZE);
+ nfsdiskless.swap_args.flags = (NFSMNT_WSIZE | NFSMNT_RSIZE |
+ NFSMNT_RESVPORT);
/* Find a server to get BOOTP reply from */
@@ -142,6 +145,10 @@ load()
printf("\n=>>"); getchar();
#endif
+ /*** check if have got info from bootp ***/
+ if (config_buffer[0])
+ goto cfg_done;
+#ifndef NO_TFTP
/* Now use TFTP to load configuration file */
sprintf(cfg,"/tftpboot/freebsd.%I",arptable[ARP_CLIENT].ipaddr);
if (tftp(cfg) || tftp(cfg+10))
@@ -152,6 +159,8 @@ load()
sprintf(cfg,"/tftpboot/cfg.%I",arptable[ARP_CLIENT].ipaddr);
if (tftp(cfg) || tftp(cfg+10))
goto cfg_done;
+#endif
+ /* not found; using default values... */
sprintf(config_buffer,"rootfs %I:/usr/diskless_root",
arptable[ARP_SERVER].ipaddr);
printf("Unable to load config file, guessing:\r\n\t%s\r\n",
@@ -223,11 +232,15 @@ cfg_done:
}
sprintf(swapfile,"swap.%I",arptable[ARP_CLIENT].ipaddr);
if (err = nfs_lookup(ARP_SWAPSERVER, swap_nfs_port,
- &swapfs_fh, swapfile, &nfsdiskless.swap_fh)) {
+ &swapfs_fh, swapfile, &nfsdiskless.swap_fh, &swsize)) {
printf("Unable to open %s: ",swapfile);
nfs_err(err);
longjmp(jmp_bootmenu,1);
}
+ if (!nfsdiskless.swap_nblks) {
+ nfsdiskless.swap_nblks = swsize / 1024;
+ printf("Swap size is: %d blocks\n",nfsdiskless.swap_nblks);
+ }
nfsdiskless.swap_saddr.sin_len = sizeof(struct sockaddr_in);
nfsdiskless.swap_saddr.sin_family = AF_INET;
nfsdiskless.swap_saddr.sin_port = htons(swap_nfs_port);
@@ -261,7 +274,7 @@ cfg_done:
if (err = nfs_lookup(ARP_ROOTSERVER, root_nfs_port,
&nfsdiskless.root_fh, *kernel == '/' ? kernel+1 : kernel,
- &kernel_handle)) {
+ &kernel_handle, NULL)) {
printf("Unable to open %s: ",kernel);
nfs_err(err);
longjmp(jmp_bootmenu,1);
@@ -587,6 +600,17 @@ await_reply(type, ival, ptr)
return(0);
}
+void
+bootp_string(char *name, char *bootp_ptr)
+{
+ char tmp_buf[512]; /* oversized, but who cares ! */
+ bzero(tmp_buf, sizeof(tmp_buf));
+ bcopy(bootp_ptr+2, tmp_buf, TAG_LEN(bootp_ptr));
+ sprintf(config_buffer+strlen(config_buffer),
+ "%s %s\n", name, tmp_buf);
+}
+
+
/**************************************************************************
DECODE_RFC1048 - Decodes RFC1048 header
**************************************************************************/
@@ -616,6 +640,22 @@ decode_rfc1048(p)
bcopy(p+2, &nfsdiskless.my_hostnam, TAG_LEN(p));
hostnamelen = (TAG_LEN(p) + 3) & ~3;
break;
+ case RFC1048_ROOT_PATH: /* XXX check len */
+ bootp_string("rootfs", p);
+ break;
+ case RFC1048_SWAP_PATH:
+ bootp_string("swapfs", p);
+ break;
+ case RFC1048_SWAP_LEN: /* T129 */
+ sprintf(config_buffer+strlen(config_buffer),
+ "swapsize %d\n", ntohl(*(long *)(p+2)) );
+ break;
+ case 130: /* root mount options */
+ bootp_string("rootopts", p);
+ break;
+ case 131: /* swap mount options */
+ bootp_string("swapopts", p);
+ break;
default:
printf("Unknown RFC1048-tag ");
for(q=p;q<p+2+TAG_LEN(p);q++)
diff --git a/sys/i386/boot/netboot/netboot.8 b/sys/i386/boot/netboot/netboot.8
new file mode 100644
index 000000000000..cae059a6cc17
--- /dev/null
+++ b/sys/i386/boot/netboot/netboot.8
@@ -0,0 +1,90 @@
+.\" $Id:$
+.Dd May 5, 1997
+.Dt NETBOOT 8
+.\".Os BSD 4
+.Sh NAME
+.Nm netboot
+.Nd Allows remote booting of the operating system
+.Sh SYNOPSIS
+.Nm
+.It Fl b
+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
+loads parameters such as IP addresses, kernel name and filesystem
+names from a bootp server, tries to mount the specified root and swap
+filesystems,
+loads the specified kernel from the root filesystem using NFSv2, and
+then gives control to the kernel.
+.Pp
+The bootp server must be configured appropriately. An example
+configuration for /etc/bootptab is the following:
+.Bd -literal
+ .default:\\
+ :sm=255.255.255.0:\\
+ :gw=your.gateway.ip:\\
+ :ds=your.nameserver.ip:\\
+ :hn:ht=1:vm=rfc1048:\\
+ :sw=server.ip:\\
+ :rp="rootfs.ip:/rootfs/path":\\
+ :T128="swapfs.ip:/swapfs/path":\\
+ :T129=swapsize:\\
+ :T130="root,mount,options":\\
+ :T131="swap,mount,options":
+ .client01:bf="kernel.300":ha=00400530d6d9:tc=.default:
+ .client02:bf="kernel.280":ha=00400530d6d3:tc=.default:
+.Ed
+.Pp
+For a precise description of the bootptab parameters, see
+bootptab (5) .
+.Pp
+The
+.Nm
+code uses options as follows.
+.Pp
+sm indicates the subnet mask.
+.Pp
+gw is the ip address of the gateway.
+.Pp
+ds is the ip address of the name server.
+.Pp
+hn instructs the bootp server to send the hostname in the reply.
+.Pp
+ht=1 indicates that the hardware is ethernet.
+.Pp
+vm=rfc1048 indicates the use of rfc1048 extensions.
+.Pp
+sw indicates the ip address of the NFS server, and is used for both
+the root filesystem and the swap filesystem server. It is optional in
+that it can be overridden from what is specified in the "rp" and "T128"
+options.
+.Pp
+rp specifies the path to the root partition. Optionally, the IP
+address of the server can be specified, followed by a :
+.Pp
+T128 specifies the path to the swap partition. Optionally, the IP
+address of the server can be specified, followed by a : . The
+actual swapfile is a file named swap.X.Y.Z.T where X.Y.Z.T is the
+IP address of the client. In both "rp" and "T128" options
+the sequence %I can be used which is replaced with the IP address of
+the client. The swap partition is optional. If specified, the swap
+file must exist and have at least the size specified with T129.
+.Pp
+T129 specifies the size of the swap file, in KB. Must be specified as
+a hexadecimal number. This argument is optional.
+.Pp
+T130 specified root mount options (e.g. soft,intr,tcp, ...).
+.Pp
+T131 specified swap mount options.
+.Pp
+bf is the name of the kernel. If not specified, it defaults to
+"kernel".
+
+.Sh SEE ALSO
+.Xr bootd 8 ,
+.Xr bootptab 5
+.Sh BUGS
+The T130 and T131 options are still unsupported.
+
diff --git a/sys/i386/boot/netboot/netboot.h b/sys/i386/boot/netboot/netboot.h
index e394c3e82c58..0e922b760401 100644
--- a/sys/i386/boot/netboot/netboot.h
+++ b/sys/i386/boot/netboot/netboot.h
@@ -98,10 +98,20 @@ Author: Martin Renters
#define RFC1048_COOKIE { 99, 130, 83, 99 }
#define RFC1048_PAD 0
#define RFC1048_NETMASK 1
+#define RFC1048_TIME_OFFSET 2
#define RFC1048_GATEWAY 3
+#define RFC1048_TIME_SERVER 4
+#define RFC1048_NAME_SERVER 5
+#define RFC1048_DOMAIN_SERVER 6
#define RFC1048_HOSTNAME 12
+#define RFC1048_BOOT_SIZE 12 /* XXX */
+#define RFC1048_SWAP_SERVER 16
+#define RFC1048_ROOT_PATH 17
+#define RFC1048_SWAP_PATH 128 /* T128 */
+#define RFC1048_SWAP_LEN 129 /* T129 */
+
#define RFC1048_END 255
-#define BOOTP_VENDOR_LEN 64
+#define BOOTP_VENDOR_LEN 256
#define TFTP_RRQ 1
#define TFTP_WRQ 2
@@ -190,7 +200,7 @@ struct bootp_t {
char bp_hwaddr[16];
char bp_sname[64];
char bp_file[128];
- char bp_vend[64];
+ char bp_vend[BOOTP_VENDOR_LEN];
};
struct tftp_t {
diff --git a/sys/i386/boot/netboot/ns8390.c b/sys/i386/boot/netboot/ns8390.c
index 833617407df5..c63846e40bf9 100644
--- a/sys/i386/boot/netboot/ns8390.c
+++ b/sys/i386/boot/netboot/ns8390.c
@@ -19,6 +19,11 @@ SMC8416 support added by Bill Paul (wpaul@ctr.columbia.edu) on 12/25/94
**************************************************************************/
+DELAY(int x)
+{ volatile long a, b, l;
+ for (x; x>0; x--) b=a;
+}
+
#include "netboot.h"
#include "ns8390.h"
@@ -284,13 +289,19 @@ eth_probe()
ne_again:
eth_asic_base = *tent_base + NE_ASIC_OFFSET;
eth_nic_base = *tent_base;
+ printf("Looking for NE1000/NE2000 at 0x%x\n", eth_nic_base);
eth_vendor = VENDOR_NOVELL;
eth_flags = FLAG_PIO;
eth_memsize = MEM_16384;
eth_tx_start = 32;
+#ifdef GWETHER
+ outb(eth_asic_base + NE_RESET, 0);
+ DELAY(200);
+#endif
c = inb(eth_asic_base + NE_RESET);
outb(eth_asic_base + NE_RESET, c);
+ DELAY(5000);
inb(0x84);
outb(eth_nic_base + D8390_P0_COMMAND, D8390_COMMAND_STP |
D8390_COMMAND_RD2);
@@ -317,7 +328,8 @@ ne_again:
return (0);
}
eth_pio_read(0, romdata, 16);
- printf("\r\nNE1000/NE2000 base 0x%x, addr ", eth_nic_base);
+ printf("\nNE1000/NE2000 (%d bit) base 0x%x, addr ",
+ eth_flags & FLAG_16BIT ? 16:8, eth_nic_base);
for (i=0; i<6; i++) {
printf("%b",(int)(arptable[ARP_CLIENT].node[i] = romdata[i
+ ((eth_flags & FLAG_16BIT) ? i : 0)]));
diff --git a/sys/i386/boot/netboot/rpc.c b/sys/i386/boot/netboot/rpc.c
index 134667d5e8d3..dd3186fd2ef7 100644
--- a/sys/i386/boot/netboot/rpc.c
+++ b/sys/i386/boot/netboot/rpc.c
@@ -86,12 +86,13 @@ nfs_mount(server, port, path, fh)
NFS_LOOKUP: Lookup Pathname
***************************************************************************/
-nfs_lookup(server, port, fh, path, file_fh)
+nfs_lookup(server, port, fh, path, file_fh, sizep)
int server;
int port;
char *fh;
char *path;
char *file_fh;
+ int *sizep;
{
struct rpc_t buf, *rpc;
char *rpcptr;
@@ -111,6 +112,8 @@ nfs_lookup(server, port, fh, path, file_fh)
return(-(ntohl(rpc->u.reply.data[0])));
} else {
bcopy(&rpc->u.reply.data[1],file_fh, 32);
+ if (sizep)
+ *sizep = ntohl(rpc->u.reply.data[14]);
return(0);
}
}
diff --git a/sys/i386/boot/netboot/start2.S b/sys/i386/boot/netboot/start2.S
index c81d87afaa07..34f1dfc13a78 100644
--- a/sys/i386/boot/netboot/start2.S
+++ b/sys/i386/boot/netboot/start2.S
@@ -360,12 +360,9 @@ GET DISK GEOMETRY INFO
_get_diskinfo:
push %ebp
mov %esp, %ebp
- push %es
push %ebx
push %esi
push %edi
- push %ecx
- push %edx
movb 0x8(%ebp), %dl /* diskinfo(drive #) */
call _prot_to_real /* enter real mode */
@@ -414,12 +411,9 @@ ok:
andb $0x3f, %cl /* mask of cylinder gunk */
movb %cl, %al /* max sector (and # sectors) */
- pop %edx
- pop %ecx
pop %edi
pop %esi
pop %ebx
- pop %es
pop %ebp
ret