rizer

Если не работает полное шифрование в прошивке.

В этой теме 19 сообщений

Если вдруг кому-то всё таки захочется включить шифрование на Life, ниже я опишу как это сделать.

Смысл в том, что раздел /data неправильно размечен, для правильного функционирования шифрования, после раздела должно оставаться 16Кб места.

Соответственно задача перебить раздел.

Источник вдохновения здесь:

http://code.google.c.../detail?id=5678

Всё ниже следующее проверялось на другой прошивке!, но ошибка и симптомы одинаковые, так что я уверен что заработает и тут.

Симптомы ошибки:

При попытке зашифроваться, появляется робот и не пропадает, хотя должен светиться всего несколько секунд.

А в логах видим следующее:

D/VoldCmdListener( 93): cryptfs enablecrypto inplace {}

E/Cryptfs ( 93): Orig filesystem overlaps crypto footer region. Cannot encrypt in place.

Вам нужно подключиться через adb shell к телефону в режиме рекавери, ну или наверное можно вводить команды прямо на телефоне, но это мучение.

В корне телефона вводим:

ls -l

# В ответ получаем список файлов,

# нас интересует "emmc@usrdata -> /dev/block/mmcblk0p5"

# т.е. /data это mmcblk0p5 блок, если вдруг номер блока будет другой, то подставляете везде другой номер

# дальше монтируем /system,для того что бы сделать архив с бекапом данных /data

/system/xbin/tar -C / -cf /sdcard/data.tar data

# бекапим и после демонтируем /data

data_dev_size=$(cat /sys/block/mmcblk0/mmcblk0p5/size)

# узнаём текущий размер /data

new_fs_size=$(( ((data_dev_size/2)-16)*1024 ))

# Убираем 16кб

/system/bin/make_ext4fs -a /data -l $new_fs_size /dev/block/mmcblk0p5

# переразмечаем и монтируем опять /data

/system/xbin/tar -C / -xf /sdcard/data.tar

# заливаем бекап обратно

Команды монтирования я не привожу, т.к. делал это через рекавери.

Всё, можно загружаться и включать шифрование.

Отредактировал rizer
5 пользователям понравился пост

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Познавательно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Источник вдохновения здесь:
http://code.google.c.../detail?id=5678

Ссылка не работает, а момент интересный. Может кто-то уже смотрел информацию, поделитесь, пожалуйста!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ссылка не работает, а момент интересный.

Да, к сожалению после редактора скаттера тоже такой баг вылезает. data не шифруется, нет зазора после раздела data

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну уж нет, позвольте с Вами не согласиться. Это не баг редактора, который размечает память непрерывно, а скорее ошибка программиста, писавшего шифрование (а может быть специально напутали).

В первом посте перепутаны причина и следствие. Фраза про "баг" должна была звучать так: кто-то пишет в область памяти, расположенную сразу за разделом data.

Здесь могут быть несколько выходов:

1) для правильной работы шифрования в скаттере нужно разместить дополнительный раздел, расположенный сразу за разделом data, тем самым раздвинув разделы;

2) переместить раздел data в конце прошивки, оставив там пустое место.

А вообще для рассуждений нужна информация, на которую ссылается rizer

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это не баг редактора

Баг - не баг. А зазор быть должен. Это проверенный факт. Исходно разработчики тоже это учитывают. Слишком широко это проявляется чтобы быть ошибкой программиста. И то что после того как делается переразметка руками (я делал только 1 раз тоже не оставиви зазоров) или редактором (мне об этом на основе экспериментов говорил другой пользователь) шифрование не работает.

Дело не в скаттре/PMT, а в EBR. Система работает по разметке, это тоже проверенный факт. Когда я ковырялся с MBR/EBR прошивал их через dd. Изменения применялись сразу (после wipe в recovery естественно) без каких-то правок в PMT. После успешных тестов я уже пересчитывал скаттер.

Вас никто не обвиняет и ничего не заставляет. Если не хотите разбираться, то это ваше право. А rizer врядли вам ответит. Его последняя активность: 28 Июнь 2013 - 10:13

Возможно имеется в виду вот это: CYAN-87 - encrypt phone

И ещё ссылка, может поможет: Disk encryption theory

1 пользователю понравился пост

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Баг - не баг. А зазор быть должен

Я не обижаюсь, даже рад, что завязалась дискуссия в "нормальных тонах". Просто хотел довести до пользователей немного информации. Я нисколько не сомневаюсь, что без пробела в разделах шифрование некоторых устройств не работает.

Спасибо за ссылки.

2 пользователям понравился пост

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мои исследования приведенной информации показали, что при шифровании используется следующий алгоритм:

1. В самом верху (по старшим адресам) РАЗДЕЛА памяти на рсстоянии 16Кб от конца РАЗДЕЛА памяти система криптования размещает свой буфер и др.

2. Используя эту область система криптования обрабатывает ОБРАЗ раздела, размер которого не может быть больше, чем размер РАЗДЕЛА-16Кб.

Это теория, а практически нужно создать образ data размером не более, чем размер раздела USERDATA-16Кб, залить его в раздел и включить шифрование. Т.е. то же, что и сделал автор этой ветки, не меняя размер РАЗДЕЛА.

 

P.S. Предупреждая вопросы по поводу Кб, отвечаю, что в исходном коде указан размер 0х4000=16384.

1 пользователю понравился пост

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это теория, а практически нужно создать образ data размером не более, чем размер раздела USERDATA-16Кб, залить его в раздел и включить шифрование. Т.е. то же, что и сделал автор этой ветки, не меняя размер РАЗДЕЛА.

Т.е. мы всё это сделали, зашифровались. После сброса таже ботва. Шифрование не пашет?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
После сброса таже ботва. Шифрование не пашет?
Пашет. Крипто область создается за рамками раздела Data.

Вся суть в том что сразу после раздела Data нужно оставить свободное место в 16Кб, а не подпирать в плотную следующим разделом, например FAT32 ... 

2 пользователям понравился пост

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо за статью, проделал всё вышеописанное, результат следующий:
Segmentation Fault

Видимо, у меня отсутствует make_ext4fs в прошивке, каким образом я могу её добавить?


Проверил, make_ext4fs всё таки присутствует, значит дело в чем-то другом.

Отредактировал -IRONHiDE-

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не люблю незавершенных дел. Вот и в вопросе по шифрованию хочу поставить точку...
Я подготовил "небольшую" статью на эту тему и сегодня выкладываю первую часть.
К вопросу о шифровании данных в ОС Android.
1. Разметка и шифрование данных у чипа МТ6572. 

Спойлер

На сегодняшний день существует мнение, что для правильной работы системы шифрования пользовательских данных, размещаемых в разделе ОС "Userdata", необходима специальная система разметки памяти. Я специально подчеркнул, что именно в разделе ОС (операционной системы Android), имеющем файловую систему ext4, а не разделе памяти мобильного устройства.
Это отличие от разметки памяти под другие чипы заключается в том, что при планировании и создании разметки необходимо делать "дырку" в памяти, т.е. разрыв, между разделами с метками "USRDATA" и последующим (как правило "FAT"). По "существующим инструкциям" он должен составлять 1-2 Мб.
Меня заинтересовал этот вопрос из тех соображений, что при выполнении перечисленных требований нарушаются принципы использования и разметки памяти мобильных устройств - непрерывное размещение разделов для максимального использования памяти.
Вот что мне удалось найти в Интернете. Сам Google в ноябре 2014 предоставлял статью [1], но теперь на ее месте размещена информация по шифрованию в 5 версии Android. Спасибо нашим китайским друзьям с их "отдельным собственным" Google, которые сохранили старую информацию [2].
Из статьи про шифрование в Android [1 или 2] видно, что для шифрования образа раздела операционной системы Android используется dm-crypt уровень ядра Linux. Для этого создается специальная область, которая называется footer. Она располагается в разделе памяти с меткой "USRDATA" на расстоянии не менее 16Кб от его конца и
содержит буфер и ключ для шифрования. Для того, чтобы пользователь случайно не удалил эту область при выполнении команды "Wipe data", размер образа "userdata.img", заливаемого в этот раздел, должен быть меньше размера самого раздела памяти "USRDATA" как раз на эти 16Кб.
Перед выполнением шифрования ОС проверяет наличие возможности инициировать (разместить) footer за ПРЕДЕЛАМИ образа "userdata.img", но в разделе "USRDATA". Для этого определяется разность размера раздела и размера образа. Если она больше 16Кб, то шифрование возможно. В противоположном случае выдается ошибка.
Вот часть кода метода cryptfs_enable(), который проверяет возможность шифрования:

Спойлер


