Subject: kern/15286: fdisk won't let you update the mbr_bootsel code
To: None <gnats-bugs@gnats.netbsd.org>
From: None <david@netbsd.org, "l8s.co.uk"@netbsd.org>
List: netbsd-bugs
Date: 01/18/2002 15:04:34
>Number:         15286
>Category:       kern
>Synopsis:       fdisk won't let you update the mbr_bootsel code
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Jan 18 15:05:00 PST 2002
>Closed-Date:
>Last-Modified:
>Originator:     David Laight
>Release:        current 1.5ZA
>Organization:
>Environment:
NetBSD snowdrop 1.5ZA NetBSD 1.5ZA (GENERIC) #1: Wed Jan 16 17:59:39 GMT 2002     dsl@snowdrop:/usr/bsd-current/src/sys/arch/i386/compile/GENERIC i386

>Description:
fdisk only loads the mbr_bootsel code from /usr/mdec/mbr_bootsel,
and then only if it isn't already installed.

'fdisk -i -c mbr_code' will delete the bootselect configuration.

'fdisk -B -c mbr_code' ignores the specified file completely
(It load /usr/mdec/mbr_bootsel if the current bootstrap isn't an mbr one)

Intuitively both the above commands should update the boot code.

While fixing fdisk's mbr_bootsel handling:

1) timeouts that are not a multiple of 5 seconds are not displayed with
   the value that was configured

2) The 'LBA reads needed' flag is never cleared

3) Useful to be able to 'wait forever' (needs mbr_bootsel change)

>How-To-Repeat:

>Fix:
Diff to $NetBSD: fdisk.c,v 1.48 2001/11/07 14:50:32
(This will suffer from cut and paste, and possibly from netscape!)

*** fdisk.c     Fri Jan 18 22:11:33 2002
--- fdisk.c.orig        Wed Nov  7 14:50:32 2001
***************
*** 631,659 ****
  init_sector0(int start, int dopart)
  {
        int i;
-       int copy_size =  sizeof(mboot.bootinst);
  
  #ifdef        DEFAULT_BOOTCODE
!       if (!bootsize) {
! #ifdef __i386__
!           if (B_flag)
!               bootsize = read_boot(DEFAULT_BOOTSELCODE, bootcode,
!                   sizeof bootcode);
!           else
! #endif
                bootsize = read_boot(DEFAULT_BOOTCODE, bootcode,
                    sizeof bootcode);
-       }
- #endif
- #ifdef __i386__
-       if (((struct mbr_bootsel *)&mboot.bootinst[MBR_BOOTSELOFF])->magic ==
-                                                               MBR_MAGIC 
-               && ((struct mbr_bootsel *)&bootcode[MBR_BOOTSELOFF])->magic ==
-                                                                MBR_MAGIC)
-           copy_size = MBR_BOOTSELOFF;
  #endif
  
!       memcpy(mboot.bootinst, bootcode, copy_size);
        putshort(&mboot.signature, MBR_MAGIC);
  
        if (dopart)
--- 631,644 ----
  init_sector0(int start, int dopart)
  {
        int i;
  
  #ifdef        DEFAULT_BOOTCODE
!       if (!bootsize)
                bootsize = read_boot(DEFAULT_BOOTCODE, bootcode,
                    sizeof bootcode);
  #endif
  
!       memcpy(mboot.bootinst, bootcode, sizeof(mboot.bootinst));
        putshort(&mboot.signature, MBR_MAGIC);
  
        if (dopart)
***************
*** 779,797 ****
                        printf("Bootselector not installed.\n");
                        return;
                }
!               /* read default bootselect code unless we already have one */
!               if (!bootsize || ((struct mbr_bootsel *)&bootcode
!                               [MBR_BOOTSELOFF])->magic != MBR_MAGIC)
!                       bootsize = read_boot(DEFAULT_BOOTSELCODE, bootcode,
!                               sizeof bootcode);
                memcpy(mboot.bootinst, bootcode, sizeof(mboot.bootinst));
                bootsel_modified = 1;
                mbs->flags |= BFL_SELACTIVE;
        } else {
-               /* If bootfile was specified with -c, copy it in */
-               if (bootsize && ((struct mbr_bootsel *)&bootcode
-                               [MBR_BOOTSELOFF])->magic == MBR_MAGIC)
-                       memcpy(mboot.bootinst, bootcode, MBR_BOOTSELOFF);
                if (mbs->flags & BFL_SELACTIVE) {
                        printf("The bootselector is installed and active.\n");
                        if (!yesno("Do you want to change its settings?")) {
--- 764,775 ----
                        printf("Bootselector not installed.\n");
                        return;
                }
!               bootsize = read_boot(DEFAULT_BOOTSELCODE, bootcode,
!                   sizeof bootcode);
                memcpy(mboot.bootinst, bootcode, sizeof(mboot.bootinst));
                bootsel_modified = 1;
                mbs->flags |= BFL_SELACTIVE;
        } else {
                if (mbs->flags & BFL_SELACTIVE) {
                        printf("The bootselector is installed and active.\n");
                        if (!yesno("Do you want to change its settings?")) {
***************
*** 892,905 ****
        bootsel_modified = 1;
  
        /* The timeout value is in ticks, 18.2 Hz. Avoid using floats. */
!       /* ticks are probably 64k/3600 - so our long timers are sligtly
!          out!  newer bootcode always waits for 1 tick, so treats 0xffff
!          as wait forever. */
!       timo = mbs->timeo == 0xffff ? -1 : (10 * mbs->timeo + 9) / 182;
        do {
!               decimal("Timeout value (seconds, -1 => never)", &timo);
!       } while (timo < -1 || timo > 3600);
!       mbs->timeo = timo == -1 ? 0xffff : (timo * 182) / 10;
  
        printf("Select the default boot option. Options are:\n\n");
        for (i = 0; i < NMBRPART; i++) {
--- 870,880 ----
        bootsel_modified = 1;
  
        /* The timeout value is in ticks, 18.2 Hz. Avoid using floats. */
!       timo = ((1000 * mbs->timeo) / 18200);
        do {
!               decimal("Timeout value", &timo);
!       } while (timo < 0 || timo > 3600);
!       mbs->timeo = (u_int16_t)((timo * 18200) / 1000);
  
        printf("Select the default boot option. Options are:\n\n");
        for (i = 0; i < NMBRPART; i++) {
***************
*** 929,936 ****
                mbs->defkey = SCAN_F1 + item;
  
  done:
-       /* scan active partitions to see if we need LBA reads */
-       mbs->flags &= ~BFL_EXTINT13;
        for (i = 0; i < NMBRPART; i++) {
                if (mboot.parts[i].mbrp_typ != 0 &&
                   mboot.parts[i].mbrp_start >=
--- 904,909 ----

>Release-Note:
>Audit-Trail:
>Unformatted: