hackiosx r/hackios GitHub

Port it to your phone

On a Snapdragon phone, almost everything that is specific to the Redmi Note 10 Pro sits in three places: the device tree generator, the boot shim, and the board drivers in the kernel patches. This page walks through all three and shows where to look up your phone's values.

Before you touch anything, back up your phone. Boot a recovery such as OrangeFox or TWRP and pull at least persist, modemst1, modemst2, fsg, fsc, boot, dtbo and vbmeta. Some of these hold calibration data that is unique to your phone and can't be downloaded anywhere. Keep them out of git.

Check the compatibility page first. This guide assumes a Snapdragon chip with UFS storage and a bootloader that supports fastboot boot.

Step 0: get your phone's hardware map

Everything you need to know about the hardware is already on the phone, in the device tree Android booted with. Boot a recovery with adb (or use a rooted Android) and copy it to the PC:

adb shell cat /sys/firmware/fdt > live.dtb
adb shell cat /proc/iomem > iomem.txt
dtc -I dtb -O dts -o live.dts live.dtb      # dtc is in the device-tree-compiler package

live.dts is a big text file. Every value below comes from searching it. You'll also want your phone's kernel source (Xiaomi, OnePlus and others publish it on GitHub) for anything the device tree doesn't spell out, like the touch controller's protocol.

Also unpack your stock boot.img, because the shim reuses its DTB:

python3 tools/unpack_bootv2.py backup/boot.img dtb/boot_unpacked

1. The device tree generator: tools/mkadt.py

XNU learns about the hardware from an Apple Device Tree. mkadt.py writes one from the constants at the top of the file. These are the ones to change:

ConstantWhat it isWhere to find it in live.dts
HIGH_PHYS_BASE, HIGH_MEM_SIZEThe RAM the kernel may useThe memory node, plus every entry under reserved-memory. Pick a range with no carve-outs in it. On sweet that's the whole bank above 4 GB.
GICD, GICRInterrupt controllerinterrupt-controller@... with compatible = "arm,gic-v3". The first two reg entries.
FB, FB_SIZEThe screen buffer the bootloader leaves oncont_splash_region (sometimes splash_region) under reserved-memory
FB_W, FB_H, FB_STRIDEPanel resolution and bytes per lineThe panel node (qcom,mdss_dsi_...), qcom,mdss-dsi-panel-width and -height. Stride is usually width x 4.
UFS, UFS_SIZEThe storage controllerufshc@..., the reg named ufs_mem
TIMEBASE, VTIMER_INTIDSystem timerThe timer node with arm,armv8-timer. The frequency is almost always 19.2 MHz on Snapdragon. The virtual timer is the third interrupt; a PPI number n becomes INTID 16 + n.
CPU nodesHow many cores, and their hardware IDsThe cpus node: each core's reg (its MPIDR). sweet has 8 cores at 0x000 to 0x700; the loop in mkadt.py builds them as core << 8.

2. The boot shim: shim/

The shim is the small program the bootloader starts. It has its own copy of a few addresses, because it runs before any device tree is read:

Two kernel patches also draw on the screen very early, before the device tree is parsed: 0010-sweet-early-framebuffer-debug and 0012-sweet-keep-debug-console-after-ttbr0. They hard-code the framebuffer address and the 1080 x 2400 size. Change those too, or the early boot messages will land in the wrong place.

3. The board drivers: xnu/patches/

The kernel is Apple's source plus a numbered series of patches that GitHub Actions applies in order. Most patches are generic. These are the ones that know about the board:

PatchWhat to check
0060-sweet-keys-touch-driversButtons: the PMIC bus (SPMI) addresses and the register offsets of the power key (PON) and volume keys. Touch: which I²C serial engine the touch chip hangs off, its I²C address, and its reset and interrupt GPIOs. Search live.dts for your touch chip's node (goodix, focaltech, novatek, synaptics, ...).
0062-sweet-touch-power-batteryThe power rail the touch chip needs (on sweet, regulator ldoc11 voted through RPMh). Your phone's touch node names its supply, like vdd-supply or avdd-name.
0063-sweet-goodix-geni-packingThe Goodix GT9896 touch protocol. A different touch chip needs a different protocol here. The Linux driver for your chip in the vendor kernel source shows the register layout.
0061-sweet-iphone-x-display-sizeCenters the real panel inside the 1125 x 2436 screen that iOS sees, and maps touch coordinates. Uses 1080 x 2400 in a few places.
0072 to 0077 (USB)Optional. The USB controller addresses for the live log over USB. You can skip these at first and read the log from recovery.

The patches add new files to XNU, such as bsd/dev/sweet_touch.c. To change one, apply the series to an xnu-8796 tree, edit the file, and regenerate that patch with diff -u. Before you spend a CI run, tools/xnu-cc.py can compile a single file locally using the commands from a previous CI log.

4. Boot arguments

The command line is baked into the payload by tools/mkpayload.py (see the README for the full line). For a first boot on a new phone, use cpus=1, and add sweettouch=0 sweetkeys=0 until those drivers are adapted. Raise cpus once the kernel is stable.

5. Build and boot

From here the steps are the same as on sweet and are in the README: build the kernel on GitHub Actions, build the iOS root image from the iPhone X IPSW, pack the boot image, flash the root to userdata, then fastboot boot the shim.

Take it in stages. You can test the shim and kernel before you flash anything: boot the shim alone, and it prints its own diagnostics to the screen.

  1. Shim text on screen. Your framebuffer address is right.
  2. Kernel messages scroll. Memory, interrupts and timer are right. If the phone reboots instantly, the memory range probably overlaps a protected carve-out.
  3. The UFS driver finds the disk. Then iOS starts from userdata. This is the point where you flash the root image.
  4. Apple logo, then the lock screen (after several minutes). Touch and buttons come last.

When something crashes, read the log from recovery with tools/sweet-log-pull.sh, and tools/sweet-crash.py turns crash reports into function names. NOTES.md has every problem sweet ran into along the way, and most of them will show up on your phone too.

Got further on your phone? Post it on r/hackios. Which chip, which step you reached, and what you had to change helps everyone after you.