diff options
author | Tor Egge <tegge@FreeBSD.org> | 1997-05-14 02:44:27 +0000 |
---|---|---|
committer | Tor Egge <tegge@FreeBSD.org> | 1997-05-14 02:44:27 +0000 |
commit | f811abf08c6441798926ef3cfcd2eb19291d2a14 (patch) | |
tree | c4fd99591789e4912ea796d7258bd550793b5fe6 /sys/i386/boot/netboot | |
parent | 6e5f0e40e6d662aa04bd73b4548dbc8fad931863 (diff) |
Notes
Diffstat (limited to 'sys/i386/boot/netboot')
-rw-r--r-- | sys/i386/boot/netboot/Makefile | 1 | ||||
-rw-r--r-- | sys/i386/boot/netboot/bootmenu.c | 110 | ||||
-rw-r--r-- | sys/i386/boot/netboot/main.c | 60 | ||||
-rw-r--r-- | sys/i386/boot/netboot/netboot.8 | 90 | ||||
-rw-r--r-- | sys/i386/boot/netboot/netboot.h | 14 | ||||
-rw-r--r-- | sys/i386/boot/netboot/ns8390.c | 14 | ||||
-rw-r--r-- | sys/i386/boot/netboot/rpc.c | 5 | ||||
-rw-r--r-- | sys/i386/boot/netboot/start2.S | 6 |
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 |