Wednesday, November 27, 2013

Your own official Linux distro in a SD card (for ARM)

Currently for us, owners of ARM devices of the Rockchip family (though this post applies to any ARM CPU), when wanting to boot Linux we have to do two things:

1) Flash a Linux kernel, usually to recovery, in order to be able to boot to Linux
2) Copy a Linux Root File System (RFS) into a MicroSD card for the OS to boot from

This post is about Step 2.



Why can't we use official distributions?


Basically because most distros are [easily] available for x86 CPUs (x86, amd64, ...), not ARM CPUs (armel, armhf). And then, when you find it compiled for ARM, there are some little extras to be done, like copying your kernel's modules into it, and throwing it all into a MicroSD card.

Hence, we are currently forced to choose among static RFS that fellow developers have made available and can update only on their free time, which isn't much. These are:

- Picuntu, from Alok Sinha
- Ubuntu 12.10 RFS, from linuxium
- Home.io, from JustinTime4Tea


These RFS are all just the Ubuntu distribution, sometimes with a different name (Xubuntu in the case of Picuntu, Ubuntu in the case of Home.io), though they usually include extras like:

- The modules (drivers) for many devices (needed for many, but not all, USB gadgets)
- The Flash video ARM support solution I posted here

However let's face it, you are forced to use Ubuntu, and then you depend on the maintainer's free time to grab the latest version of Ubuntu, add the above extras and publish it so you can use it.



Your own Linux distribution's RFS


Here I am going to show how to create your own RFS by grabbing whatever version of Ubuntu (and with few changes any other distro, like Arch Linux, OpenSUSE, CentOS, just click on the link to be taken to the specific distro's instructions), and create a RFS to use on a MicroSD card to boot Linux your ARM stick/box. Or to flash the same RFS into your device's Nand Flash chip and avoid the SD card altogether.




Getting an up-to-date official distribution, for ARM

The first thing is getting the Linux distribution (all the programs that make up your booted up Linux: from the "ls" commandline, to the GNOME desktop and the LibreOffice suite) already compiled for ARM devices, instead of the usual x86 for PCs.

This is not difficult since, actually, Linaro is doing just that!
If you want a desktop environment (XFCE, Gnome, KDE, etc.) you have two options:

Option 1) Easy way: (Older version but everything done) Head over to:
http://www.linaro.org/downloads/
Look for "Ubuntu Desktop" in the "Developers and Community Builds" section and click on any of the boards that support it on the right (Origen, Panda, etc. doesn't matter). At the time of writing (Nov 2013) this will redirect you to this page:
http://releases.linaro.org/12.11/ubuntu/precise-images/ubuntu-desktop
So the latest version with the desktop already installed is Ubuntu 12.11, you'll have to install this one in your SD and upgrade to the latest version after booting. Download the biggest .tar.gz file, in my case 473 MB of:
http://releases.linaro.org/12.11/ubuntu/precise-images/ubuntu-desktop/linaro-precise-ubuntu-desktop-20121124-560.tar.gz
Option 2) Manual way (Newer version, but starts with a commandline Linux): You can get the cutting edge latest version of Ubuntu, it will be small and fast but you'll have to type a few more commands, after booting it, in order to install a desktop. Go here:
http://releases.linaro.org/
And click in the folder link of the latest version number ("13.11" for me). A new page appears where you have to select "ubuntu", in the next page select the link that ends in "-images" (prefix depends on Ubuntu's version name, in this case it's "raring-images"), and finally select the version link that you want (nano / developer / server) to get its .tar.gz file.

All three are the same Linux but each one with different sets of packages already installed. They are:

- nano (around 50 MB) gives you a command-line with very very few things (not even a vi/vim/nano editor!), with this version you'll need a network connection (care for /etc/network/interfaces and such) soon enough, to start cranking "apt-get install" for all the little apps.

- developer (around 140 MB) a usable command-line with most things you'll need to comfortably start working and changing whatever configuration. However, IMHO, it includes many packages for software development, while lacking some others more typical of a generic user system.

- server (around 130 MB) a usable command-line with all you need for a quick setup of a desktop environment resembling a PC with Ubuntu. Even if you are a developer you can later install all the packages you need. This is the one I recommend.

