On Fri, Feb 11, 2011 at 09:47:02AM +0200, ucs...@gmail.com wrote:
> Despite the touted support, OpenBSD wouldn't be able to boot off an
> extended partition, unless it's the very first or second one.
> 
> The kernel was fixed (after a fashion) some time ago, but boot(8) and
> installboot(8) still live under the mistaken idea that extended partitions
> are defined recursively, with each of them acting like a full MBR again
> and again, each with 4 smaller partitions inside it, and the offset of
> each subsequent extended partition should be calculated wrt. the offset
> of the bigger one containing it.
> 
> That doesn't work that way and never worked that way: There is one big
> extended partition defined in the MBR, and then inside it there is a
> linked list of 'logical' partitions, each of them with a fake MBR
> defining a data sub-partition (whose offset is from the start of this
> logical partition), and possibly a link to the next logical partition
> (whose offset is from the start of the main extended partition).
> 

Can you provide some pointers to where you are deriving this
information and what testing you have done and what setups now work
that did not before? You hint in your description, but this is an
area that has been argued over many times with each fix breaking
some systems while fixing others. The last test rig I set up had
eight extended partitions and seemed to work, but that was a while
ago and my memory is vague on the testing done.

Having working extended partitions would be nice, but finally finding
definitive docs that clearly and correctly describe what is supposed
to happen would be even better.

.... Ken

