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

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libefi/common/rdwr_efi.c
          +++ new/usr/src/lib/libefi/common/rdwr_efi.c
↓ open down ↓ 16 lines elided ↑ open up ↑
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  24   24   * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  25   25   * Copyright 2014 Toomas Soome <tsoome@me.com>
  26   26   * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
  27      - * Copyright (c) 2018, Joyent, Inc.
       27 + * Copyright 2019 Joyent, Inc.
  28   28   */
  29   29  
  30   30  #include <stdio.h>
  31   31  #include <stdlib.h>
  32   32  #include <errno.h>
  33   33  #include <strings.h>
  34   34  #include <unistd.h>
  35   35  #include <smbios.h>
  36   36  #include <uuid/uuid.h>
  37   37  #include <libintl.h>
↓ open down ↓ 296 lines elided ↑ open up ↑
 334  334           */
 335  335          crc = efi->efi_gpt_HeaderCRC32;
 336  336          efi->efi_gpt_HeaderCRC32 = 0;
 337  337  
 338  338          if (((len_t)LE_32(efi->efi_gpt_HeaderSize) > dk_ioc->dki_length) ||
 339  339              crc != LE_32(efi_crc32((unsigned char *)efi,
 340  340              LE_32(efi->efi_gpt_HeaderSize)))) {
 341  341                  if (efi_debug)
 342  342                          (void) fprintf(stderr,
 343  343                              "Bad EFI CRC: 0x%x != 0x%x\n",
 344      -                            crc,
 345      -                            LE_32(efi_crc32((unsigned char *)efi,
 346      -                            sizeof (struct efi_gpt))));
      344 +                            crc, LE_32(efi_crc32((unsigned char *)efi,
      345 +                            LE_32(efi->efi_gpt_HeaderSize))));
 347  346                  return (VT_EINVAL);
 348  347          }
 349  348  
 350  349          return (0);
 351  350  }
 352  351  
 353  352  static int
 354  353  efi_read(int fd, struct dk_gpt *vtoc)
 355  354  {
 356  355          int                     i, j;
↓ open down ↓ 351 lines elided ↑ open up ↑
 708  707          uchar_t         *cp;
 709  708          diskaddr_t      size_in_lba;
 710  709          uchar_t         *buf;
 711  710          int             len, slot, active;
 712  711  
 713  712          slot = active = 0;
 714  713  
 715  714          hardware_workarounds(&slot, &active);
 716  715  
 717  716          len = (vtoc->efi_lbasize == 0) ? sizeof (mb) : vtoc->efi_lbasize;
 718      -        buf = calloc(len, 1);
      717 +        buf = calloc(1, len);
 719  718  
 720  719          /*
 721  720           * Preserve any boot code and disk signature if the first block is
 722  721           * already an MBR.
 723  722           */
 724  723          dk_ioc.dki_lba = 0;
 725  724          dk_ioc.dki_length = len;
 726  725          /* LINTED -- always longlong aligned */
 727  726          dk_ioc.dki_data = (efi_gpt_t *)buf;
 728  727          if (efi_ioctl(fd, DKIOCGETEFI, &dk_ioc) == -1) {
↓ open down ↓ 5 lines elided ↑ open up ↑
 734  733                  if (mb.signature != LE_16(MBB_MAGIC)) {
 735  734                          bzero(&mb, sizeof (mb));
 736  735                          mb.signature = LE_16(MBB_MAGIC);
 737  736                  }
 738  737          }
 739  738  
 740  739          bzero(&mb.parts, sizeof (mb.parts));
 741  740          cp = (uchar_t *)&mb.parts[slot * sizeof (struct ipart)];
 742  741          /* bootable or not */
 743  742          *cp++ = active ? ACTIVE : NOTACTIVE;
 744      -        /* beginning CHS; 0xffffff if not representable */
 745      -        *cp++ = 0xff;
 746      -        *cp++ = 0xff;
 747      -        *cp++ = 0xff;
      743 +        /* beginning CHS; same as starting LBA (but one-based) */
      744 +        *cp++ = 0x0;
      745 +        *cp++ = 0x2;
      746 +        *cp++ = 0x0;
 748  747          /* OS type */
 749  748          *cp++ = EFI_PMBR;
 750  749          /* ending CHS; 0xffffff if not representable */
 751  750          *cp++ = 0xff;
 752  751          *cp++ = 0xff;
 753  752          *cp++ = 0xff;
 754  753          /* starting LBA: 1 (little endian format) by EFI definition */
 755  754          *cp++ = 0x01;
 756  755          *cp++ = 0x00;
 757  756          *cp++ = 0x00;
↓ open down ↓ 264 lines elided ↑ open up ↑
1022 1021           */
1023 1022          lba_backup_gpt_hdr = vtoc->efi_last_u_lba + 1 + nblocks;
1024 1023          if ((dk_ioc.dki_data = calloc(1, dk_ioc.dki_length)) == NULL)
1025 1024                  return (VT_ERROR);
1026 1025  
1027 1026          efi = dk_ioc.dki_data;
1028 1027  
1029 1028          /* stuff user's input into EFI struct */
1030 1029          efi->efi_gpt_Signature = LE_64(EFI_SIGNATURE);
1031 1030          efi->efi_gpt_Revision = LE_32(vtoc->efi_version); /* 0x02000100 */
1032      -        efi->efi_gpt_HeaderSize = LE_32(sizeof (struct efi_gpt));
     1031 +        efi->efi_gpt_HeaderSize = LE_32(EFI_HEADER_SIZE);
1033 1032          efi->efi_gpt_Reserved1 = 0;
1034 1033          efi->efi_gpt_MyLBA = LE_64(1ULL);
1035 1034          efi->efi_gpt_AlternateLBA = LE_64(lba_backup_gpt_hdr);
1036 1035          efi->efi_gpt_FirstUsableLBA = LE_64(vtoc->efi_first_u_lba);
1037 1036          efi->efi_gpt_LastUsableLBA = LE_64(vtoc->efi_last_u_lba);
1038 1037          efi->efi_gpt_PartitionEntryLBA = LE_64(2ULL);
1039 1038          efi->efi_gpt_NumberOfPartitionEntries = LE_32(vtoc->efi_nparts);
1040 1039          efi->efi_gpt_SizeOfPartitionEntry = LE_32(sizeof (struct efi_gpe));
1041 1040          UUID_LE_CONVERT(efi->efi_gpt_DiskGUID, vtoc->efi_disk_uguid);
1042 1041  
↓ open down ↓ 44 lines elided ↑ open up ↑
1087 1086                          (void) uuid_generate((uchar_t *)
1088 1087                              &vtoc->efi_parts[i].p_uguid);
1089 1088                  }
1090 1089                  bcopy(&vtoc->efi_parts[i].p_uguid,
1091 1090                      &efi_parts[i].efi_gpe_UniquePartitionGUID,
1092 1091                      sizeof (uuid_t));
1093 1092          }
1094 1093          efi->efi_gpt_PartitionEntryArrayCRC32 =
1095 1094              LE_32(efi_crc32((unsigned char *)efi_parts,
1096 1095              vtoc->efi_nparts * (int)sizeof (struct efi_gpe)));
1097      -        efi->efi_gpt_HeaderCRC32 =
1098      -            LE_32(efi_crc32((unsigned char *)efi, sizeof (struct efi_gpt)));
     1096 +        efi->efi_gpt_HeaderCRC32 = LE_32(efi_crc32((unsigned char *)efi,
     1097 +            EFI_HEADER_SIZE));
