make arm64 can boot from partitions other than "a"

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

make arm64 can boot from partitions other than "a"

YASUOKA Masahiko-3
Hi,

On efiboot for arm64

  boot> boot sd0k:bsd.rd
or
  boot> set device sd0l

doesn't work properly.

The diff makes it can boot from paritions other than "a".

ok?
comments?

Index: sys/arch/arm64/arm64/autoconf.c
===================================================================
RCS file: /disk/cvs/openbsd/src/sys/arch/arm64/arm64/autoconf.c,v
retrieving revision 1.9
diff -u -p -r1.9 autoconf.c
--- sys/arch/arm64/arm64/autoconf.c 6 Feb 2018 20:35:21 -0000 1.9
+++ sys/arch/arm64/arm64/autoconf.c 4 Jan 2019 13:40:58 -0000
@@ -19,6 +19,7 @@
 #include <sys/systm.h>
 #include <sys/conf.h>
 #include <sys/device.h>
+#include <sys/disklabel.h>
 #include <sys/reboot.h>
 #include <sys/socket.h>
 #include <sys/hibernate.h>
@@ -68,7 +69,8 @@ diskconf(void)
 {
  size_t len;
  char *p;
- dev_t tmpdev;
+ dev_t tmpdev = NODEV;
+ int part = 0;
  extern uint8_t *bootmac;
 
  if (*boot_file != '\0')
@@ -82,6 +84,8 @@ diskconf(void)
  else
  len = strlen(boot_file);
  bootdv = parsedisk(boot_file, len, 0, &tmpdev);
+ if (tmpdev != NODEV)
+ part = DISKPART(tmpdev);
  }
 
 #if defined(NFSCLIENT)
@@ -105,7 +109,7 @@ diskconf(void)
  else
  printf("boot device: lookup %s failed \n", boot_file);
 
- setroot(bootdv, 0, RB_USERREQ);
+ setroot(bootdv, part, RB_USERREQ);
  dumpconf();
 
 #ifdef HIBERNATE
Index: sys/arch/arm64/stand/efiboot/efidev.c
===================================================================
RCS file: /disk/cvs/openbsd/src/sys/arch/arm64/stand/efiboot/efidev.c,v
retrieving revision 1.2
diff -u -p -r1.2 efidev.c
--- sys/arch/arm64/stand/efiboot/efidev.c 25 Aug 2018 20:43:39 -0000 1.2
+++ sys/arch/arm64/stand/efiboot/efidev.c 4 Jan 2019 13:40:58 -0000
@@ -484,7 +484,7 @@ efiopen(struct open_file *f, ...)
  part = va_arg(ap, u_int);
  va_end(ap);
 
- if (unit != 0)
+ if (unit != 0 || MAXPARTITIONS <= part)
  return (ENXIO);
 
  diskinfo.ed.blkio = disk;
@@ -512,7 +512,7 @@ efistrategy(void *devdata, int rw, daddr
 
  nsect = (size + DEV_BSIZE - 1) / DEV_BSIZE;
  blk += DL_SECTOBLK(&dip->disklabel,
-    dip->disklabel.d_partitions[B_PARTITION(dip->sc_part)].p_offset);
+    dip->disklabel.d_partitions[dip->sc_part].p_offset);
 
  if (blk < 0)
  error = EINVAL;
Index: sys/arch/arm64/stand/efiboot/exec.c
===================================================================
RCS file: /disk/cvs/openbsd/src/sys/arch/arm64/stand/efiboot/exec.c,v
retrieving revision 1.5
diff -u -p -r1.5 exec.c
--- sys/arch/arm64/stand/efiboot/exec.c 8 Feb 2017 09:18:24 -0000 1.5
+++ sys/arch/arm64/stand/efiboot/exec.c 4 Jan 2019 13:40:58 -0000
@@ -94,7 +94,7 @@ run_loadfile(u_long *marks, int howto)
  char *cp;
  void *fdt;
 
- snprintf(args, sizeof(args) - 8, "%s:%s", cmd.bootdev, cmd.image);
+ strlcpy(args, cmd.path, sizeof(args));
  cp = args + strlen(args);
 
  *cp++ = ' ';

Reply | Threaded
Open this post in threaded view
|

Re: make arm64 can boot from partitions other than "a"

YASUOKA Masahiko-3
On Wed, 09 Jan 2019 16:47:32 +0900 (JST)
YASUOKA Masahiko <[hidden email]> wrote:
> The diff makes it can boot from paritions other than "a".

Let me explain the diff.

