/* @(#)bootnd.c 1.1 94/10/31 SMI */ /* * Boot block for machine with ND in proms. Does tftp to load * next stage of boot. */ #include "../lib/common/saio.h" #include #include #include #include #include #include #include "../lib/common/sainet.h" #include #define TIMEOUT 4000 /* retransmission timeout, in milliseconds */ #define RETRIES 15 /* number of times to retransmit, before giving up */ #define MAXTIMEOUT 64000 /* max time to wait for reply to broadcast */ main() { struct bootparam *bp; struct boottab b; static char fname[] = "01234567.SUN2"; struct sockaddr_in raddr; struct ether_addr rether; int timeout; int eof; extern int random; extern struct saioreq ether_si; extern struct sainet ether_sain; extern char recvpacket[]; if (romp->v_bootparam == 0) { bp = (struct bootparam *)0x2000; /* Old Sun-1 address */ } else { bp = *(romp->v_bootparam); /* S-2: via romvec */ } /* * This is necessary to get the prom ethernet driver to work */ b = *bp->bp_boottab; bp->bp_boottab = &b; bp->bp_boottab->b_devinfo = 0; random = *romp->v_nmiclock; if (etheropen(bp, ðer_si) < 0) { printf("can't open ethernet\n"); return; } inet_init(ðer_si, ðer_sain, recvpacket); printf("Using IP Address "); printaddr(ether_sain.sain_myaddr); ultox(fname, ether_sain.sain_myaddr.s_addr); raddr.sin_addr = ether_sain.sain_hisaddr; rether = ether_sain.sain_hisether; eof = 0; printf("Booting from tftp server at "); printaddr(raddr.sin_addr); while (! eof && tftpread(raddr, rether, fname, (char *)LOADADDR, TIMEOUT, RETRIES) <= 0) { timeout = TIMEOUT; while ((eof = tftpfind(&raddr, &rether, fname, (char *)LOADADDR, timeout)) < 0) { if (timeout < MAXTIMEOUT) { timeout *= 2; /* backoff */ } printf("tftp: timeout\n"); } printf("Booting from tftp server at "); printaddr(raddr.sin_addr); } _exitto(LOADADDR); } /* * Print an internet address */ printaddr(addr) struct in_addr addr; { printf("%d.%d.%d.%d = %x.\n", addr.s_net, addr.s_host, addr.s_lh, addr.s_impno, ntohl(addr.s_addr)); } /* * Unsigned long to hex conversion */ ultox(buf, val) char *buf; unsigned long val; { int i; static char hex[] = "0123456789ABCDEF"; for (i = 7; i >= 0; i--) { buf[i] = hex[val & 0x0f]; val >>= 4; } } /* * Open the ethernet driver in proms */ etheropen(bp, si) struct bootparam *bp; struct saioreq *si; { si->si_boottab = bp->bp_boottab; si->si_ctlr = bp->bp_ctlr; si->si_unit = bp->bp_unit; si->si_boff = bp->bp_part; si->si_cc = 0; si->si_offset = 0; si->si_flgs = 0; si->si_devaddr = si->si_devdata = si->si_dmaaddr = 0; return((si->si_boottab->b_open)(si)); } /* * Nobody calls this, but must resolve reference in srt0 */ exit() { _exit(); }