[parted-devel] [PATCH] Support for Apple TV Recovery Partition

Eagle Jones eagle at newdream.net
Wed May 30 20:01:13 UTC 2007


Hi-

This patch is as yet untested, but I just wanted to check in with you
folks first for two things:

-Make sure I didn't miss anything blindingly obvious since I'm totally
unfamiliar with the parted source.
-See if you even care about this patch.

Background:

The Apple TV contains a gpt-labeled drive with four partitions:
1. EFI Boot Partition
2. Recovery - Formatted Standard HFS (non-journaled) - with GUID
5265636F-7665-11AA-AA11-00306543ECAC
3. OSBoot - Journaled HFS
4. Media - Journaled HFS

When I attempted to duplicate this partitioning scheme on a new drive,
parted happily reported that partition 2 was HFS+, ignoring the
unknown GUID. I obviously found the fall-through behavior on an
unknown GUID to be confusing, but that's another issue. After
partitioning the new drive with a scheme matching what parted
originally reported, the Apple TV booted, but always stayed in
recovery mode, ignoring the contents of OSBoot. Several hours of
research led me to realize that the partition tables did not match
despite their identical appearance in parted.

What this patch does:

-Adds a flag, atvrecv. Its behavior is modeled after msftresv to
handle the ATV recovery GUID.

diff --git a/include/parted/disk.h b/include/parted/disk.h
index 4dd81d9..109d96d 100644
--- a/include/parted/disk.h
+++ b/include/parted/disk.h
@@ -53,10 +53,11 @@ enum _PedPartitionFlag {
         PED_PARTITION_HPSERVICE=8,
         PED_PARTITION_PALO=9,
         PED_PARTITION_PREP=10,
-        PED_PARTITION_MSFT_RESERVED=11
+        PED_PARTITION_MSFT_RESERVED=11,
+        PED_PARTITION_APPLE_TV_RECOVERY=12
 };
 #define PED_PARTITION_FIRST_FLAG        PED_PARTITION_BOOT
