Date: Sun, 28 Jun 98 17:28:25 +0100 (BST) From: iedowse@maths.tcd.ie To: FreeBSD-gnats-submit@FreeBSD.ORG Subject: i386/7098: Various netboot fixes Message-ID: <9806281728.aa09864@walton.maths.tcd.ie>
next in thread | raw e-mail | index | archive | help
>Number: 7098 >Category: i386 >Synopsis: Various netboot fixes >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sun Jun 28 09:30:01 PDT 1998 >Last-Modified: >Originator: Ian Dowse >Organization: School of Mathematics, Trinity College Dublin >Release: FreeBSD 2.2.6-STABLE i386 >Environment: FreeBSD stable and current, using netboot for diskless booting. >Description: These are a selection of small problems and annoyances with the netboot code. Apart from the first one, none really affect typical configurations but are nevertheless unnecessary limitations. We use netbooted PCs as student X-terminals and all of the below fixes have been useful. Apologies for including them all in one PR, but some are just too silly or trivial to send on their own! If anyone is interested, I also have a version of netboot which works on the Intel Etherexpress Pro/100 cards. I haven't used it with a flash rom on the card yet though. a) Newer SMC cards have hardware addresses starting with 00:E0. Netboot compares the MAC address with 00:00:C0 to determine if it is a WD/SMC card, so it fails to detect these. b) Netboot is unable to boot kzipped kernels, as it assumes that the kernel load address is 0x100000. c) Users can abort the booting process and enter arbitrary network addresses, or boot from a floppy disk. This can be a problem when netbooted machines are used in a student environment. d) It is not possible to set all options via bootp. For example there is no way to remotely force a client to boot from disk. With both SECURE_BOOT(patch below) and NO_TFTP defined, short of unplugging the eprom there is no way at all to get the client to boot locally. A generic solution is to allow complete netboot commands to be sent using bootp lines such as: :T132="diskboot": e) The last character of netboot command names is not checked. You can type 'iz 10.0.0.1' and it will be interpreted as 'ip'. This is only important if you try to add a new command which is the same as an existing one except for the last character. f) We have a configuration where multiple servers are willing to serve a diskless client. The tftp config file, or the bootptab entry on each server must specify the root and swap filesystems as 'ip:/fs' even though 'ip' will usually be the responding server's IP address. It would be nice if netboot could automatically prepend the server's IP address to an entry specified as just '/fs', so that multiple servers can use the same tftp or bootp configuration files. Admittedly this is hardly a major problem! >How-To-Repeat: a) Try to use netboot with a new SMC card. b) Try to netboot a kzip'd kernel c) Install netboot clients in a student computer lab and watch what happens :) d) Try to send a 'diskboot' command via bootp. e) Add a new command 'd' to the bootcmds array, and when typed, it will be treated as '?', the first 1-character command. f) Set up a multiple-server configuration; bootp or tftp config files from one server cannot copied directly to others. >Fix: a) diff -c ../netboot.old/ns8390.c ./ns8390.c *** ../netboot.old/ns8390.c Sun Aug 24 00:38:12 1997 --- ./ns8390.c Sun Jun 28 02:44:59 1998 *************** *** 82,89 **** chksum = 0; /* Check for WD/SMC card by checking ethernet address */ if (inb(eth_asic_base+8) != 0) continue; ! if (inb(eth_asic_base+9) != 0) continue; ! if (inb(eth_asic_base+10) != 0xC0) continue; for (i=8; i<16; i++) chksum += inb(i+eth_asic_base); if ((chksum & 0x00FF) == 0x00FF) --- 82,91 ---- chksum = 0; /* Check for WD/SMC card by checking ethernet address */ if (inb(eth_asic_base+8) != 0) continue; ! if (inb(eth_asic_base+9) != 0xE0) { ! if (inb(eth_asic_base+9) != 0) continue; ! if (inb(eth_asic_base+10) != 0xC0) continue; ! } for (i=8; i<16; i++) chksum += inb(i+eth_asic_base); if ((chksum & 0x00FF) == 0x00FF) b) diff -c ../netboot.old/main.c ./main.c *** ../netboot.old/main.c Sun Jan 18 23:16:27 1998 --- ./main.c Sun Jun 28 02:59:50 1998 *************** *** 292,298 **** printf("Bad executable format!\r\n"); longjmp(jmp_bootmenu, 1); } ! loadpoint = (char *)0x100000; offset = N_TXTOFF(head); printf("text=0x%X, ",head.a_text); nfsload(head.a_text); --- 292,298 ---- printf("Bad executable format!\r\n"); longjmp(jmp_bootmenu, 1); } ! loadpoint = (char *)(head.a_entry & 0x00FFFFFF); offset = N_TXTOFF(head); printf("text=0x%X, ",head.a_text); nfsload(head.a_text); c) diff -c ../netboot.old/Makefile ./Makefile *** ../netboot.old/Makefile Sat Mar 7 11:20:13 1998 --- ./Makefile Sun Jun 28 15:46:19 1998 *************** *** 3,8 **** --- 3,9 ---- # Makefile for NETBOOT # # Basic Options: + # -DSECURE_BOOT - Disable 'boot>' prompt completely # -DASK_BOOT - Ask "Boot from Network (Y/N) ?" at startup # -DROMSIZE - Size of EPROM - Must be set (even for .COM files) # -DRELOC - Relocation address (usually 0x90000) diff -c ../netboot.old/bootmenu.c ./bootmenu.c *** ../netboot.old/bootmenu.c Wed May 14 03:44:26 1997 --- ./bootmenu.c Sun Jun 28 03:41:20 1998 *************** *** 327,332 **** --- 338,355 ---- { char cmd[80]; int ptr, c; + #ifdef SECURE_BOOT + char *p; + + printf("\r\n"); + + printf("Press any key to retry:"); + while (iskey()) + getchar(); + getchar(); + printf("\r\n"); + eth_probe(); + #else printf("\r\n"); while (1) { ptr = 0; *************** *** 349,353 **** --- 372,377 ---- printf("\r\n"); if (execute(cmd)) break; } + #endif eth_reset(); } diff -c ../netboot.old/main.c ./main.c *** ../netboot.old/main.c Sun Jan 18 23:16:27 1998 --- ./main.c Sun Jun 28 02:59:50 1998 *************** *** 343,349 **** --- 343,351 ---- **************************************************************************/ pollkbd() { + #ifndef SECURE_BOOT if (iskey() && (getchar() == ESC)) longjmp(jmp_bootmenu,1); + #endif } /************************************************************************** d) diff -c ../netboot.old/main.c ./main.c *** ../netboot.old/main.c Sun Jan 18 23:16:27 1998 --- ./main.c Sun Jun 28 02:59:50 1998 *************** *** 657,662 **** --- 659,676 ---- break; case 131: /* swap mount options */ bootp_string("swapopts", p); + break; + case 132: /* any other options */ + case 133: + case 134: + case 135: + case 136: + case 137: + case 138: + case 139: + case 140: + case 141: + bootp_string("", p); break; default: printf("Unknown RFC1048-tag "); e) diff -c ../netboot.old/bootmenu.c ./bootmenu.c *** ../netboot.old/bootmenu.c Wed May 14 03:44:26 1997 --- ./bootmenu.c Sun Jun 28 03:41:20 1998 *************** *** 305,311 **** while(cmd->name) { p = buf; q = cmd->name; ! while (*q && (*(q++) == *(p++))) ; if ((!(*q)) && ((*p == ' ') || (*p == '\t') || (!(*p)))) { if (!cmd->func) return(1); --- 315,322 ---- while(cmd->name) { p = buf; q = cmd->name; ! while (*q && *q == *p++) ! q++; if ((!(*q)) && ((*p == ' ') || (*p == '\t') || (!(*p)))) { if (!cmd->func) return(1); f) diff -c ../netboot.old/bootmenu.c ./bootmenu.c *** ../netboot.old/bootmenu.c Wed May 14 03:44:26 1997 --- ./bootmenu.c Sun Jun 28 02:58:42 1998 *************** *** 32,39 **** {"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"}, {"swapopts", cmd_swapopts, "<options> swap mount options"}, {"rootopts", cmd_rootopts, "<options> root mount options"}, --- 32,39 ---- {"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"}, {"swapopts", cmd_swapopts, "<options> swap mount options"}, {"rootopts", cmd_rootopts, "<options> root mount options"}, *************** *** 160,176 **** cmd_rootfs(p) char *p; { ! if (!setip(p, &arptable[ARP_ROOTSERVER].ipaddr)) { printf("Root filesystem is %I:%s\r\n", nfsdiskless.root_saddr.sin_addr, nfsdiskless.root_hostnam); } else { - bcopy(&arptable[ARP_ROOTSERVER].ipaddr, - &nfsdiskless.root_saddr.sin_addr, 4); while (*p && (*p != ':')) p++; if (*p == ':') p++; - sprintf(&nfsdiskless.root_hostnam, "%s", p); } } /************************************************************************** --- 160,181 ---- cmd_rootfs(p) char *p; { ! if (*p == '/') { ! bcopy(&arptable[ARP_SERVER].ipaddr, ! &arptable[ARP_ROOTSERVER].ipaddr, 4); ! } else if (!setip(p, &arptable[ARP_ROOTSERVER].ipaddr)) { printf("Root filesystem is %I:%s\r\n", nfsdiskless.root_saddr.sin_addr, nfsdiskless.root_hostnam); + return; } else { while (*p && (*p != ':')) p++; if (*p == ':') p++; } + + bcopy(&arptable[ARP_ROOTSERVER].ipaddr, + &nfsdiskless.root_saddr.sin_addr, 4); + sprintf(&nfsdiskless.root_hostnam, "%s", p); } /************************************************************************** *************** *** 179,195 **** cmd_swapfs(p) char *p; { ! if (!setip(p, &arptable[ARP_SWAPSERVER].ipaddr)) { printf("Swap filesystem is %I:%s\r\n", nfsdiskless.swap_saddr.sin_addr, nfsdiskless.swap_hostnam); } else { - bcopy(&arptable[ARP_SWAPSERVER].ipaddr, - &nfsdiskless.swap_saddr.sin_addr, 4); while (*p && (*p != ':')) p++; if (*p == ':') p++; - sprintf(&nfsdiskless.swap_hostnam, "%s", p); } } /************************************************************************** --- 184,205 ---- cmd_swapfs(p) char *p; { ! if (*p == '/') { ! bcopy(&arptable[ARP_SERVER].ipaddr, ! &arptable[ARP_SWAPSERVER].ipaddr, 4); ! } else if (!setip(p, &arptable[ARP_SWAPSERVER].ipaddr)) { printf("Swap filesystem is %I:%s\r\n", nfsdiskless.swap_saddr.sin_addr, nfsdiskless.swap_hostnam); + return; } else { while (*p && (*p != ':')) p++; if (*p == ':') p++; } + + bcopy(&arptable[ARP_SWAPSERVER].ipaddr, + &nfsdiskless.swap_saddr.sin_addr, 4); + sprintf(&nfsdiskless.swap_hostnam, "%s", p); } /************************************************************************** >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?9806281728.aa09864>