1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-18 10:35:55 +00:00

Bring in some improved bootp support for netboot submitted by Luigi:

- TFTP is not needed any longer.
Add some other improvements:
      - swapsize is now detected if no value was specified.
      - resvport is used by default
      - merged code for setting/showing mount options for root/swap.
Submitted by:   Luigi Rizzo <luigi@labinfo.iet.unipi.it>
This commit is contained in:
Tor Egge 1997-05-14 02:44:27 +00:00
parent 6e5f0e40e6
commit f811abf08c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=25806
8 changed files with 213 additions and 87 deletions

View File

@ -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

View File

@ -203,45 +203,55 @@ cmd_hostname(p)
(char*)&nfsdiskless.my_hostnam) + 3) & ~3;
else printf("Hostname is: %s\r\n",nfsdiskless.my_hostnam);
}
static void mountopts(prefix,args,p)
char *prefix;
struct onfs_args *args;
char *p;
{
char *tmp;
if (*p) {
args->flags = NFSMNT_RSIZE | NFSMNT_WSIZE | NFSMNT_RESVPORT;
args->sotype = SOCK_DGRAM;
if ((tmp = (char *)substr(p,"rsize=")))
args->rsize=getdec(&tmp);
if ((tmp = (char *)substr(p,"wsize=")))
args->wsize=getdec(&tmp);
if ((tmp = (char *)substr(p,"intr")))
args->flags |= NFSMNT_INT;
if ((tmp = (char *)substr(p,"soft")))
args->flags |= NFSMNT_SOFT;
if ((tmp = (char *)substr(p,"noconn")))
args->flags |= NFSMNT_NOCONN;
if ((tmp = (char *)substr(p, "tcp")))
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 (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;
{
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");
}
mountopts("Rootfs",&nfsdiskless.root_args,p);
}
/**************************************************************************
@ -250,39 +260,7 @@ CMD_SWAPOPTS - Set swap mount options
cmd_swapopts(p)
char *p;
{
char *tmp;
if (*p) {
nfsdiskless.swap_args.flags = NFSMNT_RSIZE | NFSMNT_WSIZE;
nfsdiskless.swap_args.sotype = SOCK_DGRAM;
if ((tmp = (char *)substr(p,"rsize=")))
nfsdiskless.swap_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;
if ((tmp = (char *)substr(p,"intr")))
nfsdiskless.swap_args.flags |= NFSMNT_INT;
if ((tmp = (char *)substr(p,"soft")))
nfsdiskless.swap_args.flags |= NFSMNT_SOFT;
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)
printf (",intr");
if (nfsdiskless.swap_args.sotype == SOCK_STREAM)
printf (",tcp");
else
printf (",udp");
printf ("\r\n");
}
mountopts("Swapfs",&nfsdiskless.swap_args,p);
}
/**************************************************************************

View File

@ -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 @@ load()
}
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 @@ load()
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++)

View File

@ -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.

View File

@ -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 {

View File

@ -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 @@ eth_probe()
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)]));

View File

@ -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);
}
}

View File

@ -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