Compiling Persee kernel and flashing it on the Persee

If you wish to compile a new kernel and flash it on your persee, you will first need several things

  • Persee kernel sources. I got them by mailing Orbbec, and I’m not sure what the rules are for distributing them. The kernel is largely just the rockchip linux kernel though.
  • The Orbbec Persee Ubuntu image
  • MicroUSB OTG cable
  • Orbbec Persee
  • Linux computer. I use debian stable.

Flashing the existing Ubuntu image

To be able to do some later steps, you must first flash the Orbbec Ubuntu image on the Persee as this modifies the partition tables. I’m not sure how these tables could be modified without this image, and I hope someone else can shed some light on this.

  • Get the Ubuntu 16 image from here: Universal Download Thread for Persee
  • Get the upgrade_tool from here Rock/flash the image - Radxa Wiki. It would nice to be able to flash this image using rkflashkit as upgrade_tool is proprietary - any ideas?
  • Boot Persee in loader mode
    • Remove any SD cards from the Persee
    • Unplug all cables
    • Connect the OTG USB cable in the microUSB slot on the Persee
    • Using some small object press the reset pin down, in the hole next to the power plug
    • Connect the USB OTG cable to your Linux PC
    • Release the reset pin after a few seconds
    • sudo upgrade_tool uf /path/to/ubuntu/img
  • Unplug and replug the OTG cable, make sure the Persee boots to Ubuntu

Install rkflashkit

git clone
cd rkflashkit
./waf debian
sudo dpkg -i rkflashkit_0.1.5_all.deb

Backup old images

Connect the Persee using the USB OTG cable in loader mode.

sudo rkflashkit part # Should list partitions for a device that's in Loader mode
sudo rkflashkit backup @linuxroot linuxroot_old.img
sudo rkflashkit backup @boot boot_old.img
sudo rkflashkit backup @backup backup_old.img

Build kernel sources

  • Acquire the kernel sources from Orbbec
  • Extract the sources
  • GCC >= 5 cannot be used on this old kernels. Make sure your GCC is 4.8 or 4.9: /usr/bin/arm-linux-gnueabihf-gcc -v
  • If not:
sudo apt-get install gcc-4.8-arm-linux-gnueabihf
sudo update-alternatives --install /usr/bin/arm-linux-gnueabihf-gcc arm-linux-gnueabihf-gcc /usr/bin/arm-linux-gnueabihf-gcc-4.8 10
sudo update-alternatives --install /usr/bin/arm-linux-gnueabihf-g++ arm-linux-gnueabihf-g++ /usr/bin/arm-linux-gnueabihf-g++-4.8 10
arm-linux-gnueabihf-gcc -v
  • Compile the kernel. This takes 10 minutes on my aging laptop with a weak CPU
cd  kerneldir
make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabihf- persee-rk3288_defconfig
make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabihf- persee-rk3288.img -j4

Retrieve a missing bootloader

  • The kernel sources I got did not contain second_bootloader which is used by the boot sequence. This can be found by retrieving the boot partition from the Persee after flashing the Orbbec Ubuntu.
unmkbootimg -i boot_old.img
cp second_bootloader /kerneldir/OBTools/

Make the final boot image

mkbootimg --kernel arch/arm/boot/zImage --ramdisk OBTools/out/initrd.img --second OBTools/second_bootloader  -o linux-boot.img

Flash onto the device

sudo rkflashkit flash @boot linux-boot.img

Creating a linuxroot partition from a running Persee

  • Log in to the persee

Reduce the linuxroot partition used space as much as possible as flashing a large image takes ages. You can use this oneliner to see what’s using space:

sudo su
cd /
du -S . | sort -nr | head -25
  • Then insert a USB stick, mount it and create a file to store the linuxroot partition
sudo su
mkdir /root/usb
mount /dev/sda1 /root/usb
cd /root/usb
mkdir myrootfs && cd myrootfs
dd if=/dev/zero bs=1M count=2500 | pv -s 2G | dd of=linuxroot.img # Adjust size based on linuxroot
mkfs.ext4 -F -L linuxroot linuxroot.img
  • Mount the linuxroot in a temp mount point and copy the entire system
cd /root
mkdir mnt
mkdir mnt2
cd /root/usb/myrootfs
mount -o loop linuxroot.img /root/mnt
mount /dev/mmcblk0p5 /root/mnt2 # change as appropriate from `mount` output. You need the about 7GB partition
cp -a /root/mnt2/* /root/mnt/
  • Create the firstboot flag. This will be used by /usr/local/bin/ to expand the file system.
touch /root/mnt/firstboot
  • Cleanup
umount  /root/mnt
umount /root/mnt2
cd /root/usb/myrootfs
e2fsck -p -f linuxroot.img
resize2fs -M linuxroot.img
  • Use rkflashkit to flash the image
sudo rkflashkit backup @linuxroot old_linuxroot.img
sudo rkflashkit flash @linuxroot linuxroot.img


  • How could we create a completely flashable image similar to the Orbbec Ubuntu image? This would allow flashing the image in without having to first flash the Orbbec image. This might be simple - perhaps some tool in the rkflashkit can create a complete image
  • Can the Orbbec image be flashed on the Persee using rkflashkit? I’m not a huge fan of using the upgrade_tool from an unknown origin.

Thank you for those very usefull informations.
Did you find answers to you questions ?

We moved from using the Persee to using a dedicated SoC, preferring to separate the computer and sensor. As such, we never really looked into this stuff after I wrote the above summary. There’s several issues with the Persee, starting with the fact that it’s running an ancient kernel without any updates.

For anyone who’s interested, I was able to get a completely flashable image similar to Orbbec’s Ubuntu image by creating the linuxroot.img as described above, then using the tools and instructions on this page:
I just unpacked Orbbec’s Ubuntu image using the tools, then swapped Orbbec’s linuxroot for my own, and re-packed it using the Firefly tools.

Couple of gotchas to note:

  1. The linuxroot.img must be under 4GB. This is because the Rockchip container format uses a 32-bit field to store the image length. It looks like AndroidTool is still smart enough to create a larger partition if it sees more available space, but trying to prepackage more than 4GB inside the packed partition will result in an image which will fail validity checks.
  2. You can compile and run the Firefly tools on the Persee itself (and thus execute all the steps to create a backup on the Persee), but you’ll have to add “-D_FILE_OFFSET_BITS=64” to CFLAGS when building, otherwise you’ll run into issues with the tools being unable to read files larger than 2GB.
  3. When packing with img_maker, supply “-rk32” instead of “-rk33” as stated in the instructions.

Hi it is very interesting to have a fresh kernel. I have a mobile robot with a Persee on wich i have installed a YDLidar for eraly detection of obstacle bur it is using the CP210X driver that is not in the persee image ( it is in the linux-module-extra ) package that i have not been able to install with the 3.#0.0 kernel.

Is your new kernel including the CP210X driver ?

Thanks, electrickshepherd! I got it working with your instructions.

I want to add a couple notes:

  1. I was running the Firefly tools on the Persee (haven’t got a good Linux dev machine) so I had to do ‘apt install libssl-dev’ to get the dev headers and libs for OpenSSL.

  2. The Firefly tools don’t like the checksum that the Orbbec uses, so in afptool.c I commented out the “goto unpack_fail” line which causes it to fail unpacking if the CRC is bad.

So with that we are able to create a custom image and the Orbbec boots it. The CRC didn’t seem to matter.

However, I messed up and shrank the filesystem wrong or something - When it boots, it throws a lot of warnings that the disk is full.

Thank you all, this has been really helpfull.
I just noticed something weird about my “new” patched kernel. It’s really slower, and it looks that the module cpufreq is missing:

On the original kernel (installed with Orbbec image), lshw -c cpu gives me:
physical id: 1
bus info: cpu@0
size: 600MHz
capacity: 1800MHz
capabilities: swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 evtstrm cpufreq

But on the patched one (using make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabihf- persee-rk3288_defconfig)
It gives me:
root@ORBPER-01-5B-37:~# lshw -c cpu
physical id: 1
bus info: cpu@0
capabilities: swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 evtstrm

Do somebody noticed the same thing ?