Return to BSD News archive
Path: sserve!newshost.anu.edu.au!munnari.oz.au!spool.mu.edu!howland.reston.ans.net!gatech!news-feed-1.peachnet.edu!emory!ogicse!psgrain!percy!agora!implode!davidg From: davidg@implode.rain.com (David Greenman) Newsgroups: comp.os.386bsd.questions Subject: Re: Diskless 386bsd ?? Message-ID: <C74wG3.106@implode.rain.com> Date: 16 May 93 19:21:38 GMT Article-I.D.: implode.C74wG3.106 Organization: Delta Systems, Portland, OR. Lines: 959 A friend of mine looked through his alt.sources archive and found the following. -DG # This is a shell archive. Save it in a file, remove anything before # this line, and then unpack it by entering "sh file". Note, it may # create directories; files and directories will be owned by you and # have default permissions. # # This archive contains: # # 319 # echo x - 319 sed 's/^X//' >319 << 'END-of-319' XNewsgroups: comp.os.386bsd.development XPath: percy!psgrain!uunet!usc!cs.utexas.edu!utnut!torn!mcshub!martin XFrom: martin@innovus.com (Martin Renters) XSubject: diskless 386bsd patches XMessage-ID: <1993Mar22.053826.17787@mcshub.dcss.mcmaster.ca> XSender: usenet@mcshub.dcss.mcmaster.ca XNntp-Posting-Host: foxtrot.innovus.com XOrganization: Innovus Inc., Hamilton, Ontario, Canada XDate: Mon, 22 Mar 1993 05:38:26 GMT XLines: 929 X XHere are the patches required to allow diskless 386bsd operation. The Xfollowing should be considered a BETA release since, while it provides Xthe diskless functionality, it still has some rough edges. In particular, Xthe setup program searches for a magic cookie in the kernel which it Xthen patches with the appropriate nfs_diskless structure, the hostname Xis not set up by the setup program, no boot rom exists yet, etc. X XTo configure a diskless 386bsd kernel: X X 1) un-shar the following file and apply the patch file 'diffs.out' X X 2) do a make install in /usr/src/usr.sbin/config to recompile the config X program X X 3) create a kernel description file in /sys/i386/conf, making sure X to add: X X option DISKLESS X config "386bsd" swap on nfs size 50000 X X The size in the above example indicates the number of 512 byte blocks X of swap space configured (ie: 25Mb). An example configuration is X included in the file DISKLESS in this package X X 4) generate a kernel: X X /usr/sbin/config DISKLESS X cd ../../compile/DISKLESS X make X X 5) Compile the program 'setup.c' on the NFS server which will provide X the root and swap file systems. This program has been tested on X HP-UX 9.0 (350 and 720) and a 386bsd system. It requires the use X of the getfh() system call which takes a filename as a parameter. X It will not work with versions that require a file descriptor X (HP-UX 8.X comes to mind). nfsdiskless.h must match X /sys/nfs/nfsdiskless.h on the 386bsd system. diskless.h contains X excerpts from socket.h, mount.h, if.h and nfsv2.h X X 6) copy the kernel created in step 4 into the directory the setup program X lives in. X X 7) ./setup -intf <your interface> -rootfs <your root> -swap <your swapfile> X -hostname <diskless hostname> -netmask <diskless netmask> X X eg: ./setup -intf we0 -rootfs /var/386bsd -swap /var/swap/alpha X -hostname alpha -netmask 255.255.255.0 X X 8) copy the resulting 386bsd file to a tinyBSD boot floppy. You will X probably need to remove most of the other files on the disk to make X enough space. X X 9) Boot with the disk. You will probably have to modify the /etc/rc X script so it doesn't try and fsck a non-existant filesystem, etc. X If you get a panic "nfs swap" it probably means you haven't exported X your filesystems correctly. X X XProblem areas: X X 1) NFS on 386bsd does not support the flock() system call. This prevents X the passwd(1) program and others from working. A wordaround would be X to use lock-files if the flock() function is not supported. X X 2) The setup program cannot re-setup a kernel. This is because the X magic cookie is overwritten. A better way of patching the kernel X would be to use the symbol table in the executable, but this is not X portable (easily at 1am in the morning) X X 3) The hostname should be configured by the setup program. X XAcknowledgements: X X Wolfgang Solfrank (ws@tools.de) provided input and some of the patches X from his implementation. X X The setup program is loosely based on a similar program in the 4.4BSD X distribution. X X XHave fun... X XMartin Renters martin@innovus.com X X X# This is a shell archive. Remove anything before this line, X# then unpack it by saving it in a file and typing "sh file". X# X# Wrapped by Martin Renters <martin@foxtrot> on Sun Mar 21 23:22:03 1993 X# X# This archive contains: X# diffs.out DISKLESS setup.c diskless.h X# nfsdiskless.h X# X XLANG=""; export LANG XPATH=/bin:/usr/bin:$PATH; export PATH X Xecho x - diffs.out Xcat >diffs.out <<'@EOF' X X*** /mnt/usr/src/sys.386bsd/i386/i386/pmap.c Tue Jan 26 20:11:25 1993 X--- /sys/i386/i386/pmap.c Sat Jan 30 10:24:35 1993 X*************** X*** 999,1004 **** X--- 999,1005 ---- X #endif X npv = (pv_entry_t) X malloc(sizeof *npv, M_VMPVENT, M_NOWAIT); X+ if (npv == NULL) panic("pmap_enter: malloc returned NULL"); X npv->pv_va = va; X npv->pv_pmap = pmap; X npv->pv_next = pv->pv_next; X*** /mnt/usr/src/sys.386bsd/i386/i386/autoconf.c Tue Jul 14 18:53:09 1992 X--- /sys/i386/i386/autoconf.c Fri Jan 29 16:48:38 1993 X*************** X*** 142,147 **** X--- 142,150 ---- X */ X setroot() X { X+ #ifdef DISKLESS X+ return; X+ #else X int majdev, mindev, unit, part, adaptor; X dev_t temp, orootdev; X struct swdevt *swp; X*************** X*** 189,192 **** X--- 192,196 ---- X if (temp == dumpdev) X dumpdev = swdevt[0].sw_dev; X #endif X+ #endif /* DISKLESS */ X } X*** /mnt/usr/src/sys.386bsd/kern/vfs_conf.c Mon May 25 02:43:56 1992 X--- /sys/kern/vfs_conf.c Fri Jan 29 15:07:30 1993 X*************** X*** 40,47 **** X--- 40,49 ---- X * This specifies the filesystem used to mount the root. X * This specification should be done by /etc/config. X */ X+ #ifndef DISKLESS X extern int ufs_mountroot(); X int (*mountroot)() = ufs_mountroot; X+ #endif X X /* X * These define the root filesystem and device. X*** /mnt/usr/src/sys.386bsd/nfs/nfsdiskless.h Tue Dec 24 14:24:15 1991 X--- /sys/nfs/nfsdiskless.h Sun Mar 21 18:23:19 1993 X*************** X*** 44,49 **** X--- 44,50 ---- X * For now it is statically initialized in swapvmunix.c, but someday a primary X * bootstrap should fill it in. X */ X+ #define NFSMNAMELEN 64 X struct nfs_diskless { X struct ifaliasreq myif; /* Info. for partial ifconfig */ X struct sockaddr mygateway; /* Default gateway for "route add" */ X*************** X*** 50,58 **** X struct nfs_args swap_args; /* Mount args for swap file */ X u_char swap_fh[NFS_FHSIZE]; /* Swap file's file handle */ X struct sockaddr swap_saddr; /* Address of swap server */ X! char *swap_hostnam; /* Host name for mount pt */ X struct nfs_args root_args; /* Mount args for root fs */ X u_char root_fh[NFS_FHSIZE]; /* File handle of root dir */ X struct sockaddr root_saddr; /* Address of root server */ X! char *root_hostnam; /* Host name for mount pt */ X }; X--- 51,59 ---- X struct nfs_args swap_args; /* Mount args for swap file */ X u_char swap_fh[NFS_FHSIZE]; /* Swap file's file handle */ X struct sockaddr swap_saddr; /* Address of swap server */ X! char swap_hostnam[NFSMNAMELEN]; /* Host name for mount pt */ X struct nfs_args root_args; /* Mount args for root fs */ X u_char root_fh[NFS_FHSIZE]; /* File handle of root dir */ X struct sockaddr root_saddr; /* Address of root server */ X! char root_hostnam[NFSMNAMELEN]; /* Host name for mount pt */ X }; X*** /mnt/usr/src/sys.386bsd/vm/swap_pager.c Tue Jan 26 20:16:16 1993 X--- /sys/vm/swap_pager.c Fri Jan 29 19:55:33 1993 X*************** X*** 593,598 **** X--- 593,599 ---- X splx(s); X bp->b_flags = B_BUSY | (flags & B_READ); X bp->b_proc = &proc0; /* XXX (but without B_PHYS set this is ok) */ X+ bp->b_rcred = bp->b_wcred = bp->b_proc->p_ucred; /* DISKLESS (WS)*/ X bp->b_un.b_addr = (caddr_t)kva; X bp->b_blkno = swb->swb_block + btodb(off); X VHOLD(swapdev_vp); X*************** X*** 625,630 **** X--- 626,633 ---- X spc->spc_m = m; X bp->b_flags |= B_CALL; X bp->b_iodone = swap_pager_iodone; X+ bp->b_dirtyoff = 0; /* DISKLESS: (WS) */ X+ bp->b_dirtyend = bp->b_bcount; X s = splbio(); X swp->sw_poip++; X queue_enter(&swap_pager_inuse, spc, swp_clean_t, spc_list); X*** bak/config.y Fri Mar 19 16:50:57 1993 X--- /usr/src/usr.sbin/config/config.y Fri Mar 19 18:42:33 1993 X*************** X*** 244,250 **** X = { X struct file_list *fl = newswap(); X X! if (eq($1, "generic")) X fl->f_fn = $1; X else { X fl->f_swapdev = nametodev($1, 0, 'b'); X--- 244,250 ---- X = { X struct file_list *fl = newswap(); X X! if (eq($1, "generic") || eq($1,"nfs")) X fl->f_fn = $1; X else { X fl->f_swapdev = nametodev($1, 0, 'b'); X*************** X*** 641,647 **** X */ X if (system->f_fn) X return; X! if (eq(fl->f_fn, "generic")) X system->f_fn = ns(fl->f_fn); X else X system->f_fn = ns(system->f_needs); X--- 641,647 ---- X */ X if (system->f_fn) X return; X! if (eq(fl->f_fn, "generic") || eq(fl->f_fn, "nfs")) X system->f_fn = ns(fl->f_fn); X else X system->f_fn = ns(system->f_needs); X*************** X*** 812,818 **** X { X char buf[BUFSIZ]; X register struct file_list *swap; X! int generic; X X if (fl == 0 || fl->f_type != SYSTEMSPEC) { X yyerror("internal error, bad system specification"); X--- 812,818 ---- X { X char buf[BUFSIZ]; X register struct file_list *swap; X! int generic,nfs; X X if (fl == 0 || fl->f_type != SYSTEMSPEC) { X yyerror("internal error, bad system specification"); X*************** X*** 820,826 **** X } X swap = fl->f_next; X generic = swap && swap->f_type == SWAPSPEC && eq(swap->f_fn, "generic"); X! if (fl->f_rootdev == NODEV && !generic) { X yyerror("no root device specified"); X exit(1); X } X--- 820,827 ---- X } X swap = fl->f_next; X generic = swap && swap->f_type == SWAPSPEC && eq(swap->f_fn, "generic"); X! nfs = swap && swap->f_type == SWAPSPEC && eq(swap->f_fn, "nfs"); X! if (fl->f_rootdev == NODEV && !generic && !nfs) { X yyerror("no root device specified"); X exit(1); X } X*************** X*** 912,918 **** X { X X for (;fl && fl->f_type == SWAPSPEC; fl = fl->f_next) { X! if (eq(fl->f_fn, "generic")) X continue; X if (alreadychecked(fl->f_swapdev, checked, pchecked)) X continue; X--- 913,919 ---- X { X X for (;fl && fl->f_type == SWAPSPEC; fl = fl->f_next) { X! if (eq(fl->f_fn, "generic") || eq(fl->f_fn, "nfs")) X continue; X if (alreadychecked(fl->f_swapdev, checked, pchecked)) X continue; X*** bak/mkswapconf.c Fri Mar 19 16:50:57 1993 X--- /usr/src/usr.sbin/config/mkswapconf.c Sat Mar 20 21:27:38 1993 X*************** X*** 79,84 **** X--- 79,93 ---- X } X fprintf(fp, "#include \"sys/param.h\"\n"); X fprintf(fp, "#include \"sys/conf.h\"\n"); X+ if (eq(fl->f_fn, "nfs")) { X+ fprintf(fp, "#include \"../sys/socket.h\"\n"); X+ fprintf(fp, "#include \"../sys/mount.h\"\n"); X+ fprintf(fp, "#include \"../net/if.h\"\n"); X+ fprintf(fp, "#include \"../nfs/nfsv2.h\"\n"); X+ fprintf(fp, "#include \"../nfs/nfsdiskless.h\"\n"); X+ fprintf(fp, "\nextern int nfs_mountroot();\n"); X+ fprintf(fp, "\nint (*mountroot)() = nfs_mountroot;\n"); X+ } X fprintf(fp, "\n"); X /* X * If there aren't any swap devices X*************** X*** 105,110 **** X--- 114,124 ---- X } while (swap && swap->f_type == SWAPSPEC); X fprintf(fp, "\t{ 0, 0, 0 }\n"); X fprintf(fp, "};\n"); X+ if (eq(fl->f_fn, "nfs")) { X+ fprintf(fp,"struct nfs_diskless nfs_diskless = {\n"); X+ fprintf(fp," { { 'D', 'i', 'S', 'k', 'L', 'e', 'S', 's', '\\0' }}\n"); X+ fprintf(fp,"};\n"); X+ } X fclose(fp); X return (swap); X } X@EOF X Xchmod 640 diffs.out X Xecho x - DISKLESS Xcat >DISKLESS <<'@EOF' X# X# DISKLESS - Diskless 386bsd with DDB X# Xmachine "i386" Xcpu "i386" Xident DISKLESS Xtimezone 5 dst Xmaxusers 10 Xoptions INET,NFS,UFS,DISKLESS,XSERVER Xoptions "COMPAT_43" Xoptions "TCP_COMPAT_42" X Xconfig "386bsd" swap on nfs size 50000 X Xcontroller isa0 X#controller wd0 at isa? port "IO_WD1" bio irq 14 vector wdintr X#disk wd0 at wd0 drive 0 X#disk wd0 at wd0 drive 1 X Xcontroller fd0 at isa? port "IO_FD1" bio irq 6 drq 2 vector fdintr Xdisk fd0 at fd0 drive 0 Xdisk fd1 at fd0 drive 1 X X#controller as0 at isa? port 0x330 bio irq 11 drq 5 vector asintr X#disk as0 at as0 drive 0 X#disk as1 at as0 drive 1 X Xdevice pc0 at isa? port "IO_KBD" tty irq 1 vector pcrint Xdevice npx0 at isa? port "IO_NPX" irq 13 vector npxintr Xdevice com1 at isa? port "IO_COM1" tty irq 4 vector comintr X#device com2 at isa? port "IO_COM2" tty irq 3 vector comintr X Xdevice we0 at isa? port 0x280 net irq 3 iomem 0xd0000 iosiz 8192 vector weintr X#device ne0 at isa? port 0x320 net irq 3 vector neintr X#device ec0 at isa? port 0x250 net irq 2 iomem 0xd8000 iosiz 8192 vector ecintr X Xdevice wt0 at isa? port 0x300 bio irq 5 drq 1 vector wtintr X Xpseudo-device loop Xpseudo-device ether Xpseudo-device sl 2 Xpseudo-device log Xpseudo-device ddb Xpseudo-device pty 4 X Xpseudo-device swappager Xpseudo-device vnodepager Xpseudo-device devpager X@EOF X Xchmod 640 DISKLESS X Xecho x - setup.c Xcat >setup.c <<'@EOF' X/************************************************************************* X XDiskless Configuration Program X XBased loosely on the 4.4BSD diskless setup code X X*************************************************************************/ X#include <stdio.h> X#include <fcntl.h> X#include <sys/stat.h> X#include <netdb.h> X X#include "diskless.h" X#include "nfsdiskless.h" X X#ifndef i386 /* Most other systems BIG ENDIAN */ X#define BIG_ENDIAN X#endif X Xstruct nfs_diskless nfs_diskless; X X#define MAGIC_COOKIE "DiSkLeSs" X#define NFS_SOCKET 2049 X X#define KW_HELP 0 X#define KW_INTERFACE 1 X#define KW_ROOTFS 2 X#define KW_SWAP 3 X#define KW_RSIZE 4 X#define KW_WSIZE 5 X#define KW_NETMASK 6 X#define KW_HOSTNAME 7 X#define KW_KERNEL 8 X Xstruct { X char *name; X int keyval; X} keywords[] = { X { "-intf", KW_INTERFACE }, X { "-rootfs", KW_ROOTFS }, X { "-swap", KW_SWAP }, X { "-netmask", KW_NETMASK }, X { "-rsize", KW_RSIZE }, X { "-wsize", KW_WSIZE }, X { "-hostname", KW_HOSTNAME }, X { "-kernel", KW_KERNEL }, X { NULL, KW_HELP } X}; X Xchar *hostname = "386bsd"; Xchar *kernel = "386bsd"; Xchar *rootpath = "/var/386bsd"; Xchar *swappath = "/var/swap/386bsd"; Xchar servername[256]; Xint rsize = 8192; Xint wsize = 8192; X Xmain(argc, argv) X int argc; char *argv[]; X{ X int fd,i,j,cmd; X unsigned int broadcast, netmask, myip; X struct hostent *hp; X struct stat statbuf; X char buf[1024]; X char *p, *q; X X netmask = 0; X bzero(&nfs_diskless, 0, sizeof(struct nfs_diskless)); X strcpy(nfs_diskless.myif.ifra_name,"we0"); X nfs_diskless.myif.ifra_addr.sa_len = sizeof(struct sockaddr); X nfs_diskless.myif.ifra_addr.sa_family = AF_INET; X nfs_diskless.myif.ifra_broadaddr.sa_len = sizeof(struct sockaddr); X nfs_diskless.myif.ifra_broadaddr.sa_family = AF_INET; X nfs_diskless.myif.ifra_mask.sa_len = sizeof(struct sockaddr); X nfs_diskless.myif.ifra_mask.sa_family = AF_UNSPEC; X nfs_diskless.swap_args.sotype = i386order(SOCK_DGRAM); X nfs_diskless.swap_args.flags = i386order(NFSMNT_WSIZE | NFSMNT_RSIZE); X nfs_diskless.swap_args.timeo = i386order(10); X nfs_diskless.swap_args.retrans = i386order(100); X nfs_diskless.swap_saddr.sa_len = sizeof(struct sockaddr); X nfs_diskless.swap_saddr.sa_family = AF_INET; X nfs_diskless.root_args.sotype = i386order(SOCK_DGRAM); X nfs_diskless.root_args.flags = i386order(NFSMNT_WSIZE | NFSMNT_RSIZE); X nfs_diskless.root_args.timeo = i386order(10); X nfs_diskless.root_args.retrans = i386order(100); X nfs_diskless.root_saddr.sa_len = sizeof(struct sockaddr); X nfs_diskless.root_saddr.sa_family = AF_INET; X X if (gethostname(servername, 256) < 0) { X fprintf(stderr,"%s: unable to get host server name\n",argv[0]); X exit(2); X } X if ((hp = gethostbyname(servername)) == NULL) { X fprintf(stderr,"%s: unable to get host address\n",argv[0]); X exit(2); X } X nfs_diskless.swap_saddr.sa_data[0] = nfs_diskless.root_saddr.sa_data[0] X = NFS_SOCKET >> 8; X nfs_diskless.swap_saddr.sa_data[1] = nfs_diskless.root_saddr.sa_data[1] X = NFS_SOCKET & 0x00FF; X bcopy(*hp->h_addr_list, &nfs_diskless.swap_saddr.sa_data[2], 4); X bcopy(*hp->h_addr_list, &nfs_diskless.root_saddr.sa_data[2], 4); X X i = 1; X while (i < argc) { X cmd = KW_HELP; X for (j=0; keywords[j].name; j++) { X if (!strcmp(keywords[j].name, argv[i])) { X if ((i+1) < argc) { X cmd = keywords[j].keyval; X break; X } X } X } X switch(cmd) { X case KW_HELP: X help(argv[0], argv[i]); X exit(2); X case KW_INTERFACE: X if (strlen(argv[i+1]) >= IFNAMSIZ) { X fprintf(stderr, X "%s: interface name '%s' too long.\n", X argv[0], argv[i+1]); X exit(2); X } X strcpy(nfs_diskless.myif.ifra_name, argv[i+1]); X i += 2; X break; X case KW_ROOTFS: X rootpath = argv[i+1]; X i += 2; X break; X case KW_SWAP: X swappath = argv[i+1]; X i += 2; X break; X case KW_RSIZE: X rsize = atoi(argv[i+1]); X i += 2; X break; X case KW_WSIZE: X wsize = atoi(argv[i+1]); X i += 2; X break; X case KW_NETMASK: X netmask = inet_addr(argv[i+1]); X i +=2; X break; X case KW_HOSTNAME: X hostname = argv[i+1]; X i += 2; X break; X case KW_KERNEL: X kernel = argv[i+1]; X i += 2; X break; X } X } X nfs_diskless.swap_args.rsize = i386order(rsize); X nfs_diskless.swap_args.wsize = i386order(wsize); X nfs_diskless.root_args.rsize = i386order(rsize); X nfs_diskless.root_args.wsize = i386order(wsize); X if ((hp = gethostbyname(hostname)) == NULL) { X fprintf(stderr,"%s: unable to get diskless address\n",argv[0]); X exit(2); X } X bcopy(*hp->h_addr_list, &nfs_diskless.myif.ifra_addr.sa_data[2], 4); X if (!netmask) { X unsigned char net; X net = nfs_diskless.myif.ifra_addr.sa_data[2]; X if (net <= 127) X netmask = inet_addr("255.0.0.0"); X else if (net < 192) X netmask = inet_addr("255.255.0.0"); X else netmask = inet_addr("255.255.255.0"); X } X bcopy(*hp->h_addr_list, &myip, 4); X broadcast = (myip & netmask) | ~netmask; X bcopy(&broadcast, &nfs_diskless.myif.ifra_broadaddr.sa_data[2], 4); X bcopy(&netmask, &nfs_diskless.myif.ifra_mask.sa_data[2], 4); X if (stat(rootpath, &statbuf) < 0) { X fprintf(stderr,"%s: unable to stat '%s'\n", X argv[0],rootpath); X exit(2); X } X if (!S_ISDIR(statbuf.st_mode)) { X fprintf(stderr,"%s: '%s' is not a directory\n", X argv[0],rootpath); X exit(2); X } X if (getfh(rootpath, nfs_diskless.root_fh) < 0) { X fprintf(stderr,"%s: unable to get handle for '%s'\n", X argv[0],rootpath); X exit(2); X } X sprintf(buf,"%s:%s",servername, rootpath); X buf[NFSMNAMELEN-1] = 0; X strcpy(nfs_diskless.root_hostnam,buf); X printf("root is on %s\n",nfs_diskless.root_hostnam); X if (stat(swappath, &statbuf) < 0) { X fprintf(stderr,"%s: unable to stat '%s'\n", X argv[0],swappath); X exit(2); X } X if (!S_ISREG(statbuf.st_mode)) { X fprintf(stderr,"%s: '%s' is not a regular file\n", X argv[0],swappath); X exit(2); X } X if (getfh(swappath, nfs_diskless.swap_fh) < 0) { X fprintf(stderr,"%s: unable to get handle for '%s'\n", X argv[0],swappath); X exit(2); X } X sprintf(buf,"%s:%s",servername, swappath); X buf[NFSMNAMELEN-1] = 0; X strcpy(nfs_diskless.swap_hostnam,buf); X printf("swap is on %s\n",nfs_diskless.swap_hostnam); X X /***********************/ X /* Now update kernel */ X /***********************/ X if (stat(kernel, &statbuf) < 0) { X fprintf(stderr,"%s: unable to stat '%s'\n", X argv[0],kernel); X exit(2); X } X if ((fd = open(kernel, O_RDWR)) < 0) { X fprintf(stderr,"%s: unable to open kernel file '%s'\n", X argv[0],kernel); X exit(2); X } X if ((p = q = malloc(statbuf.st_size)) == NULL) { X fprintf(stderr,"%s: unable to allocate memory for kernel\n", X argv[0]); X exit(2); X } X if (read(fd, p, statbuf.st_size) != statbuf.st_size) { X fprintf(stderr,"%s: unable to read kernel\n", X argv[0]); X exit(2); X } X while ((q < (p + statbuf.st_size)) && memcmp(q, MAGIC_COOKIE, X sizeof(MAGIC_COOKIE) - 1)) q++; X if (q == (p+statbuf.st_size)) { X fprintf(stderr,"%s: unable to find magic cookie in kernel '%s'\n", X argv[0],kernel); X exit(2); X } X printf("kernel size = %d bytes, nfs_diskless at offset %d\n", X statbuf.st_size, q-p); X bcopy(&nfs_diskless, q, sizeof(struct nfs_diskless)); X if (lseek(fd, 0L, SEEK_SET) < 0) { X fprintf(stderr,"%s: unable to rewind kernel '%s'\n", X argv[0],kernel); X exit(2); X } X if (write(fd, p, statbuf.st_size) != statbuf.st_size) { X fprintf(stderr,"%s: unable to write to kernel '%s'\n", X argv[0],kernel); X exit(2); X } X close(fd); X} X X/******************************************************************** XHELP - Print help message X********************************************************************/ Xhelp(prog, keywd) X char *prog, *keywd; X{ X int i; X fprintf(stderr,"%s: invalid keyword '%s' or not enough parameters\n",prog,keywd); X fprintf(stderr," valid keywords: "); X for (i=0; keywords[i].name; i++) fprintf(stderr,"%s ", keywords[i].name); X fprintf(stderr,"\n"); X} X X/********************************************************************* XI386ORDER - Byte swap X*********************************************************************/ Xi386order(i) X unsigned int i; X{ X#ifdef BIG_ENDIAN X return( ((i >> 24) & 0x000000FF) | X ((i >> 8) & 0x0000FF00) | X ((i << 8) & 0x00FF0000) | X ((i << 24) & 0xFF000000)); X#else X return(i); X#endif X} X@EOF X Xchmod 640 setup.c X Xecho x - diskless.h Xcat >diskless.h <<'@EOF' X/* X * Copyright (c) 1982,1985,1986,1988 Regents of the University of California. X * All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * 3. All advertising materials mentioning features or use of this software X * must display the following acknowledgement: X * This product includes software developed by the University of X * California, Berkeley and its contributors. X * 4. Neither the name of the University nor the names of its contributors X * may be used to endorse or promote products derived from this software X * without specific prior written permission. X * X * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE X * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF X * SUCH DAMAGE. X * X * @(#)socket.h 7.13 (Berkeley) 4/20/91 X */ X X/* X * Definitions related to sockets: types, address families, options. X */ X X/* X * Types X */ X#define SOCK_STREAM 1 /* stream socket */ X#define SOCK_DGRAM 2 /* datagram socket */ X#define SOCK_RAW 3 /* raw-protocol interface */ X#define SOCK_RDM 4 /* reliably-delivered message */ X#define SOCK_SEQPACKET 5 /* sequenced packet stream */ X X/* X * Option flags per-socket. X */ X#define SO_DEBUG 0x0001 /* turn on debugging info recording */ X#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */ X#define SO_REUSEADDR 0x0004 /* allow local address reuse */ X#define SO_KEEPALIVE 0x0008 /* keep connections alive */ X#define SO_DONTROUTE 0x0010 /* just use interface addresses */ X#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */ X#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */ X#define SO_LINGER 0x0080 /* linger on close if data present */ X#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */ X X/* X * Additional options, not kept in so_options. X */ X#define SO_SNDBUF 0x1001 /* send buffer size */ X#define SO_RCVBUF 0x1002 /* receive buffer size */ X#define SO_SNDLOWAT 0x1003 /* send low-water mark */ X#define SO_RCVLOWAT 0x1004 /* receive low-water mark */ X#define SO_SNDTIMEO 0x1005 /* send timeout */ X#define SO_RCVTIMEO 0x1006 /* receive timeout */ X#define SO_ERROR 0x1007 /* get error status and clear */ X#define SO_TYPE 0x1008 /* get socket type */ X X/* X * Structure used for manipulating linger option. X */ Xstruct linger { X int l_onoff; /* option on/off */ X int l_linger; /* linger time */ X}; X X/* X * Level number for (get/set)sockopt() to apply to socket itself. X */ X#define SOL_SOCKET 0xffff /* options for socket level */ X X/* X * Address families. X */ X#define AF_UNSPEC 0 /* unspecified */ X#define AF_UNIX 1 /* local to host (pipes, portals) */ X#define AF_INET 2 /* internetwork: UDP, TCP, etc. */ X#define AF_IMPLINK 3 /* arpanet imp addresses */ X#define AF_PUP 4 /* pup protocols: e.g. BSP */ X#define AF_CHAOS 5 /* mit CHAOS protocols */ X#define AF_NS 6 /* XEROX NS protocols */ X#define AF_ISO 7 /* ISO protocols */ X#define AF_OSI AF_ISO X#define AF_ECMA 8 /* european computer manufacturers */ X#define AF_DATAKIT 9 /* datakit protocols */ X#define AF_CCITT 10 /* CCITT protocols, X.25 etc */ X#define AF_SNA 11 /* IBM SNA */ X#define AF_DECnet 12 /* DECnet */ X#define AF_DLI 13 /* DEC Direct data link interface */ X#define AF_LAT 14 /* LAT */ X#define AF_HYLINK 15 /* NSC Hyperchannel */ X#define AF_APPLETALK 16 /* Apple Talk */ X#define AF_ROUTE 17 /* Internal Routing Protocol */ X#define AF_LINK 18 /* Link layer interface */ X#define pseudo_AF_XTP 19 /* eXpress Transfer Protocol (no AF) */ X X#define AF_MAX 20 X X/* X * Structure used by kernel to store most X * addresses. X */ Xstruct sockaddr { X u_char sa_len; /* total length */ X u_char sa_family; /* address family */ X char sa_data[14]; /* actually longer; address value */ X}; X X#define IFNAMSIZ 16 X Xstruct ifaliasreq { X char ifra_name[IFNAMSIZ]; /* if name, e.g. "en0" */ X struct sockaddr ifra_addr; X struct sockaddr ifra_broadaddr; X struct sockaddr ifra_mask; X}; X X X/* X * File Handle (32 bytes for version 2), variable up to 1024 for version 3 X */ X X#define NFS_FHSIZE 32 Xtypedef struct { u_char f[NFS_FHSIZE] } nfsv2fh_t; X/* X * Arguments to mount NFS X */ Xstruct nfs_args { X struct sockaddr *addr; /* file server address */ X int sotype; /* Socket type */ X int proto; /* and Protocol */ X nfsv2fh_t *fh; /* File handle to be mounted */ X int flags; /* flags */ X int wsize; /* write size in bytes */ X int rsize; /* read size in bytes */ X int timeo; /* initial timeout in .1 secs */ X int retrans; /* times to retry send */ X char *hostname; /* server's name */ X}; X/* X * NFS mount option flags X */ X#define NFSMNT_SOFT 0x0001 /* soft mount (hard is default) */ X#define NFSMNT_WSIZE 0x0002 /* set write size */ X#define NFSMNT_RSIZE 0x0004 /* set read size */ X#define NFSMNT_TIMEO 0x0008 /* set initial timeout */ X#define NFSMNT_RETRANS 0x0010 /* set number of request retrys */ X#define NFSMNT_HOSTNAME 0x0020 /* set hostname for error printf */ X#define NFSMNT_INT 0x0040 /* allow interrupts on hard mount */ X#define NFSMNT_NOCONN 0x0080 /* Don't Connect the socket */ X#define NFSMNT_SCKLOCK 0x0100 /* Lock socket against others */ X#define NFSMNT_WANTSCK 0x0200 /* Want a socket lock */ X#define NFSMNT_SPONGY 0x0400 /* spongy mount (soft for stat and lookup) */ X#define NFSMNT_COMPRESS 0x0800 /* Compress nfs rpc xdr */ X#define NFSMNT_LOCKBITS (NFSMNT_SCKLOCK | NFSMNT_WANTSCK) X X@EOF X Xchmod 644 diskless.h X Xecho x - nfsdiskless.h Xcat >nfsdiskless.h <<'@EOF' X/* X * Copyright (c) 1991 The Regents of the University of California. X * All rights reserved. X * X * This code is derived from software contributed to Berkeley by X * Rick Macklem at The University of Guelph. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * 3. All advertising materials mentioning features or use of this software X * must display the following acknowledgement: X * This product includes software developed by the University of X * California, Berkeley and its contributors. X * 4. Neither the name of the University nor the names of its contributors X * may be used to endorse or promote products derived from this software X * without specific prior written permission. X * X * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE X * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF X * SUCH DAMAGE. X * X * @(#)nfsdiskless.h 7.1 (Berkeley) 3/4/91 X */ X X/* X * Structure that must be initialized for a diskless nfs client. X * This structure is used by nfs_mountroot() to set up the root and swap X * vnodes plus do a partial ifconfig(8) and route(8) so that the critical net X * interface can communicate with the server. X * For now it is statically initialized in swapvmunix.c, but someday a primary X * bootstrap should fill it in. X */ X#define NFSMNAMELEN 64 Xstruct nfs_diskless { X struct ifaliasreq myif; /* Info. for partial ifconfig */ X struct sockaddr mygateway; /* Default gateway for "route add" */ X struct nfs_args swap_args; /* Mount args for swap file */ X u_char swap_fh[NFS_FHSIZE]; /* Swap file's file handle */ X struct sockaddr swap_saddr; /* Address of swap server */ X char swap_hostnam[NFSMNAMELEN]; /* Host name for mount pt */ X struct nfs_args root_args; /* Mount args for root fs */ X u_char root_fh[NFS_FHSIZE]; /* File handle of root dir */ X struct sockaddr root_saddr; /* Address of root server */ X char root_hostnam[NFSMNAMELEN]; /* Host name for mount pt */ X}; X@EOF X Xchmod 640 nfsdiskless.h X Xexit 0 END-of-319 exit