N.B.: Compare the *.packages files to get a glimpse for yourself of what's inside each version.

So, following the recommendation we would download this file for the latest Ubuntu 13.11 (Nov 2013, or else go into the page above and get yourself the latest and very best.




Getting the RFS into the MicroSD card (or flash)

First of all introduce the MicroSD card into your PC to partition it in the way that the kernel expects it (please don't use partition utilities, they won't do it!).

Let's say that the MicroSD appears at the folder "/mnt/whatever_folder", then type the following command to know the device name:
df -h | grep whatever_folder
You should see a line somewhat like this:
/dev/sdg1   7,3G   612M  6,4G   9% /mnt/whatever_folder
Now that we know the MicroSD is in "/dev/sdg" (remove the number!!) unmount the MicroSD:
sudo umount /mnt/whatever_folder
And the most important step to avoid later problems: partition & format in this one step:
mkfs.ext4 -F -L linuxroot /dev/sdg
Which labels it "linuxroot" and at "/dev/mmcblk0", where the kernel expects it (CMDLINE), instead of where a partition tool would place it (at "/dev/mmcblk0p1").

SIDE-NOTE ONLY FOR USING INTERNAL FLASH INSTEAD OF A MICROSD:
If you want your RFS to be in your device's Flash chip, and 1) have flashed the right parms, 2) have a kernel with the right CMDLINE for those parms, 3) the kernel has an initramfs.cpio with rknand...ko, then the you have to format it with this command: "mkfs.ext4 /dev/mtdblock0" (mtdblock number is that of your [big] partition).

It may take a couple minutes and when finished you should mount it and start following these steps:

1) Become root (necessary to keep file permissions in the RFS!)
sudo su -
2) Go to the folder where the SD card (or flash) is mounted:
cd /mnt/whatever_folder
3) Extract the downloaded ARM RFS in it:
tar xvfz /home/username/Downloads/linaro-raring-server-20131124-562.tar.gz
4) Since the Linaro .tar.gz contains the RFS inside a folder named "binary", we have to move its contents to the real root of the SD card and then remove the, now empty, "binary" folder:
mv binary/* .
rmdir binary
5) If you are doing this process on a PC, you have to uncompress the modules+firmware file (that came with the kernel you flashed into your stick) into the "/mnt/whatever_folder/lib/" folder.


Or, if you are on an ARM stick, you can just copy your own modules (drivers) and firmware to the new RFS so you have everything from the beginning:
mkdir ./lib/modules
cp -R /lib/modules/* ./lib/modules
cp -R /lib/firmware/* ./lib/firmware
And it won't hurt to copy the library for playing Adobe Flash videos (think YouTube) in ARM (and all the Flash ads and websites, of course):
cp /usr/lib/libpepflashplayer.so ./usr/lib/
If you didn't have it, follow this quick post.


6) You may also want to "touch" certain files to make sure networking works out of the box. For example, if you have an Ethernet connection in your ARM device, then modify the /mnt/whatever_folder/etc/network/interfaces file to add these lines:
auto eth0
iface eth0 inet dhcp
7) It's always a good idea to end operations with this command (to finish all write operations):
sync

You can unmount that MicroSD, because it's ready to boot. If you installed the desktop version the easy way, that's it.
However, if you installed a trimmed commandline version the manual way, you should continue reading the following section.



Getting a desktop environment


Once you boot your device with the created MicroSD card, your first task is to check the network connection. For example type:
apt-get update
If the software repositories start updating, you're good to go. If there is no connectivity: Internet is full of Q&A about networking in Linux :)

Now, with Internet on, in order to install a desktop environment, in my case XFCE (the one used in Xubuntu), I would just type this:
apt-get install xubuntu-desktop
And when asked, say Yes to downloading >400 MB of packages that will use up >1 GB of space when installed, but will land me on the very latest desktop environment for an ARM PC, whatever your CPU (Rockchip, Allwinner, Samsung, ...).




Sorry if it took too long to explain something that is actually simple, but everybody is welcome!
The more users discover that a tiny and cheap stick/TV-box is actually a full-fledged low to mid-end PC (without the noise, size, and the Watts!), the better for all!


Tuesday, November 19, 2013

Linux on UG008 TV Box (RK3066)

I was looking for the cheapest Rockchip device with external Wifi antenna and/or Ethernet connection, just to find both capabilities in the UG008 TV Box, a RK3066 (dual core) device at just 55 USD (shipping included).

After purchasing it and a quick delivery of 2 weeks to Europe, I set out to test it, since I worried it may be lagging behind the newer 4 core experience with the RK3188 CPUs.

The TV box surprised me being very small, at 7.5cm x 7.5cm and looking really slick and solid. I was glad to see Android feels zippy.


Small and cheap UG008 TV Box (wifi antenna is also just 7 cm)


So, hacking started:

1) Backup internal flash: The recovery button is at a tiny hole in one side, near the front. The only quirk here is that you insert a clip there and stay pressing the recovery button, plug the MicroUSB from the PC to the TV box and then: you also have to press a couple of seconds the power button, before you can release the recovery.

A red light appears around the MicroUSB slot, and on your [Linux] PC you can type "lsusb" and find a nameless device (for my PC's buses/devices, it is: "Bus 002 Device 004: ID 2207:300a  "), the 2207:300a ID is what matters, that is our UG008.

First's first, the "partition table", extracted with:
sudo ./rkflashtool r 0 1 | head -n 11
looks like:
CMDLINE: console=ttyFIQ0 androidboot.console=ttyFIQ0 init=/init initrd=0x62000000,0x00800000 mtdparts=rk29xxnand:0x00002000@0x00002000(misc),0x00006000@0x00004000(kernel),0x00006000@0x0000A000(boot),0x00008000@0x00010000(recovery),0x00120000@0x00018000(backup),0x00040000@0x00138000(cache),0x00300000@0x00178000(userdata),0x00002000@0x00478000(kpanic),0x00120000@0x0047A000(system),-@0x0059A000(user)
We go one by one backing them up into our PC (you can safely leave out some, like user, cache, kpanic), just remember for the rkflashtool command you have to swap the hex numbers above.

For example to backup recovery (to flash our Linux kernel on it), which is listed above as "0x00008000@0x00010000(recovery)", you'd do:

sudo ./rkflashtool r 0x10000 0x8000 > UG008_recovery.img

2) Rooting UG008: Once we are done with that, we should root the device (even if just for the sake of being able to dual boot Android or Linux), the rooting procedure is fairly standard and described here. If you only want Linux on the box, you don't need to root it, keep reading,


3) Flash Linux kernel: You have two options depending on what you want:

a) Dual Boot Android/Linux: This is the usual way, you want to flash the recovery partition. I've found this box to be a close relative of the Measy U2C, for which I published several recovery kernels that are compatible with UG008, you'd be missing Wifi (RK901) and Ethernet. Flashing being just:

sudo ./rkflashtool w 0x10000 0x8000 < recovery.img
sudo ./rkflashtool b 

      If you're into working your way around, it should be easy to add the connectivity. Wifi with RK901 has been supported in Linux sticks for some time already (though I never bothered to check myself, being used to wired LAN), and Ethernet should require only to enable this .config options before building your kernel: CONFIG_NET_ETHERNET and CONFIG_RK29_VMAC.

Generic Linux Kernel building for RK devices is described here. Just remember this is a RK3066 device, so don't compile it for RK3188! The audio codec is the well known RK1000.

Now, in order to boot to Linux from Android you can use this excellent "Autorun Linux" app, or install "Android Terminal Emulator" get inside type "su" and then "reboot recovery" every time.


b) Only Linux (remove Android): Very legitimate. Using the same recovery kernel as above, the flashing procedure is all explained here (but follow the instructions for flashing "boot" partition, instead of "kernel" partition, since you are using a recovery kernel). The boot writing (after you back up that partition!!) can be done with this command:

sudo ./rkflashtool w 0xA000 0x6000 < recovery.img
sudo ./rkflashtool b 

Note: I haven't tested the "Only Linux" approach on my UG008, though it should work, or else you can always flash again your backed up stock partition and be back where you started.



4) Booting Linux: Insert your usual MicroSD card with Linux root file system (rfs) and you're good to go.


Any questions, and polite criticism is welcome in the comments below. I hope this post helps!