> Index: sys/arch/arm64/arm64/autoconf.c
> ===================================================================
> RCS file: /disk/cvs/openbsd/src/sys/arch/arm64/arm64/autoconf.c,v
> retrieving revision 1.9
> diff -u -p -r1.9 autoconf.c
> --- sys/arch/arm64/arm64/autoconf.c 6 Feb 2018 20:35:21 -0000 1.9
> +++ sys/arch/arm64/arm64/autoconf.c 4 Jan 2019 13:40:58 -0000
> @@ -19,6 +19,7 @@
>  #include <sys/systm.h>
>  #include <sys/conf.h>
>  #include <sys/device.h>
> +#include <sys/disklabel.h>
>  #include <sys/reboot.h>
>  #include <sys/socket.h>
>  #include <sys/hibernate.h>
> @@ -68,7 +69,8 @@ diskconf(void)
>  {
>   size_t len;
>   char *p;
> - dev_t tmpdev;
> + dev_t tmpdev = NODEV;
> + int part = 0;
>   extern uint8_t *bootmac;
>  
>   if (*boot_file != '\0')
> @@ -82,6 +84,8 @@ diskconf(void)
>   else
>   len = strlen(boot_file);
>   bootdv = parsedisk(boot_file, len, 0, &tmpdev);
> + if (tmpdev != NODEV)
> + part = DISKPART(tmpdev);
>   }
>  

parsedisk() parses the parition part.  The diff is to keep it.

>  #if defined(NFSCLIENT)
> @@ -105,7 +109,7 @@ diskconf(void)
>   else
>   printf("boot device: lookup %s failed \n", boot_file);
>  
> - setroot(bootdv, 0, RB_USERREQ);
> + setroot(bootdv, part, RB_USERREQ);
>   dumpconf();
>  
>  #ifdef HIBERNATE

Previously 0 ("a" partition) is passed to setroot() always.
By the diff, the partition kept above will be passed to setroot().

Then the kernel will use the partition specified by the bootargs for
the default root.

> Index: sys/arch/arm64/stand/efiboot/efidev.c
> ===================================================================
> RCS file: /disk/cvs/openbsd/src/sys/arch/arm64/stand/efiboot/efidev.c,v
> retrieving revision 1.2
> diff -u -p -r1.2 efidev.c
> --- sys/arch/arm64/stand/efiboot/efidev.c 25 Aug 2018 20:43:39 -0000 1.2
> +++ sys/arch/arm64/stand/efiboot/efidev.c 4 Jan 2019 13:40:58 -0000
> @@ -484,7 +484,7 @@ efiopen(struct open_file *f, ...)
>   part = va_arg(ap, u_int);
>   va_end(ap);
>  
> - if (unit != 0)
> + if (unit != 0 || MAXPARTITIONS <= part)
>   return (ENXIO);
>  
>   diskinfo.ed.blkio = disk;
> @@ -512,7 +512,7 @@ efistrategy(void *devdata, int rw, daddr
>  
>   nsect = (size + DEV_BSIZE - 1) / DEV_BSIZE;
>   blk += DL_SECTOBLK(&dip->disklabel,
> -    dip->disklabel.d_partitions[B_PARTITION(dip->sc_part)].p_offset);
> +    dip->disklabel.d_partitions[dip->sc_part].p_offset);
>  
>   if (blk < 0)
>   error = EINVAL;

Second chunk is to fix a misuse of B_PARTITION().  B_PARTITION()'s
argument must be a "boot-style device number".  dip->sc_part is usable
just as it is.  First chunk is to check the value more strict since
it's used just as it is.

> Index: sys/arch/arm64/stand/efiboot/exec.c
> ===================================================================
> RCS file: /disk/cvs/openbsd/src/sys/arch/arm64/stand/efiboot/exec.c,v
> retrieving revision 1.5
> diff -u -p -r1.5 exec.c
> --- sys/arch/arm64/stand/efiboot/exec.c 8 Feb 2017 09:18:24 -0000 1.5
> +++ sys/arch/arm64/stand/efiboot/exec.c 4 Jan 2019 13:40:58 -0000
> @@ -94,7 +94,7 @@ run_loadfile(u_long *marks, int howto)
>   char *cp;
>   void *fdt;
>  
> - snprintf(args, sizeof(args) - 8, "%s:%s", cmd.bootdev, cmd.image);
> + strlcpy(args, cmd.path, sizeof(args));
>   cp = args + strlen(args);
>  
>   *cp++ = ' ';

cmd.bootdev is the "device" variable and cmd.image is the "image"
variable of boot(8).  They are used as defaults, but if a kernel is
specified as an argument for "boot" command, they are not used.
cmd.path is the real path that is used for loading a kernel.  The diff
is to use it as the bootargs as it is.

Reply | Threaded
Open this post in threaded view
|

Re: make arm64 can boot from partitions other than "a"

Mark Kettenis
> Date: Wed, 09 Jan 2019 17:25:12 +0900 (JST)
> From: YASUOKA Masahiko <[hidden email]>
>
> On Wed, 09 Jan 2019 16:47:32 +0900 (JST)
> YASUOKA Masahiko <[hidden email]> wrote:
> > The diff makes it can boot from paritions other than "a".
>
> Let me explain the diff.
>
> > Index: sys/arch/arm64/arm64/autoconf.c
> > ===================================================================
> > RCS file: /disk/cvs/openbsd/src/sys/arch/arm64/arm64/autoconf.c,v
> > retrieving revision 1.9
> > diff -u -p -r1.9 autoconf.c
> > --- sys/arch/arm64/arm64/autoconf.c 6 Feb 2018 20:35:21 -0000 1.9
> > +++ sys/arch/arm64/arm64/autoconf.c 4 Jan 2019 13:40:58 -0000
> > @@ -19,6 +19,7 @@
> >  #include <sys/systm.h>
> >  #include <sys/conf.h>
> >  #include <sys/device.h>
> > +#include <sys/disklabel.h>
> >  #include <sys/reboot.h>
> >  #include <sys/socket.h>
> >  #include <sys/hibernate.h>
> > @@ -68,7 +69,8 @@ diskconf(void)
> >  {
> >   size_t len;
> >   char *p;
> > - dev_t tmpdev;
> > + dev_t tmpdev = NODEV;
> > + int part = 0;
> >   extern uint8_t *bootmac;
> >  
> >   if (*boot_file != '\0')
> > @@ -82,6 +84,8 @@ diskconf(void)
> >   else
> >   len = strlen(boot_file);
> >   bootdv = parsedisk(boot_file, len, 0, &tmpdev);
> > + if (tmpdev != NODEV)
> > + part = DISKPART(tmpdev);
> >   }
> >  
>
> parsedisk() parses the parition part.  The diff is to keep it.
>
> >  #if defined(NFSCLIENT)
> > @@ -105,7 +109,7 @@ diskconf(void)
> >   else
> >   printf("boot device: lookup %s failed \n", boot_file);
> >  
> > - setroot(bootdv, 0, RB_USERREQ);
> > + setroot(bootdv, part, RB_USERREQ);
> >   dumpconf();
> >  
> >  #ifdef HIBERNATE
>
> Previously 0 ("a" partition) is passed to setroot() always.
> By the diff, the partition kept above will be passed to setroot().
>
> Then the kernel will use the partition specified by the bootargs for
> the default root.
>
> > Index: sys/arch/arm64/stand/efiboot/efidev.c
> > ===================================================================
> > RCS file: /disk/cvs/openbsd/src/sys/arch/arm64/stand/efiboot/efidev.c,v
> > retrieving revision 1.2
> > diff -u -p -r1.2 efidev.c
> > --- sys/arch/arm64/stand/efiboot/efidev.c 25 Aug 2018 20:43:39 -0000 1.2
> > +++ sys/arch/arm64/stand/efiboot/efidev.c 4 Jan 2019 13:40:58 -0000
> > @@ -484,7 +484,7 @@ efiopen(struct open_file *f, ...)
> >   part = va_arg(ap, u_int);
> >   va_end(ap);
> >  
> > - if (unit != 0)
> > + if (unit != 0 || MAXPARTITIONS <= part)
> >   return (ENXIO);

Can you make that "part >= MAXPARTITIONS".  Easier to understand for
my brain!

> >  
> >   diskinfo.ed.blkio = disk;
> > @@ -512,7 +512,7 @@ efistrategy(void *devdata, int rw, daddr
> >  
> >   nsect = (size + DEV_BSIZE - 1) / DEV_BSIZE;
> >   blk += DL_SECTOBLK(&dip->disklabel,
> > -    dip->disklabel.d_partitions[B_PARTITION(dip->sc_part)].p_offset);
> > +    dip->disklabel.d_partitions[dip->sc_part].p_offset);
> >  
> >   if (blk < 0)
> >   error = EINVAL;
>
> Second chunk is to fix a misuse of B_PARTITION().  B_PARTITION()'s
> argument must be a "boot-style device number".  dip->sc_part is usable
> just as it is.  First chunk is to check the value more strict since
> it's used just as it is.
>
> > Index: sys/arch/arm64/stand/efiboot/exec.c
> > ===================================================================
> > RCS file: /disk/cvs/openbsd/src/sys/arch/arm64/stand/efiboot/exec.c,v
> > retrieving revision 1.5
> > diff -u -p -r1.5 exec.c
> > --- sys/arch/arm64/stand/efiboot/exec.c 8 Feb 2017 09:18:24 -0000 1.5
> > +++ sys/arch/arm64/stand/efiboot/exec.c 4 Jan 2019 13:40:58 -0000
> > @@ -94,7 +94,7 @@ run_loadfile(u_long *marks, int howto)
> >   char *cp;
> >   void *fdt;
> >  
> > - snprintf(args, sizeof(args) - 8, "%s:%s", cmd.bootdev, cmd.image);
> > + strlcpy(args, cmd.path, sizeof(args));
> >   cp = args + strlen(args);
> >  
> >   *cp++ = ' ';
>
> cmd.bootdev is the "device" variable and cmd.image is the "image"
> variable of boot(8).  They are used as defaults, but if a kernel is
> specified as an argument for "boot" command, they are not used.
> cmd.path is the real path that is used for loading a kernel.  The diff
> is to use it as the bootargs as it is.

Thanks for the explanation.  ok kettenis@ with the change suggested above.