Jailbreak a Nixplay W10P Photo Frame

I own an older Nixplay W10P frame from 2023 which, despite having gigabytes of free space, will no longer accept new photos due to recent mandatory changes in the Nixplay’s terms of service. I’m not opposed to a company charging for services but their reasoning of “rising storage and bandwidth costs” is unconvincing given both have declined significantly in recent years. It’s reasonable to speculate that the next update will continue to erode the reasons I chose the frame in the first place. Who wants to bet it will be something to do with AI?

Anyway, I’ve decided to decline these new terms and delete my Nixplay account. However, I don’t want to lose the functionality of the hardware. Yo-less uploaded a detailed video on youtube demonstrating how to jailbreak the Nixplay frame. The process seemed straightforward, involving nothing more than plugging a cord into a W10E frame and connecting to adbd. I found that the process for the older W10P model was not as seamless. Since I spent a chunk my weekend working through this, I wanted to document the steps here to help others who may face similar issues.


The good news: You don’t have to take your frame apart at all. Both the USB port and the reset button are accessible externally.

The bad news: Unfortunately, the firmware does not include the adbd executable in the system image, so it’s not immediately possible to connect to the frame using adb. I am using macOS for this process, and when first plugging in the frame, it does not show up in the system by default:

% brew install usbutils
% lsusb
Bus 000 Device 001: ID 1d6b:XHCI
XHCI
XHCI Linux Foundation USB 3.1 Bus

Hold down the reset button for about 5 seconds and try it again though:

% lsusb
Bus 002 Device 001: ID 2207:310d Fuzhou Rockchip Electronics Co., Ltd. Composite Device
Bus 000 Device 000: ID 2207:310d Fuzhou Rockchip Electronics Co., Ltd. USB 3.1 Bus
Bus 000 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub

It lives! At this point, the frame is detected. The screen will go black, and Android tools will not yet be functional, but we can use this bootloader to proceed. Let’s start by getting the necessary tools.

# brew's rkflashtool.  Note the syntax is slightly different than linux's...
brew install rkflashtool
# adb & friends
brew install --cask android-platform-tools

I suggest taking a full backup just in case but we actually only need the system and recovery images. Skip the userdata.img at the end unless you have a specific need as it takes a couple of hours to run.

#!/bin/bash

# Script courtesy of ChatGPT.  Note that if you don't have a `W10P` model frame these offsets might not be right!

# Make sure rkflashtool is in your PATH or use full path
RKFLASHTOOL=rkflashtool

echo "Dumping uboot..."
$RKFLASHTOOL r 0x00002000 0x00002000 > uboot.img

echo "Dumping trust..."
$RKFLASHTOOL r 0x00004000 0x00002000 > trust.img

echo "Dumping misc..."
$RKFLASHTOOL r 0x00006000 0x00002000 > misc.img

echo "Dumping resource..."
$RKFLASHTOOL r 0x00008000 0x00008000 > resource.img

echo "Dumping kernel..."
$RKFLASHTOOL r 0x00010000 0x00006000 > kernel.img

echo "Dumping boot..."
$RKFLASHTOOL r 0x00016000 0x00006000 > boot.img

echo "Dumping recovery..."
$RKFLASHTOOL r 0x0001C000 0x00010000 > recovery.img

echo "Dumping backup..."
$RKFLASHTOOL r 0x0002C000 0x000A0000 > backup.img

echo "Dumping cache..."
$RKFLASHTOOL r 0x000CC000 0x000A0000 > cache.img

echo "Dumping metadata..."
$RKFLASHTOOL r 0x0016C000 0x00008000 > metadata.img

echo "Dumping kpanic..."
$RKFLASHTOOL r 0x00174000 0x00002000 > kpanic.img

echo "Dumping radical_update..."
$RKFLASHTOOL r 0x00176000 0x00020000 > radical_update.img

echo "Dumping keys..."
$RKFLASHTOOL r 0x00196000 0x00008000 > keys.img

echo "Dumping system..."
$RKFLASHTOOL r 0x0019E000 0x00280000 > system.img

echo "Dumping userdata (rest of flash)..."
# adjust length if you know exact remaining size
$RKFLASHTOOL r 0x0041E000 0x00C00000 > userdata.img

echo "All partitions dumped."

The next step is to add the adbd executable, which is missing from the system image. Fortunately, it exists in the recovery image. I had to use Debian to manage all the image modification because I didn’t want to fight OS X and ext4. Here’s how to extract it.

# on debian
mkdir recovery_wd
cd recovery_wd
cp ../recovery.img .
# creates zImage, initrd.img, and bootimg.cfg.
# `apt install abootimg` if you need to
abootimg -x recovery.img
mkdir ramdisk
cd ramdisk
gzip -dc ../initrd.img | cpio -i

# You'll find a copy of `adbd` in /sbin/ but first we'll need to mount the system image so we have a place to put it.

cd ../..
mkdir simg
mount -t ext4 system.img simg
cd simg
# Now you're in the system image we dumped from the frame
mkdir sbin
cd sbin
cp ../../recovery_wd/ramdisk/sbin/adbd .
chmod 755 adbd
cd ../..
sync
umount simg

Now that the system image includes adbd, it’s time to write it back to the frame.

# Write to the system partition
rkflashtool w system < /path/to/system.img
# Reboot
rkflashtool b

At this point adbd is present but not auto-starting. There are multiple conditions in the system’s init.rc file to start adbd (e.g. on property:sys.usb.config=adb && property:sys.usb.configfs=1) and presumably one of those doesn’t get set. I didn’t want to keep chasing this so next we’ll patch the boot image to just start adbd directly:

# back on debian
mkdir bood_wd
cd boot_wd
cp ../boot.img .
abootimg -x boot.img
mkdir ramdisk
cd ramdisk
gzip -dc ../initrd.img | cpio -i

Add these lines within the existing on boot section of the init.rc above the class_start default line.

    setprop sys.usb.config adb
    setprop sys.usb.configfs 1
    setprop service.adb.root 1
    start adbd

    write /sys/class/android_usb/android0/enable 0
    write /sys/class/android_usb/android0/idVendor 18D1
    write /sys/class/android_usb/android0/idProduct D001
    write /sys/class/android_usb/android0/functions adb
    write /sys/class/android_usb/android0/enable 1

And then create a new boot image with this change:

find . | cpio -o -H newc | gzip > ../initrd-new.img
cd ..
abootimg --create ../boot-new.img -f bootimg.cfg -k zImage -r initrd-new.img

Transfer the new image to the frame

rkflashtool w boot < boot-new.img
rkflashtool b

After rebooting the frame adbd should fire up. adb commands (and vysor from the original video) should be able to connect and you can follow the directions in the video to install the apps you want.

This is a static site. If you have any comments please tag me or send an email.