【Android Q】super分区里的metadata解析

一:layout

先放一张根据结构画的super分区的 layout图。
在这里插入图片描述

二:metadata数据结构

定义super分区中metadata结构详细信息。
路径:system\core\fs_mgr\liblp\include\liblp\metadata_format.h
下面配合具体从super分区中抓取的数据解析。
命令:dd if=/dev/block/platform/soc/7824900.sdhci/by-name/super bs=4096 count=1048576 of=/data/super.data

typedef struct LpMetadataGeometry {
    /*  0: Magic signature (LP_METADATA_GEOMETRY_MAGIC). */
    uint32_t magic;

    /*  4: Size of the LpMetadataGeometry struct. */
    uint32_t struct_size;

    /*  8: SHA256 checksum of this struct, with this field set to 0. */
    uint8_t checksum[32];

    /* 40: Maximum amount of space a single copy of the metadata can use. This
     * must be a multiple of LP_SECTOR_SIZE.
     */
    uint32_t metadata_max_size;

    /* 44: Number of copies of the metadata to keep. For A/B devices, this
     * will be 2. For an A/B/C device, it would be 3, et cetera. For Non-A/B
     * it will be 1. A backup copy of each slot is kept, so if this is "2",
     * there will be four copies total.
     */
    uint32_t metadata_slot_count;

    /* 48: Logical block size. This is the minimal alignment for partition and
     * extent sizes, and it must be a multiple of LP_SECTOR_SIZE. Note that
     * this must be equal across all LUNs that comprise the super partition,
     * and thus this field is stored in the geometry, not per-device.
     */
    uint32_t logical_block_size;
} __attribute__((packed)) LpMetadataGeometry;

在这里插入图片描述

typedef struct LpMetadataHeader {
    /*  0: Four bytes equal to LP_METADATA_HEADER_MAGIC. */
    uint32_t magic;

    /*  4: Version number required to read this metadata. If the version is not
     * equal to the library version, the metadata should be considered
     * incompatible.
     */
    uint16_t major_version;

    /*  6: Minor version. A library supporting newer features should be able to
     * read metadata with an older minor version. However, an older library
     * should not support reading metadata if its minor version is higher.
     */
    uint16_t minor_version;

    /*  8: The size of this header struct. */
    uint32_t header_size;

    /* 12: SHA256 checksum of the header, up to |header_size| bytes, computed as
     * if this field were set to 0.
     */
    uint8_t header_checksum[32];

    /* 44: The total size of all tables. This size is contiguous; tables may not
     * have gaps in between, and they immediately follow the header.
     */
    uint32_t tables_size;

    /* 48: SHA256 checksum of all table contents. */
    uint8_t tables_checksum[32];

    /* 80: Partition table descriptor. */
    LpMetadataTableDescriptor partitions;
    /* 92: Extent table descriptor. */
    LpMetadataTableDescriptor extents;
    /* 104: Updateable group descriptor. */
    LpMetadataTableDescriptor groups;
    /* 116: Block device table. */
    LpMetadataTableDescriptor block_devices;
} __attribute__((packed)) LpMetadataHeader;
typedef struct LpMetadataTableDescriptor {
    /*  0: Location of the table, relative to end of the metadata header. */
    uint32_t offset;
    /*  4: Number of entries in the table. */
    uint32_t num_entries;
    /*  8: Size of each entry in the table, in bytes. */
    uint32_t entry_size;
} __attribute__((packed)) LpMetadataTableDescriptor;

在这里插入图片描述