1099 1098  
1100 1099          if (efi_ioctl(fd, DKIOCSETEFI, &dk_ioc) == -1) {
1101 1100                  free(dk_ioc.dki_data);
1102 1101                  switch (errno) {
1103 1102                  case EIO:
1104 1103                          return (VT_EIO);
1105 1104                  case EINVAL:
1106 1105                          return (VT_EINVAL);
1107 1106                  default:
1108 1107                          return (VT_ERROR);
↓ open down ↓ 26 lines elided ↑ open up ↑
1135 1134          dk_ioc.dki_lba = lba_backup_gpt_hdr;
1136 1135          dk_ioc.dki_length = vtoc->efi_lbasize;
1137 1136          /* LINTED */
1138 1137          dk_ioc.dki_data = (efi_gpt_t *)((char *)dk_ioc.dki_data -
1139 1138              vtoc->efi_lbasize);
1140 1139          efi->efi_gpt_AlternateLBA = LE_64(1ULL);
1141 1140          efi->efi_gpt_MyLBA = LE_64(lba_backup_gpt_hdr);
1142 1141          efi->efi_gpt_PartitionEntryLBA = LE_64(vtoc->efi_last_u_lba + 1);
1143 1142          efi->efi_gpt_HeaderCRC32 = 0;
1144 1143          efi->efi_gpt_HeaderCRC32 =
1145      -            LE_32(efi_crc32((unsigned char *)dk_ioc.dki_data,
1146      -            sizeof (struct efi_gpt)));
     1144 +            LE_32(efi_crc32((unsigned char *)dk_ioc.dki_data, EFI_HEADER_SIZE));
1147 1145  
1148 1146          if (efi_ioctl(fd, DKIOCSETEFI, &dk_ioc) == -1) {
1149 1147                  if (efi_debug) {
1150 1148                          (void) fprintf(stderr,
1151 1149                              "write of backup header to block %llu failed, "
1152 1150                              "errno %d\n",
1153 1151                              lba_backup_gpt_hdr,
1154 1152                              errno);
1155 1153                  }
1156 1154          }
↓ open down ↓ 179 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX