• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef LOGICAL_PARTITION_METADATA_FORMAT_H_
18 #define LOGICAL_PARTITION_METADATA_FORMAT_H_
19 
20 #ifdef __cplusplus
21 #include <string>
22 #include <vector>
23 #endif
24 
25 #include <stdint.h>
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
31 /* Magic signature for LpMetadataGeometry. */
32 #define LP_METADATA_GEOMETRY_MAGIC 0x616c4467
33 
34 /* Space reserved for geometry information. */
35 #define LP_METADATA_GEOMETRY_SIZE 4096
36 
37 /* Magic signature for LpMetadataHeader. */
38 #define LP_METADATA_HEADER_MAGIC 0x414C5030
39 
40 /* Current metadata version. */
41 #define LP_METADATA_MAJOR_VERSION 10
42 #define LP_METADATA_MINOR_VERSION_MIN 0
43 #define LP_METADATA_MINOR_VERSION_MAX 2
44 
45 /* Metadata version needed to use the UPDATED partition attribute. */
46 #define LP_METADATA_VERSION_FOR_UPDATED_ATTR 1
47 
48 /* Metadata version needed for the new expanded header struct. */
49 #define LP_METADATA_VERSION_FOR_EXPANDED_HEADER 2
50 
51 /* Attributes for the LpMetadataPartition::attributes field.
52  *
53  * READONLY - The partition should not be considered writable. When used with
54  * device mapper, the block device will be created as read-only.
55  */
56 #define LP_PARTITION_ATTR_NONE 0x0
57 #define LP_PARTITION_ATTR_READONLY (1 << 0)
58 
59 /* This flag is only intended to be used with super_empty.img and super.img on
60  * retrofit devices. On these devices there are A and B super partitions, and
61  * we don't know ahead of time which slot the image will be applied to.
62  *
63  * If set, the partition name needs a slot suffix applied. The slot suffix is
64  * determined by the metadata slot number (0 = _a, 1 = _b).
65  */
66 #define LP_PARTITION_ATTR_SLOT_SUFFIXED (1 << 1)
67 
68 /* This flag is applied automatically when using MetadataBuilder::NewForUpdate.
69  * It signals that the partition was created (or modified) for a snapshot-based
70  * update. If this flag is not present, the partition was likely flashed via
71  * fastboot.
72  */
73 #define LP_PARTITION_ATTR_UPDATED (1 << 2)
74 
75 /* This flag marks a partition as disabled. It should not be used or mapped. */
76 #define LP_PARTITION_ATTR_DISABLED (1 << 3)
77 
78 /* Mask that defines all valid attributes. When changing this, make sure to
79  * update ParseMetadata().
80  */
81 #define LP_PARTITION_ATTRIBUTE_MASK_V0 \
82     (LP_PARTITION_ATTR_READONLY | LP_PARTITION_ATTR_SLOT_SUFFIXED)
83 #define LP_PARTITION_ATTRIBUTE_MASK_V1 (LP_PARTITION_ATTR_UPDATED | LP_PARTITION_ATTR_DISABLED)
84 #define LP_PARTITION_ATTRIBUTE_MASK \
85     (LP_PARTITION_ATTRIBUTE_MASK_V0 | LP_PARTITION_ATTRIBUTE_MASK_V1)
86 
87 /* Default name of the physical partition that holds logical partition entries.
88  * The layout of this partition will look like:
89  *
90  *     +--------------------+
91  *     | Disk Geometry      |
92  *     +--------------------+
93  *     | Geometry Backup    |
94  *     +--------------------+
95  *     | Metadata           |
96  *     +--------------------+
97  *     | Backup Metadata    |
98  *     +--------------------+
99  *     | Logical Partitions |
100  *     +--------------------+
101  */
102 #define LP_METADATA_DEFAULT_PARTITION_NAME "super"
103 
104 /* Size of a sector is always 512 bytes for compatibility with the Linux kernel. */
105 #define LP_SECTOR_SIZE 512
106 
107 /* Amount of space reserved at the start of every super partition to avoid
108  * creating an accidental boot sector.
109  */
110 #define LP_PARTITION_RESERVED_BYTES 4096
111 
112 /* This structure is stored at block 0 in the first 4096 bytes of the
113  * partition, and again in the following block. It is never modified and
114  * describes how logical partition information can be located.
115  */
116 typedef struct LpMetadataGeometry {
117     /*  0: Magic signature (LP_METADATA_GEOMETRY_MAGIC). */
118     uint32_t magic;
119 
120     /*  4: Size of the LpMetadataGeometry struct. */
121     uint32_t struct_size;
122 
123     /*  8: SHA256 checksum of this struct, with this field set to 0. */
124     uint8_t checksum[32];
125 
126     /* 40: Maximum amount of space a single copy of the metadata can use. This
127      * must be a multiple of LP_SECTOR_SIZE.
128      */
129     uint32_t metadata_max_size;
130 
131     /* 44: Number of copies of the metadata to keep. For A/B devices, this
132      * will be 2. For an A/B/C device, it would be 3, et cetera. For Non-A/B
133      * it will be 1. A backup copy of each slot is kept, so if this is "2",
134      * there will be four copies total.
135      */
136     uint32_t metadata_slot_count;
137 
138     /* 48: Logical block size. This is the minimal alignment for partition and
139      * extent sizes, and it must be a multiple of LP_SECTOR_SIZE. Note that
140      * this must be equal across all LUNs that comprise the super partition,
141      * and thus this field is stored in the geometry, not per-device.
142      */
143     uint32_t logical_block_size;
144 } __attribute__((packed)) LpMetadataGeometry;
145 
146 /* The logical partition metadata has a number of tables; they are described
147  * in the header via the following structure.
148  *
149  * The size of the table can be computed by multiplying entry_size by
150  * num_entries, and the result must not overflow a 32-bit signed integer.
151  */
152 typedef struct LpMetadataTableDescriptor {
153     /*  0: Location of the table, relative to end of the metadata header. */
154     uint32_t offset;
155     /*  4: Number of entries in the table. */
156     uint32_t num_entries;
157     /*  8: Size of each entry in the table, in bytes. */
158     uint32_t entry_size;
159 } __attribute__((packed)) LpMetadataTableDescriptor;
160 
161 /* Binary format for the header of the logical partition metadata format.
162  *
163  * The format has three sections. The header must occur first, and the
164  * proceeding tables may be placed in any order after.
165  *
166  *  +-----------------------------------------+
167  *  | Header data - fixed size                |
168  *  +-----------------------------------------+
169  *  | Partition table - variable size         |
170  *  +-----------------------------------------+
171  *  | Partition table extents - variable size |
172  *  +-----------------------------------------+
173  *
174  * The "Header" portion is described by LpMetadataHeader. It will always
175  * precede the other three blocks.
176  *
177  * All fields are stored in little-endian byte order when serialized.
178  *
179  * This struct is versioned; see the |major_version| and |minor_version|
180  * fields.
181  */
182 typedef struct LpMetadataHeader {
183     /*  0: Four bytes equal to LP_METADATA_HEADER_MAGIC. */
184     uint32_t magic;
185 
186     /*  4: Version number required to read this metadata. If the version is not
187      * equal to the library version, the metadata should be considered
188      * incompatible.
189      */
190     uint16_t major_version;
191 
192     /*  6: Minor version. A library supporting newer features should be able to
193      * read metadata with an older minor version. However, an older library
194      * should not support reading metadata if its minor version is higher.
195      */
196     uint16_t minor_version;
197 
198     /*  8: The size of this header struct. */
199     uint32_t header_size;
200 
201     /* 12: SHA256 checksum of the header, up to |header_size| bytes, computed as
202      * if this field were set to 0.
203      */
204     uint8_t header_checksum[32];
205 
206     /* 44: The total size of all tables. This size is contiguous; tables may not
207      * have gaps in between, and they immediately follow the header.
208      */
209     uint32_t tables_size;
210 
211     /* 48: SHA256 checksum of all table contents. */
212     uint8_t tables_checksum[32];
213 
214     /* 80: Partition table descriptor. */
215     LpMetadataTableDescriptor partitions;
216     /* 92: Extent table descriptor. */
217     LpMetadataTableDescriptor extents;
218     /* 104: Updateable group descriptor. */
219     LpMetadataTableDescriptor groups;
220     /* 116: Block device table. */
221     LpMetadataTableDescriptor block_devices;
222 
223     /* Everything past here is header version 1.2+, and is only included if
224      * needed. When liblp supporting >= 1.2 reads a < 1.2 header, it must
225      * zero these additional fields.
226      */
227 
228     /* 128: See LP_HEADER_FLAG_ constants for possible values. Header flags are
229      * independent of the version number and intended to be informational only.
230      * New flags can be added without bumping the version.
231      */
232     uint32_t flags;
233 
234     /* 132: Reserved (zero), pad to 256 bytes. */
235     uint8_t reserved[124];
236 } __attribute__((packed)) LpMetadataHeader;
237 
238 /* This device uses Virtual A/B. Note that on retrofit devices, the expanded
239  * header may not be present.
240  */
241 #define LP_HEADER_FLAG_VIRTUAL_AB_DEVICE 0x1
242 
243 /* This struct defines a logical partition entry, similar to what would be
244  * present in a GUID Partition Table.
245  */
246 typedef struct LpMetadataPartition {
247     /*  0: Name of this partition in ASCII characters. Any unused characters in
248      * the buffer must be set to 0. Characters may only be alphanumeric or _.
249      * The name must include at least one ASCII character, and it must be unique
250      * across all partition names. The length (36) is the same as the maximum
251      * length of a GPT partition name.
252      */
253     char name[36];
254 
255     /* 36: Attributes for the partition (see LP_PARTITION_ATTR_* flags above). */
256     uint32_t attributes;
257 
258     /* 40: Index of the first extent owned by this partition. The extent will
259      * start at logical sector 0. Gaps between extents are not allowed.
260      */
261     uint32_t first_extent_index;
262 
263     /* 44: Number of extents in the partition. Every partition must have at
264      * least one extent.
265      */
266     uint32_t num_extents;
267 
268     /* 48: Group this partition belongs to. */
269     uint32_t group_index;
270 } __attribute__((packed)) LpMetadataPartition;
271 
272 /* This extent is a dm-linear target, and the index is an index into the
273  * LinearExtent table.
274  */
275 #define LP_TARGET_TYPE_LINEAR 0
276 
277 /* This extent is a dm-zero target. The index is ignored and must be 0. */
278 #define LP_TARGET_TYPE_ZERO 1
279 
280 /* This struct defines an extent entry in the extent table block. */
281 typedef struct LpMetadataExtent {
282     /*  0: Length of this extent, in 512-byte sectors. */
283     uint64_t num_sectors;
284 
285     /*  8: Target type for device-mapper (see LP_TARGET_TYPE_* values). */
286     uint32_t target_type;
287 
288     /* 12: Contents depends on target_type.
289      *
290      * LINEAR: The sector on the physical partition that this extent maps onto.
291      * ZERO: This field must be 0.
292      */
293     uint64_t target_data;
294 
295     /* 20: Contents depends on target_type.
296      *
297      * LINEAR: Must be an index into the block devices table.
298      * ZERO: This field must be 0.
299      */
300     uint32_t target_source;
301 } __attribute__((packed)) LpMetadataExtent;
302 
303 /* This struct defines an entry in the groups table. Each group has a maximum
304  * size, and partitions in a group must not exceed that size. There is always
305  * a "default" group of unlimited size, which is used when not using update
306  * groups or when using overlayfs or fastbootd.
307  */
308 typedef struct LpMetadataPartitionGroup {
309     /*  0: Name of this group. Any unused characters must be 0. */
310     char name[36];
311 
312     /* 36: Flags (see LP_GROUP_*). */
313     uint32_t flags;
314 
315     /* 40: Maximum size in bytes. If 0, the group has no maximum size. */
316     uint64_t maximum_size;
317 } __attribute__((packed)) LpMetadataPartitionGroup;
318 
319 /* This flag is only intended to be used with super_empty.img and super.img on
320  * retrofit devices. If set, the group needs a slot suffix to be interpreted
321  * correctly. The suffix is automatically applied by ReadMetadata().
322  */
323 #define LP_GROUP_SLOT_SUFFIXED (1 << 0)
324 
325 /* This struct defines an entry in the block_devices table. There must be at
326  * least one device, and the first device must represent the partition holding
327  * the super metadata.
328  */
329 typedef struct LpMetadataBlockDevice {
330     /* 0: First usable sector for allocating logical partitions. this will be
331      * the first sector after the initial geometry blocks, followed by the
332      * space consumed by metadata_max_size*metadata_slot_count*2.
333      */
334     uint64_t first_logical_sector;
335 
336     /* 8: Alignment for defining partitions or partition extents. For example,
337      * an alignment of 1MiB will require that all partitions have a size evenly
338      * divisible by 1MiB, and that the smallest unit the partition can grow by
339      * is 1MiB.
340      *
341      * Alignment is normally determined at runtime when growing or adding
342      * partitions. If for some reason the alignment cannot be determined, then
343      * this predefined alignment in the geometry is used instead. By default
344      * it is set to 1MiB.
345      */
346     uint32_t alignment;
347 
348     /* 12: Alignment offset for "stacked" devices. For example, if the "super"
349      * partition itself is not aligned within the parent block device's
350      * partition table, then we adjust for this in deciding where to place
351      * |first_logical_sector|.
352      *
353      * Similar to |alignment|, this will be derived from the operating system.
354      * If it cannot be determined, it is assumed to be 0.
355      */
356     uint32_t alignment_offset;
357 
358     /* 16: Block device size, as specified when the metadata was created. This
359      * can be used to verify the geometry against a target device.
360      */
361     uint64_t size;
362 
363     /* 24: Partition name in the GPT. Any unused characters must be 0. */
364     char partition_name[36];
365 
366     /* 60: Flags (see LP_BLOCK_DEVICE_* flags below). */
367     uint32_t flags;
368 } __attribute__((packed)) LpMetadataBlockDevice;
369 
370 /* This flag is only intended to be used with super_empty.img and super.img on
371  * retrofit devices. On these devices there are A and B super partitions, and
372  * we don't know ahead of time which slot the image will be applied to.
373  *
374  * If set, the block device needs a slot suffix applied before being used with
375  * IPartitionOpener. The slot suffix is determined by the metadata slot number
376  * (0 = _a, 1 = _b).
377  */
378 #define LP_BLOCK_DEVICE_SLOT_SUFFIXED (1 << 0)
379 
380 /* For ease of writing compatibility checks, the original metadata header is
381  * preserved below, and typedefs are provided for the current version.
382  */
383 typedef struct LpMetadataHeaderV1_0 {
384     uint32_t magic;
385     uint16_t major_version;
386     uint16_t minor_version;
387     uint32_t header_size;
388     uint8_t header_checksum[32];
389     uint32_t tables_size;
390     uint8_t tables_checksum[32];
391     LpMetadataTableDescriptor partitions;
392     LpMetadataTableDescriptor extents;
393     LpMetadataTableDescriptor groups;
394     LpMetadataTableDescriptor block_devices;
395 } __attribute__((packed)) LpMetadataHeaderV1_0;
396 
397 typedef LpMetadataHeader LpMetadataHeaderV1_2;
398 
399 #ifdef __cplusplus
400 } /* extern "C" */
401 #endif
402 
403 #endif /* LOGICAL_PARTITION_METADATA_FORMAT_H_ */
404