1626    /* Get the size of the real block device */
1627    fd = open(real_blkdev, O_RDONLY);
1628    if ( (nr_sec = get_blkdev_size(fd)) == 0) {
1629        SLOGE("Cannot get size of block device %s\n", real_blkdev);
1630        goto error_unencrypted;
1631    }
1632    close(fd);
1633
1634    /* If doing inplace encryption, make sure the orig fs doesn't include the crypto footer */
1635    if ((how == CRYPTO_ENABLE_INPLACE) && (!strcmp(key_loc, KEY_IN_FOOTER))) {
1636        unsigned int fs_size_sec, max_fs_size_sec;
1637
1638        fs_size_sec = get_fs_size(real_blkdev);
1639        max_fs_size_sec = nr_sec - (CRYPT_FOOTER_OFFSET / 512);
1640
1641        if (fs_size_sec > max_fs_size_sec) {
1642            SLOGE("Orig filesystem overlaps crypto footer region.  Cannot encrypt in place.");
1643            goto error_unencrypted;
1644        }
1645    }

В строке 1628 переменная nr_sec принимает значение размера блочного устройства, т.е. размер раздела памяти, в блоках, используя функцию ioctl(). В строке 1638 переменная fs_size_sec получает размер файловой системы, размещенной на том же разделе, используя суперблок файловой системы. В строке 1639 вычисляется максимальный допустимый размер файловой системы, т.е. ВЕРХНИЙ предел размера образа, заливаемого в раздел памяти. А в строках 1641...1644 производится определение возможности создания "crypto footer region".
Желающие могут посмотреть все это в исходных кодах любых мобильных аппаратов, работающих под управлением ОС Android, т.к. это код Google-разработчиков, например, [3].
На сегодня все.

Далее будет:
2. Как создается разметка с учетом "разрыва" под шифрование для чипа МТ6572?
3. А если посмотреть информацию по другим чипам, что там?
4. Выводы.

 
5. Литература.
  1. http://www.source.android.com/Encryption/"Notes on the implementation of encryption in Android 3.0".
  2. http://www.programmershare.com/3851648/
  3.
  4. http://support.lenovo.com/us/en/products/phones/s-series/s660-smartphone/downloads/DS100187

3 пользователям понравился пост

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для того, чтобы пользователь случайно не удалил эту область при выполнении команды "Wipe data", размер образа "userdata.img", заливаемого в этот раздел, должен быть меньше размера самого раздела памяти "USRDATA" как раз на эти 16Кб.

Не знаю как это обрабатывается ядром и recovery, но моя технология перезда на новую разметку:

Прошиваю разметку для userdata в 2,2GB но образ userdata для 1GB.

Запускаю систему, она говорит что у меня userdata 1GB.

Делаю в recovery wipe (если есть fat) или format data (если fuse) и размер data в системе становится 2GB.

Снимаю дамп с нового data через dd.

Под линуксом на основе размера образа перепаковываю в sparse.

Чувствую что при вайпе или форматировании в TWRP может случится "неучитывание" этих 16КБ.

Либо dd сольёт весь data с 16KB и в суперблок запишется (при моей перепаковке) не тот размер.

Что-то не сходится. Хотябы то что при вайпе на новой разметке меняется размер userdata (даже в варианте с fat-разделом). Это железно.

Отредактировал linerty
1 пользователю понравился пост

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я привел мои чисто теоретические рассуждения, основанные на анализе исходного кода Android. Хотя я встречал и практические решения, подтверждающие мои выводы.

Чтобы не "мучаться" с 16Кб Google предлагает просто "откусывать 1Мб. Я это покажу в продолжении.

Отредактировал vin2809
1 пользователю понравился пост

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну это я не спорю. Но при прочтении у меня возникло ощущение, что практика не полностью сходится.
Надо будет проверить шифрование просто после wipe/format и после перепаковки образа в sparse.
Блин, только мне честно говоря это шифрование побоку. Не пользовался пока. Потому будет вопрос по срокам.
Но думаю тут опростоволосится и recovery со своим вайпом.
А то что перепаковка образа снятого с блочного устройства через dd не учтет 16КБ, то это скорее 99%

Ну а за информацию одночзначно  :spasibo:


А то что перепаковка образа снятого с блочного устройства через dd не учтет 16КБ, то это скорее 99%
Но в таком случае переписать sh мне 2 минуты с отладкой.

Главное понять как вайпит recovery на новый размер. С учетом или без. 


