Как стать автором
Обновить

Мобильные устройства изнутри. Что такое GPT?

Время на прочтение 9 мин
Количество просмотров 17K

Что такое GPT?



1. Введение


Продолжаем рассматривать строение программной части (software) мобильных устройств (МУ). Сегодня поговорим об устройстве GPT-раздела памяти. Написать об этом меня побудила публикация Изучаем структуры MBR и GPT, вместо того, чтобы писать комментарии к ней. Я хотел бы не поругать или поправить автора, а дополнить вышеуказанную публикацию с уклоном в МУ.


Итак, GPT (GUID Partition Table) это:

  • в первую очередь название схемы разметки памяти (GPT-схема) МУ ;
  • затем уж название раздела памяти (GPT-раздел), где расположена физически эта схема;
  • ну и также название файла-образа GPT-раздела памяти (GPT-файл).

Существует две схемы разметки памяти: MBR и GPT. Каждая схема содержится в отдельном разделе памяти, называемом, соответственно, MBR или GPT.

Как устроена MBR-схема разметки можно посмотреть в [1], а GPT это другой формат описания разметки памяти — GUID (GUID Partition Table). Он является частью EFI (Extensible Firmware Interface) — стандарта UEFI, используемого вместо BIOS для загрузки разделов памяти.

Переход на другой формат позволил устранить самый существенный недостаток MBR-формата — малое число разделов. Если в MBR помещалось только 4 записи с ограничением на длину раздела и его смещение из-за того, что эти параметры описывались 32-разрядными числами, то в GPT можно разместить 128 записей о разделах. Причем их параметры уже описываются в 64-разрядной системе счисления…

Для совместимости со старым стандартом загрузки (BIOS) и с целью защиты самой таблицы описания разделов памяти GPT-раздел тоже начинается с MBR, которая описывает всего один раздел — всю память МУ. Сама MBR называется теперь «защитной» (protective), т.е. PMBR. Она располагается тоже в первом секторе памяти по адресу 0х0000-0х01FF (512 байт). Поле Смещение указывает на начало заголовка GPT, а размер раздела устанавливается равным длине всей памяти устройства. Тип раздела имеет значение 0хEE (GPT-раздел).

Суть защиты GPT-раздела да и всей памяти МУ сводится к следующему. Если такой раздел откроет средство работы с MBR-схемой разметки, то оно увидит пустую неразмеченную память, состоящую только из раздела описания разметки. Соответственно, что-либо сделать с этой памятью ему не удасться.

Вот как выглядит PMBR, например, от МУ ...:

PMBR

Рис.1 «Защитная» MBR, т.е. PMBR

По адресу 0х01FE видна сигнатура MBR (0xAA55).

Перейдем к рассмотрению непосредственно структуры GPT-раздела.

2. Структура GPT


GPT-раздел состоит из PMBR, заголовка и таблицы описания разделов памяти.

Сразу за PMBR, т.е. с адреса 0х0200, располагается заголовок GPT, имеющий длину 0х5С (92) байта, но занимающий весь сектор (512 байт). Вот как он выглядит в том же МУ:

Заголовок GPT


Рис.2 Заголовок GPT

Он имеет следующую структуру:

 ===============================================================================
| Смещение |       Имя       | Длина |                 Значение                 |
|   байт   |       поля      |  байт |                   поля                   |
|==========|=================|=======|==========================================|
|   0x00   | Magic           |   8   | сигнатура раздела                        |
|   0x08   | Revision        |   4   | версия GPT-раздела                       |
|   0x0C   | HeaderSize      |   4   | размер заголовка в байтах                |
|   0x10   | HeaderCRC32     |   4   | CRC32 заголовка                          |
|   0x14   | Reserved1       |   4   | резерв; должен быть 0                    |
|   0x18   | MyLBA           |   8   | LBA первичного GPT-раздела               |
|   0x20   | AlternateLBA    |   8   | LBA резервного GPT-раздела               |
|   0x28   | FirstUsableLBA  |   8   | LBA первого сектора для использования    |
|   0x30   | LastUsableLBA   |   8   | LBA последнего сектора для использования |
|   0x38   | DiskGUID        |  16   | GUID диска (памяти)                      |
|   0x48   | PartitionsLBA   |   8   | LBA первого сектора GPT                  |
|   0x50   | NumberParts     |   4   | число записей о разделах                 |
|   0x54   | PartitionSize   |   4   | размер записи о разделе в байтах         |
|   0x58   | PartitionsCRC32 |   4   | CRC32 таблицы записей о разделах         |
|   0x5C   | Reserved2       |   *   | резерв                                   |
 ===============================================================================