-#define PED_PARTITION_LAST_FLAG         PED_PARTITION_MSFT_RESERVED
+#define PED_PARTITION_LAST_FLAG         PED_PARTITION_APPLE_TV_RECOVERY

 enum _PedDiskTypeFeature {
         PED_DISK_TYPE_EXTENDED=1,       /**< supports extended partitions */
diff --git a/libparted/disk.c b/libparted/disk.c
index d23fe15..e92b47f 100644
--- a/libparted/disk.c
+++ b/libparted/disk.c
@@ -2181,6 +2181,8 @@ ped_partition_flag_get_name (PedPartitionFlag flag)
 		return N_("prep");
 	case PED_PARTITION_MSFT_RESERVED:
 		return N_("msftres");
+	case PED_PARTITION_APPLE_TV_RECOVERY:
+		return N_("atvrecv");

 	default:
 		ped_exception_throw (
diff --git a/libparted/labels/gpt.c b/libparted/labels/gpt.c
index 86c31c7..aef21e8 100644
--- a/libparted/labels/gpt.c
+++ b/libparted/labels/gpt.c
@@ -123,6 +123,10 @@ typedef struct {
     ((efi_guid_t) { PED_CPU_TO_LE32 (0x48465300), PED_CPU_TO_LE16 (0x0000), \
 		    PED_CPU_TO_LE16 (0x11AA), 0xaa, 0x11, \
 		    { 0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC }})
+#define PARTITION_APPLE_TV_RECOVERY_GUID \
+    ((efi_guid_t) { PED_CPU_TO_LE32 (0x5265636F), PED_CPU_TO_LE16 (0x7665), \
+		    PED_CPU_TO_LE16 (0x11AA), 0xaa, 0x11, \
+		    { 0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC }})

 struct __attribute__ ((packed)) _GuidPartitionTableHeader_t {
 	uint64_t Signature;
@@ -249,6 +253,7 @@ typedef struct _GPTPartitionData {
 	int		hp_service;
         int             hidden;
         int             msftres;
+        int             atvrecv;
 } GPTPartitionData;

 static PedDiskType gpt_disk_type;
@@ -751,7 +756,8 @@ _parse_part_entry (PedDisk* disk, GuidPartitionEntry_t* pte)

         gpt_part_data->lvm = gpt_part_data->raid
                 = gpt_part_data->boot = gpt_part_data->hp_service
-                = gpt_part_data->hidden = gpt_part_data->msftres = 0;
+                = gpt_part_data->hidden = gpt_part_data->msftres
+                = gpt_part_data->atvrecv = 0;

         if (pte->Attributes.RequiredToFunction & 0x1)
                 gpt_part_data->hidden = 1;
@@ -766,6 +772,8 @@ _parse_part_entry (PedDisk* disk, GuidPartitionEntry_t* pte)
 		gpt_part_data->hp_service = 1;
         else if (!guid_cmp (gpt_part_data->type, PARTITION_MSFT_RESERVED_GUID))
                 gpt_part_data->msftres = 1;
+	else if (!guid_cmp (gpt_part_data->type, PARTITION_APPLE_TV_RECOVERY_GUID))
+		gpt_part_data->atvrecv = 1;

 	return part;
 }
@@ -1131,6 +1139,7 @@ gpt_partition_new (const PedDisk* disk,
 	gpt_part_data->hp_service = 0;
         gpt_part_data->hidden = 0;
         gpt_part_data->msftres = 0;
+        gpt_part_data->atvrecv = 0;
 	uuid_generate ((unsigned char*) &gpt_part_data->uuid);
 	swap_uuid_and_efi_guid((unsigned char*)(&gpt_part_data->uuid));
 	strcpy (gpt_part_data->name, "");
@@ -1214,7 +1223,11 @@ gpt_partition_set_system (PedPartition* part,
const PedFileSystemType* fs_type)
                 gpt_part_data->type = PARTITION_MSFT_RESERVED_GUID;
                 return 1;
         }
-
+	if (gpt_part_data->atvrecv) {
+		gpt_part_data->type = PARTITION_APPLE_TV_RECOVERY_GUID;
+		return 1;
+	}
+
 	if (fs_type) {
 		if (strncmp (fs_type->name, "fat", 3) == 0
 		    || strcmp (fs_type->name, "ntfs") == 0) {
@@ -1305,7 +1318,8 @@ gpt_partition_set_flag(PedPartition *part,
                         gpt_part_data->raid
                                 = gpt_part_data->lvm
                                 = gpt_part_data->hp_service
-                                = gpt_part_data->msftres = 0;
+                                = gpt_part_data->msftres
+                                = gpt_part_data->atvrecv = 0;
 		return gpt_partition_set_system (part, part->fs_type);
 	case PED_PARTITION_RAID:
 		gpt_part_data->raid = state;
@@ -1313,7 +1327,8 @@ gpt_partition_set_flag(PedPartition *part,
                         gpt_part_data->boot
                                 = gpt_part_data->lvm
                                 = gpt_part_data->hp_service
-                                = gpt_part_data->msftres = 0;
+                                = gpt_part_data->msftres
+                                = gpt_part_data->atvrecv = 0;
 		return gpt_partition_set_system (part, part->fs_type);
 	case PED_PARTITION_LVM:
 		gpt_part_data->lvm = state;
@@ -1321,7 +1336,8 @@ gpt_partition_set_flag(PedPartition *part,
                         gpt_part_data->boot
                                 = gpt_part_data->raid
                                 = gpt_part_data->hp_service
-                                = gpt_part_data->msftres = 0;
+                                = gpt_part_data->msftres
+                                = gpt_part_data->atvrecv = 0;
 		return gpt_partition_set_system (part, part->fs_type);
 	case PED_PARTITION_HPSERVICE:
 		gpt_part_data->hp_service = state;
@@ -1329,7 +1345,8 @@ gpt_partition_set_flag(PedPartition *part,
                         gpt_part_data->boot
                                 = gpt_part_data->raid
                                 = gpt_part_data->lvm
-                                = gpt_part_data->msftres = 0;
+                                = gpt_part_data->msftres
+                                = gpt_part_data->atvrecv = 0;
 		return gpt_partition_set_system (part, part->fs_type);
         case PED_PARTITION_MSFT_RESERVED:
                 gpt_part_data->msftres = state;
@@ -1337,7 +1354,17 @@ gpt_partition_set_flag(PedPartition *part,
                         gpt_part_data->boot
                                 = gpt_part_data->raid
                                 = gpt_part_data->lvm
-                                = gpt_part_data->hp_service = 0;
+                                = gpt_part_data->hp_service
+                                = gpt_part_data->atvrecv = 0;
+                return gpt_partition_set_system (part, part->fs_type);
+        case PED_PARTITION_APPLE_TV_RECOVERY:
+                gpt_part_data->atvrecv = state;
+                if (state)
+                        gpt_part_data->boot
+                                = gpt_part_data->raid
+                                = gpt_part_data->lvm
+                                = gpt_part_data->hp_service
+                                = gpt_part_data->msftres = 0;
                 return gpt_partition_set_system (part, part->fs_type);
         case PED_PARTITION_HIDDEN:
                 gpt_part_data->hidden = state;
@@ -1369,6 +1396,8 @@ gpt_partition_get_flag(const PedPartition *part,
PedPartitionFlag flag)
 		return gpt_part_data->hp_service;
         case PED_PARTITION_MSFT_RESERVED:
                 return gpt_part_data->msftres;
+        case PED_PARTITION_APPLE_TV_RECOVERY:
+                return gpt_part_data->atvrecv;
         case PED_PARTITION_HIDDEN:
                        return gpt_part_data->hidden;
 	case PED_PARTITION_SWAP:
@@ -1390,6 +1419,7 @@ gpt_partition_is_flag_available(const PedPartition * part,
 	case PED_PARTITION_BOOT:
 	case PED_PARTITION_HPSERVICE:
         case PED_PARTITION_MSFT_RESERVED:
+    case PED_PARTITION_APPLE_TV_RECOVERY:
         case PED_PARTITION_HIDDEN:
 		return 1;
 	case PED_PARTITION_SWAP:



More information about the parted-devel mailing list