Before getting started with the port, a few things needs to be sorted out, either because they are mandatory or will get very useful down the road.
- Unlock the bootloader
- Rooting with magisk
- Flashing TWRP
- Decrypting userdata
I’ll only cover the parts that weren’t clear for me at first glance and leave as an exercise to the reader to figure the rest.
Make a backup here. Not later.
Unlock the bootloader follow this tutorial
You can download samsung FW update here.
Create a tar archive containing boot.img and vbmeta.img exracted from the FW update you downloaded previously.
In magisk app, patch the tar archive, reboot to download mode then use odin (or heimdall if your PC is running Linux) and flash your tar archive in the AP slot.
Download my TWRP image from here then flash it in the AP slot.
Boot TWRP (poweroff -> plug to a computer + press volume up + power button)
In TWRP, first go to Advanced->Terminal and run
multidisabler then format /data make sure to have it decrypted.
You can restore your backup here.
1. GKI in a nutshell
During the port I had a lot of trouble understanding how the GKI (Generic Kernel Image) was supposed to work and what was going where.
As far as my understanding goes, the GKI is supposed to be a base that manufacturers / vendor use and apply their changes on top of.
The kernel Image gets to the boot.img while the modules go into vendor_boot.img, both partitions contains a ramdisk, boot.img contains a first_stage_ramdisk and the vendor_boot.img the second stage.
2. Halium boot
Once I had this figured out I began editing the main boot.img, I choose to have all the drivers builtin instead of repacking the vendor_boot.img.
Since the device should support it, I decided to follow the standalone kernel porting method.
This method consist of repacking a new boot.img containing the edited kernel Image with halium changes and halium ramdisk. The ramdisk is responsible of preparing the partitions, mounting the ubuntu touch GSI (Generic System Image) as well as ubuntu touch rootfs. Both are contained within the userdata partition (this is why we had to decrypt it in TWRP so halium ramdisk can access it).
The first issue I stumbled upon was that the kernel cmdline is set and enforced by the bootloader, but ubuntu touch requires
console= to be set to an actual tty to boot, where in this case the console parameter was set to null. After discussing with @NotKit on UBport telegram channel I picked a printk commit which enforces console but since I don’t like editing kernel libraries, I ended up having the kernel enforce the full cmdline including my changes.
Second issue, vndkservicemanager doesn’t work well when SELinux is not prepared by the first stage ramdisk (which we don’t have anymore since halium-boot.img was flashed in place of android’s boot.img), @NotKit shared an edited vndkservicemanager which overrides android’s.
A few firmware issues later (which I embedded into the kernel directly) I finally see Unity8 splashscreen BUT since the Fold has 2 displays, and, unity8 doesn’t currently support multiple displays properly, @NotKit shared an edited version of unity8 shell that works around this issue.
3. Fixing issues – Ubuntu touch overlay
At first glance many things where not working… No WiFi, no GSM, no cameras, no cellular data, no audio, wrong orientation, defaulting to desktop modemintead of tablet and so on. As of now I haven’t got around all of those issues but I’ll share how I fixed some of them.
For audio and GSM, a few configuration files overlayed on the system where enough (see the relevant link for the halium overlay sources) and those issues where gone.
Making WiFi works was a troublesome experience. By checking similar SoC overlays with existing ubuntu touch ports, the first thing required is to load the IPA firmware, good, but that’s not enough, in AOSP a kernel module is loaded responsible for setting up the wlan chardev (/dev/wlan) but this module isn’t built by the kernel. It turns out that the module was simply missing in the kernel sources distributed by samsung… After searching github I came across this kernel for an asus device with the same SoC and it turns out that it pulls a few commits for the wlan driver.
WiFi works, but bluetooth was lost in the battle….
And that’s all I got working for now.
4. Remaining issues
Ubuntu touch requires apparmor in order to function properly, cameras are likely to be affected by apparmor not working. Since the second stage ramdisk in vendor_boot requires SELinux for it’s setup, but, LSM (Linux Security Module) can’t stack multiple major modules Apparmor is currently disabled because SELinux is loaded first.
After pulling the driver to make wlan work, bluetooth isn’t starting anymore.
Cellular data doesn’t work, I am currently thinking that it could be caused by a setup issue or a missing driver issue (like the wlan one) or both.
Orientation and desktop mode are likely due to the system image build.prop being set to Generic/halium_arm64 but since ubuntu-session and deviceinfo requires build.prop to be set to a specific device so they can use the proper device configuration files.
5. Additional Notes
Special thanks to :
@NotKit for his precious help with the port.
Everyone involved with Ubuntu Touch.
Useful links and sources
Samsung Z Fold 3 sources (kernel, TWRP and ubuntu touch overlay)