Дуалбут Android 14 и postmarketOS на OnePlus 6 без кастомного рекавери
Для OnePlus 6 есть кастомные рекавери на базе TWRP или OrangeFox, которые позволяют установить 2 андроид системы, разделяя раздел userdata
на userdata_a
и userdata_b
. Однако эти рекавери заточены на версию Android 9 и 10.
У мобильных Linux дистрибутивов, использующих mainline ядро, есть особенность - у них не захардкожен раздел для хранения данных и можно использовать какой угодно, нам не придётся патчить рекавери и сам Android не сможет никак взаимодействовать с этим разделом!
Переведенная цитата из pmOS Wiki
[...] Поскольку pmOS initramfs ищет название раздела, а не конкретный раздел, он автоматически определит раздел, на который был установлен pmOS rootfs.
Увы, такая возможность есть только у mainline дистрибутивов по типу postmarketOS, Mobian и Kupfer Linux (ArchLinux ARM) - с Droidian так не выйдет, так как "под капотом" там Halium и Android ядро.
Выделяем место для postmarketOS¶
Опасная зона!
С этого момента мы начинаем модификацию разделов и тут есть большой шанс накосячить! На всякий случай лучше приготовить Windows компьютер для восстановления через EDL.
Впрочем, оригинальная схема разделов будет ниже и по ней можно будет попробовать восстановить.
В качестве примера используется OnePlus 6 с хранилищем на 128 Гб. Нас интересует раздел userdata
, от него нам и нужно будет "откусить" часть.
За основу был взять этот гайд с XDA. Бинарник parted
тоже оттуда.
-
Загружаемся в рекавери - TWRP или LineageOS Recovery и включаем adb.
-
Передаём скаченный
parted
в/sbin/
и делаем его исполняемым:adb push /path/to/parted /sbin/parted adb shell chmod 777 /sbin/parted parted /dev/block/sda p free
Вывод таблицы разделов до модификаций (LineageOS 20)
Model: SAMSUNG KLUDG4U1EA-B0C1 (scsi)
Disk /dev/block/sda: 125GB
Sector size (logical/physical): 4096B/4096B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
12.3kB 24.6kB 12.3kB Free Space
1 24.6kB 32.8kB 8192B ssd
2 32.8kB 33.6MB 33.6MB ext4 persist
3 33.6MB 34.6MB 1049kB misc
4 34.6MB 35.7MB 1049kB param
5 35.7MB 36.2MB 524kB keystore
6 36.2MB 36.7MB 524kB frp
7 36.7MB 305MB 268MB ext4 op2
8 305MB 316MB 10.5MB oem_dycnvbk
9 316MB 326MB 10.5MB oem_stanvbk
10 326MB 334MB 8290kB reserve1
11 334MB 351MB 16.6MB reserve2
12 351MB 352MB 524kB config
13 352MB 3350MB 2999MB ext2 system_a
14 3350MB 6349MB 2999MB ext4 system_b
15 6349MB 6454MB 105MB ext4 odm_a
16 6454MB 6559MB 105MB ext4 odm_b
17 6559MB 125GB 118GB ext4 userdata
125GB 125GB 12.3kB Free Space
-
Удаляем раздел
userdata
, в моём случае он под номером 17:rm 17
-
Создаём раздел
userdata
заново, но выделяем ему меньше места. Я пытался выделить 64 Гб поровну как для Android, так и для Linux:mkpart userdata ext4 6559MB 70.5GB
Шаблон для mkpart
mkpart name fs_type start end
- name - название раздела, например
userdata
. parted не всегда его сохраняет, то этому его надо писать ещё и после mkpart; - fs_type - файловая система, оставляем ext4;
- start - см. где заканчивается прерырущий раздел в столбце End;
- end - прибавляем значение start + размер будущего раздела.
-
Проверяем имя раздела через
p free
. Если оно пустое, то задаём заново:name 17 userdata
-
Создаём раздел с данными для Linux под названием
linux_rootfs
:mkpart linux_rootfs ext4 70.5GB 125GB name 18 linux_rootfs
-
Проверяем созданную таблицу разделов:
Таблица разделов после модификаций
Model: SAMSUNG KLUDG4U1EA-B0C1 (scsi)
Disk /dev/block/sda: 125GB
Sector size (logical/physical): 4096B/4096B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
12.3kB 24.6kB 12.3kB Free Space
1 24.6kB 32.8kB 8192B ssd
2 32.8kB 33.6MB 33.6MB ext4 persist
3 33.6MB 34.6MB 1049kB misc
4 34.6MB 35.7MB 1049kB param
5 35.7MB 36.2MB 524kB keystore
6 36.2MB 36.7MB 524kB frp
7 36.7MB 305MB 268MB ext4 op2
8 305MB 316MB 10.5MB oem_dycnvbk
9 316MB 326MB 10.5MB oem_stanvbk
10 326MB 334MB 8290kB reserve1
11 334MB 351MB 16.6MB reserve2
12 351MB 352MB 524kB config
13 352MB 3350MB 2999MB ext2 system_a
14 3350MB 6349MB 2999MB ext4 system_b
15 6349MB 6454MB 105MB ext4 odm_a
16 6454MB 6559MB 105MB ext4 odm_b
17 6559MB 70.5GB 63.9GB ext4 userdata
70.5GB 70.5GB 1004kB Free Space
18 70.5GB 125GB 54.2GB linux_rootfs
125GB 125GB 1040kB Free Space
-
Выходим из parted командой
quit
. -
После форматирования разделов, сделайте в рекавери сброс на заводские настройки, чтобы рекавери отформатировала раздел
userdata
как нужно и не было бутлупа.
Прошивка Android в Слот A¶
Примеры команд для прошивки LineageOS 20 (A13). Будем использовать стандартный рекавери LineageOS, так как рабочих и актуальных вариантов TWRP и OrangeFox нет.
- Прошиваем разделы, не забываем указывать
_a
:
fastboot flash boot_a boot.img
fastboot flash dtbo_a dtbo.img
fastboot flash vbmeta_a vbmeta.img
- Для прошивки LineageOS через LOS Recovery нам нужен рекавери на слоте B. Прошиваем его и перезагружаемся:
fastboot flash boot_b boot.img
fastboot --set-active=b
- Перезагружаемся в рекавери: Выбираем кнопками громкости "Recovery mode" и нажимаем на кнопку питания. Из bootloader нельзя перезагрузиться в рекавери командой.
Рекавери должно выдать, что у нас сейчас активен B слот - так и должно быть, так как пакет с обновлениями будет прошиваться на соседний слот.
- Прошиваем .zip пакет с обновлениями через "Apply update" и adb sideload.
adb sideload имя-пакета.zip
После прошивки система будет загружаться с слота А. Это можно проверить следующей командой в режиме bootloader:
fastboot getvar current-slot
-
Если вы хотите установить пакет GAPPS, то подтвердите перезагрузку в рекавери. (Magisk ставится уже после первой загрузки в систему)
-
Перед первой загрузкой в систему лучше сделать Factory reset.
Прошивка pmOS в Слот B¶
Перед тем как продолжить...
Я полагаю что вы уже знаете как прошивать postmarketOS на OnePlus 6 и делали это самостоятельно хотя бы раз. По этому ниже только краткая сводка команд.
Готовый образ¶
Переключаемся на слот B и прошиваем образы на второй boot раздел и на наш новый специально созданный раздел под данные:
fastboot --set-active=b
fastboot erase dtbo_b
fastboot flash boot_b [файл который заканчивается на -boot.img]
fastboot flash linux_rootfs [второй .img файл]
Во время первой загрузки отключите устройство от USB, чтобы не было вот такого.
Сборка своего образа с шифрованием данных¶
Клонируем исходники pmbootstrap, проходим инициализацию и сборку, переключаемся на слот B и прошиваем образы на второй boot раздел и на наш новый специально созданный раздел под данные:
git clone --depth=1 https://git.sr.ht/~postmarketos/pmbootstrap
mkdir -p ~/.local/bin
ln -s "$PWD/pmbootstrap/pmbootstrap.py" ~/.local/bin/pmbootstrap
pmbootstrap init
pmbootstrap install --fde
fastboot --set-active=b
fastboot erase dtbo_b
pmbootstrap flasher flash_kernel --partition boot_b
pmbootstrap flasher flash_rootfs --partition linux_rootfs
pmbootstrap shutdown
Во время первой загрузки отключите устройство от USB, чтобы не было вот такого.
Как обновлять Android¶
Обновление Android на A/B устройствах при дуалбуте - это боль, но это возможно.
LineageOS всё ещё будет пытаться обновлять наше устройство как A/B, то есть устанавливать все обновления на соседний системный слот и перезаписывая boot раздел, на котором находится postmarketOS
Однако, обновления можно установить через bootloader!
Внимание!
Во время обновления у вас слетят GAPPS'ы, Magisk и прочие модификации которые вы делали с системным разделом! Их нужно будет прошивать заново!
И перед тем как обновляться лучше всего сделать бэкап важных файлов. Быстрее всего это можно сделать через adb pull /sdcard/Название_папки
Как сделать бэкап разделов в виде прошиваемого .img-образа
Для этого нам нужен adb с root доступом - это можно включить в настройках разработчика LineageOS:
Показан пример только для system раздела, но вы можете указать какой угодно:
adb root
adb shell
dd if=/dev/block/bootdevice/by-name/system_a of=/sdcard/system_a_backup.img bs=4k
exit
adb pull /sdcard/system_a_backup.img
В таком случае нужно устанавливать Android обновления, не через рекавери или встроенные обновления в систему, а через fastboot.
- Скачиваем .zip архив с обновлением и распаковываем его при помощи payload-dumper-go
В итоге мы получим следующий список прошиваемых через fastboot образов:
- system.img
- vendor.img
- boot.img
- vbmeta.img
- dtbo.img
- и т.д.
В составе LineageOS рекавери есть fastbootd, которым я рекомендую пользоваться при прошивке разделов из пакета обновлений.
Синтаксис будет тот же самый что и в режиме bootloader'а, просто багов меньше. Энтузиасты часто жаловались на кривую стоковую реализацию fastboot и по возможности лучше использовать fastbootd в составе рекавери.
Совет пользователям Magisk
Перед тем как шить boot.img
образ, его можно перекинуть на устройство через adb push /sdcard
и пропатчить его Magisk'ом заранее.
- Загружаемся в рекавери, переходим в режим fastbootd и прошиваем образы:
fastboot flash system_a system.img fastboot flash vendor_a vendor.img fastboot flash boot_a boot.img # Напомню, можете перед этим пропатчить образ Magisk'ом fastboot flash vbmeta_a vbmeta.img fastboot flash dtbo_a dtbo.img
Если в распакованном образе помимо system
и vendor
образов есть ещё что-то (например, обновление модема и других разделов), то шьём их тоже!
Payload dumper может также распаковать из архива образы boot
, dtbo
, vbmeta
. Если вы до этого уже скачали их отдельно и прошили, то распакованные можно игнорировать - они идентичные.
-
Если вы используете GAPPS'ы, то загрузитесь в рекавери сейчас и прошейте пакет заново!
-
На этом обновление закончено - можно загружаться!
Работает даже между мажорными релизами!
Протестировано при обновлении с LineageOS 20 на 21 с сохранением рабочего пакета NikGapps Core и Magisk.