OnePlus 6 (oneplus-enchilada)/Multi Booting and Custom Partitioning
WARNING: THIS PROCESS CAN BRICK YOUR PHONE IF DONE INCORRECTLY! IF YOU DON'T FEEL COMFORTABLE RECOVERING YOUR PHONE VIA EDL MODE, DO NOT ATTEMPT THIS!!! IN SOME CASE EDL IS NOT ENOUGH AND YOU WILL NEED TO USE MSMDOWNLOADTOOL (WINDOWS APP) SEE FACTORY RESET SECTION |
Currently, there are 2 UEFI implementations for these devices (Renegade Project or U-Boot) (See Qualcomm_SDM845_(qualcomm-sdm845)) |
Custom Partitioning
Prerequisites
A custom recovery containing sgdisk, parted, or other partitioning tools.
It is easiest to use these from Jumpdrive or a netbooted pmOS image.
If U-Boot or the Renegade Project is already installed then putting the device in USB Mass Storage mode allows partitioning from another device like a PC.
Keeping Android
Shrinking the UserData partition is required to free up space for any custom partition.
1. Shrink UserData in the partition table.
TODO: Figure out the minimum size of the UserData partition. |
2. Boot up to TWRP to format UserData how Android wants it.
After that you are ready to create a custom partition.
Removing Android
On the OnePlus 6, it is safe to wipe those android partition /dev/sda13-17 (system_a , system_b , odm_a , odm_b , userdata)
without any harm being done to the bootloader.
On OnePlus 6T, you can only safely remove /dev/sda17 (userdata)
.
Partitioning
Creating Custom Partition for Subpartitions
As of now, pmOS only support subpartitions on the system* (any partition that has prefix of system) partition or userdata partition. Also, system* and userdata have to be labeled in the GPT partition table. The postmarketOS initramfs checks those partiton label via the GPT partition table, not the filesystem. Therefore, the partitions have to have a system* prefix in the label. However, in order to not confuse the bootloader: DO NOT LABEL THE PARTITION WITH A NAME LIKE system system_a system_b system_c userdata. For example: systempmos is a perfect name that would work. |
1. Create a partition named system{suffix}. (Replace {suffix} with the real partition name.)
Creating Custom Partition to Use the Whole Storage Device
pmOS_boot and pmOS_root have to be labelled in the filesystem. The postmarketOS initramfs checks these partiton labels via the filesystem, not the GPT partition table. However, it is recommended to label those partition in the GPT partition table if you want them to be flashable via fastboot. (It doesn't matter what you have labelled them in partition table as long as fastboot is able to read those labels.) |
Disk images generated by pmbootstrap are already labeled with the filesystem labels. |
1. Create a new boot partition labeled pmOS_boot
in the file system.
2. Create a new root partition that labeled pmOS_root
in the file system.
Multi-Booting
There are a few configurations for multi-booting:
- #UEFI Implementation Only: Multi-booting Multiple UEFI OSes.
- #UEFI Implementation + A/B slot: Multi-booting Multiple UEFI OSes alongside Android,
- #A/B slot Only: Multi-booting pmOS alongside Android.
UEFI Implementation
As of now most of UEFI implementations cannot replace the stock bootloader due to chain of trust, thus they usually are chainloaded from the stock bootloader. |
1. Flash the boot.img of the UEFI Implementation in to slot b (boot_b)
After that, the UEFI implementation should boot if you selected slot b.
UEFI Implementation + A/B slot
Android should be installed on the device's slot A already. You need to fellow #Shrink UserData to free some space for the custom partition.
A/B slot Only
Currently, the dedicated port of pmOS would generate boot.img by default so that pmOS can be directly booted from the stock bootloader.
There are two ways to run pmOS in this configuration: In a dedicated partition or as a stowaway (sharing userdata with Android).
Before flashing pmOS's Subpartitions/Stowaway/boot/root partition to your device, you have to:
1. Flash pmOS's boot.img into slot B
2. fastboot erase dtbo_b
If you don't want to do custom partitioning then flash pmOS subpartitions to system_b, but you will be limited to the the small partition size of system_b. If you want a bigger partition then create a custom partition. |
Switching OS
UEFI
You should able to switch OSes via the boot menu of your UEFI implementation boot menu or bootloader (if you use a bootloader like systemd-boot to manage multiple UEFI OSes).
Slot A/B
Switch to Slot A
$ fastboot set_active a
$ fastboot reboot
Switch to Slot b
$ fastboot set_active b
$ fastboot reboot
Check Current Slot
$ fastboot getvar current-slot
Switching Slot From pmOS
These instructions may not work if pmOS is installed as a UEFI OS. |
Switch to slot A
$ qbootctl -s a
Switch to Slot b
$ qbootctl -s b
Check Current Slot
$ qbootctl -c
Switching Slot From Android
This requires root access to work. |
There are a Android apps like Switch My Slot .
UEFI implementation
Depend on your UEFI implementation, there might be a option for switching the slot in the boot menu.
Tips and Tricks
UEFI Implementations
U-Boot
There is boot menu in U-Boot. However, this isn't for booting multiple UEFI OSes. You might need to make your own custom boot menu or use a bootloader like systemd-boot for managing multiple UEFI OSes.
TODO: Decide whether to only document U-Boot. |
Renegade Project
The Renegade Project can boot pmOS without a UEFI runtime. (See bootmenu).
Non-Functional Audio
Booting pmOS under the Renegade Project UEFI Implementation via the normal UEFI way is known to have broken audio. However, it is possible to boot pmOS without the UEFI runtime to getting around the issue.
TODO: Describe how to boot without the runtime. |
pmOS_boot Doesn't Appear in the Boot Menu
For some reason Renegade fails to read fat32 flashed from an image made by pmbootstrap. To fix this:
1. Backup anything in the boot partition.
2. Reformat the boot partition.
3. Restore everything back into the boot partition.
4. Modify the fstab to have the new UUID of the reformatted boot partition
5. Regenerate the boot config via mkinitfs
Android
Upgrading/Flashing Android
WARNING: Make sure you selected the right slot before you upgrading/flashing android. |
If you decided to upgrade Android or flash another Android ROM it is always a good idea to backup system_b
and boot_b
because Android might wipe the partitions and anything on the other slot during the process of upgrading/flashing. Generally speaking Android wont touch custom partitions.
Unbricking/factory reset
Factory reset to original stock OS (old version)
Download MsmDownloadTool (windows app), original stock OS and windows drivers from https://xdaforums.com/t/tool-msmdownloadtool-v4-0-international-oxygen-os-5-1-5.3798892/.
Using a virtul machine won't work unless you do passthrough https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF#USB_controller. Note it was not tested.
Other option is to use hirens live https://www.hirensbootcd.org/.
Update stock OS (Oxygen OS)
After it is recommended to update Oxygen OS to the latest you can download it from https://service.oneplus.com/us/search/search-detail?id=2096229.
Then using https://github.com/ssut/payload-dumper-go or similar tool you can extract the files.
You can update with fastboot from bootloader/fastboot mode see https://wiki.postmarketos.org/index.php?title=OnePlus_6_(oneplus-enchilada)&oldid=66185#Upgrading_firmware_without_Android_installed.
Or you can update using this edl script:
#!/bin/sh
COMMAND="dialog"
if ! command -v $COMMAND &> /dev/null; then
echo "\"$COMMAND\" package is not installed. Please install it to proceed."
exit 1
fi
commands=(
"system_a system.img"
"system_b system.img"
"vendor_a vendor.img"
"vendor_b vendor.img"
"boot_a boot.img"
"boot_b boot.img"
"dtbo_a dtbo.img"
"dtbo_b dtbo.img"
"abl_a abl.img"
"abl_b abl.img"
"aop_a aop.img"
"aop_b aop.img"
"bluetooth_a bluetooth.img"
"bluetooth_b bluetooth.img"
"cmnlib_a cmnlib.img"
"cmnlib_b cmnlib.img"
"cmnlib64_a cmnlib64.img"
"cmnlib64_b cmnlib64.img"
"devcfg_a devcfg.img"
"devcfg_b devcfg.img"
"dsp_a dsp.img"
"dsp_b dsp.img"
"fw_4j1ed_a fw_4j1ed.img"
"fw_4j1ed_b fw_4j1ed.img"
"fw_4u1ea_a fw_4u1ea.img"
"fw_4u1ea_b fw_4u1ea.img"
"hyp_a hyp.img"
"hyp_b hyp.img"
"keymaster_a keymaster.img"
"keymaster_b keymaster.img"
"LOGO_a LOGO.img"
"LOGO_b LOGO.img"
"modem_a modem.img"
"modem_b modem.img"
"oem_stanvbk oem_stanvbk.img"
"qupfw_a qupfw.img"
"qupfw_b qupfw.img"
"storsec_a storsec.img"
"storsec_b storsec.img"
"tz_a tz.img"
"tz_b tz.img"
"vbmeta_a vbmeta.img"
"vbmeta_b vbmeta.img"
"xbl_a xbl.img"
"xbl_b xbl.img"
"xbl_config_a xbl_config.img"
"xbl_config_b xbl_config.img"
)
dialog --title "Confirmation" --yesno "Do you want to confirm each flashing?" 7 60
response=$?
function error {
echo ""
echo -e "\e[31;5mERROR SOMETHING FAILED\e[0m"
echo ""
exit 1
}
trap 'error' ERR
for i in "${!commands[@]}"; do
cmd=${commands[$i]}
function flash {
echo ""
echo -e "\e[1;34;5mFlashing ${cmd} $(($i + 1))/$((${#commands[@]}))\e[0m"
echo ""
edl w $cmd
}
if [ "$response" -eq 0 ]; then
inp=$(dialog --menu "Flash ${cmd} $(($i + 1))/$((${#commands[@]}))?" 0 0 0 \
1 "Yes" \
2 "Yes and don't ask anymore" \
3>&1 1>&2 2>&3)
if [ $? -ne 0 ]; then
exit 1
fi
case "$inp" in
1)
flash
;;
2)
response=1
flash
;;
esac
else
flash
fi
done
echo -e "\e[1;34;5mSuccessfully flashed all\e[0m"
echo -e "\e[1;34;5mRebooting...\e[0m"
echo ""
edl reset