Введение.Разметка памяти, т.е. разбивка на разделы, в устройствах на чипах МТК производится при помощи файла, который называется "scatter file".
Он используется программами-прошивальщиками, т.н. флешерами (от английского "flasher") при прошивке полного образа памяти или отдельных ее частей, называемых разделами.
Структура scatter file содержит описание всех существующих разделов памяти, независимо от того, что они будут содержать в работающем устройстве.
Строение scatter file.Существует две версии структуры scatter-файла. Рассмотрим первую версию, используемую в большинстве мобильных устройств на чипах MTхх.
Полное описание раздела памяти представляет собой набор строк вида:
[__NODL_]name offset [length]
{
}, где
- __NODL_ - "No download" признак того, что раздел будет пропущен флешером, и для его работы не требуется файл для прошивки. Такой раздел можно вообще исключить из scatter file;
- name - название раздела;
- offset - смещение раздела от начала памяти в 16-ричном виде, байт;
- length - длина раздела в 16-ричном виде, байт.
Квадратные скобки означают необязательный параметр.
Чаще всего используется сокращенная запись вида:
Такое описание разделов памяти предполагает, что:
- каждый раздел имеет длину до начала следующего;
- между двумя разделами не существует третьего (скрытого).
Для примера приведу типичный scatter-file для МТ6589. Он имеет следующий вид:
PRELOADER 0x0
{
}
MBR 0x600000
{
}
EBR1 0x680000
{
}
__NODL_PMT 0x700000
{
}
__NODL_PRO_INFO 0xb00000
{
}
__NODL_NVRAM 0xe00000
{
}
__NODL_PROTECT_F 0x1300000
{
}
__NODL_PROTECT_S 0x1d00000
{
}
__NODL_SECCFG 0x2700000
{
}
UBOOT 0x2720000
{
}
BOOTIMG 0x2780000
{
}
RECOVERY 0x2d80000
{
}
SEC_RO 0x3380000
{
}
__NODL_MISC 0x3980000
{
}
LOGO 0x3a00000
{
}
EBR2 0x3d00000
{
}
__NODL_EXPDB 0x3d80000
{
}
ANDROID 0x4780000
{
}
CACHE 0x2d180000
{
}
USRDATA 0x34f80000
{
}
__NODL_FAT 0x74f80000
{
}
__NODL_BMTPOOL 0xffff00a8
{
}
Рассмотрим структуру scatter-файла второй версии.
Полное описание каждого раздела памяти представляет собой набор строк вида:
partition_index: SYS1
partition_name: MBR
file_name: MBR
is_download: true
type: NORMAL_ROM
linear_start_addr: 0x0
physical_start_addr: 0x0
partition_size: 0x80000
region: EMMC_USER
storage: HW_STORAGE_EMMC
boundary_check: true
is_reserved: false
operation_type: UPDATE
reserve: 0x00, где
- - partition_index - индексный номер раздела, например, SYS1;
- - partition_name - имя раздела, например, MBR;
- - file_name - имя файла, содержащего образ раздела, или NONE;
- - is_download - признак загружаемости раздела (что-то типа __NODL_);
- - type - тип раздела. Указывает на содержимое раздела. Может принимать следующие значения:
EXT4_IMG - раздел содержит часть файловой системы EXT4;
NORMAL_ROM - раздел содержит сохраненный образ или отдельный файл;
SV5_BL_BIN - раздел содержит "сырой код" (Raw Code), т.е. исполнимый код;
- - linear_start_addr - начальный адрес размещения раздела в файле прошивки, байт;
- - physical_start_addr - начальный адрес размещения раздела в памяти устройства (физический адрес), байт;
- - partition_size - размер раздела, байт;
- - region - размещение раздела. Может принимать следующие значения:
EMMC_BOOT_1 -
EMMC_USER -
- - storage - HW_STORAGE_EMMC
- - boundary_check - признак необходимости отметки границы раздела (во внутренней БД или PMT);
- - is_reserved - признак необходимости резервного копирования;
- - operation_type - тип операции. Может принимать следующие значения:
BINREGION - область "сырого кода";
BOOTLOADERS - загрузчик;
INVISIBLE - невидимый раздел;
PROTECTED - защищенный раздел;
RESERVED - зарезервирован;
UPDATE - обновляемый раздел.
Пример полного scatter-файла второй версии, приведен в файле "Scatter_v2.txt".
Работа со scatter file.Любой флешер использует scatter file только для ПОЛНОЙ разметки памяти.
Если Вы прошиваете один или несколько разделов, то флешер размещение разделов берет из внутренней "базы данных" - файла PMT (Partitions Map Table). Он считывает значение смещения для раздела (физический адрес) и копирует,т.е. "прошивает" образ раздела в память, начиная с этого физического адреса.
Т.к. scatter file содержит перечень и физические адреса размещения всех разделов памяти, то изменив его можно произвести переразметку этой памяти. Для этого необходимо изменить значения смещений необходимых разделов.
Например, в разделе USRDATA располагаются данные программ пользователя: логи работы и ошибок, данные о рекордах игр и т.д. Поэтому этот раздел чаще других переполняется, что приводит к появлению сообщений вида "Память переполнена".
В типовом scatter file он имеет смещение 0x34f80000 и размер 0x74f80000-0x34f80000=0х40000000(или 1073741824=1Гб). Увеличим его, например, на 256Мб(268435456). Тогда размер раздела станет 1073741824+268435456=1342177280(или 0х50000000 в hex). Т.е. мы добавили в раздел еще 0х10000000 байт. Тогда смещение следующего раздела передвинется на эту же величину:
было - 0х74f80000
стало - 0х84f80000
Если сделать так со смещениями ВСЕХ последующих разделов, то они ВСЕ передвинутся и на эту величину увеличится ОБЩИЙ размер памяти, занимаемой прошивкой. А это недопустимо. Поэтому нужно уменьшить размер какого-либо последующего раздела. У нас это раздел пользователя (FAT).
Изменить его размер мы не можем, т.к. он расположен до конца существующей памяти. Он просто автоматически укоротится.
Казалось бы и все, но укорачивать разделы можно до определенного предела (до "нуля"). Поэтому, если смещение последнего раздела переходит верхнюю границу памяти, то придется откатывать назад все изменения или уменьшать размер "прибавки" раздела.