typedef struct LpMetadataPartition {
    /*  0: Name of this partition in ASCII characters. Any unused characters in
     * the buffer must be set to 0. Characters may only be alphanumeric or _.
     * The name must include at least one ASCII character, and it must be unique
     * across all partition names. The length (36) is the same as the maximum
     * length of a GPT partition name.
     */
    char name[36];

    /* 36: Attributes for the partition (see LP_PARTITION_ATTR_* flags above). */
    uint32_t attributes;

    /* 40: Index of the first extent owned by this partition. The extent will
     * start at logical sector 0. Gaps between extents are not allowed.
     */
    uint32_t first_extent_index;

    /* 44: Number of extents in the partition. Every partition must have at
     * least one extent.
     */
    uint32_t num_extents;

    /* 48: Group this partition belongs to. */
    uint32_t group_index;
} __attribute__((packed)) LpMetadataPartition;

在这里插入图片描述

typedef struct LpMetadataExtent {
    /*  0: Length of this extent, in 512-byte sectors. */
    uint64_t num_sectors;

    /*  8: Target type for device-mapper (see LP_TARGET_TYPE_* values). */
    uint32_t target_type;

    /* 12: Contents depends on target_type.
     *
     * LINEAR: The sector on the physical partition that this extent maps onto.
     * ZERO: This field must be 0.
     */
    uint64_t target_data;

    /* 20: Contents depends on target_type.
     *
     * LINEAR: Must be an index into the block devices table.
     * ZERO: This field must be 0.
     */
    uint32_t target_source;
} __attribute__((packed)) LpMetadataExtent;

在这里插入图片描述

typedef struct LpMetadataPartitionGroup {
    /*  0: Name of this group. Any unused characters must be 0. */
    char name[36];

    /* 36: Flags (see LP_GROUP_*). */
    uint32_t flags;

    /* 40: Maximum size in bytes. If 0, the group has no maximum size. */
    uint64_t maximum_size;
} __attribute__((packed)) LpMetadataPartitionGroup;

在这里插入图片描述

typedef struct LpMetadataBlockDevice {
    /* 0: First usable sector for allocating logical partitions. this will be
     * the first sector after the initial geometry blocks, followed by the
     * space consumed by metadata_max_size*metadata_slot_count*2.
     */
    uint64_t first_logical_sector;

    /* 8: Alignment for defining partitions or partition extents. For example,
     * an alignment of 1MiB will require that all partitions have a size evenly
     * divisible by 1MiB, and that the smallest unit the partition can grow by
     * is 1MiB.
     *
     * Alignment is normally determined at runtime when growing or adding
     * partitions. If for some reason the alignment cannot be determined, then
     * this predefined alignment in the geometry is used instead. By default
     * it is set to 1MiB.
     */
    uint32_t alignment;

    /* 12: Alignment offset for "stacked" devices. For example, if the "super"
     * partition itself is not aligned within the parent block device's
     * partition table, then we adjust for this in deciding where to place
     * |first_logical_sector|.
     *
     * Similar to |alignment|, this will be derived from the operating system.
     * If it cannot be determined, it is assumed to be 0.
     */
    uint32_t alignment_offset;

    /* 16: Block device size, as specified when the metadata was created. This
     * can be used to verify the geometry against a target device.
     */
    uint64_t size;

    /* 24: Partition name in the GPT. Any unused characters must be 0. */
    char partition_name[36];

    /* 60: Flags (see LP_BLOCK_DEVICE_* flags below). */
    uint32_t flags;
} __attribute__((packed)) LpMetadataBlockDevice;

在这里插入图片描述
以上就是metadata的相关内容,还有部分是metadata的备份数据。metadata total size是4096+4096✖2+65536✖4。也就是开头放的layout的图的前面部分。由于我这里没有启用A/B,所以metadata的备份是4份,如果启用则是6份。

三:命令解析

可以通过命令直观解析数据:lpdump /dev/block/by-name/super
在这里插入图片描述

四:辅助工具

另外之前学习这一块内容的时候发现有个大佬做了一个tool,将super分区的数据放进去,就能清晰解析出以上的metadata的内容,以及各个logical partition的起始地址和大小。附上tool作者的source code链接:super_image_tool
下面是根据tool解析出来的数据,和我上面分析的数据结果一致。
在这里插入图片描述在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值