просто "откусывать 1Мб.
Эт запросто.

 

Получается в пределах размера раздела мы создаем файловую систему на размер мегабайтом меньше? Впринципе проверить легко. Как раз есть пациент на 5-ке. Сегодня мучать буду. 

1 пользователю понравился пост

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А вот с пятеркой я бы не торопился. Там, похоже, вообще не делают разрыв. т.к. шифрование выполняется другим способом.

1 пользователю понравился пост

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Продолжаю публикацию по особенностям шифрования.
2. Как создается разметка с учетом "разрыва" под шифрование для чипа МТ6572?

Спойлер

Когда прояснилось, как должна быть построена разметка памяти мобильного устройства для обеспечения работы шифрования данных пользователя, я решил посмотреть, а как на самом деле рассчитываются параметры разметки. Для этого я просмотрел текст исходных кодов МТК.
Совсем недавно фирмой Lenovo был выложен свежий вариант кода для смартфона Lenovo S660 на чипе МТ6582 [4]. Пройдя по пути /mediatek/build/tools/ptgen, я к своему удивлению обнаружил там целый список папок с настройками от чипов МТК: МТ6572, МТ6575, МТ6577, МТ6582, МТ6589, МТ6592, МТ6595, МТ8127, МТ8135.
Создание файлов разметки производится при помощи файла ptgen.pl, написанного на Perl. Он производит чтение экселевского файла partition_table_MT6572.xls и выполняет все необходимые расчеты.
Меня будет интересовать только та часть, которая формирует набор параметров разделов, необходимый для создания файлов разметки. Заодно посмотрю есть ли и как формируется "разрыв" в разметке.
За расчет параметров разделов памяти отвечает метод ReadExcelFile(). Посмотрим, что же там написано для чипа МТ6572. Вот текст цикла заполнения данных разделов:

Спойлер


01  for($row=1;$row < @PARTITION_FIELD;$row++){
02    if($PARTITION_FIELD[$row] eq "MBR"){
03        $START_FIELD_Byte[$row] = $MBR_Start_Address_KB*1024;
04        $SIZE_FIELD_KB[$row-1] = ($START_FIELD_Byte[$row] - $START_FIELD_Byte[$row-1])/1024;
05        next;
06    }
07    if($PARTITION_FIELD[$row] eq "BMTPOOL" || $PARTITION_FIELD[$row] eq "OTP"){
08    #    $START_FIELD_Byte[$row] = &xls_cell_value($sheet, $row+1, $COLUMN_START,$SHEET_NAME);
09        $START_FIELD_Byte[$row] = $SIZE_FIELD_KB[$row]*1024;
10        if($PARTITION_FIELD[$row] eq "OTP"){
11                $otp_row = $row;
12            }
13        next; 
14    }
15    
16    $START_FIELD_Byte[$row] = $START_FIELD_Byte[$row-1]+$SIZE_FIELD_KB[$row-1]*1024;
17    
18 }

 

  Поясню немного. Весь цикл можно разделить на три части:
  1. строки 02..06. Это заполнение параметров для раздела с меткой MBR. В строке 03 смещение начала раздела принимается равным заранее заданному параметру MBR_Start_Address_KB. В строке 04 высчитывается длина предыдущего раздела как разность смещений текущего и предыдущего разделов;
  2. строки 07..14. Это заполнение параметров для разделов BMTPOOL и OTP. В строке 08,09 смещение начала раздела берется либо из экселевского файла, т.е. заданное ранее, или принимается равным размеру раздела;
  3. строка 16. Это расчет смещения всех остальных разделов: смещение предыдущего + его размер.
  Как видно, нет и намека на "разрыв" разделов, все они размещаются строго НЕПРЕРЫВНО. Исключение могут составлять разделы BMTPOOL и OTP, но они никому не мешают, т.к. расположены ПОСЛЕДНИМИ.
  Теперь давайте посмотрим метод GenPartSizeFile(), который рассчитывает размеры файлов образов, прошиваемых в разделы памяти:
Спойлер