> diff -rup osys/arch/i386/stand/installboot/installboot.c 
> sys/arch/i386/stand/installboot/installboot.c
> --- osys/arch/i386/stand/installboot/installboot.c    2011-01-26 
> 01:56:16.000000000 +0200
> +++ sys/arch/i386/stand/installboot/installboot.c     2011-02-07 
> 19:33:08.000000000 +0200
> @@ -103,7 +103,7 @@ static void       devread(int, void *, daddr_t
>  static void  sym_set_value(struct sym_data *, char *, u_int32_t);
>  static void  pbr_set_symbols(char *, char *, struct sym_data *);
>  static void  usage(void);
> -static long  findopenbsd(int, struct disklabel *, off_t, int *);
> +static long  findopenbsd(int, struct disklabel *);
>  static void  write_bootblocks(int devfd, struct disklabel *);
>  
>  static int   sr_volume(int, int *, int *);
> @@ -213,7 +213,6 @@ write_bootblocks(int devfd, struct diskl
>       struct  stat sb;
>       off_t   startoff = 0;
>       long    start = 0;
> -     int     n = 8;
>  
>       /* Write patched proto bootblock(s) into the superblock. */
>       if (fstat(devfd, &sb) < 0)
> @@ -233,7 +232,7 @@ write_bootblocks(int devfd, struct diskl
>       if (dl->d_type != 0 && dl->d_type != DTYPE_FLOPPY &&
>           dl->d_type != DTYPE_VND) {
>               /* Find OpenBSD partition. */
> -             start = findopenbsd(devfd, dl, (off_t)DOSBBSECTOR, &n);
> +             start = findopenbsd(devfd, dl);
>               if (start == -1)
>                       errx(1, "no OpenBSD partition");
>               startoff = (off_t)start * dl->d_secsize;
> @@ -247,35 +246,30 @@ write_bootblocks(int devfd, struct diskl
>  }
>  
>  long
> -findopenbsd(int devfd, struct disklabel *dl, off_t mbroff, int *n)
> +findopenbsd(int devfd, struct disklabel *dl)
>  {
>       struct          dos_mbr mbr;
>       struct          dos_partition *dp;
> -     off_t           startoff;
> -     long            start;
> +     off_t           off, eoff, noff;
>  
> -     /* Limit the number of recursions */
> -     if (!(*n)--)
> -             return (-1);
> -
> -     if (lseek(devfd, mbroff * dl->d_secsize, SEEK_SET) < 0 ||
> +     off = eoff = 0;
> +redo:
> +     if (lseek(devfd, off * dl->d_secsize, SEEK_SET) < 0 ||
>           read(devfd, &mbr, sizeof(mbr)) != sizeof(mbr))
>               err(4, "can't read master boot record");
>  
>       if (mbr.dmbr_sign != DOSMBR_SIGNATURE)
>               errx(1, "broken MBR");
>  
> -     for (dp = mbr.dmbr_parts; dp < &mbr.dmbr_parts[NDOSPART];
> +     for (noff = 0, dp = mbr.dmbr_parts; dp < &mbr.dmbr_parts[NDOSPART];
>           dp++) {
> -             if (!dp->dp_size)
> -                     continue;
>               if (dp->dp_typ == DOSPTYP_OPENBSD) {
>                       if (verbose)
>                               fprintf(stderr,
>                                   "using MBR partition %ld: type 0x%02X 
> offset %d\n",
>                                   (long)(dp - mbr.dmbr_parts),
>                                   dp->dp_typ, dp->dp_start);
> -                     return (dp->dp_start + mbroff);
> +                     return (dp->dp_start + off);
>               } else if (dp->dp_typ == DOSPTYP_EXTEND ||
>                   dp->dp_typ == DOSPTYP_EXTENDL) {
>                       if (verbose)
> @@ -283,12 +277,14 @@ findopenbsd(int devfd, struct disklabel 
>                                   "extended partition %ld: type 0x%02X offset 
> %d\n",
>                                   (long)(dp - mbr.dmbr_parts),
>                                   dp->dp_typ, dp->dp_start);
> -                     startoff = (off_t)dp->dp_start + mbroff;
> -                     start = findopenbsd(devfd, dl, startoff, n);
> -                     if (start != -1)
> -                             return (start);
> +                     noff = dp->dp_start + eoff;
>               }
>       }
> +     if(noff){
> +             if(!eoff) eoff = noff;
> +             off = noff;
> +             goto redo;
> +     }
>  
>       return (-1);
>  }
> diff -rup osys/arch/i386/stand/libsa/biosdev.c 
> sys/arch/i386/stand/libsa/biosdev.c
> --- osys/arch/i386/stand/libsa/biosdev.c      2011-01-09 01:15:25.000000000 
> +0200
> +++ sys/arch/i386/stand/libsa/biosdev.c       2011-02-07 19:18:04.000000000 
> +0200
> @@ -46,7 +46,7 @@ static int biosdisk_errno(u_int);
>  int CHS_rw (int, int, int, int, int, int, void *);
>  static int EDD_rw (int, int, u_int64_t, u_int32_t, void *);
>  
> -static daddr_t findopenbsd(bios_diskinfo_t *, daddr_t, const char **, int *);
> +static daddr_t findopenbsd(bios_diskinfo_t *, const char **);
>  
>  extern int debug;
>  int bios_bootdev;
> @@ -345,21 +345,17 @@ biosd_io(int rw, bios_diskinfo_t *bd, da
>   * Try to read the bsd label on the given BIOS device
>   */
>  static daddr_t
> -findopenbsd(bios_diskinfo_t *bd, daddr_t mbroff, const char **err, int *n)
> +findopenbsd(bios_diskinfo_t *bd, const char **err)
>  {
>       int error, i;
>       struct dos_mbr mbr;
>       struct dos_partition *dp;
> -     daddr_t off;
> -
> -     /* Limit the number of recursions */
> -     if (!(*n)--) {
> -             *err = "too many extended partitions";
> -             return (-1);
> -     }
> +     daddr_t off, eoff, noff;
>  
> +     off = eoff = 0;
> +redo:
>       /* Read MBR */
> -     error = biosd_io(F_READ, bd, mbroff, 1, &mbr);
> +     error = biosd_io(F_READ, bd, off, 1, &mbr);
>       if (error) {
>               *err = biosdisk_err(error);
>               return (-1);
> @@ -372,10 +368,8 @@ findopenbsd(bios_diskinfo_t *bd, daddr_t
>       }
>  
>       /* Search for OpenBSD partition */
> -     for (i = 0; i < NDOSPART; i++) {
> +     for (i = 0, noff = 0; i < NDOSPART; i++) {
>               dp = &mbr.dmbr_parts[i];
> -             if (!dp->dp_size)
> -                     continue;
>  #ifdef BIOS_DEBUG
>               if (debug)
>                       printf("found partition %u: "
> @@ -385,14 +379,17 @@ findopenbsd(bios_diskinfo_t *bd, daddr_t
>                           dp->dp_start, dp->dp_start);
>  #endif
>               if (dp->dp_typ == DOSPTYP_OPENBSD) {
> -                     return (dp->dp_start + mbroff);
> +                     return (dp->dp_start + off);
>               } else if (dp->dp_typ == DOSPTYP_EXTEND ||
>                   dp->dp_typ == DOSPTYP_EXTENDL) {
> -                     off = findopenbsd(bd, dp->dp_start + mbroff, err, n);
> -                     if (off != -1)
> -                             return (off);
> +                     noff = dp->dp_start + eoff;
>               }
>       }
> +     if(noff){
> +             if(!eoff) eoff = noff;
> +             off = noff;
> +             goto redo;
> +     }
>  
>       return (-1);
>  }
> @@ -404,7 +401,6 @@ bios_getdisklabel(bios_diskinfo_t *bd, s
>       char *buf;
>       const char *err = NULL;
>       int error;
> -     int n = 8;
>  
>       /* Sanity check */
>       if (bd->bios_edd == -1 &&
> @@ -413,7 +409,7 @@ bios_getdisklabel(bios_diskinfo_t *bd, s
>  
>       /* MBR is a harddisk thing */
>       if (bd->bios_number & 0x80) {
> -             off = findopenbsd(bd, DOSBBSECTOR, &err, &n);
> +             off = findopenbsd(bd, &err);
>               if (off == -1) {
>                       if (err != NULL)
>                               return (err);
> 62ccd6efa3a20d4a2684fc7e41566b11de0dfe955e899ce6d1f984ba9f3d9bb1

Reply via email to