Поле Magic содержит строка символов «EFI PART» — 45h 46h 49h 20h 50h 41h 52h 54h, которая выделена на рис.2 бирюзовым цветом и однозначно идентифицирует GPT-раздел.

Поле Revision, выделенное зеленым цветом, содержит номер версии структуры GPT-раздела (0х00010000). Например, для GPT версии 1.0 должно быть 00h 00h 01h 00h

Поле HeaderSize, выделенное оранжевым цветом, содержит размер заголовка, выраженный в байтах. Пока это 0х0000005Ch, что означает 92 байта.

Поле HeaderCRC32, выделенное розовым цветом, содержит контрольную сумму заголовка (0x09BE8E1F), расчитанную по алгоритму CRC32. При непосредственном выполнении расчета учитываются только 92 байта, а в это поле перед расчетом заносится 0.

Следующее поле Reserved1 никак не выделено, является резервным и содержит 0.

Поле MyLBA, выделенное темно-синим цветом, содержит смещение в блоках размещения первичного GPT-раздела (0х00000001).

Поле AlternateLBA содержит смещение в блоках размещения резервного GPT-раздела. Оно не указано.

Поле FirstUsableLBA, выделенное красным цветом, содержит смещение в блоках размещения первого разрешенного для использования сектора памяти (0х00000022). Расчитывается так: LBA последнего сектора, занятого первичным GPT-разделом, + 1.

Поле LastUsableLBA содержит смещение размещения последнего сектора памяти, разрешенного для использования. Расчитывается так: LBA первого сектора резервного GPT-раздела — 1. Оно не указано.

Поле DiskGUID, выделенное голубым цветом, содержит GUID прошивки.

Поле PartitionsLBA, выделенное красным цветом, содержит смещение начала GPT. В первичном всегда равен 2, а в резервном равен LastUsableLBA.

Поле NumberParts, выделенное ярко-зеленым цветом, содержит размер таблицы описания разделов, т.е. число записей о разделах (0х00000018).

Поле PartitionSize, выделенное розовым цветом, содержит размер одной записи о разделе в байтах. Согласно UEFI Specification размер записи фиксирован и составляет 128 байт или 0х00000080.

Поле PartitionsCRC, выделенное красным цветом, содержит контрольную сумму таблицы описания разделов (0x93D54D33), расчитанную по алгоритму CRC32. При выполнении расчета учитываются все байты, начиная с PartitionsLBA и до FirstUsableLBA.

Поле Reserved2 содержит резервное поле. Содержит 0 до конца сектора, т.е. 420 байт для сектора размером 512 байт.

Непосредственно сразу за заголовком, начиная с адреса 0х400, располагается таблица описания разделов, содержащая записи о каждом разделе памяти, включая и сам раздел разметки. Вот как она выглядит:


Рис.3 Таблица описания разделов

Каждая запись размером 128 байт имеет следующую структуру:

 ====================================================================================
| Смещение  | Длина, |         Имя         |                 Значение                |
|   байт    |  байт  |         поля        |                   поля                  |
|===========|========|=====================|=========================================|
|  0 | 0x00 |   16   | PartitionTypeGUID   | GUID типа раздела                       |
| 16 | 0x10 |   16   | UniquePartitionGUID | GUID раздела                            |
| 32 | 0x20 |    8   | StartingLBA         | LBA первого сектора размещения раздела  |
| 40 | 0x24 |    8   | EndingLBA           | последний LBA сектор размещения раздела |
| 48 | 0x30 |    8   | Attributes          | атрибуты раздела                        |
| 56 | 0x38 |   72   | PartitionName       | строка из имени раздела                 |
 ====================================================================================

