Installing Linux on a RK3066 based device

Contents

  1. Prerequisites
  2. Create a root filesystem
  3. Build a kernel and create a recovery image
  4. Install the Android SDK
  5. Flash the recovery image
  6. Boot into Linux

Prerequisites

This howto presumes an up to date Ubuntu 12.04 64-bit installation. It might work on other distros but then your mileage may vary.

Create a root filesystem

First step is to create a root filesystem on a MicroSD card, in this case a Debian Wheezy rootfs. Basically you can use any armhf root filesystem, be it Ubuntu, Arch, Debian, Fedora etc. You can also use something like Picuntu, but a) it’s based on a non-LTS Ubuntu version which I personally don’t use, b) it’s not a minimal installation and I prefer clean, lean installs and c) I’m using debootstrap to create the root filesystem and that’s almost as much work as downloading Picuntu and putting it on the MicroSD card.

  1. Install the necessary packages
    sudo apt-get install qemu-user-static binfmt-support debootstrap
  2. create an ext4 partition labeled linuxroot on a micro SD card, for example with gparted
  3. Mount the newly created partition on the MicroSD card in /mnt/tmp
    sudo mkdir /mnt/tmp
    sudo mount /dev/sdx1 /mnt/tmp
  4. Then install Debian Wheezy on it
    sudo qemu-debootstrap --verbose --variant=minbase --arch=armhf \
    wheezy /mnt/tmp http://ftp.debian.org/debian
  5. Chroot into your freshly installed rootfs
    mount -t proc proc /mnt/tmp/proc
    mount -t sysfs sysfs /mnt/tmp/sys
    mount -o bind /dev /mnt/tmp/dev
    mount -t devpts devpts /mnt/tmp/dev/pts
    chroot /mnt/tmp
  6. Configure the rootfs: http://linux-sunxi.org/index.php?title=Debian&oldid=4302#Configure_the_new_rootfs
    Use wheezy instead of sid for the source.list part and skip the filesystem mounts part. And you shouldn’t set a password for root but create your own user instead and add this user to the sudo group:
    adduser someuser
    passwd someuser
    addgroup someuser sudo
  7. Unmount the MicroSD card
    exit
    sudo umount /mnt/tmp/{proc,sys,dev/pts,dev,}
  8. Reinsert the MicroSD card in your cardreader and make sure it mounts in /media/linuxroot/

Build a kernel and create a recovery image

Next step is to create a kernel. You can of course use one of the precompiled kernels available but I prefer rolling my own so I can tinker with the kernel config a bit. The best howto I could find on compiling your own kernel for RK3066 based devices can be found here: http://hwswbits.blogspot.nl/2013/03/compiling-picuntu-kernel-ubuntu-linux.html
I’ve adapted it a bit to my situation.

  1. Install the necessary packages to build the kernel
    sudo apt-get install git-core flex bison build-essential gcc-arm-linux-gnueabihf \
    libncurses5-dev zlib1g-dev lib32z1 lib32ncurses5 sharutils lzop

    If you’re building on a 32-bit 12.04 installation you can omit the lib32z1 and lib32ncurses5 packages.
  2. Create a directory for the kernel source and other needed tools
    mkdir -p $HOME/src/rk/mod_fw
    cd $HOME/src/rk
  3. Clone git repo with the mkbootimg tool to create recovery images
    git clone --depth 1 https://github.com/olegk0/tools.git
  4. Clone git repo with a RK3066 specific initramfs and create a cpio file out of it
    git clone --depth 1 https://github.com/Galland/rk30_linux_initramfs.git initramfs
    cd initramfs
    gzip -dc debian-3.0.8+fkubi.cpio.gz > initramfs.cpio
    cd ..
  5. Clone git repo with kernel source tailored for RK3066 based devices
    git clone --depth 1 https://github.com/Galland/rk3x_kernel_3.0.36.git
    cd rk3x_kernel_3.0.36/
  6. Create a build script with the following contents
    #!/bin/bash
    export ARCH=arm
    export CROSS_COMPILE=arm-linux-gnueabihf-
    export LOCALVERSION=
    export INSTALL_MOD_PATH=$HOME/src/rk/mod_fw
    MAKE="make -j$(getconf _NPROCESSORS_ONLN)"
    
    $MAKE mrproper
    
    cp config.galland .config
    
    $MAKE
    
    rm -rf $INSTALL_MOD_PATH
    $MAKE modules_install

    Alternatively you can also do it the Debian way
    sudo apt-get install kernel-package

    Build script contents

    #!/bin/bash
    
    export $(dpkg-architecture -aarmhf)
    export CROSS_COMPILE=arm-linux-gnueabihf-
    export LOCALVERSION=
    export CONCURRENCY_LEVEL=$(getconf _NPROCESSORS_ONLN)
    export DEBIAN_REVISION=0
    export INITRD=YES
    export IMAGE_TYPE=zImage
    
    cp config.galland .config
    make-kpkg clean
    fakeroot make-kpkg kernel_image

    This will create a deb package called linux-image-3.0.36_0_armhf.deb in the directory above the directory with your kernel source.

  7. Make the script executable
    chmod +x build_rk3066
  8. Run the build script
    ./build_rk3066
  9. Generate the recovery.img file that has te be flashed to the recovery partition of the TV stick
    cd ..
    tools/mkbootimg --kernel rk3x_kernel_3.0.36/arch/arm/boot/Image --ramdisk \
    initramfs/fakeramdisk.gz --base 60400000 --pagesize 16384 --ramdiskaddr 62000000 \
    -o recovery.img