1    if($TYPE_FIELD[$index] eq "EXT4" || $TYPE_FIELD[$index] eq "FAT"){
2        $temp = $SIZE_FIELD_KB[$index]/1024;
3        if($PARTITION_FIELD[$index] eq "USRDATA"){
4            $temp -=1;    
5        }
6        if(exists($PSalias{$PARTITION_FIELD[$index]})){
7            print $part_size_fh "BOARD_$PSalias{$PARTITION_FIELD[$index]}IMAGE_PARTITION_SIZE:=$temp". "M\n" ;
8        }else{
9            print $part_size_fh "BOARD_$PARTITION_FIELD[$index]IMAGE_PARTITION_SIZE:=$temp". "M\n" ;
10        }
11    }

 

 

  Приведенный код пересчитывает размер каждого раздела памяти из Кб в Мб (строка 2), если они имеют тип EXT4 или FAT, т.к. они имеют самые большие размеры. 
  Если же среди них попадется раздел USRDATA, то его размер уменьшается на 1 Мб (строка 3,4) и в строке 7 или 9 параметру "IMAGE_PARTITION_SIZE" присвоят результат вычислений. Имя этого параметра говорит само за себя.
 
2 пользователям понравился пост

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Итак, часть 3, самая "маленькая".

 

3. А если посмотреть информацию по другим чипам, что там?
Спойлер
3.1. МТ6575 и МТ6577.
  Стартовый адрес раздела (его смещение) формируется точно также, а вот при расчете размера файла-образа разработчики пошли еще дальше и уменьшают размер как USRDATA, так и ANDROID, CACHE и SEC_RO. Причем "USRDATA" на 2Мб, а остальные разделы на 1Мб:
Спойлер


1 if($PARTITION_FIELD[$index] eq "ANDROID" || $PARTITION_FIELD[$index] eq "CACHE" || $PARTITION_FIELD[$index] eq "SEC_RO"){
2     $temp -=1*1024*1024;
3 }
4 if($PARTITION_FIELD[$index] eq "USRDATA"){
5    $temp -=2*1024*1024;    
6 }
  Это, скорее всего, связано с поиском разработчиками структуры процедуры шифрования, т.е. а что же на самом деле необходимо прятать от чужих глаз.
3.2. МТ6582, МТ6589, МТ8127, МТ8135.
  Начиная с чипа МТ6582, у МТК адресное пространство памяти стало разбиваться на регионы, что привело к некоторым изменениям при формировании стартовых адресов разделов. Хотя в целом это никак не повлияло на принципы распределения памяти:
Спойлер


01 for($row=1;$row < @PARTITION_FIELD;$row++){
02    if($PL_MODE ne "" && $EMMC_SUPPORT eq "yes"){
03        if($PARTITION_FIELD[$row] ne "MBR" && $REGION_FIELD[$row] eq "USER" && ($first_user == 1)){
04            $START_FIELD_Byte[$row] = $MBR_Start_Address_KB*1024;
05            $SIZE_FIELD_KB[$row-1] = ($START_FIELD_Byte[$row] - $START_FIELD_Byte[$row-1])/1024;
06            $first_user = 0;
07            next;            
08        }        
09    }
10    if($PARTITION_FIELD[$row] eq "MBR"){
11        $START_FIELD_Byte[$row] = $MBR_Start_Address_KB*1024;
12        $SIZE_FIELD_KB[$row-1] = ($START_FIELD_Byte[$row] - $START_FIELD_Byte[$row-1])/1024;
13        next;
14    }
15    if($PARTITION_FIELD[$row] eq "BMTPOOL" || $PARTITION_FIELD[$row] eq "OTP"){
16    #    $START_FIELD_Byte[$row] = &xls_cell_value($sheet, $row+1, $COLUMN_START,$SHEET_NAME);
17    $START_FIELD_Byte[$row] = $SIZE_FIELD_KB[$row]*1024;
18        if($PARTITION_FIELD[$row] eq "OTP"){
19                $otp_row = $row;
20            }
21        next; 
22    }
23    
24    $START_FIELD_Byte[$row] = $START_FIELD_Byte[$row-1]+$SIZE_FIELD_KB[$row-1]*1024;
25    
26 }

 

  К уже рассмотренному выше циклу расчета смещений (строки 10...25) добавился кусок с настройкой в режиме PL_MODE (строка 04...07).
  А при расчете размеров файлов-образов разделов разработчики вернулись к варианту, опробованному на МТ6572:
Спойлер


    if($TYPE_FIELD[$index] eq "EXT4" || $TYPE_FIELD[$index] eq "FAT"){
        $temp = $SIZE_FIELD_KB[$index]*1024;
        if($PARTITION_FIELD[$index] eq "USRDATA"){
            $temp -=1024*1024;    
        }
            #print "$PSalias{$PARTITION_FIELD[$index]} $PARTITION_FIELD[$index]\n";
        if(exists($PSalias{$PARTITION_FIELD[$index]})){
            print $part_size_fh "BOARD_$PSalias{$PARTITION_FIELD[$index]}IMAGE_PARTITION_SIZE:=$temp\n" ;
        }else{
            print $part_size_fh "BOARD_$PARTITION_FIELD[$index]IMAGE_PARTITION_SIZE:=$temp\n" ;
        }
    }
3.3. МТ6592, МТ6595. 
  Начиная с этого чипа МТК существенно переработала код и теперь расчет смещений производится в методе ProcessRawPartitionLayoutData(). Вот часть текста этого метода:
Спойлер


00    for ($partition_idx = 0 ; $partition_idx < @partition_layout_process ; $partition_idx++)
01    {
02        if ($partition_layout_process[$partition_idx]->{Reserved} eq "N")
03        {
04            if ($partition_idx != 0 && $partition_layout_process[$partition_idx]->{Region} eq $partition_layout_process[$partition_idx - 1]->{Region})
05            {
06                my $st_addr = $partition_layout_process[$partition_idx - 1]->{Start_Addr} + $partition_layout_process[$partition_idx - 1]->{Size_KB} * 1024;
07
08                #auto adjust to alignment
09                if (exists $AlignPartList{$partition_layout_process[$partition_idx]->{Partition_Name}})
10              {
11                    # print "got aligned partition $partition_layout_process[$partition_idx]->{Partition_Name}\n";
12                    if ($st_addr % scalar($AlignPartList{$partition_layout_process[$partition_idx]->{Partition_Name}}) != 0)
13                    {
14                        printf("Need adjust start address for %s, because it is 0x%x now. ", $partition_layout_process[$partition_idx]->{Partition_Name}, $st_addr % scalar($AlignPartList{$partition_layout_process[$partition_idx]->{Partition_Name}}));
15                        my $pad_size = $AlignPartList{$partition_layout_process[$partition_idx]->{Partition_Name}} - $st_addr % scalar($AlignPartList{$partition_layout_process[$partition_idx]->{Partition_Name}});
16                        if ($pad_size % 1024 != 0)
17                        {
18                            &error_handler("pad size is not KB align,please review the size of $AlignPartList{$partition_layout_process[$partition_idx]->{Partition_Name}}", __FILE__, __LINE__);
19                        }
20                        $partition_layout_process[$partition_idx - 1]->{Size_KB} = $partition_layout_process[$partition_idx - 1]->{Size_KB} + $pad_size / 1024;
21                        $st_addr = $partition_layout_process[$partition_idx - 1]->{Start_Addr} + $partition_layout_process[$partition_idx - 1]->{Size_KB} * 1024;
22                        printf("pad size is 0x%x, and pre part [%s]size is 0x%x \n", $pad_size, $partition_layout_process[$partition_idx - 1]->{Partition_Name}, $partition_layout_process[$partition_idx - 1]->{Size_KB} * 1024);
23                    }
24                }
25                $partition_layout_process[$partition_idx]->{Start_Addr} = $st_addr;
26            }
26            else
27            {
28                $partition_layout_process[$partition_idx]->{Start_Addr} = 0;
29            }
30            $partition_layout_process[$partition_idx]->{Start_Addr_Text} = sprintf("0x%x", $partition_layout_process[$partition_idx]->{Start_Addr});
31        }
32        else
33        {
34            if ($ArgList{EMMC_SUPPORT} eq "yes")
35            {
36                $partition_layout_process[$partition_idx]->{Start_Addr_Text} = sprintf("0xFFFF%04x", $partition_layout_process[$partition_idx]->{Start_Addr} / (128 * 1024));
37            }
38            else
39            {
40                $partition_layout_process[$partition_idx]->{Start_Addr_Text} = sprintf("0xFFFF%04x", $partition_layout_process[$partition_idx]->{Start_Addr} / (64 * $ArgList{PAGE_SIZE} * 1024));
41            }
42        }
43        $Used_Size += $partition_layout_process[$partition_idx]->{Size_KB};
44    }
  Что же изменилось? Просмотрев код, я обнаружил следующие моменты:  
  • добавилось разделение на разделы в зависимости от флага RESERVED (строка 02);
  • каждый регион рассчитывается отдельно и смещение в новом регионе начинается с нуля;
  • начало раздела теперь подстраивается под т.н. границу размещения (adjust to alignment).
  Если флаг RESERVED имеет значение "yes", то раздел является резервным и предназначен для хранения системных данных при определенных обстоятельствах, т.е. является по сути фиктивным разделом. Это такие разделы как OTP, BMTPOOL. Смещение такого раздела рассчитывается как и раньше (см. строки 33...42). 
  Смещение разделов каждого региона рассчитывается по отдельности. Если рассматриваемый в цикле раздел принадлежит новому региону, то его смещение начинается с нуля (см. строки 26...29). Если раздел продолжает регион, то его смещение рассчитывается как и ранее, но с учетом границы размещения (строки 08...25). Если смещение раздела не располагается на границе размещения, т.е. некратна значению из массива AlignPartList (строка 12), то размер предыдущего раздела увеличивается на величину несоответствия (строка 15...20), а смещение текущего раздела примет допустимое значение (строка 21).
  Возможные значения и разделы, на которые эта привязка распространяется, приведены в массиве AlignPartList:
