Print this page
10570 Need workaround to EFI boot on AMI BIOS

@@ -22,11 +22,11 @@
 /*
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  * Copyright 2014 Toomas Soome <tsoome@me.com>
  * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
- * Copyright (c) 2018, Joyent, Inc.
+ * Copyright 2019 Joyent, Inc.
  */
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <errno.h>

@@ -339,13 +339,12 @@
             crc != LE_32(efi_crc32((unsigned char *)efi,
             LE_32(efi->efi_gpt_HeaderSize)))) {
                 if (efi_debug)
                         (void) fprintf(stderr,
                             "Bad EFI CRC: 0x%x != 0x%x\n",
-                            crc,
-                            LE_32(efi_crc32((unsigned char *)efi,
-                            sizeof (struct efi_gpt))));
+                            crc, LE_32(efi_crc32((unsigned char *)efi,
+                            LE_32(efi->efi_gpt_HeaderSize))));
                 return (VT_EINVAL);
         }
 
         return (0);
 }

@@ -713,11 +712,11 @@
         slot = active = 0;
 
         hardware_workarounds(&slot, &active);
 
         len = (vtoc->efi_lbasize == 0) ? sizeof (mb) : vtoc->efi_lbasize;
-        buf = calloc(len, 1);
+        buf = calloc(1, len);
 
         /*
          * Preserve any boot code and disk signature if the first block is
          * already an MBR.
          */

@@ -739,14 +738,14 @@
 
         bzero(&mb.parts, sizeof (mb.parts));
         cp = (uchar_t *)&mb.parts[slot * sizeof (struct ipart)];
         /* bootable or not */
         *cp++ = active ? ACTIVE : NOTACTIVE;
-        /* beginning CHS; 0xffffff if not representable */
-        *cp++ = 0xff;
-        *cp++ = 0xff;
-        *cp++ = 0xff;
+        /* beginning CHS; same as starting LBA (but one-based) */
+        *cp++ = 0x0;
+        *cp++ = 0x2;
+        *cp++ = 0x0;
         /* OS type */
         *cp++ = EFI_PMBR;
         /* ending CHS; 0xffffff if not representable */
         *cp++ = 0xff;
         *cp++ = 0xff;

@@ -1027,11 +1026,11 @@
         efi = dk_ioc.dki_data;
 
         /* stuff user's input into EFI struct */
         efi->efi_gpt_Signature = LE_64(EFI_SIGNATURE);
         efi->efi_gpt_Revision = LE_32(vtoc->efi_version); /* 0x02000100 */
-        efi->efi_gpt_HeaderSize = LE_32(sizeof (struct efi_gpt));
+        efi->efi_gpt_HeaderSize = LE_32(EFI_HEADER_SIZE);
         efi->efi_gpt_Reserved1 = 0;
         efi->efi_gpt_MyLBA = LE_64(1ULL);
         efi->efi_gpt_AlternateLBA = LE_64(lba_backup_gpt_hdr);
         efi->efi_gpt_FirstUsableLBA = LE_64(vtoc->efi_first_u_lba);
         efi->efi_gpt_LastUsableLBA = LE_64(vtoc->efi_last_u_lba);

@@ -1092,12 +1091,12 @@
                     sizeof (uuid_t));
         }
         efi->efi_gpt_PartitionEntryArrayCRC32 =
             LE_32(efi_crc32((unsigned char *)efi_parts,
             vtoc->efi_nparts * (int)sizeof (struct efi_gpe)));
-        efi->efi_gpt_HeaderCRC32 =
-            LE_32(efi_crc32((unsigned char *)efi, sizeof (struct efi_gpt)));
+        efi->efi_gpt_HeaderCRC32 = LE_32(efi_crc32((unsigned char *)efi,
+            EFI_HEADER_SIZE));
 
         if (efi_ioctl(fd, DKIOCSETEFI, &dk_ioc) == -1) {
                 free(dk_ioc.dki_data);
                 switch (errno) {
                 case EIO:

@@ -1140,12 +1139,11 @@
         efi->efi_gpt_AlternateLBA = LE_64(1ULL);
         efi->efi_gpt_MyLBA = LE_64(lba_backup_gpt_hdr);
         efi->efi_gpt_PartitionEntryLBA = LE_64(vtoc->efi_last_u_lba + 1);
         efi->efi_gpt_HeaderCRC32 = 0;
         efi->efi_gpt_HeaderCRC32 =
-            LE_32(efi_crc32((unsigned char *)dk_ioc.dki_data,
-            sizeof (struct efi_gpt)));
+            LE_32(efi_crc32((unsigned char *)dk_ioc.dki_data, EFI_HEADER_SIZE));
 
         if (efi_ioctl(fd, DKIOCSETEFI, &dk_ioc) == -1) {
                 if (efi_debug) {
                         (void) fprintf(stderr,
                             "write of backup header to block %llu failed, "