Поле PartitionTypeGUID, выделенное красным цветом, содержит GUID типа раздела, который определяет файловую систему, используемую для хранения данных в этом разделе. Каждая файловая система получает свой GUID, однозначно её идентифицирующий. Стандарт UEFI жестко определяет только следующие GUID типов разделов:

 =============================================================================
| Значение GUID                        |   Описание                           |
|======================================|======================================|
| 00000000-0000-0000-0000-000000000000 | Неиспользуемый раздел                |
| C12A7328-F81F-11d2-BA4B-00A0C93EC93B | Системный раздел UEFI                |
| 024DEE41-33E7-11d3-9D69-0008C781F39F | Раздел, содержащий традиционную MBR  |
 =============================================================================

Поставщикам ОС (vendors) нужно генерировать свой собственный GUID типа раздела, чтобы идентифицировать их. Некоторые известные GUID можно посмотреть в [3].

При записи в память или в файл-образ значение GUID записывается в другом порядке. Например, GUID системного раздела EFI имеет следующий вид: C12A7328-F81F-11D2-BA4B-00A0C93EC93B. Порядок записи байтов в написаниях GUID является little-endian, причем задом наперед пишутся байты только в первых трех блоках. Для приведенного выше GUID запись в таблице разделов будет иметь такой вид:

28 73 2A C1 1F F8 D2 11 BA 4B 00 A0 C9 3E C9 3B

Поле UniquePartitionGUID, выделенное синим цветом, содержит GUID раздела. Является уникальным идентификатором раздела, поэтому создается каждый раз, когда создается раздел.

Поле StartingLBA, выделенное зеленым цветом, содержит смещение в блоках на первый сектор раздела (0x00020000).

Поле EndingLBA, выделенное оранжевым цветом, содержит смещение на последний сектор раздела (0x0003FFFF). При этом размер раздела (PartitionSize) определяется по формуле

	PartitionSize = EndingLBA - StartingLBA + 1

Поле Attributes, выделенное фиолетовымым цветом, содержит атрибуты (флаги) раздела. 8 байт (64 бита) флагов распределены следующим образом. Биты с 0 по 47 (48 шт.) отведены под общие атрибуты типов разделов, а остальные 16 битов (с 48 по 63) описывают конкретный раздел.

Вот небольшое описание этих битов:

 ================================================
| Бит  |   Значение                              |
|======|=========================================|
|   0  | системный раздел                        |
|   1  | EFI игнорирует содержимое этого раздела |
| 2-47 | Зарезервировано для нужд UEFI           |
| ---- |                                         |
|  60  | Read-only (только для чтения)           |
|  61  | Теневая копия другого раздела           |
|  62  | Hidden (скрытый)                        |
|  63  | автоматически не монтируется            |
 ================================================

Поле PartitionName, выделенное синим цветом, содержит метку раздела («modem»), содержащую строку текста с завершающим нулем числом не более 36 символов, выраженную в кодировке UTF-16LE.

Все, что такое GPT мы уже знаем, только это стандартная структура GPT-раздела. Оказывается, имеется и модификация…

Т.к. я обнаружил GPT-раздел другой структуры при работе с МУ на основе чипа Intel, то я и назвал ее GPT-раздел типа Intel.

3. Что такое GPT-раздел типа Intel?


Прошивка новых мобильных устройств (МУ) Lenovo, выполненных на основе чипов Intel, имеет Gpt-схему разметки памяти, но структура самого Gpt-файла отличается от стандартной, описанной в [1]. Это касается, например, устройств YOGA BOOK YB1-X90.

