Get started
Unlock your PF1007L and get root ADB
On this page
- Before you start
- What you need
- The map
- Step 1: Set up your computer
- Step 2: Build U-Boot
- Step 3: Get fel-sdboot.sunxi
- Step 4: Make the FEL card
- Step 5: Show the frame's storage to Windows
- Step 6: Back up the storage
- Step 7: Make the patch from your backup
- Step 8: Apply the patch
- Step 9: First boot with ADB
- When you finish
- If something goes wrong
- Related
This guide is for owners of a PF1007L photo frame who can use a Linux shell and PowerShell. When you finish, the frame boots normally but accepts root ADB connections, and you have a verified backup of its storage. No soldering, and you never open the case.
Do this guide first. After it, go to Build the kiosk and set up a frame. Provisioning also needs a running server, which you set up with Install the frame server. The server does not depend on this guide, so you can do it before or after.
Before you start
Warning
This can brick the frame. You write to its storage. Follow the backup step before any write, and check each write the way the guide says.
- The backup holds the frame's private credentials. The image of the storage includes the vendor's device certificate. Keep
backups/out of Git, and never upload or share it. The repository's.gitignorealready ignores it. - Root ADB has no password. After this guide, anyone who can reach the frame's network port 5555 has full control. Provisioning shows how to restrict it with
ADB_ALLOW. - Only the January 2026 firmware was tested. The one-sector ADB method was verified on firmware
AEEZO/astar_m86_8723cs:6.0.1/MOB30R/20260113:eng/test-keys. Other firmware may store files in different places. The patch is made from your own backup, so it adapts, but nothing here is verified on other builds. Iftools/derive-sector.shstops with an error, stop and do not guess. - Only modify hardware you own.
What you need
- A PF1007L frame, with its USB-C cable. The frame takes power from USB.
- Windows 10 or 11 with WSL2 (Ubuntu 22.04 or later). The scripts call
powershell.exeand PowerShell disk commands, so this guide does not work on a plain Linux machine without changes. - usbipd-win 4 or later on Windows.
- A microSD card, any size. Its contents survive. The guide changes only bytes 8 KiB to 16 KiB.
- About 16 GB of free disk space for the backup, and patience. The backup takes about 90 minutes.
In this guide, WSL means a shell in your Linux distribution. PowerShell means an Administrator PowerShell on Windows. <repo> means the folder holding this repository, written the way Windows sees it.
Note
The .ps1 scripts write backups\ next to themselves and read patch\ there. If your clone lives inside the WSL file system, the Windows path looks like \\wsl.localhost\Ubuntu\home\you\frame. Writing a 15 GB image over that path is slow. Cloning to a Windows drive such as /mnt/d/frame gives both sides the same fast folder. Neither layout has been compared.
The map
Nine steps. The backup in step 6 is not optional, and nothing writes to the frame's storage before it.
flowchart TD
A["1. Set up your computer"] --> B["2. Build U-Boot"]
B --> C["3. Get fel-sdboot.sunxi"]
C --> D["4. Make the FEL card"]
D --> E["5. Show the frame's storage to Windows"]
E --> F["6. Back up and verify the storage"]
F -->|"backup verified"| G["7. Make the patch from your backup"]
G --> H["8. Apply the patch"]
H --> I["9. First boot with ADB"]
F -.->|"not verified"| X["Stop. Do not write anything."]
Each step ends with a You are here box. If what you see does not match, stop and use If something goes wrong.
Step 1: Set up your computer
-
In WSL, install the tools:
sudo apt install -y sunxi-tools adb e2fsprogs fdisk -
Allow your user to talk to the frame in FEL mode (the Allwinner USB recovery mode):
echo 'SUBSYSTEM=="usb", ATTR{idVendor}=="1f3a", ATTR{idProduct}=="efe8", MODE="0666"' | sudo tee /etc/udev/rules.d/61-sunxi-fel.rules sudo udevadm control --reload -
In PowerShell, tell usbipd it may share the frame's two USB identities with WSL automatically:
usbipd policy add --effect Allow --operation AutoBind --hardware-id 1f3a:efe8 usbipd policy add --effect Allow --operation AutoBind --hardware-id 1f3a:10011f3a:efe8is FEL mode.1f3a:1001is Android with ADB on. -
In PowerShell, stop Windows from mounting the frame's partitions. First note the current value so you can restore it later:
Get-StorageSetting | Select NewDiskPolicy Set-StorageSetting -NewDiskPolicy OfflineAllWrite down the value the first command prints. You put it back in When you finish.
-
Copy
.env.exampleto.envin the repository root. You fill inUSBIP_BUSIDin step 5. Provisioning explains every key.cp .env.example .env
You are here
Your computer has the tools, the udev rule and the usbipd policy. Windows no longer mounts new disks automatically. Nothing has touched the frame.
Step 2: Build U-Boot
The frame's storage is not visible to your PC while Android runs. You temporarily boot a small program called U-Boot that shows the storage as a USB disk. The repository holds the patch for it but no binaries, so you build them.
The build needs an ARM cross-compiler.
-
Install the build tools (Debian or Ubuntu package names):
sudo apt install -y gcc-arm-linux-gnueabihf bison flex swig device-tree-compiler \ python3-pyelftools python3-setuptools libgnutls28-dev uuid-dev git makeThe
python3-packages are U-Boot's own build dependencies. Project code uses no Python. -
Build it, using a work directory outside the repository:
uboot/build.sh ~/frame-uboot-build
The script clones U-Boot v2025.01, applies the patch and writes u-boot-sunxi-with-spl.bin and sunxi-spl-ck5.bin into uboot/. It prints their SHA-256 hashes. The first run needs network access to source.denx.de. See uboot/README.md for what the patch changes.
Note
The build is not bit-for-bit reproducible. The binaries embed a build timestamp, so two builds from the same source have different hashes.
You are here
uboot/ holds u-boot-sunxi-with-spl.bin and sunxi-spl-ck5.bin, and the script printed a SHA-256 for each.
Step 3: Get fel-sdboot.sunxi
fel-sdboot.sunxi is a tiny boot program that puts the frame into FEL mode and keeps it there. It comes from linux-sunxi/sunxi-tools. Its license differs from this repository's, so it is not included.
-
Get the file from the sunxi-tools repository. If the repository does not hold a ready-made copy, build it. The on-device programs are not built by default, and need an ARM bare-metal compiler (
arm-none-eabi-gcc). Install it the same way as the U-Boot tools in step 2:git clone https://github.com/linux-sunxi/sunxi-tools ~/sunxi-tools make -C ~/sunxi-tools target-tools CROSS_COMPILE=arm-none-eabi-Not verified
This build command was not checked. The linux-sunxi wiki page on sunxi-tools describes
fel-sdboot. -
Copy the file to
uboot/fel-sdboot.sunxi. -
Check its SHA-256:
sha256sum uboot/fel-sdboot.sunxiwrite-sd.ps1accepts only this hash, the one the procedure was tested with:19db8994363b1464a1de82e1c90ab63c5a985d1c96b57403d039d69bfff39f14If your hash differs, the script stops with
fel-sdboot.sunxi hash mismatch. A different build of sunxi-tools produces a different file. Check that your file is the realfel-sdbootfrom the upstream source, then edit$ImageShaat the top ofwrite-sd.ps1to your hash. Do not skip the check.
You are here
uboot/fel-sdboot.sunxi exists, and its hash is either the one above or a hash you checked against upstream and wrote into write-sd.ps1.
Step 4: Make the FEL card
The frame's boot ROM looks at the microSD slot before the internal storage. With this card in the slot, pressing RESET puts the frame into FEL mode and keeps it there. Pressing RESET alone also enters FEL, but it times out after a second or two, which is too short for this procedure.
-
Put the microSD card in your PC.
-
In PowerShell, find the card:
Get-DiskNote its Number and its exact Size in bytes. Check this twice. The script writes to the disk number you give it.
-
Write the file:
powershell -ExecutionPolicy Bypass -File <repo>\write-sd.ps1 -DiskNumber <number> -ExpectSize <size in bytes>The script refuses to run unless the disk is a USB disk of exactly that size. It first backs up the card's first 16 MiB to
backups\sd-<size>-first-16MiB.bin, writes the file at the 8 KiB offset, and reads it back. You seeOK: fel-sdboot.sunxi written at offset 8192 and verified. -
Put the card in the frame's microSD slot.
From now on: RESET with the card in enters FEL mode (1f3a:efe8). RESET with the card removed boots Android normally.
You are here
The script printed OK: fel-sdboot.sunxi written at offset 8192 and verified. and the card is in the frame.
Step 5: Show the frame's storage to Windows
-
Plug the frame's USB-C port directly into your PC, not through a hub.
-
In PowerShell, find the frame's bus ID:
usbipd listThe frame is
1f3a:efe8if it is in FEL mode. Press the RESET pinhole with the card in if it is not. -
Put the bus ID in
.env:USBIP_BUSID=<bus id from usbipd list>A bus ID looks like
1-13. The script refuses anything else. -
In WSL, run:
scripts/boot-ums.sh -
Press the frame's RESET button.
The script waits up to 30 minutes for FEL mode and attaches the frame to WSL. It runs a first DRAM set-up pass, because the first memory set-up after power-on fails and the second succeeds. Then it loads U-Boot. U-Boot shows the storage as a USB disk named Linux UMS disk 0. The script ends with eMMC visible to Windows and a table with a disk number and size.
Rules for this step:
-
Never attach
1f3a:1010(U-Boot's disk) with usbipd. The disk drops and does not recover. Never runusbipd attach --auto-attachon this bus ID. - Cancel every "format this disk" prompt. The partition table mislabels the Android data partition as FAT32.
- If the disk disappears, U-Boot returns to FEL mode on its own, or its 16 second watchdog resets the frame into FEL mode. Run
scripts/boot-ums.shagain. Press RESET only if FEL does not answer.
You are here
The script printed eMMC visible to Windows and a table with a disk number and a size of 15758000128. Windows shows the disk offline. You have not written anything to it.
Step 6: Back up the storage
Warning
Do not go on until the backup is verified.
In PowerShell, while the disk is up:
powershell -ExecutionPolicy Bypass -File <repo>\backup-emmc.ps1
The script marks the disk read-only, writes backups\emmc-full.img, then reads the whole disk a second time and compares the SHA-256 of both passes. At about 5.7 MB/s, each pass takes around 45 minutes. It ends with OK: ... verified by two independent reads. and writes backups\emmc-full.img.sha256.
The script expects a 15,758,000,128 byte disk, the size of the tested unit. If yours differs, pass -ExpectSize <bytes>.
If the second pass is interrupted, run verify-backup.ps1 instead. It compares the image with the disk up to the user-data partition (about 2 GB, 7 minutes). If the disk drops, run it again with -Start <byte offset> from the last progress line:
powershell -ExecutionPolicy Bypass -File <repo>\verify-backup.ps1
Then check the system partition read-only in WSL. Expect only the message padding at end of inode bitmap, which is normal for Android images:
fdisk -l backups/emmc-full.img
Find the start sector of partition 7 (system), then:
dd if=backups/emmc-full.img of=system.img bs=512 skip=<start sector> count=<sectors>
e2fsck -fn system.img
rm system.img
You are here
backups\emmc-full.img and backups\emmc-full.img.sha256 exist, the script printed OK: ... verified by two independent reads. (or verify-backup.ps1 passed), and e2fsck -fn found nothing but padding at end of inode bitmap. Copy backups/ somewhere private. Do not continue without this.
Step 7: Make the patch from your backup
Android decides whether to turn ADB on from one line in /system/build.prop: persist.sys.usb.config=mass_storage. The patch changes mass_storage to adb, followed by a newline and #padding. The file stays the same length and no file-system structures change.
tools/derive-sector.sh finds that one 512-byte sector in your own backup and writes the original and patched copies to patch/.
-
In WSL, run:
tools/derive-sector.shIt reads
backups/emmc-full.imgby default. Pass another image path as an argument. If the system partition is not number 7, setSYSTEM_PART=<number>. -
Check the output. You expect something like:
bytes changed (expect up to 12): 12 sector <n>, in-sector offset <m>; wrote patch/sector-{number.txt,orig.bin,adb.bin}If the script prints
'persist.sys.usb.config=mass_storage' not found, the line is already patched or your firmware differs. Stop. -
Confirm the data partition has no override. A file at
/property/persist.sys.usb.configon the data partition would beatbuild.prop. On the tested firmware, the data partition starts at byte 2,235,564,032 (sector 4,366,336):debugfs -R 'stat /property/persist.sys.usb.config' 'backups/emmc-full.img?offset=2235564032'You expect
File not found. The?offset=form needs e2fsprogs 1.43 or later. On other firmware, take the start of the last partition fromfdisk -l.
You are here
patch/ holds sector-number.txt, sector-orig.bin and sector-adb.bin, and the data partition has no override file.
Step 8: Apply the patch
With the storage still showing as a disk, in PowerShell:
powershell -ExecutionPolicy Bypass -File <repo>\patch-sector.ps1
The script:
- refuses to write unless the live sector is identical to
patch\sector-orig.bin, - writes the 512-byte sector,
- reads it back and compares it,
- marks the disk read-only again.
It ends with OK: sector <n> now holds the ADB-enabled build.prop line, verified by readback. If the sector is already patched it says so and does nothing.
If your disk is not 15,758,000,128 bytes, pass -ExpectSize <bytes>.
To put the stock sector back later, run the same command with -Restore while U-Boot shows the disk.
You are here
The script printed OK: sector <n> now holds the ADB-enabled build.prop line, verified by readback. The frame's storage differs from the backup by one sector.
Step 9: First boot with ADB
-
Take the microSD card out of the frame.
-
Press RESET. The frame boots Android as usual, with the stock home app.
-
In PowerShell, find the frame. It now reports
1f3a:1001:usbipd list usbipd attach --wsl --busid <bus id> -
In WSL:
adb devices adb shell id
You see the frame in adb devices, and adb shell id prints uid=0(root). ADB asks for no authorization. You are done unlocking.
Keep the microSD card. It is your way back into FEL mode.
You are here
adb shell id prints uid=0(root). The frame is unlocked. The backup is safe. Next you build the kiosk.
When you finish
-
Put Windows back to the disk policy you wrote down in step 1. Use the value the first command printed:
Set-StorageSetting -NewDiskPolicy <the value you noted> -
Keep
backups/andpatch/private and backed up. Do not add them to Git. -
Keep the FEL microSD card. You use it for any later recovery.
If something goes wrong
- Frame will not enter FEL mode. Check that the card is in, and that
usbipd listshows1f3a:efe8. Press RESET again. -
boot-ums.shsayswarm-up SPL did not return. Press RESET to restart FEL, and run the script again. -
boot-ums.shsayseMMC disk did not appear in Windows. Check that Windows has not set the disk offline for another reason, then run the script again. -
boot-ums.shsaystimeout. It waited 30 minutes without seeing FEL. Check the card, the cable, and that the frame is not plugged into a hub. - A write script says it expected exactly one disk. U-Boot's disk is not up, or its size differs from the default. Pass
-ExpectSize. -
patch-sector.ps1says the sector does not match. Do not force it. Check thatpatch/was made from this frame's own backup. - Undo the ADB change. Show the disk with
scripts/boot-ums.sh, then runpatch-sector.ps1 -Restore. - The frame will not boot after a write. Follow step 4 of The frame does not boot. It restores your backup.
-
adb devicesshows nothing. Runusbipd list, find the frame (1f3a:1001), and attach it again.
More recovery steps, including a frame that does not boot and a lost PIN, are in Troubleshooting and recovery.
Related
Next: Install the frame server, if you have not already. Then Build the kiosk and set up a frame.