UFS软件分区介绍
整体布局
我们都知道UFS最大支持的LU为8个,但是我们在实际使用中往往没有用到这么多,以某司为例,分区概况如下:
每个分区的size及属性如下:
/*lu_index, bootable, log2blksz, blkcnt, lu_context, memory_type*/
{0x00, MAIN_BOOT,0x0C,
1024, 0x0, ENHANCED_MEMORY_1},
{0x01, ALTERNATE_BOOT, 0x0C,1024, 0x0,
ENHANCED_MEMORY_1},
{0x02, NONE_BOOT, 0x0C,
0 , 0xFF, NORMAL_MEMORY}
none_boot
接下来的分区就和emmc一样了,而且必须得一样因为代码是要互相兼容的
其实软件中写分区表已经读写分区的操作都是根据上面这个结构进行操作的,具体的数据结构如下:
MBR:MBR支持最大2TB磁盘,它无法处理大于2TB容量的磁盘。MBR还只支持最多4个主分区;如果这部分数据被覆盖或破坏,很难修复typedef struct _legacy_mbr {
u8 boot_code[440];
__le32 unique_mbr_signature;
__le16 unknown;
struct partition partition_record[4];
__le16 signature;
} __packed legacy_mbr;
GPT:磁盘驱动器容量可以大得多,大到操作系统和文件系统都没法支持。它同时还支持几乎无限个分区数量,限制只在于操作系统;GPT在整个磁盘上保存了这部分信息的副本
typedef struct _gpt_header {
__le64 signature;
__le32 revision;
__le32 header_size;
__le32 header_crc32;
__le32 reserved1;
__le64 my_lba;
__le64 alternate_lba;
__le64 first_usable_lba;
__le64 last_usable_lba;
efi_guid_t disk_guid;
__le64 partition_entry_lba;
__le32 num_partition_entries;
__le32 sizeof_partition_entry;
__le32 partition_entry_array_crc32;
} __packed gpt_header;
分区表项结构体:
typedef struct _gpt_entry {efi_guid_t partition_type_guid;
efi_guid_t unique_partition_guid;
__le64 starting_lba;
__le64 ending_lba;
gpt_entry_attributes attributes;
efi_char16_t partition_name[PARTNAME_SZ];
} __packed gpt_entry;
往往我们在操作一个分区的时候,首先我们需要清楚当前操作的分区是在哪个硬件分区:(main_boot、alternate_boot、none_boot),一般情况下前两者都是用来烧写uboot或者spl或者boot镜像的,对于用户来说是只读分区。对于用户来说,比如我们操作userdata分区时,首先找到硬件分区为none_boot,然后读取响应的头获取分区表项,然后for循环查询分区名partition_name为userdata的gpt_entry,相应的我们就清楚了该分区的其实block地址starting_lba和结束的block地址ending_lba,进而我们就可以对指定的分区进行操作了,具体如何定位操作哪一个文件可以参考我的另一篇博客:ext4文件系统文件定位流程。
至此我们对ufs的软件分区管理有了一个大体的认识,然而驱动中是如何初始化并获取每个硬件分区的信息的,后面的博客我会继续给大家介绍。