Index: distrib/amd64/ramdisk_cd/list.local =================================================================== RCS file: /cvs/src/distrib/amd64/ramdisk_cd/list.local,v retrieving revision 1.10 diff -u -p -r1.10 list.local --- distrib/amd64/ramdisk_cd/list.local 26 Jun 2008 16:31:01 -0000 1.10 +++ distrib/amd64/ramdisk_cd/list.local 30 Sep 2008 01:35:42 -0000 @@ -23,3 +23,6 @@ COPY ${DESTDIR}/etc/firmware/zd1211b et # dhcp things SCRIPT ${DESTDIR}/sbin/dhclient-script sbin/dhclient-script SPECIAL chmod 755 sbin/dhclient-script + +# netboot automated install script +SCRIPT ${CURDIR}/../../miniroot/install.netboot install.netboot Index: distrib/i386/ramdisk_cd/list.local =================================================================== RCS file: /cvs/src/distrib/i386/ramdisk_cd/list.local,v retrieving revision 1.18 diff -u -p -r1.18 list.local --- distrib/i386/ramdisk_cd/list.local 26 Jun 2008 16:31:01 -0000 1.18 +++ distrib/i386/ramdisk_cd/list.local 30 Sep 2008 01:35:42 -0000 @@ -40,3 +40,6 @@ COPY ${DESTDIR}/etc/firmware/zd1211b et #COPY ${DESTDIR}/etc/firmware/atu-rfmd2958-int etc/firmware/atu-rfmd2958-int #COPY ${DESTDIR}/etc/firmware/atu-rfmd2958smc-ext etc/firmware/atu-rfmd2958smc-ext #COPY ${DESTDIR}/etc/firmware/atu-rfmd2958smc-int etc/firmware/atu-rfmd2958smc-int + +# netboot automated install script +SCRIPT ${CURDIR}/../../miniroot/install.netboot install.netboot Index: distrib/miniroot/dot.profile =================================================================== RCS file: /cvs/src/distrib/miniroot/dot.profile,v retrieving revision 1.8 diff -u -p -r1.8 dot.profile --- distrib/miniroot/dot.profile 3 Aug 2008 14:18:00 -0000 1.8 +++ distrib/miniroot/dot.profile 30 Sep 2008 01:35:43 -0000 @@ -42,12 +42,17 @@ rootdisk=$3 if [ "X${DONEPROFILE}" = "X" ]; then DONEPROFILE=YES + export DONEPROFILE mount -u /dev/${rootdisk:-rd0a} / # set up some sane defaults echo 'erase ^?, werase ^W, kill ^U, intr ^C, status ^T' stty newcrt werase ^W intr ^C kill ^U erase ^? status ^T + + if [ -f /install.netboot ]; then + . /install.netboot + fi # Installing or upgrading? _forceloop="" Index: distrib/miniroot/install.netboot =================================================================== RCS file: distrib/miniroot/install.netboot diff -N distrib/miniroot/install.netboot --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ distrib/miniroot/install.netboot 30 Sep 2008 01:35:43 -0000 @@ -0,0 +1,55 @@ +echo "Checking for netboot..." +netboot_if=`ifconfig netboot | sed -n 's/:.*//;p;q'` + +if [ "X$netboot_if" != "X" ]; then + echo "netboot detected on $netboot_if" + echo "ifconfig $netboot_if:" + ifconfig $netboot_if + + mac=`ifconfig $netboot_if | sed -n '/lladdr/h;${g;s/.*lladdr \(.*\)/\1/;s/://g;p;}'` + vers=`dmesg|sed -n '/^OpenBSD /h;${g;s/OpenBSD \([^-]*\)-.*/\1/;p;}'` + arch=`dmesg|sed -n '/arch\/.*\/compile/h;${g;s#.*arch/\([^/]*\)/compile.*#\1#p;}'` + + echo "Configure dhclient for option-225..." + cat > /etc/dhclient.conf <<__EOT +request subnet-mask, broadcast-address, time-offset, routers, domain-name, + domain-name-servers, host-name, ntp-servers, option-225; +require option-225; +__EOT + + echo "Run dhclient for interface: netboot=$netboot_if..." + dhclient $netboot_if + + url=`sed -n '/option-225/h;${g;s/^[^"]*"\([^"]*\)".*/\1/;p;}' \ + < /var/db/dhclient.leases.$netboot_if` + + if [ "X$url" = "X" ]; then + echo "No boot script found:" + echo "dhclient.leases:" + cat /var/db/dhclient.leases.$netboot_if + echo "dhclient.conf:" + cat /etc/dhclient.conf + else + echo "Boot script base url: $url" + for option in $url.$mac $url.OpenBSD-$vers-$arch $url; do + ftp -o /bootscript $option + if [ -f /bootscript ]; then + echo "Executing boot script from $option..." + chmod +x /bootscript + echo " with args: $netboot_if $option $vers $arch" + /bootscript $netboot_if $option $vers $arch + echo "Return from $option" + rm /bootscript + break + fi + done + fi + + echo "Cleaning up $netboot_if..." + rm /etc/dhclient.conf + rm /var/db/dhclient.leases.$netboot_if + ifconfig $netboot_if down + ifconfig $netboot_if delete + + echo "Finished install.netboot..." +fi Index: sys/arch/amd64/stand/libsa/pxe.c =================================================================== RCS file: /cvs/src/sys/arch/amd64/stand/libsa/pxe.c,v retrieving revision 1.5 diff -u -p -r1.5 pxe.c --- sys/arch/amd64/stand/libsa/pxe.c 27 Jul 2007 17:48:01 -0000 1.5 +++ sys/arch/amd64/stand/libsa/pxe.c 30 Sep 2008 01:37:01 -0000 @@ -110,6 +110,7 @@ void pxecall_bangpxe(u_int16_t); /* pxe_ void pxecall_pxenv(u_int16_t); /* pxe_call.S */ char pxe_command_buf[256]; +extern char boot_mac_str[14]; BOOTPLAYER bootplayer; @@ -207,6 +208,9 @@ static struct iodesc desc; int pxe_netif_open() { + char hexdigits[] = "0123456789abcdef"; + int i; + t_PXENV_UDP_OPEN *uo = (void *) pxe_command_buf; #ifdef NETIF_DEBUG @@ -232,6 +236,13 @@ pxe_netif_open() } bcopy(bootplayer.CAddr, desc.myea, ETHER_ADDR_LEN); + addbootarg(BOOTARG_BOOTMAC, sizeof(bios_bootmac_t), bootplayer.CAddr); + boot_mac_str[0] = '.'; + for (i = 1; i <= 12; i += 2) { + boot_mac_str[i] = hexdigits[desc.myea[i / 2] >> 4 & 0xf]; + boot_mac_str[i+1] = hexdigits[desc.myea[i / 2] & 0xf]; + } + boot_mac_str[13] = '\0'; /* ensure proper termination */ bootmac = bootplayer.CAddr; /* Index: sys/arch/amd64/stand/pxeboot/Makefile =================================================================== RCS file: /cvs/src/sys/arch/amd64/stand/pxeboot/Makefile,v retrieving revision 1.8 diff -u -p -r1.8 Makefile --- sys/arch/amd64/stand/pxeboot/Makefile 25 Nov 2007 18:25:30 -0000 1.8 +++ sys/arch/amd64/stand/pxeboot/Makefile 30 Sep 2008 01:37:01 -0000 @@ -12,6 +12,7 @@ PROG= pxeboot SRCS= srt0.S conf.c devopen.c net.c open.c LD?= ld SIZE?= size +CPPFLAGS+=-DPXEBOOT LDFLAGS+=-melf_i386 -nostdlib -Bstatic -Ttext $(LINKADDR) -N -x -noinhibit-exec LDFLAGS+=-L/usr/libdata INSTALL_STRIP= @@ -43,6 +44,12 @@ SRCS+= divdi3.c moddi3.c qdivrem.c .PATH: ${S}/lib/libz SRCS+= adler32.c crc32.c inflate.c inftrees.c + +# version info for pxeboot +SRCS+= vers.c + +vers.c: $S/conf/newvers.sh + sh $S/conf/newvers.sh ${PROG}: $(OBJS) $(LD) $(LDFLAGS) -o ${PROG} $(OBJS) Index: sys/arch/amd64/stand/pxeboot/pxeboot.8 =================================================================== RCS file: /cvs/src/sys/arch/amd64/stand/pxeboot/pxeboot.8,v retrieving revision 1.9 diff -u -p -r1.9 pxeboot.8 --- sys/arch/amd64/stand/pxeboot/pxeboot.8 31 May 2007 19:20:02 -0000 1.9 +++ sys/arch/amd64/stand/pxeboot/pxeboot.8 30 Sep 2008 01:37:02 -0000 @@ -50,11 +50,32 @@ The ROM downloads the boot program using .Pp The .Nm -boot program will look for an +boot program searches for a configuration file on the TFTP server +using paths in the following order: +.Bd -literal -offset indent +.Bl -item -compact +.It +.Pa /etc/boot.conf.x0x1x2x3x4x5 +.It +.Pa /etc/boot.conf.OpenBSD-mm.nn-arch +.It .Pa /etc/boot.conf -configuration -file on the TFTP server. -If it finds one, it processes the commands within it. +.El +.Ed +.Pp +where +.Em x0x1x2x3x4x5 +corresponds to the hardware address of the +PXE network interface with the colons removed, +.Em mm.nn +is the version number as reported by +.Ic uname -r +and +.Em arch +is the machine architecture as reported by +.Ic uname -m +.Nm +will only exectute the commands in the first file found. .Pa boot.conf processing can be skipped by holding down either Control key as .Nm @@ -74,9 +95,7 @@ kernel .Pa bsd via TFTP. It may be told to boot an alternative kernel, -either by commands in the -.Pa boot.conf -file, +either by commands in the configuration file, or by commands typed by the user at the .Ic boot\*(Gt prompt. Index: sys/arch/i386/stand/libsa/Makefile =================================================================== RCS file: /cvs/src/sys/arch/i386/stand/libsa/Makefile,v retrieving revision 1.47 diff -u -p -r1.47 Makefile --- sys/arch/i386/stand/libsa/Makefile 30 May 2007 01:25:43 -0000 1.47 +++ sys/arch/i386/stand/libsa/Makefile 30 Sep 2008 01:37:03 -0000 @@ -45,6 +45,12 @@ SRCS+= ufs.c nfs.c tftp.c cd9660.c # debugger SRCS+= debug.c +# version info for pxeboot +SRCS+= vers.c + +vers.c: $S/conf/newvers.sh + sh $S/conf/newvers.sh + NOPROFILE=noprofile NOPIC=nopic Index: sys/arch/i386/stand/libsa/pxe.c =================================================================== RCS file: /cvs/src/sys/arch/i386/stand/libsa/pxe.c,v retrieving revision 1.5 diff -u -p -r1.5 pxe.c --- sys/arch/i386/stand/libsa/pxe.c 27 Jul 2007 17:46:56 -0000 1.5 +++ sys/arch/i386/stand/libsa/pxe.c 30 Sep 2008 01:37:04 -0000 @@ -110,6 +110,7 @@ void pxecall_bangpxe(u_int16_t); /* pxe_ void pxecall_pxenv(u_int16_t); /* pxe_call.S */ char pxe_command_buf[256]; +extern char boot_mac_str[14]; BOOTPLAYER bootplayer; @@ -207,6 +208,9 @@ static struct iodesc desc; int pxe_netif_open() { + char hexdigits[] = "0123456789abcdef"; + int i; + t_PXENV_UDP_OPEN *uo = (void *) pxe_command_buf; #ifdef NETIF_DEBUG @@ -232,6 +236,13 @@ pxe_netif_open() } bcopy(bootplayer.CAddr, desc.myea, ETHER_ADDR_LEN); + addbootarg(BOOTARG_BOOTMAC, sizeof(bios_bootmac_t), bootplayer.CAddr); + boot_mac_str[0] = '.'; + for (i = 1; i < 12; i += 2) { + boot_mac_str[i] = hexdigits[desc.myea[i / 2] >> 4 & 0xf]; + boot_mac_str[i+1] = hexdigits[desc.myea[i / 2] & 0xf]; + } + boot_mac_str[13] = '\0'; /* ensure proper termination */ bootmac = bootplayer.CAddr; /* Index: sys/arch/i386/stand/pxeboot/Makefile =================================================================== RCS file: /cvs/src/sys/arch/i386/stand/pxeboot/Makefile,v retrieving revision 1.3 diff -u -p -r1.3 Makefile --- sys/arch/i386/stand/pxeboot/Makefile 25 Nov 2007 18:25:32 -0000 1.3 +++ sys/arch/i386/stand/pxeboot/Makefile 30 Sep 2008 01:37:04 -0000 @@ -8,6 +8,7 @@ MAN= pxeboot.8 PROG= pxeboot LD?= ld SIZE?= size +CPPFLAGS+=-DPXEBOOT LDFLAGS+=-nostdlib -Bstatic INSTALL_STRIP= Index: sys/arch/i386/stand/pxeboot/pxeboot.8 =================================================================== RCS file: /cvs/src/sys/arch/i386/stand/pxeboot/pxeboot.8,v retrieving revision 1.8 diff -u -p -r1.8 pxeboot.8 --- sys/arch/i386/stand/pxeboot/pxeboot.8 31 May 2007 19:20:03 -0000 1.8 +++ sys/arch/i386/stand/pxeboot/pxeboot.8 30 Sep 2008 01:37:04 -0000 @@ -50,11 +50,32 @@ The ROM downloads the boot program using .Pp The .Nm -boot program will look for an +boot program searches for a configuration file on the TFTP server +using paths in the following order: +.Bd -literal -offset indent +.Bl -item -compact +.It +.Pa /etc/boot.conf.x0x1x2x3x4x5 +.It +.Pa /etc/boot.conf.OpenBSD-mm.nn-arch +.It .Pa /etc/boot.conf -configuration -file on the TFTP server. -If it finds one, it processes the commands within it. +.El +.Ed +.Pp +where +.Em x0x1x2x3x4x5 +corresponds to the hardware address of the +PXE network interface with the colons removed, +.Em mm.nn +is the version number as reported by +.Ic uname -r +and +.Em arch +is the machine architecture as reported by +.Ic uname -m +.Nm +will only exectute the commands in the first file found. .Pa boot.conf processing can be skipped by holding down either Control key as .Nm @@ -74,9 +95,7 @@ kernel .Pa bsd via TFTP. It may be told to boot an alternative kernel, -either by commands in the -.Pa boot.conf -file, +either by commands in the configuration file, or by commands typed by the user at the .Ic boot\*(Gt prompt. Index: sys/stand/boot/cmd.c =================================================================== RCS file: /cvs/src/sys/stand/boot/cmd.c,v retrieving revision 1.59 diff -u -p -r1.59 cmd.c --- sys/stand/boot/cmd.c 27 Apr 2007 10:08:34 -0000 1.59 +++ sys/stand/boot/cmd.c 30 Sep 2008 01:37:12 -0000 @@ -61,6 +61,13 @@ extern int CHECK_SKIP_CONF(void); #endif extern const struct cmd_table cmd_set[]; +#ifdef PXEBOOT +/* dot (.) plus 12 chars plus null term */ +char boot_mac_str[14] = + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +extern char ostype[]; +extern char osrelease[]; +#endif const struct cmd_table cmd_table[] = { {"#", CMDT_CMD, Xnop}, /* XXX must be first */ {"boot", CMDT_CMD, Xboot}, @@ -84,6 +91,12 @@ char *nextword(char *); static char *whatcmd(const struct cmd_table **ct, char *); static char *qualify(char *); +#ifdef PXEBOOT +/* from $arch/stand/libsa/pxe_netif.h */ +void pxe_netif_open(void); +void pxe_netif_close(int); +#endif + char cmd_buf[CMD_BUFF_SIZE]; int @@ -103,7 +116,16 @@ read_conf(void) #ifndef INSECURE struct stat sb; #endif - int fd, rc = 0; +#ifdef PXEBOOT + /* needs to be at least big enough to hold the following (so far): + /etc/boot.conf.x1x2x3x4x5x6 + /etc/boot.conf.OpenBSD-mm.n-arch + bottom one is 32 chars plus null term. + */ +#define ALTCONF_SIZE 40 + char altconf[ALTCONF_SIZE]; +#endif + int fd = -1, rc = 0; #ifdef CHECK_SKIP_CONF if (CHECK_SKIP_CONF()) { @@ -112,12 +134,50 @@ read_conf(void) } #endif - if ((fd = open(qualify(cmd.conf), 0)) < 0) { - if (errno != ENOENT && errno != ENXIO) { - printf("open(%s): %s\n", cmd.path, strerror(errno)); - return 0; +#ifdef PXEBOOT + pxe_netif_open(); + if ( (strlen(boot_mac_str) > 6) && (boot_mac_str[0] == '.')) { + snprintf(altconf, ALTCONF_SIZE, "/etc/boot.conf%s", boot_mac_str); + pxe_netif_close(0); + printf("trying %s\n", altconf); + if ((fd = open(qualify(altconf), 0)) < 0) { + if (errno != ENOENT && errno != ENXIO) { + printf("open(%s): %s\n", altconf, + strerror(errno)); + return 0; + } + } else { + printf("using %s\n", altconf); + } + } + + pxe_netif_open(); + if (fd < 0 && (strlen(ostype) + strlen(osrelease)) > 0) { + snprintf(altconf, ALTCONF_SIZE, "/etc/boot.conf.%s-%s-%s", + ostype, osrelease, MACHINE_ARCH); + pxe_netif_close(0); + printf("trying %s\n", altconf); + if ((fd = open(qualify(altconf), 0)) < 0) { + if (errno != ENOENT && errno != ENXIO) { + printf("open(%s): %s\n", altconf, + strerror(errno)); + return 0; + } + } else { + printf("using %s\n", altconf); + } + } +#endif + if (fd < 0) { + printf("trying %s\n", cmd.conf); + if ((fd = open(qualify(cmd.conf), 0)) < 0) { + if (errno != ENOENT && errno != ENXIO) { + printf("open(%s): %s\n", cmd.path, + strerror(errno)); + return 0; + } + return -1; } - return -1; } #ifndef INSECURE