По сравнению со стандартной структурой Intel-тип сокращен до максимума:

  • из заголовка убраны Guid, контрольные суммы, смещения всех разделов, кроме саамого первого и все стандартные значения или пустые, например, размер записи параметров раздела, размещение Primary и Backup таблиц;
  • из описания параметров раздела удалены атрибуты, а смещения первого и последнего блока заменены на размер раздела.

Т.к. структура Gpt-файла этого типа отличается от стандартной структуры, то для его прошивки необходимо использовать специальный флешер фирмы Intel — PhoneFlashTool_5.3.2.0.

GPT-раздел, как и стандартный, состоит из:

  • заголовка;
  • таблицы описания параметров разделов.


Рис.4 Строение Gpt-файла Intel-типа

Рассмотрим строение заголовка.

3.1. Структура заголовка нового GPT-раздела.


Заголовок имеет размер всего 12 (0x0C) байт (против 512 в стандартном варианте):


Рис.5 Заголовок Gpt-файла Intel-типа

и содержит следующие поля:

 =============================================================
|  №  | Смещение |   Имя    | Размер | Значение поля            |
| п/п |   поля   |   поля   |  байт  |                          |
|=============================================================|
|  1  |   0x00   | Magic    |    4   | Сигнатура файла          |
|  2  |   0x04   | StartLba |    4   | Смещение первого раздела |
|  3  |   0x08   | Number   |    4   | Число разделов памяти    |
 =============================================================

Поле Magic, отмеченное синим цветом, содержит число 0х6А8В0DA1, идентифицирующее образ GPT-раздела Intel-типа.

Поле StartLba, отмеченное красным цветом, содержит значение смещения размещения первого раздела памяти.

Поле Number, отмеченное зеленым цветом, содержит общее число разделов памяти, т.е. число записей таблицы описания разделов. Сама таблица расположена сразу после заголовка.

3.2. Структура записи описания нового GPT-раздела


Таблица описания разделов содержит записи, содержащие параметры каждого раздела памяти. Число записей равно числу разделов, а окончание таблицы ничем не отмечается.

Каждая запись имеет размер 108 (0x6C) байт, тогда как по UEFI она содержала 128 байт. Вот как выглядит запись описания раздела нового формата:


Рис.6 Запись описания раздела

и содержит следующие поля, описывающие параметры раздела:

 =============================================================
|  №  | Смещение |      Имя      | Размер | Значение поля     |
| п/п |   поля   |      поля     |  байт  |                   |
|=============================================================|
|  1  |   0x00   | Size          |    4   | Размер раздела    |
|  2  |   0x04   | Label         |   72   | метка раздела     |
|  3  |   0x4C   | GuidType      |   16   | GUID типа раздела |
|  3  |   0x5C   | GuidPartition |   16   | GUID раздела      |
 =============================================================

Поле Size, выделенное на рис.6 синим цветом, содержит размер раздела, выраженный в Мб (1024 * 1024 = 1048576 байт).

Поле Label, выделенное на рис.6 красным цветом, содержит метку раздела, т.е. имя раздела, выраженное в кодировке UTF-16.

Поле GuidType, выделенное на рис.6 зеленым цветом, содержит GUID типа раздела.

Поле GuidPartition, выделенное на рис.6 желтым цветом, содержит GUID самого раздела.

4. Заключение


Изучив строение GPT-раздела разметки памяти МУ, можно приступить и к практическим занятиям.

В следующих публикациях я поделюсь опытом переразметки памяти МУ, выполненного по GPT-схеме.

5. Источники информации


1. «Что такое MBR?»
2. UEFI Specification, Version 2.7 Errata A
3. GUID Partition Table.
Теги:
Хабы:
+36
Комментарии 8
Комментарии Комментарии 8

Публикации

Истории

Работа

Ближайшие события

PG Bootcamp 2024
Дата 16 апреля
Время 09:30 – 21:00
Место
Минск Онлайн
EvaConf 2024
Дата 16 апреля
Время 11:00 – 16:00
Место
Москва Онлайн
Weekend Offer в AliExpress
Дата 20 – 21 апреля
Время 10:00 – 20:00
Место
Онлайн