Спойлер


    #1MB=1048576 byte align
    #8MB=8388608 byte align
    %AlignPartList = (
                      ANDROID => 8388608,
                      CACHE   => 8388608,
                      USRDATA => 8388608,
                      FAT     => 8388608
                     );
3.4. МТ6752.
  Размещение разделов осталось прежним - непрерывно. Пересчет длины образов разделов НЕ ПРОИЗВОДИТСЯ:
Спойлер


        if ($part->{Type} eq "EXT4" || $part->{Type} eq "FAT")
        {
            $temp = $part->{Size_KB} * 1024;
             printf $part_size_fh ("BOARD_%sIMAGE_PARTITION_SIZE:=%d\n",uc($part->{Partition_Name}),$temp);
        }
Это отличие от предыдущих версий кода объясняется очень просто: файл ptgen.pl для МТ6752 мне достался от исходного кода Android версии 5, в которой был изменен принцип шифрования пользовательских данных. Описание можно посмотреть в [5].
С этим и связаны изменения в коде. Теперь не производится пересчет размеров образов, заливаемых в раздел памяти, т.к. данные шифрования хранятся не в "data", а в виде метаданных в специальном разделе.

 

2 пользователям понравился пост

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну, и часть 4, действительно небольшая, но может быть будет и дополнена.
 
4. Выводы.

  • Разметка памяти всегда выполнялась и выполняется непрерывно, без пропусков (разрывов, промежутков и т.п.) между разделами.
  • Для хранения данных шифрования (ключ, буфер и т.д.) в вершине раздела подлежащего шифрованию, т.е. со стороны старших адресов, создавалась специальная область "footer", размером не менее 16Кб. Чтобы оградить ее от несанкционированного доступа и обеспечить сохранность при выполнении пользователем команд типа "wipe", образ, заливаемый в этот раздел, имел размер меньше на 1Мб, чем размер раздела памяти. Это никак не влияло на работоспособность файловой системы, размещенной внутри образа, т.к. ФС типа ext4 всегда имеет "пустое" место, т.е. свободные от информации блоки.

 

Дополнение от 06.02.2016.

Современные мобильные устройства в файлах *.fstab, где описываются параметры файловых систем (ФС) и места их расположения, для ФС с меткой (label) "data" содержат примерно такие строки:

/data            ext4    /dev/block/bootdevice/by-name/userdata            length=-16384,encryptable=/dev/block/bootdevice/by-name/metadata

означающее, что ФС "data", расположенная в разделе "userdata", создается с размером меньше размера раздела на 16384 байта. Таким образом не раздел уменьшается для размещения crypto-области, а уменьшается размер ФС, прошиваемой в раздел. 

 

P.S. чтобы раз и навсегда прекратить споры, что означает 1Кб или 1Мб, приведу строку исходного текста для формирования одного из файлов *.h:

 

    print $partition_define_h "\n\n\n#define KB  (1024)\n#define MB  (1024 * KB)\n#define GB  (1024 * MB)\n\n";

Эта запись означает, что все размеры в исходных текстах, т.е. в ПРОГРАММАХ, указаны не в числах по степени 10, а в числах по степени 2: 1Кб=1024 байт, 1Мб=1024 Кб, 1Гб=1024Мб.

3 пользователям понравился пост

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!


Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.


Войти

  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу