diff --git a/IMAGE.md b/IMAGE.md new file mode 100644 index 0000000..3ecf755 --- /dev/null +++ b/IMAGE.md @@ -0,0 +1,62 @@ +# Building a Mobian Image for the Pixel 3a + +## Prerequisites + +Cloning the repositories + +Kernel: https://salsa.debian.org/erebion/sdm-670-linux + +Mobian Recipes does not have the changes merged, as the kernel is not yet part of Mobian: https://salsa.debian.org/Mobian-team/mobian-recipes/-/merge_requests/113 + +Take my temporary fork of Mobian Recipes instead, for now: https://salsa.debian.org/erebion/mobian-recipes/-/tree/erebion/sargo-build?ref_type=heads + +The fork will be maintained until there are official Mobian images for the Pixel 3a. + +## Compiling the Kernel + +First `cd` to the kernel repo. + +Then: + +```bash +gbp pq import # import the patches to a patch-queue branch with the patches applied +ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- make defconfig sdm845.config sdm670.config usb-gadget.config # make kernel config, usb-gadget ist required for SSH via USB Cable +ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- make -j$(nproc) bindeb-pkg # make Kernel deb (one directory level up) +``` + +## Building the Image + +First `cd` to the Mobian repo. + +Copy the kernel deb to `devices/qcom/packages`, so that it gets installed onta the image we are about to build. + +Temporary workarounds: + +- Comment `loupe` in `include/packages-phosh.yaml` as that is currently not available in the repo. The image viewer can be installed later. +- Comment `mobian-phosh` because of a broken dependency and insert `phosh-core`, the metapackage just installs things like an XMPP client and nothing important we couldn't install later. +- Add your SSH authorized keys file to `overlays/ssh/authorized_keys`, important so you can log in later + +```bash +./build.sh -t qcom -s -u mobian | tee mobian-build.log # -s for SSH, which we need later +``` + +(If you replace `mobian` with your own username, you will have to use that one for SSH later, of course) + +Wait. It takes a while. Make sure the internet connection is stable, as the build fails if it cannot download all packages successfully. + +Note: Your SSH Host Keys currently get generated while building the image, please don't give your image to anyone else. + +## Flash to device: + +``` +fastboot --set-active --slot a +fastboot flash boot_a mobian-qcom-phosh-20240614.boot-bonito-sdc.img +fastboot flash userdata mobian-qcom-phosh-20240614.rootfs.img +fastboot erase dtbo +``` + +Boot up the device. Connect it via USB. + +## Temporary manual changes + +Documented in README.md in this repo. diff --git a/README.md b/README.md index 05ab974..2bf3d42 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,98 @@ # sargo-temp -Temporary fixes that make Mobian work on sargo \ No newline at end of file +Temporary fixes that make Mobian work on sargo. + +Please note that the MIT license does not apply to `qcom-firmware`. + +## What to do + +### Build Image + +Instructions can be found in IMAGE.md in this repo. + +### Flash image + +First flash the image. Boot the phone. + +Connect via SSH: `ssh mobian@10.66.0.1` + +Accept the host key. + +### Roll out workarounds using Ansible + +You have to have `ansible-playbook` installed. + +Go to the Ansible folder: `cd ansible` + +Roll out workarounds: `./workarounds.sh` + +Reboot phone via SSH. + +Connect to wifi. + +Rolling out the workarounds for audio requires installing packages from the repo, so we need an internet connection. + +Roll out audio workarounds: `./audio.sh` + +## Project Status + +### This Works + +- booting +- display +- touch +- modem +- plymouth +- battery/charging +- mobile data +- wifi +- torch +- suspend +- SMS (only receiving was tested, but I don’t have reason to believe sending wouldn’t work) +- vibration (udev rule needs to be added to the corresponding package) +- audio (ALSA config not packaged, but can be manually added using the playbook in this repo) +- Bluetooth™ (mac address currently has to be set manually after each boot, a udev rule for that can be manually added using the playbook in this repo) +- eSIM (supported, but needs a bit more testing) +- camera (front camera buggy, back camera works but patches not in git yet) +- GPS (needs some improvements to accuracy) + +### This Does Not Work (Soon) + +- USB host mode +- call audio (requires packaging q6voiced to get audio from the modem, but of course VoIP would already work) +- full disk encryption (no installer images yet, once the other stuff is done this will magically be there) + +### This Has An Unknown Status + +- Fingerprint Sensor +- NFC (no idea what software I could use for testing, but should work, does so on pmOS) + +### This Is Missing And Will Come Later + +- accelerometer +- magnetometer +- ambient light sensor +- barometer + +### The Main Issues That Prevail + +- A systemd unit with a hard-coded value, that has to be manually edited for now (`droid-juicer.service`) +- ALSA config not yet packaged, has to be manually copied for now +- few things to do for kernel packaging and then submitting that to Mobian +- no call audio yet, as the daemon (q6voiced) is not yet packaged, but can be manually added for now using the playbook in this repo +- simple script that brings up Bluetooth has to be added somewhere (for now this repo contains a udev rule) + +### The Sources (Use The Source, Luke) + +- My efforts of packaging a device-specific kernel: https://salsa.debian.org/erebion/sdm-670-linux (which will be used until all patches are part of upstream Linux and we can finally use a regular mainline kernel) +- `mobian-recipes`, which is used to build images: https://salsa.debian.org/Mobian-team/mobian-recipes +- `droid-juicer`, which retrieves some important files from some partitions: https://gitlab.com/mobian1/droid-juicer +- https://wiki.postmarketos.org (lovely folks, thanks for sharing everything you found out the hard way :D) + +### Thanks For All The Fish + +Huge thanks to be sdm670-linux project and flamingradian who runs the project (just one person!) to make sure the Kernel works on those devices! :) + +I don’t know how Kernel development works, so I would have never started porting without this project. + +Find that here: https://gitlab.com/sdm670-mainline/linux diff --git a/ansible/ansible.cfg b/ansible/ansible.cfg new file mode 100644 index 0000000..8c6a9ea --- /dev/null +++ b/ansible/ansible.cfg @@ -0,0 +1,6 @@ +[defaults] +ansible_ssh_user=mobian +become=true + +[ssh_connection] +pipelining = True diff --git a/ansible/audio.sh b/ansible/audio.sh new file mode 100755 index 0000000..7b8d8d3 --- /dev/null +++ b/ansible/audio.sh @@ -0,0 +1 @@ +ansible-playbook --ask-become-pass --become -i 10.66.0.1, audio.yml diff --git a/ansible/audio.yml b/ansible/audio.yml new file mode 100644 index 0000000..5e8e44b --- /dev/null +++ b/ansible/audio.yml @@ -0,0 +1,101 @@ +--- + +- hosts: 10.66.0.1 + tasks: + + ### ALSA Config ### + + - name: "Download https://gitlab.com/sdm670-mainline/alsa-ucm-conf/-/archive/master/alsa-ucm-conf-master.tar.gz" + ansible.builtin.get_url: + url: "https://gitlab.com/sdm670-mainline/alsa-ucm-conf/-/archive/master/alsa-ucm-conf-master.tar.gz" + dest: /root/alsa-ucm-conf-master.tar.gz + mode: '0440' + + - name: "Remove alsa ucm configs" + ansible.builtin.file: + path: "/usr/share/alsa/{{ item }}" + state: absent + loop: + - ucm + - ucm2 + + - name: "Unpack alsa-ucm-conf-master.tar.gz to /usr/share/alsa" + ansible.builtin.shell: | + tar xvzf /root/alsa-ucm-conf-master.tar.gz -C /usr/share/alsa --strip-components=1 --wildcards "*/ucm" "*/ucm2" + args: + chdir: /usr/share/alsa + + ### Call Audio ### + + - name: "Install gcc, git, libdbus-1-dev, libdbus-cpp-dev and make" + ansible.builtin.apt: + pkg: + - gcc + - git + - libdbus-1-dev + - libdbus-cpp-dev + - make + state: present + update_cache: true + + - name: "Clone tinyalsa repo" + ansible.builtin.git: + repo: 'https://github.com/tinyalsa/tinyalsa.git' + dest: /opt/tinyalsa + version: master + + - name: "Compile tinyalsa" + community.general.make: + chdir: /opt/tinyalsa + + - name: "Install tinyalsa" + community.general.make: + chdir: /opt/tinyalsa + target: install + + - name: "Run ldconfig" + ansible.builtin.command: /sbin/ldconfig + args: + chdir: /opt/tinyalsa + + - name: "Clone q6voiced repo" + ansible.builtin.git: + repo: 'https://gitlab.com/postmarketOS/q6voiced' + dest: /opt/q6voiced + version: master + + - name: "Compile q6voiced" + ansible.builtin.shell: + cmd: "gcc $(pkg-config --cflags dbus-1) q6voiced.c -o q6voiced -ltinyalsa -ldbus-1 -ldl" + args: + chdir: /opt/q6voiced + creates: /opt/q6voiced/q6voiced + + - name: "Create /etc/q6voiced.conf" + ansible.builtin.copy: + src: q6voiced.conf + dest: /etc/q6voiced.conf + owner: root + group: root + mode: u+rwx + force: false + + - name: "Create q6voiced-temp.service" + ansible.builtin.copy: + src: q6voiced-temp.service + dest: /etc/systemd/system/q6voiced-temp.service + owner: root + group: root + mode: u+rwx + force: true + register: unit + + - name: Reload systemd units + ansible.builtin.systemd: + daemon_reload: yes + when: unit.changed + + - name: "Enable custom service unit for q6voiced" + ansible.builtin.service: + enabled: true + name: "q6voiced-temp.service" diff --git a/ansible/files/bluetooth-mac.bash b/ansible/files/bluetooth-mac.bash new file mode 100644 index 0000000..7661542 --- /dev/null +++ b/ansible/files/bluetooth-mac.bash @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +set -x +rfkill unblock bluetooth +echo $"stdin for btmgmt" | btmgmt -i hci0 public-addr $(hciconfig hci0 | grep -o $"[[:xdigit:]:]\\{11,17\\}")' +# btmgmt requires stdin, so we feed it some garbage... diff --git a/ansible/files/bluetooth-udev.rules b/ansible/files/bluetooth-udev.rules new file mode 100644 index 0000000..5bbbeeb --- /dev/null +++ b/ansible/files/bluetooth-udev.rules @@ -0,0 +1 @@ +ACTION=="add", SUBSYSTEM=="bluetooth", KERNEL=="hci0", RUN+="/opt/bluetooth-mac.bash" diff --git a/ansible/files/droid-juicer-sdm670.service b/ansible/files/droid-juicer-sdm670.service new file mode 100644 index 0000000..c07e11c --- /dev/null +++ b/ansible/files/droid-juicer-sdm670.service @@ -0,0 +1,15 @@ +[Unit] +Description=Android vendor firmware extraction +Wants=sysinit.target make-dynpart-mappings@system_a.service +After=-.mount tmp.mount boot.mount make-dynpart-mappings@system_a.service +Before=plymouth-quit.service display-manager.service +ConditionPathExists=!/var/lib/droid-juicer/status.json + +[Service] +Type=oneshot +ExecStartPre=-/usr/bin/plymouth display-message --text="Extracting binary firmware..." +ExecStart=/usr/bin/droid-juicer +ExecStartPost=/usr/sbin/reboot + +[Install] +WantedBy=basic.target diff --git a/ansible/files/q6voiced-temp.service b/ansible/files/q6voiced-temp.service new file mode 100644 index 0000000..3b7a020 --- /dev/null +++ b/ansible/files/q6voiced-temp.service @@ -0,0 +1,12 @@ +[Unit] +Description=q6voiced routes call audio between modem and audio device +After=dbus.service + +[Service] +EnvironmentFile=/etc/q6voiced.conf +ExecStart=/opt/q6voiced/q6voiced hw:${q6voice_card},${q6voice_device} +User=nobody +Group=audio + +[Install] +WantedBy=multi-user.target diff --git a/ansible/files/q6voiced.conf b/ansible/files/q6voiced.conf new file mode 100644 index 0000000..88a20b4 --- /dev/null +++ b/ansible/files/q6voiced.conf @@ -0,0 +1,2 @@ +q6voice_card=0 +q6voice_device=4 diff --git a/ansible/files/qcom-firmware b/ansible/files/qcom-firmware new file mode 100644 index 0000000..3ce6ad7 --- /dev/null +++ b/ansible/files/qcom-firmware @@ -0,0 +1,64 @@ +#!/bin/sh +set -e + +PREREQS="" +case $1 in + prereqs) echo "${PREREQS}"; exit 0;; +esac + +. /usr/share/initramfs-tools/hook-functions + +# Fetch the device parameters +for x in $(cat /proc/cmdline); do + case $x in + mobile.qcomsoc=*) QCOMSOC="${x#mobile.qcomsoc=}" ;; + mobile.model=*) MODEL="${x#mobile.model=}" ;; + esac +done + +if [ "${QCOMSOC}" ] && [ "${MODEL}" ]; then + # Special case for the OnePlus 6 & 6T: both models use the same + # firmware folder: sdm845/oneplus6 + if [ "${MODEL}" = "enchilada" ] || [ "${MODEL}" = "fajita" ]; then + MODEL="oneplus6" + fi + # Special case for the "fp4" (Fairphone 4): this model uses the + # "fairphone4" firmware folder + if [ "${MODEL}" = "fp4" ]; then + MODEL="fairphone4" + fi + # Special case for "bonito" (Pixel 3a XL): this model uses the "sargo" (Pixel 3a) firmware folders + if [ "${MODEL}" = "bonito" ]; then + MODEL="sargo" + fi + + FW_LIST="${QCOMSOC}/${MODEL}/adsp.mbn \ + ${QCOMSOC}/${MODEL}/cdsp.mbn \ + ${QCOMSOC}/${MODEL}/ipa_fws.mbn" + + FW_RADIO="ath10k/WCN3990/hw1.0/board-2.bin \ + qca/${MODEL}/crnv21.bin \ + qca/crbtfw21.tlv \ + qca/crnv21.bin" + + if [ "${QCOMSOC}" = "qcom/sdm845" ]; then + FW_LIST="${FW_LIST} \ + ${QCOMSOC}/${MODEL}/a630_zap.mbn" + elif [ "${QCOMSOC}" = "qcom/sm7225" ] || [ "${QCOMSOC}" = "qcom/sdm670" ]; then + FW_LIST="${FW_LIST} \ + ${QCOMSOC}/${MODEL}/a615_zap.mbn" + fi + + FW_LIST="${FW_LIST} ${FW_RADIO}" + + for fwfile in ${FW_LIST}; do + if [ -f "/lib/firmware/updates/${version?}/${fwfile}" ] || + [ -f "/lib/firmware/updates/${fwfile}" ] || + [ -f "/lib/firmware/${version}/${fwfile}" ] || + [ -f "/lib/firmware/${fwfile}" ]; then + add_firmware "${fwfile}" + else + echo "I: Ignoring missing firmware ${fwfile}" + fi + done +fi diff --git a/ansible/workarounds.sh b/ansible/workarounds.sh new file mode 100755 index 0000000..5bad242 --- /dev/null +++ b/ansible/workarounds.sh @@ -0,0 +1 @@ +ansible-playbook --ask-become-pass --become -i 10.66.0.1, workarounds.yml diff --git a/ansible/workarounds.yml b/ansible/workarounds.yml new file mode 100644 index 0000000..226a4e5 --- /dev/null +++ b/ansible/workarounds.yml @@ -0,0 +1,67 @@ +--- + +- hosts: 10.66.0.1, + + tasks: + + ### Various Small Fixes ### + + - name: "Copy /usr/share/initramfs-tools/hooks/qcom-firmware" + ansible.builtin.copy: + src: qcom-firmware + dest: /usr/share/initramfs-tools/hooks/qcom-firmware + owner: root + group: root + mode: u+rwx + force: true + + # Has been merged, but package did not have a new release yet + # https://salsa.debian.org/DebianOnMobile-team/qcom-phone-utils/-/merge_requests/2 + + - name: "Copy custom droid-juicer service unit" + ansible.builtin.copy: + src: droid-juicer-sdm670.service + dest: /etc/systemd/system/droid-juicer-sdm670.service + owner: root + group: root + mode: u+rwx + force: true + register: unit + # Original unit has a hardcoded value, we'll just use our own temporarily + # https://gitlab.com/mobian1/droid-juicer/-/issues/4 + + - name: Reload systemd units + ansible.builtin.systemd: + daemon_reload: yes + when: unit.changed + + - name: "Disable regular service unit for droid-juicer" + ansible.builtin.service: + enabled: false + masked: true + name: "droid-juicer.service" + + - name: "Enable custom service unit for droid-juicer" + ansible.builtin.service: + enabled: true + name: "droid-juicer-sdm670.service" + + ### Bluetooth ### + + - name: "Copy /opt/bluetooth-mac.bash" + ansible.builtin.copy: + src: bluetooth-mac.bash + dest: /opt/bluetooth-mac.bash + owner: root + group: root + mode: u+rwx + force: true + + - name: "Copy /etc/udev/rules.d/bluetooth.rules" + ansible.builtin.copy: + src: bluetooth-udev.rules + dest: /etc/udev/rules.d/bluetooth.rules + owner: root + group: root + mode: u+rw + force: true