Install the Android SDK

In order to be able to communicate with the TV stick from your PC you will need the adb tool. With the adb tool you can tell the stick to boot into different modes, like the recovery or bootloader modes.

  1. Install the following packages
    sudo apt-get --no-install-recommends install openjdk-7-jre lib32stdc++6
  2. Download the Android SDK Tools Only package
    wget -c http://dl.google.com/android/android-sdk_r22.0.1-linux.tgz
  3. untar it and move it to $HOME/android
    tar zxvf android-sdk_r22.0.1-linux.tgz
    mv android-sdk-linux $HOME/android
  4. Install adb
    $HOME/android/tools/android
  5. Create an udev rules file /etc/udev/rules.d/51-android.rules with the following content
    SUBSYSTEM=="usb", ATTR{idVendor}=="2207", MODE="0666"
  6. Reload udev rules
    sudo udevadm control --reload-rules
  7. Create $HOME/.android/adb_usb.ini with the following content
    # ANDROID 3RD PARTY USB VENDOR ID LIST -- DO NOT EDIT.
    # USE 'android update adb' TO GENERATE.
    # 1 USB VENDOR ID PER LINE.
    0x2207

Flash the recovery image

Now we have to flash the recovery image that contains our kernel to the stick. The advantage of using a recovery image is that you can still use the Android installation on the TV stick. So normally the stick boots into Android but when you force it to boot into recovery mode it will boot into Linux once you’ve flashed it with your custom recovery image.

  1. Make sure you’re still in $HOME/src/rk
  2. Clone git repo with the rkflashtool tool with support for RK3066 based devices
    git clone --depth 1 https://github.com/Galland/rkflashtool_rk3066.git
  3. Compile rkflashtool
    cd rkflashtool_rk3066
    make
  4. Connect the TV stick with the MicroUSB cable to your PC and connect a mouse or keyboard to the USB port of the stick
  5. Once the TV stick has booted into Android go the Setting window, select Advance SettingSystem and select USB settings which should change from Disconnected to Computer to Connected to Computer. You can verify if the TV stick is indeed connected with lsusb on your PC, it should output the USB id of the TV stick
    Bus 003 Device 006: ID 2207:0010
  6. Assuming you have the Android SDK installed on your PC you can now reboot the TV stick into flash mode
    $HOME/android/platform-tools/adb reboot bootloader
    The TV stick should now reboot into flash mode. It will now have a different USB id so check with lsusb again, it should output the following id
    Bus 003 Device 014: ID 2207:300a
  7. Now flash the stick
    Stock ROM:
    ./rkflashtool w 0x00010000 0x00008000 < ../recovery.img
    Finless ROM:
    ./rkflashtool w 0x00014000 0x00008000 < ../recovery.img
    and reboot
    ./rkflashtool b
    This should reboot the stick into Android again
  8. Repeat step 5 and have the stick reboot into recovery to test if the kernel loads properly
    $HOME/android/platform-tools/adb reboot recovery

An alternative method to boot the TV stick into flash mode would be to hold down the reset button of your device when powering it up or if your device doesn’t have a reset button, find the pads on the PCB that boot the device in flash mode and short those when powering up. More info on shorting pads can be found here.

Boot into Linux

On to the last part, booting the TV stick with your Debian Wheezy installation. Before doing so you will have to copy the modules and firmware that you’ve created when building the kernel on to your MicroSD card. Then you can insert the MicroSD into the TV stick and have it boot into recovery mode. It should then boot into your Debian Wheezy installation.

  1. The MicroSD card should still be mounted on /media/linuxroot. Copy the modules and firmware
    sudo cp -a $HOME/src/rk/mod_fw/lib/* /media/linuxroot/lib/
    sudo chown -R root: /media/linuxroot/lib/{firmware,modules/3.0.36}
    If you went the Debian way:
    sudo cp $HOME/src/rk/linux-image-3.0.36_0_armhf.deb /media/linuxroot/tmp
    mount -t proc proc /media/linuxroot/proc
    mount -t sysfs sysfs /media/linuxroot/sys
    mount -o bind /dev /media/linuxroot/dev
    mount -t devpts devpts /media/linuxroot/dev/pts
    chroot /media/linuxroot
    dpkg -i /tmp/linux-image-3.0.36_0_armhf.deb
    exit
    sudo umount /media/linuxroot/{proc,sys,dev/pts,dev}
  2. Unmount the MicroSD card and insert it in your TV stick
  3. Boot the TV stick and repeat step 8 of the Flash the recovery image part
  4. Your TV stick should now boot into Debian Wheezy. To initialize all modules run depmod -a as root (not necessary if you went the Debian way).