Bootstrap

Журнал установки Nura (postmarketOS) на OnePlus One: mainline-ядро, Phosh, Docker, проброс USB в VM,

Журнал установки Nura (postmarketOS) на OnePlus One: mainline-ядро, Phosh, Docker, проброс USB в VM,

OnePlus One (bacon) → Nura (бывший postmarketOS) с Phosh и Docker

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

Источники:

  • https://itdid.ru/one_plus_bacon_ubuntu_toach.html — как ставилась Ubuntu Touch
  • https://itdid.ru/one_plus_bacon_nura.html — установка Nura на bacon

0. Исходное состояние

  • Хост: MX Linux (ramanzes@mx).
  • Сборочная VM: Debian 13, запущена через qemu-system-x86_64 (q35, KVM), 16 ГБ RAM, 2 vCPU.
  • Телефон: OnePlus One bacon, серийный номер 13b6717d. Стоит Ubuntu Touch 16.04 (OTA, ядро 3.4.0-Sultan-CAF, armv7l).

Почему не Docker на Ubuntu Touch

Конфиг ядра UT снят командой adb shell zcat /proc/config.gz. В нём нет обязательных для Docker опций:

ОпцияUbuntu Touch 3.4
CONFIG_MEMCGнет
CONFIG_CGROUP_DEVICEнет
CONFIG_CPUSETSнет
CONFIG_OVERLAY_FSнет
namespaces, veth, bridge, NATесть

Кроме того, корень / смонтирован только для чтения, и на нём свободно 197 МБ.

Решение: перепрошить на Nura с mainline-ядром (linux-postmarketos-qcom-msm8974) и Docker из apk.

1. Проброс телефона в VM по USB

Телефон на хосте:

☯

Terminal:

⌕

≡

✕
$ lsusb
Bus 003 Device 005: ID 05c6:6764 Qualcomm, Inc. A0001 Phone [OnePlus One]
$ lsusb -t
/:  Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 480M
    |__ Port 2: Dev 5, If 0, Class=Vendor Specific Class, Driver=, 480M

При смене режима телефон меняет USB ID: MTP 05c6:6764 → MTP+ADB 05c6:6765 → fastboot. Поэтому проброс сделан по физическому порту (hostbus=3,hostport=2), а не по ID. Изначально в VM не было USB-контроллера, поэтому горячее подключение через монитор было невозможно. Добавлен qemu-xhci, VM перезапущена:

☯

Terminal:

⌕

≡

✕
sudo qemu-system-x86_64 -enable-kvm -m 16384 -smp 2 -machine pc-q35-7.2 -cpu host \
  -drive file=/var/lib/libvirt/images/debian13.qcow2,if=virtio,format=qcow2 -boot order=c \
  -netdev bridge,br=virbr0,id=net0 -device virtio-net-pci,netdev=net0,mac=52:54:00:12:34:56 \
  -vga qxl -device virtio-tablet \
  -device qemu-xhci,id=xhci -device usb-host,bus=xhci.0,hostbus=3,hostport=2 \
  -spice port=5930,disable-ticketing=on -device intel-hda -device hda-duplex -monitor stdio

Проверка в VM:

☯

Terminal:

⌕

≡

✕
$ lsusb
Bus 001 Device 002: ID 05c6:6764 Qualcomm, Inc. A0001 Phone [OnePlus One]

ADB в Ubuntu Touch включается так: задать код блокировки, затем Настройки → Об устройстве → Режим разработчика. Телефон переподключился как 05c6:6765. Чтобы adb его увидел, понадобилось adb kill-server:

☯

Terminal:

⌕

≡

✕
$ adb devices -l
13b6717d   device usb:1-1 product:bacon model:bacon device:bacon transport_id:1

2. Подготовка VM

☯

Terminal:

⌕

≡

✕
sudo apt-get install -y fastboot pmbootstrap   # fastboot 34.0.5; pmbootstrap 3.1.0 из Debian — старый, ниже ставим из git
sudo apt-get clean                              # освобождено ~3 ГБ: на диске было 3.7 ГБ, стало 6.6 ГБ

3. pmbootstrap init

Параметры заранее записаны в ~/.config/pmbootstrap_v3.cfg:

☯

Terminal:

⌕

≡

✕
[pmbootstrap]
device = oneplus-bacon
ui = phosh
user = user
hostname = bacon
extra_packages = docker,docker-cli-compose,nano,htop
timezone = Europe/Moscow
locale = ru_RU.UTF-8
ssh_keys = False
sudo_timer = False
build_pkgs_on_install = True

Первая попытка с pmbootstrap 3.1.0 из Debian. pmaports склонировался примерно за 7 минут в ~/.local/var/pmbootstrap/cache_git/pmaports, после чего init завершился ошибкой:

☯

Terminal:

⌕

≡

✕
$ yes '' | pmbootstrap init
NOTE: you are using pmbootstrap version 3.1.0, but version 3.11.0 is required.
ERROR: Please update your pmbootstrap version ...

Вывод: пакет Debian слишком старый, нужен pmbootstrap из git (>= 3.11.0).

Проверка bacon в pmaports (ветка main = edge, коммит 0951615aac от 27.10.2026):

☯

Terminal:

⌕

≡

✕
device/testing/device-oneplus-bacon            ← mainline, категория testing
device/testing/firmware-oneplus-bacon
device/archived/device-oneplus-bacon-downstream ← старое ядро 3.4, в архиве
deviceinfo_arch="armv7", deviceinfo_flash_method="fastboot"

Категория testing собирается только в edge, в стабильных релизах её нет. Поэтому ветка — edge.

3.1. pmbootstrap из git

☯

Terminal:

⌕

≡

✕
docker image prune -f        # удалены висячие образы: освобождено 1.39 ГБ, на диске стало 7.8 ГБ
git clone --depth 1 https://gitlab.postmarketos.org/postmarketOS/pmbootstrap.git ~/src/pmbootstrap
python3 ~/src/pmbootstrap/pmbootstrap.py --version   # 3.12.1 (коммит ff954a6 от 21.10.2026)

Дальше везде pmbootstrap означает python3 ~/src/pmbootstrap/pmbootstrap.py.

3.2. init

☯

Terminal:

⌕

≡

✕
yes '' | pmbootstrap init     # все ответы берутся из ~/.config/pmbootstrap_v3.cfg

Ключевые ответы init:

  • Channel: edge (у v26.06 нет bacon, он в категории testing)
  • Vendor/device: oneplus / bacon (testing)
  • Audio: pulseaudio; WiFi: wpa_supplicant; usb-moded: developer (USB-сеть включена всегда)
  • Service manager: default → systemd
  • Extra packages: docker,docker-cli-compose,nano,htop

Проблема: NOTE: 9 UIs are hidden because "deviceinfo_drm" is not set. Phosh скрыт, init выставил ui = console.

Разбор:

  • kernel-cmdline.conf у bacon: msm.vram=192m msm.allow_vram_carveout=1, то есть экран работает через DRM-драйвер msm;
  • в зависимостях есть firmware-qcom-adreno-a330 (GPU);
  • у других устройств на msm8974 с тем же ядром (fairphone-fp2, lg-hammerhead, samsung-lt03lte) стоит deviceinfo_drm="true";
  • у bacon флаг просто не выставлен. Вики (wiki.nura.eco) закрыта антиботом Anubis, проверить по ней не удалось.

Решение: выставить Phosh вручную. Если не заработает, пересобрать с ui console.

Также исправлен часовой пояс: init взял America/Chicago из VM.

☯

Terminal:

⌕

≡

✕
pmbootstrap config ui phosh
pmbootstrap config timezone Europe/Moscow
pmbootstrap config ssh_keys True   # ключи VM (~/.ssh/*.pub) копируются на телефон для входа по ssh

Ядро: linux-postmarketos-qcom-msm8974 6.16.12 (https://github.com/msm8974-mainline/linux), загрузчик — lk2nd-msm8974.

4. Сборка образа: pmbootstrap install

☯

Terminal:

⌕

≡

✕
pmbootstrap --details-to-stdout install --password 147147 > install.log 2>&1

Пароль 147147 временный и цифровой: в Phosh пароль вводится как PIN. После первого входа сменить командой passwd.

Ход сборки (22:55 → 23:05, около 10 минут, всё из готовых бинарных пакетов, без компиляции):

ВремяЭтап
22:55:39(1/4) PREPARE NATIVE CHROOT — x86_64 chroot; зеркало перенаправляет на mirror.nura.eco
22:56:00(2/4) CREATE DEVICE ROOTFS — база 100 пакетов, затем UI и extra 1093 пакета (Phosh, ядро, прошивки, docker)
23:05:01установка пароля для user
23:05:15(3/4) PREPARE INSTALL BLOCKDEVICE — образ с таблицей разделов: boot 512M + rootfs
23:05:32(4/4) FILL INSTALL BLOCKDEVICE
23:05:49DONE, EXIT=0

Безобидные сообщения в логе:

  • WARNING: opening .../packages/edge/.../APKINDEX.tar.gz: No such file — локальный репозиторий собранных пакетов пуст;
  • Error loading shared library libsystemd-shared-262.so (needed by /usr/sbin/udevadm) — post-install скрипт device-mapper-udev вызвал udevadm раньше, чем apk поставил libsystemd-shared в той же транзакции;
  • Firewall is enabled, but may not work (couldn't determine if kernel supports nftables).

Результат:

☯

Terminal:

⌕

≡

✕
~/.local/var/pmbootstrap/chroot_native/home/pmos/rootfs/oneplus-bacon.img   2.8G (sparse, реально ~2.0G)

На диске VM осталось 3.1 ГБ.

Инструкция pmbootstrap по прошивке:

☯

Terminal:

⌕

≡

✕
* Your device supports and may even require flashing lk2nd. You should flash it before flashing anything else.
  -> pmbootstrap flasher flash_lk2nd
* pmbootstrap flasher flash_rootfs
* pmbootstrap flasher flash_kernel

SSH включён; после загрузки вход: ssh user@172.16.42.1 (USB-сеть).

5. Прошивка

5.1. Fastboot и проверка загрузчика

☯

Terminal:

⌕

≡

✕
$ adb reboot bootloader
$ lsusb
Bus 001 Device 004: ID 18d1:d00d Google Inc. ... (fastboot)   ← VM подхватила сама: проброс по порту
$ fastboot oem device-info
(bootloader)    Device tampered: true
(bootloader)    Device unlocked: true          ← разблокирован ещё при установке Ubuntu Touch
$ fastboot getvar product
product: MSM8974

5.2. lk2nd (вторичный загрузчик, ставится первым)

☯

Terminal:

⌕

≡

✕
$ pmbootstrap flasher flash_lk2nd
Sending 'boot' (320 KB)     OKAY
Writing 'boot'              OKAY
$ fastboot reboot           # ядра ещё нет, поэтому lk2nd сам остаётся в своём fastboot
$ fastboot getvar product
product: lk2nd-msm8974      ← дальше всё шьётся уже через lk2nd

5.3. Rootfs → userdata (Ubuntu Touch и /home стёрты)

☯

Terminal:

⌕

≡

✕
$ pmbootstrap flasher flash_rootfs --partition userdata
Invalid sparse file format at header magic        ← не ошибка: fastboot переводит raw-образ в sparse
Sending sparse 'userdata' 1/4 (509446 KB)  OKAY [12.3s]   Writing OKAY [66.0s]
Sending sparse 'userdata' 2/4 (508151 KB)  OKAY [12.3s]   Writing OKAY [11.6s]
Sending sparse 'userdata' 3/4 (523688 KB)  OKAY [12.7s]   Writing OKAY [16.3s]
Sending sparse 'userdata' 4/4 (453282 KB)  OKAY [11.0s]   Writing OKAY [45.9s]
Finished. Total time: 194.877s

5.4. Ядро + initramfs

☯

Terminal:

⌕

≡

✕
$ pmbootstrap flasher flash_kernel
Sending 'boot' (8038 KB)    OKAY       ← lk2nd пишет ядро после себя, сам lk2nd не затирается

Предупреждение kconfig в категории containers: не хватает только CONFIG_NFT_FIB_INET и CONFIG_NFT_FIB_NETDEV (nftables rpfilter), Docker без них работает.

Опции для Docker в ядре 6.16 есть (сравнить с UT в разделе 0):

MEMCG=y CGROUP_DEVICE=y CPUSETS=y CGROUP_PIDS=y BLK_CGROUP=y OVERLAY_FS=m VETH=m BRIDGE=m NF_NAT=m IP_NF_TARGET_MASQUERADE=m NFT_MASQ=m, все namespaces = y.

6. Первая загрузка: застряли в initramfs (баг edge) и ручная починка

После fastboot reboot в VM появилась USB-сеть 18d1:d001, интерфейс enx…, но DHCP не сработал. Адрес назначен вручную:

☯

Terminal:

⌕

≡

✕
sudo ip addr add 172.16.42.2/24 dev enxda164df1f7ca   # имя интерфейса меняется при каждой загрузке телефона

SSH (22) был закрыт, зато открыт telnet (23) — отладочная оболочка initramfs. Лог /pmOS_init.log:

☯

Terminal:

⌕

≡

✕
Mount subpartitions of /dev/mmcblk0p28
Mount boot partition (/dev/loop0p1) to /boot (read-only)
Extract /boot/initramfs-extra
gzip: invalid magic
[pmOS-rd] ERROR: /init_2nd.sh not found!

Причина — несовпадение версий пакетов в edge (на 27.10.2026):

  • postmarketos-mkinitfs 2.12.0 по умолчанию сжимает initramfs-extra в zstd (file → Zstandard compressed data);
  • postmarketos-initramfs 3.12.5 распаковывает его жёстко через gzip: init_functions.sh:655: gzip -d -c "$initramfs_extra" | cpio -iu;
  • в initramfs телефона нет zstd.

Починка без перепрошивки:

  1. В VM перепаковать в gzip: ``bash sudo cat ~/.local/var/pmbootstrap/chroot_rootfs_oneplus-bacon/boot/initramfs-extra | zstd -dc | gzip -9 > initramfs-extra.gz # 9238011 байт, md5 98be36cb2f8b35f04d7da7878224af19, внутри init_2nd.sh ``
  2. Передать на телефон в debug shell. Нюансы: - в VM включён ufw (INPUT DROP), поэтому телефон не может подключиться к VM — передаём с VM на телефон; - busybox nc -l завершается, когда закрывается его stdin, и файл обрезается. Нужен вечный stdin: ``bash # на телефоне (telnet 172.16.42.1 23): setsid sh -c "sleep 120 | nc -l -p 9003 > /tmp/ie.gz" & # в VM (nc.traditional, без -N): nc -q 5 172.16.42.1 9003 < initramfs-extra.gz # на телефоне: md5sum /tmp/ie.gz → 98be36cb... совпало ``
  3. Заменить файл и закрепить настройку: ``sh # в debug shell телефона: mount -o rw /dev/loop0p1 /boot cp /boot/initramfs-extra /boot/initramfs-extra.zst.bak cp /tmp/ie.gz /boot/initramfs-extra && sync gzip -d -c /boot/initramfs-extra | cpio -t | grep -c . # 282 файла umount /boot mount /dev/loop0p2 /mnt/r echo 'deviceinfo_initfs_extra_compression="gzip"' >> /mnt/r/etc/deviceinfo # чтобы mkinitfs при обновлениях ядра снова делал gzip umount /mnt/r reboot -f ` Ту же строку дописал в ~/.local/var/pmbootstrap/chroot_rootfs_oneplus-bacon/etc/deviceinfo` в VM.

> ⚠ При следующих apk upgrade на телефоне проверять, что /boot/initramfs-extra в gzip (file /boot/initramfs-extra), пока баг не исправят в edge. Override в /etc/deviceinfo должен это обеспечивать.

7. Система загрузилась

После перезагрузки интерфейс получил новое имя (enxb29dd9fb3571), IP снова назначен вручную. Затем:

☯

Terminal:

⌕

≡

✕
$ ssh user@172.16.42.1        # вход по ключу VM
PRETTY_NAME="Nura edge"
Linux bacon 6.16.12 #2-postmarketos-qcom-msm8974 SMP PREEMPT armv7l
Mem: 2895 MB, Swap (zram): 4342 MB
/dev/loop0p2  11.4G  1.9G  9.0G  17% /        ← rootfs сам расширился на весь userdata
/dev/loop0p1 454.2M   40M        9% /boot
systemctl is-system-running → running, упавших юнитов нет
/dev/dri/card0, /dev/dri/renderD128           ← DRM/GPU работают, ручное включение Phosh оправдалось
greetd → phoc → phrog                         ← экран входа Phosh (Phrog)

Некритичные ошибки в журнале: нет прошивки датчиков (qcom/sensors/sns.reg), qcom_smgr ... ETIMEDOUT, а также предупреждения pipewire-pulse/pulseaudio.

8. Docker

☯

Terminal:

⌕

≡

✕
# часы были 15.10 (нет RTC/NTP): выставлены по VM, иначе TLS при docker pull не пройдёт
sudo date -u -s "<время VM>"; sudo hwclock -w
sudo systemctl enable --now docker
sudo addgroup user docker

☯

Terminal:

⌕

≡

✕
$ docker info
 Server Version: 29.9.2      Storage Driver: overlayfs
 Cgroup Driver: systemd      Cgroup Version: 2
 Kernel Version: 6.16.12     Architecture: armv7l
 (без WARNING)
$ docker compose version → v5.6.1

Офлайн-тест (интернета на телефоне пока нет), образ собран из busybox самого телефона:

☯

Terminal:

⌕

≡

✕
tar -C / -c bin/busybox lib/ld-musl-armhf.so.1 lib/libc.musl-armv7.so.1 | docker import -c 'CMD ["/bin/busybox","sh"]' - local/busybox-test
docker run --rm --memory 64m --pids-limit 50 local/busybox-test /bin/busybox sh -c '...'

☯

Terminal:

⌕

≡

✕
armv7l
67108864                  ← memory.max = 64M, memcg работает
inet 172.17.0.2/16        ← bridge-сеть docker0
PID1=1                    ← PID namespace

Docker на OnePlus One работает.

9. Wi-Fi и Docker с интернетом

☯

Terminal:

⌕

≡

✕
sudo nmcli dev wifi connect "RT-5WiFi-5A20" password "<пароль>"   # SSID чувствителен к регистру: "rt-5wifi-5a20" → Error: No network found

☯

Terminal:

⌕

≡

✕
Device 'wlan0' successfully activated
wlan0  UP  192.168.0.13/24
ping 1.1.1.1 → avg 27 ms

Время: sudo timedatectl set-ntp true. С первого раза timesyncd пошёл на NTP по IPv6 и не синхронизировался; после systemctl restart systemd-timesyncd → NTPSynchronized=yes.

☯

Terminal:

⌕

≡

✕
$ docker run --rm alpine sh -c "uname -m; cat /etc/alpine-release; wget -qO- http://ifconfig.me/ip"
latest: Pulling from library/alpine ... Pull complete
armv7l
3.24.3
INTERNET_IN_CONTAINER_OK          ← за 9.8 с вместе с pull
$ docker rmi local/busybox-test   ← тестовый образ удалён

SSH по Wi-Fi: файрвол телефона пропускает 22 на всех интерфейсах (/etc/nftables.d/50_sshd.nft).

Из VM 192.168.0.13 недоступен, потому что VM маршрутизирует всё через VPN (ip route get 192.168.0.13 → via 10.28.0.1 dev tun0). С хоста или других устройств домашней сети:

☯

Terminal:

⌕

≡

✕
ssh user@192.168.0.13

10. Итог и что осталось

✅ Nura edge, ядро 6.16.12, Phosh (Phrog), Wi-Fi, Docker 29.9.2 + Compose v5.6.1 — работают.

  • [ ] Сменить пароль/PIN: passwd (сейчас 147147)
  • [ ] На хосте добавить свой ключ: ssh-copy-id user@192.168.0.13 (сейчас на телефоне только ключи VM)
  • [ ] После apk upgrade проверять file /boot/initramfs-extra → должен быть gzip (см. раздел 6)
  • [ ] В VM IP на USB-интерфейсе телефона назначается вручную (sudo ip addr add 172.16.42.2/24 dev enx…); имя интерфейса меняется при каждой загрузке

Копирование материалов разрешается только с указанием автора Roman Sakhno и индексируемой прямой ссылкой на сайт (http://itdid.ru)!

Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/sahroman.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/sahroman.

Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

Порекомендуйте эту статью друзьям:

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

  1. Кнопка:

    Она выглядит вот так: Как настроить свой компьютер

  2. Текстовая ссылка:

    Она выглядит вот так: Как настроить свой компьютер

  3. BB-код ссылки для форумов (например, можете поставить её в подписи):

Комментарии (0):

Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.