From 687f54b6b892411897628fc32ac2343921b1b97a Mon Sep 17 00:00:00 2001 From: okuji Date: Sat, 12 Feb 2000 07:00:47 +0000 Subject: [PATCH] fix several bugs in netboot and one bug in the command geometry. --- ChangeLog | 30 +++++++++++++++ configure | 6 +-- configure.in | 6 +-- netboot/README.netboot | 6 +-- netboot/fsys_tftp.c | 84 +++++++++++++++++++++++++++++++++++------- netboot/main.c | 4 +- stage2/builtins.c | 11 ++++++ 7 files changed, 123 insertions(+), 24 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4555dea3e..f3cd4c590 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,33 @@ +2000-02-12 OKUJI Yoshinori + + * stage2/builtins.c (geometry_func): Attempt to read the first + sector to examine if LBA mode is really supported. + + * netboot/fsys_tftp.c (buf_fill) [TFTP_DEBUG]: Added some debug + messages. + (send_rrq) [TFTP_DEBUG]: Likewise. + (tftp_read) [TFTP_DEBUG]: Likewise. + (tftp_dir) [TFTP_DEBUG]: Likewise. + (tftp_close) [TFTP_DEBUG]: Likewise. + (tftp_read): Call buf_fill with the argument 1 first, if FILEPOS + has been moved backwards, and use grub_memmove for copying + SAVED_TP to TP instead of a direct assignment. + If send_rrq fails, set ERRNUM to ERR_WRITE instead of ERR_READ. + Check if BUF_READ is zero instead of if BUF_EOF is non-zero at + the end of the loop. + (tftp_dir): Set ERRNUM to ERR_WRITE instead of ERR_READ, if + send_rrq fails. + Save TP and LEN in SAVED_TP and SAVED_LEN respectively before + buf_fill instead of after it, because it destroys the contents + of TP. + * netboot/main.c (print_network_configuration): The order of the + arguments for grub_sprintf in the local function sprint_ip_addr + is reversed. + + * configure.in (--enable-packet_retransmission): Renamed to ... + (--disable-packet-retransmission): ... this. Assume that a + network is congested by default. + 2000-02-11 OKUJI Yoshinori From Pavel Roskin: diff --git a/configure b/configure index 09d477e08..02242f492 100644 --- a/configure +++ b/configure @@ -35,8 +35,8 @@ ac_arg_enable_help="$ac_arg_enable_help ac_arg_enable_help="$ac_arg_enable_help --disable-gunzip disable decompression in Stage 2" ac_arg_enable_help="$ac_arg_enable_help - --enable-packet-retransmission - turn on packet retransmission" + --disable-packet-retransmission + turn off packet retransmission" ac_arg_enable_help="$ac_arg_enable_help --enable-pci-direct access PCI directly instead of using BIOS" ac_arg_enable_help="$ac_arg_enable_help @@ -2425,7 +2425,7 @@ if test "${enable_packet_retransmission+set}" = set; then : fi -if test "x$enable_packet_retransmission" = xyes; then +if test "x$enable_packet_retransmission" != xno; then NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DCONGESTED=1" fi diff --git a/configure.in b/configure.in index 00947d9d5..a56d9297f 100644 --- a/configure.in +++ b/configure.in @@ -217,9 +217,9 @@ fi dnl The netboot support. dnl General options. AC_ARG_ENABLE(packet-retransmission, - [ --enable-packet-retransmission - turn on packet retransmission]) -if test "x$enable_packet_retransmission" = xyes; then + [ --disable-packet-retransmission + turn off packet retransmission]) +if test "x$enable_packet_retransmission" != xno; then NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DCONGESTED=1" fi diff --git a/netboot/README.netboot b/netboot/README.netboot index 9740b46af..138c2728a 100644 --- a/netboot/README.netboot +++ b/netboot/README.netboot @@ -7,9 +7,9 @@ The URL is . These below are common options for configure. Perhaps you may not need to specify them. ---enable-packet-retransmission - Turns on packet retransmission. Use it on a congested network, where - the normal operation can't boot the image. +--disable-packet-retransmission + Turns off packet retransmission. Use it on an empty network, where + no packet collision can happen. --enable-pci-direct Define this for PCI BIOSes that do not implement BIOS32 or not diff --git a/netboot/fsys_tftp.c b/netboot/fsys_tftp.c index b1c84291c..a3748e67b 100644 --- a/netboot/fsys_tftp.c +++ b/netboot/fsys_tftp.c @@ -26,6 +26,8 @@ Author: Martin Renters **************************************************************************/ +/* #define TFTP_DEBUG 1 */ + #include #include @@ -47,6 +49,10 @@ static char *buf; static int buf_fill (int abort) { +#ifdef TFTP_DEBUG + grub_printf ("buf_fill (%d)\n", abort); +#endif + while (! buf_eof && (buf_read + packetsize <= FSYS_BUFLEN)) { struct tftp_t *tr; @@ -63,6 +69,9 @@ buf_fill (int abort) if (! block && retry++ < MAX_TFTP_RETRIES) { /* Maybe initial request was lost. */ +#ifdef TFTP_DEBUG + grub_printf ("Maybe initial request was lost.\n"); +#endif rfc951_sleep (retry); if (! udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr, ++isocket, TFTP, len, (char *) &tp)) @@ -75,7 +84,7 @@ buf_fill (int abort) if (block && ((retry += TFTP_REXMT) < TFTP_TIMEOUT)) { /* We resend our last ack. */ -# ifdef MDEBUG +# ifdef TFTP_DEBUG grub_printf ("\n"); # endif udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr, @@ -87,7 +96,7 @@ buf_fill (int abort) /* Timeout. */ return 0; } - + tr = (struct tftp_t *) &nic.packet[ETHER_HDR_SIZE]; if (tr->opcode == ntohs (TFTP_ERROR)) { @@ -100,7 +109,10 @@ buf_fill (int abort) if (tr->opcode == ntohs (TFTP_OACK)) { char *p = tr->u.oack.data, *e; - + +#ifdef TFTP_DEBUG + grub_printf ("OACK "); +#endif /* Shouldn't happen. */ if (prevblock) /* Ignore it. */ @@ -118,6 +130,9 @@ buf_fill (int abort) p += 8; if ((packetsize = getdec (&p)) < TFTP_DEFAULTSIZE_PACKET) goto noak; +#ifdef TFTP_DEBUG + grub_printf ("blksize = %d\n", packetsize); +#endif } else if (! grub_strcmp ("tsize", p)) { @@ -127,10 +142,16 @@ buf_fill (int abort) filemax = -1; goto noak; } +#ifdef TFTP_DEBUG + grub_printf ("tsize = %d\n", filemax); +#endif } else { noak: +#ifdef TFTP_DEBUG + grub_printf ("NOAK\n"); +#endif tp.opcode = htons (TFTP_ERROR); tp.u.err.errcode = 8; len = (grub_sprintf ((char *) tp.u.err.errmsg, @@ -158,6 +179,9 @@ buf_fill (int abort) } else if (tr->opcode == ntohs (TFTP_DATA)) { +#ifdef TFTP_DEBUG + grub_printf ("DATA "); +#endif len = ntohs (tr->udp.len) - sizeof (struct udphdr) - 4; /* Shouldn't happen. */ @@ -178,7 +202,10 @@ buf_fill (int abort) /* Should be continuous. */ tp.opcode = abort ? htons (TFTP_ERROR) : htons (TFTP_ACK); osocket = ntohs (tr->udp.src); - + +#ifdef TFTP_DEBUG + grub_printf ("ACK\n"); +#endif /* Ack. */ udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr, isocket, osocket, TFTP_MIN_PACKET, (char *) &tp); @@ -224,7 +251,10 @@ send_rrq (void) buf_eof = 0; buf_read = 0; saved_filepos = 0; - + +#ifdef TFTP_DEBUG + grub_printf ("send_rrq ()\n"); +#endif /* Send the packet. */ return udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr, ++isocket, TFTP, len, (char *) &tp); @@ -252,15 +282,35 @@ tftp_read (char *addr, int size) { /* How many bytes is read? */ int ret = 0; + +#ifdef TFTP_DEBUG + grub_printf ("tftp_read (0x%x, %d)\n", (int) addr, size); +#endif if (filepos < saved_filepos) { /* Uggh.. FILEPOS has been moved backwards. So reopen the file. */ - tp = saved_tp; + buf_fill (1); + grub_memmove ((char *) &tp, (char *) &saved_tp, saved_len); len = saved_len; +#ifdef TFTP_DEBUG + { + int i; + grub_printf ("opcode = 0x%x, rrq = ", (unsigned long) tp.opcode); + for (i = 0; i < TFTP_DEFAULTSIZE_PACKET; i++) + { + if (tp.u.rrq[i] >= ' ' && tp.u.rrq[i] <= '~') + grub_putchar (tp.u.rrq[i]); + else + grub_putchar ('*'); + } + grub_putchar ('\n'); + } +#endif + if (! send_rrq ()) { - errnum = ERR_READ; + errnum = ERR_WRITE; return 0; } } @@ -302,7 +352,8 @@ tftp_read (char *addr, int size) return 0; } - if (size > 0 && buf_eof) + /* Sanity check. */ + if (size > 0 && buf_read == 0) { errnum = ERR_READ; return 0; @@ -319,6 +370,10 @@ tftp_dir (char *dirname) { int ch; +#ifdef TFTP_DEBUG + grub_printf ("tftp_dir (%s)\n", dirname); +#endif + /* In TFTP, there is no way to know what files exis. */ if (print_possibilities) return 1; @@ -338,9 +393,12 @@ tftp_dir (char *dirname) + TFTP_MIN_PACKET + 1); /* Restore the original DIRNAME. */ dirname[grub_strlen (dirname)] = ch; + /* Save the TFTP packet so that we can reopen the file later. */ + grub_memmove ((char *) &saved_tp, (char *) &tp, len); + saved_len = len; if (! send_rrq ()) { - errnum = ERR_READ; + errnum = ERR_WRITE; return 0; } @@ -377,10 +435,6 @@ tftp_dir (char *dirname) goto reopen; } - /* Save the TFTP packet so that we can reopen the file later. */ - saved_tp = tp; - saved_len = len; - return 1; } @@ -388,6 +442,10 @@ tftp_dir (char *dirname) void tftp_close (void) { +#ifdef TFTP_DEBUG + grub_printf ("tftp_close ()\n"); +#endif + buf_read = 0; buf_fill (1); } diff --git a/netboot/main.c b/netboot/main.c index fa950687e..87d3ccf01 100644 --- a/netboot/main.c +++ b/netboot/main.c @@ -129,8 +129,8 @@ print_network_configuration (void) static void sprint_ip_addr (char *buf, unsigned long addr) { grub_sprintf (buf, "%d.%d.%d.%d", - addr >> 24, (addr >> 16) & 0xFF, - (addr >> 8) & 0xFF, addr & 0xFF); + addr & 0xFF, (addr >> 8) & 0xFF, + (addr >> 16) & 0xFF, addr >> 24); } if (! eth_probe ()) diff --git a/stage2/builtins.c b/stage2/builtins.c index ead35eabe..d4d8caa24 100644 --- a/stage2/builtins.c +++ b/stage2/builtins.c @@ -979,16 +979,27 @@ geometry_func (char *arg, int flags) char *ptr; #endif + /* Get the device number. */ set_device (device); if (errnum) return 1; + /* Check for the geometry. */ if (get_diskinfo (current_drive, &geom)) { errnum = ERR_NO_DISK; return 1; } + /* Attempt to read the first sector, because some BIOSes turns out not + to support LBA even though they set the bit 0 in the support + bitmap, only after reading something actually. */ + if (biosdisk (BIOSDISK_READ, current_drive, &geom, 0, 1, SCRATCHSEG)) + { + errnum = ERR_READ; + return 1; + } + #ifdef GRUB_UTIL ptr = skip_to (0, device); if (*ptr)