Beginning to describe EFI isohybrid with Apple partition map and GPT.

This commit is contained in:
Thomas Schmitt 2012-05-06 10:08:21 +02:00
parent ff95a84130
commit abd2137906

View File

@ -17,7 +17,8 @@ EL Torito CD booting, for PC-BIOS x86, PowerPC, (old) Mac, EFI.
MBR, for PC-BIOS x86 from (pseudo-) hard disk
- SYSLINUX isohybrid MBR
- GRUB2 grub-mkrescue MBR.
>>> under construction: - SYSLINUX isohybrid for UEFI and x86 Mac
- GRUB2 grub-mkrescue MBR
MIPS Volume Header, for MIPS Big Endian, e.g. SGI Indigo2.
@ -394,6 +395,257 @@ hpa about MBR templates and partition table filesystem types:
IFS Hidden") seems safeish, some people believe 0x83 (Linux) is better.
"
>>> SYSLINUX isohybrid for UEFI and x86-Mac
Sources:
http://mjg59.dreamwidth.org/11285.html
http://mjg59.fedorapeople.org/Fedora-LiveCD.iso
http://opensource.apple.com/source/IOStorageFamily/IOStorageFamily-116/IOApplePartitionScheme.h (typedef struct Block0)
http://www.informit.com/articles/article.aspx?p=376123&seqNum=3
http://en.wikipedia.org/wiki/GUID_Partition_Table
syslinux-4.05/utils/isohybrid.c
>>> Motivation: What systems will use the additional data ? amd64 UEFI ?
Newer SYSLINUX MBR templates begin by 32 bytes of machine code which are
intentionally non-essential:
33 ed 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
They may be overwritten by other bytes which must not produce errors or
undesirable side effects when executed as x86 machine code.
The following 32 bytes from block 0 of an Apple Partiton Map (APM) are such
harmless code. They stem from Fedora-LiveCD.iso by Matthew Garret:
45 52 08 00 00 00 90 90 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
The layout of a Block0 of an APM is:
Byte Range | Value | Meaning (all numbers are stored big endian)
---------- | ---------- | ----------------------------------------------------
0 - 1 | sig | Signature 0x45 = 'E' , 0x52 = 'R'
2 - 3 | block_size | 0x0800 = 2048
4 - 7 | block_count| 0x9090 = 37008
8 - 9 | dev_type | obscure: "device type"
10 - 11 | dev_id | obscure: "device id"
12 - 15 | drv_data | obscure: "driver data"
16 - 17 | drv_count | obscure: "driver descriptor count"
18 - 81 | drv_map | obscure: "driver descriptor table"
| | with 8 entries of 16 bytes each
82 - 511 | reserved |
---------- | ---------- | ----------------------------------------------------
(The block_count of 0x9090 is pure fantasy. It shall only mark the disc as
not empty.)
For the purpose of booting, there may be two EFI boot image files in the
ISO image. A VFAT image and a HFS+ image. The content of both is not in the
scope of this document.
These boot images get announced by EL Torito boot catalog entries with
Platform Id 0xef.
The data block ranges of the two EFI boot images get described by MBR
partition entries 2 and 3, which thus claim blocks inside of partition 1.
This partition nesting is acceptable to some EFI implementations only if the
type of partition 1 is 0x00.
The second 512-block in the ISO image is a GPT header.
45 46 49 20 50 41 52 54 00 00 01 00 5c 00 00 00
E F I P A R T
13 db 71 5d 00 00 00 00 01 00 00 00 00 00 00 00
fe 4f 14 00 00 00 00 00 30 00 00 00 00 00 00 00
de 4f 14 00 00 00 00 00 73 23 c8 79 19 e6 97 4d
95 17 69 30 c5 38 e2 99 10 00 00 00 00 00 00 00
80 00 00 00 80 00 00 00 5b 6b 8a 65
Byte Range | Value | Meaning (little endian numbers, LBA unit is 512 byte)
---------- | ---------- | ----------------------------------------------------
0 - 7 | sig | Signature "EFI PART" (with no trailing zero)
8 - 11 | revision | Revision = {0x00, 0x00, 0x01, 0x00} meaning "1.0"
12 - 15 | head_size | Header size = 0x5c = 92
16 - 19 | head_crc | CRC-32 of this header while head_crc is 0
20 - 23 | reserved | = 0
24 - 31 | curr_lba | Location of this header block = 0x1
32 - 39 | back_lba | Location of header backup block = 0x144ffe = 1331198
>>> ??? That is 437.5 2K-blocks after the image end
>>> ??? which is at 332362 (* 4 = 1329448)
>>> ??? 1 MiB alignment ?
40 - 47 | first_lba | First usable LBA for partitions = 0x30 = 48
48 - 55 | last_lba | Last usable LBA for partitions = 0x144fde = 1331166
56 - 71 | guid | Disk GUID / UUID = {
| | 0x73, 0x23, 0xc8, 0x79, 0x19, 0xe6, 0x97, 0x4d,
| | 0x95, 0x17, 0x69, 0x30, 0xc5, 0x38, 0xe2, 0x99 }
72 - 79 | part_start | Partition entries start LBA = 0x10 = 16 = byte 0x2000
| | (This is unusual. It leaves room for the Apple
| | partition map entries.)
80 - 83 | entry_count| Number of partition entries = 0x80 = 128
84 - 87 | entry_size | Size of a partition entry = 0x80 = 128
88 - 91 | p_arr_crc | CRC-32 of the partition array
92 - 511 | reserved | Must be 0
---------- | ---------- | ----------------------------------------------------
>>> CRC-32: Generating polynomial 0x104c11db7, mirrored bit order in and out,
>>> seed 0xffffffff, result gets exored by 0xffffffff.
>>> ??? This works as byte shifter with a bitwise mirrored table
>>> ??? but not as simple bit shifter.
>>> ??? Both do match if seed == 0. But not with other seeds.
>>> ??? An algebraic miracle ?
The ISO image has a size of 332362 blocks of 2K = 1329448 blocks of 512.
Because the block size was announced as 2048, the first Apple partition map
entry is located at byte 0x800.
It describes the partition map itself:
50 4d 00 00 00 00 00 03 00 00 00 01 00 00 00 10
P M
41 70 70 6c 65 00 00 00 00 00 00 00 00 00 00 00
A p p l e
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
41 70 70 6c 65 5f 70 61 72 74 69 74 69 6f 6e 5f
A p p l e _ p a r t i t i o n _
6d 61 70 00 00 00 00 00 00 00 00 00 00 00 00 00
m a p
00 00 00 00 00 00 00 0a 00 00 00 03 00 00 00 00
The layout of an Apple partition map entry is:
Byte Range | Value | Meaning (all numbers are stored big endian)
---------- | ---------- | ----------------------------------------------------
0 - 1 | sig | Signature 0x50 = 'P' , 0x4d = 'M'
2 - 3 | reserved |
4 - 7 | map_entries| "number of partition entries" = 3
8 - 11 | start_block| "physical block start of partition" = 1
12 - 15 | block_count| "physical block count of partition" = 16
| | (The value of 16 claims the ISO 9660 PVD as part of
| | the partition table. This might be unhealthy.)
16 - 47 | name | Partition name = "Apple"
48 - 79 | type | Type string = "Apple_partition_map"
80 - 83 | lb_start | Logical block start = 0
84 - 87 | lb_count | Logical block count = 10
88 - 91 | flags | Status flags = 3
| | bit0= entry is valid
| | bit1= entry is allocated
| | bit4= partition is readable
| | bit5= partition is writable
92 - 95 | boot_block | Logical start block number of boot code = 0
96 - 99 | boot_bytes | Number of bytes in boot code = 0
100 - 119 | | More boot code stuff = 0
120 - 135 | processor | "processor type" = 0
136 - 511 | reserved |
---------- | ---------- | ----------------------------------------------------
The next Apple partition map entry is at byte 0x1000:
50 4d 00 00 00 00 00 03 00 00 00 29 00 00 04 70
45 46 49 00 00 00 00 00 00 00 00 00 00 00 00 00
E F I
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
41 70 70 6c 65 5f 48 46 53 00 00 00 00 00 00 00
A p p l e _ H F S
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 04 70 00 00 00 33 00 00 00 00
3 partitions, start block is 0x29 = 41, block count is 0x0470 = 1136,
name is "EFI", type is "Apple_HFS"
>>> although this is a FAT image
, logical block start = 0, lb_count = 1136,
flags = 0x33 : valid, allocated, readable, writable.
This points to file /isolinux/efiboot.img in the ISO image,
>>> but misrepresents its size of 284 blocks of 2048.
At byte 0x1800, there is map entry 3:
50 4d 00 00 00 00 00 03 00 00 01 51 00 00 08 c0
45 46 49 00 00 00 00 00 00 00 00 00 00 00 00 00
E F I
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
41 70 70 6c 65 5f 48 46 53 00 00 00 00 00 00 00
A p p l e _ H F S
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 08 c0 00 00 00 33 00 00 00 00
3 partitions, start block is 0x0151 = 337 (LBA of /isolinux/macboot.img),
block count = 2240
>>> (4 times higher than ISO size of 560 blocks)
, name is "EFI", type is "Apple_HFS",
, logical block start = 0, lb_count = 2240,
flags = 0x33 : valid, allocated, readable, writable.
>>> GPT partitions marking ISO image, VFAT image within, HFS+ image within
At byte 0x2000 begins the GPT partition array. It ends at byte 0x4000.
a2 a0 d0 eb e5 b9 33 44 87 c0 68 b6 b7 26 99 c7
a1 87 a1 ba 4d 2c 27 45 ae 05 cf ab a6 fa 87 c1
00 00 00 00 00 00 00 00 28 49 14 00 00 00 00 00
00 00 00 00 00 00 00 00 49 53 4f 48 79 62 72 69
I S O H y b r i
64 20 49 53 4f 00 49 53 4f 48 79 62 72 69 64 00
d I S O I S O H y b r i d
41 70 70 6c 00 00 00 00 00 00 00 00 00 00 00 00
A p p l
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
A GPT partion entry looks like:
Byte Range | Value | Meaning (numbers are stored little endian)
---------- | ---------- | ----------------------------------------------------
0 - 15 | type_guid | Partition type guid = random
16 - 31 | part_guid | Unique partition GUID = random
32 - 39 | start_lba | First LBA = 0
40 - 47 | end_lba | Last LBA (inclusive) = 0x144828 = 1329448
| | This is the ISO image size in blocks of 512.
>>> But it should be 1 block less than that
48 - 55 | flags | Attribute flags
| | bit0= "System Partition" Do not alter.
| | bit2= Legacy BIOS bootable (MBR partition type 0x80)
| | bit60= read-only
56 - 127 | name | >>> Wikipedia says UTF-16LE.
| | >>> The name in Fedora-LiveCD.iso is 8 bit and result
| | >>> of faulty memory operation on a text constant.
---------- | ---------- | ----------------------------------------------------
Next entry:
a2 a0 d0 eb e5 b9 33 44 87 c0 68 b6 b7 26 99 c7
c8 de c8 1f fb f0 51 40 8c 8a d2 f6 b1 46 16 dc
a4 00 00 00 00 00 00 00 13 05 00 00 00 00 00 00
00 00 00 00 00 00 00 00 49 53 4f 48 79 62 72 69
I S O H y b r i
64 00 41 70 70 6c 65 00 41 70 70 6c 00 00 00 00
d A p p l e A p p l
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Start at block 0xa4 = 164 * 512 = 41 * 2048. The VFAT image file.
Last block is 0x0513 = 1299 = 164 + 1135. This end is correct.
>>> The name is an unintentional patchwork in an 8 bit character set.
Next entry:
00 53 46 48 00 00 aa 11 aa 11 00 30 65 43 ec ac
c8 de c8 1f fb f0 51 40 8c 8a d2 f6 b1 46 16 dc
44 05 00 00 00 00 00 00 03 0e 00 00 00 00 00 00
00 00 00 00 00 00 00 00 49 53 4f 48 79 62 72 69
I S O H y b r i
64 00 41 70 70 6c 65 00 41 70 70 6c 00 00 00 00
d A p p l e A p p l
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Start block is 0x0544 = 1348 * 512 = 337 * 2048. The HFS+ image file.
Last block is 0x0e03 = 3587 = 1348 + 2239. Correct.
>>> Frankenstein's name, again.
The rest of the System Area is 0 up to the Primary Volume Descriptor
at block 16.
------------------------------------------------------------------------------