svn commit: r334444 - in stable/11: release/amd64 stand/efi/boot1

Glen Barber gjb at FreeBSD.org
Thu May 31 20:02:00 UTC 2018


Author: gjb
Date: Thu May 31 20:01:58 2018
New Revision: 334444
URL: https://svnweb.freebsd.org/changeset/base/334444

Log:
  MFC r334310, r334337:
  
   r334310 (imp):
    Teach ufs_module.c about bsd labels and probe 'a' partition.
  
    If the check for a UFS partition at offset 0 on the disk fails, check
    to see if there's a BSD disklabel at block 1 (standard) or at offset
    512 (install images assume 512 sector size). If found, probe for UFS
    on the 'a' partition.
  
    This fixes UEFI booting images from a BSD labeled MBR slice when the
    'a' partiton isn't at offset 0. This is a stop-gap fix since we plan
    on removing boot1.efi in FreeBSD 12. We can't easily do that for 11.2,
    however, hence the short MFC window.
  
   r334337 (emaste):
    switch amd64 memstick installer images to MBR
  
    A good number of BIOSes have trouble booting from GPT in non-UEFI
    mode.
  
    With this change amd64 memsticks remain dual-mode (booting from either
    UEFI or CSM); the partitioning type is just switched from GPT to MBR.
  
  PR:		227954
  
  Note, there are two changes specific to stable/11 where there is code
  that had diverged from head and never merged back.  The two changes are
  an include in stand/efi/boot1/ufs_module.c, replacing sys/disk/bsd.h
  with sys/disklabel.h and replacing BSD_MAGIC with DISKMAGIC in the
  same file.  The latter two are direct commits to stable/11 in order to
  avoid unexpected regressions at this point of the 11.2 cycle.  Thank
  you to imp@ for pointing out what changes needed to be made.
  
  Approved by:	re (marius)
  
  Sponsored by:	The FreeBSD Foundation

Modified:
  stable/11/release/amd64/make-memstick.sh
  stable/11/stand/efi/boot1/boot_module.h
  stable/11/stand/efi/boot1/ufs_module.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/release/amd64/make-memstick.sh
==============================================================================
--- stable/11/release/amd64/make-memstick.sh	Thu May 31 19:36:24 2018	(r334443)
+++ stable/11/release/amd64/make-memstick.sh	Thu May 31 20:01:58 2018	(r334444)
@@ -36,12 +36,11 @@ makefs -B little -o label=FreeBSD_Install -o version=2
 rm ${1}/etc/fstab
 rm ${1}/etc/rc.conf.local
 
-mkimg -s gpt \
-    -b ${1}/boot/pmbr \
+mkimg -s mbr \
+    -b ${1}/boot/mbr \
     -p efi:=${1}/boot/boot1.efifat \
-    -p freebsd-boot:=${1}/boot/gptboot \
-    -p freebsd-ufs:=${2}.part \
-    -p freebsd-swap::1M \
+    -p freebsd:-"mkimg -s bsd -b ${1}/boot/boot -p freebsd-ufs:=${2}.part" \
+    -a 2 \
     -o ${2}
 rm ${2}.part
 

Modified: stable/11/stand/efi/boot1/boot_module.h
==============================================================================
--- stable/11/stand/efi/boot1/boot_module.h	Thu May 31 19:36:24 2018	(r334443)
+++ stable/11/stand/efi/boot1/boot_module.h	Thu May 31 20:01:58 2018	(r334444)
@@ -50,6 +50,7 @@ typedef struct dev_info
 	EFI_DEVICE_PATH *devpath;
 	EFI_HANDLE *devhandle;
 	void *devdata;
+	uint64_t partoff;
 	BOOLEAN preferred;
 	struct dev_info *next;
 } dev_info_t;

Modified: stable/11/stand/efi/boot1/ufs_module.c
==============================================================================
--- stable/11/stand/efi/boot1/ufs_module.c	Thu May 31 19:36:24 2018	(r334443)
+++ stable/11/stand/efi/boot1/ufs_module.c	Thu May 31 20:01:58 2018	(r334444)
@@ -36,10 +36,14 @@
 #include <stdbool.h>
 #include <sys/cdefs.h>
 #include <sys/param.h>
+#include <sys/disklabel.h>
 #include <efi.h>
 
 #include "boot_module.h"
 
+#define BSD_LABEL_BUFFER	8192
+#define BSD_LABEL_OFFSET	DEV_BSIZE
+
 static dev_info_t *devinfo;
 static dev_info_t *devices;
 
@@ -49,6 +53,7 @@ dskread(void *buf, uint64_t lba, int nblk)
 	int size;
 	EFI_STATUS status;
 
+	lba += devinfo->partoff;
 	lba = lba / (devinfo->dev->Media->BlockSize / DEV_BSIZE);
 	size = nblk * DEV_BSIZE;
 
@@ -73,11 +78,50 @@ static struct dmadat __dmadat;
 static int
 init_dev(dev_info_t* dev)
 {
+	char buffer[BSD_LABEL_BUFFER];
+	struct disklabel *dl;
+	uint64_t bs;
+	int ok;
 
 	devinfo = dev;
 	dmadat = &__dmadat;
 
-	return fsread(0, NULL, 0);
+	/*
+	 * First try offset 0. This is the typical GPT case where we have no
+	 * further partitioning (as well as the degenerate MBR case where
+	 * the bsdlabel has a 0 offset).
+	 */
+	devinfo->partoff = 0;
+	ok = fsread(0, NULL, 0);
+	if (ok >= 0)
+		return (ok);
+
+	/*
+	 * Next, we look for a bsdlabel. This is technically located in sector
+	 * 1. For 4k sectors, this offset is 4096, for 512b sectors it's
+	 * 512. However, we have to fall back to 512 here because we create
+	 * images that assume 512 byte blocks, but these can be put on devices
+	 * who have 4k (or other) block sizes. If there's a crazy block size, we
+	 * skip the 'at one sector' and go stright to checking at 512 bytes.
+	 * There are other offsets that are historic, but we don't probe those
+	 * since they were never used for MBR disks on FreeBSD on systems that
+	 * could boot UEFI. UEFI is little endian only, as are BSD labels. We
+	 * will retry fsread(0) only if there's a label found with a non-zero
+	 * offset.
+	 */
+	if (dskread(buffer, 0, BSD_LABEL_BUFFER / DEV_BSIZE) != 0)
+		return (-1);
+	dl = NULL;
+	bs = devinfo->dev->Media->BlockSize;
+	if (bs != 0 && bs <= BSD_LABEL_BUFFER / 2)
+		dl = (struct disklabel *)&buffer[bs];
+	if (dl == NULL || dl->d_magic != DISKMAGIC || dl->d_magic2 != DISKMAGIC)
+		dl = (struct disklabel *)&buffer[BSD_LABEL_OFFSET];
+	if (dl->d_magic != DISKMAGIC || dl->d_magic2 != DISKMAGIC ||
+	    dl->d_partitions[0].p_offset == 0)
+		return (-1);
+	devinfo->partoff = dl->d_partitions[0].p_offset;
+	return (fsread(0, NULL, 0));
 }
 
 static EFI_STATUS


More information about the svn-src-all mailing list