Friday, January 3, 2014

Hacking into the Minix Neo X7


       Recently, just in time for the holiday season, I have been testing and developing with a Minix Neo X7 and its very handy A2 airmouse.
Minix NEO X7 TV box with RK3188 Quad-Core CPU and 2GB RAM


    This TV box is remarkable to me on the outside for the quality of its finishes, that do make it sturdy and good looking. On the inside there are some probably good choices on the design, namely:

- A quality Audio CODEC (RT5616 that afaik is a Realtek ALC5616) instead of the usual cheap RK1000 shipped on most TV boxes.

- A well suited on-board Ethernet MAC (Realtek RTL8152) as opposed to using the internal MAC of the RK3188, as is done by most other TV boxes, which are riddled with bugs (to list a just few of RK MAC's problems: quirks when connecting Ethernet directly to a PC, stops working on TV-box Linux restart, CPU shut-down upon serving heavy files over SAMBA, ...).

- An on-board battery for the RTC chip (real-time clock HYM8563 to keep the time even without network), which may be interesting for embedded projects with a Linux OS.


    Also, as a less precisely statement, though based on my electronics background, just by looking at the X7 PCB one can find many more capacitors than on most other devices. This is maybe one of the most important good points of this box, since having those capacitors means much more stability, so that it is far less likely for it to hang/reboot while doing heavy duty stuff.

Next time your Android stick/tablet/phone reboots, hangs, or throws you out of an app, think that more than half the times this is due to trimmed down capacitor count, while the rest of the times it's just buggy SW.




Apart from that, Minix has already released twice their kernel sources:

- In September 2013, to well known developer phjanderson (here)

- And then again in December 2013, for the MINIX Developer Challenge, which by the way may be of interest to Android hackers and artists, since they offer well rewarded prizes for the best UI (up until Feb. 9, 2014).





    The practice of respecting the GPL license is something we, as an open source community, value most and certainly distinguishes one vendor from another.

    Think that, even for Android, having kernel sources means an "explosion" of ROMs, developers, and, generally, features such as safer overclocking, updates, fixes (i.e. Vsync screen fix), etc, without the irksome binary patching.

     However, if I could make a wish, that would be the schematics of this TV box, so we can know which CPU pins are connected to which pins of the many ICs on the board, so as to give an even better support for all its components.
     Please note that plain schematics are like the blueprint on hotel room doors, they don't disclose how the hotel was built, just how the rooms are set up.
   

Hacking the machine


1) First things first, you may want to backup your recovery partition (no need to backup the others, unless you have your data on it, since MINIX offers the latest stock ROMs on their site). For that we do the following:
- Coonect the X7 to the power outlet (but don't press the power button yet)
- Connect the X7 to the PC through its USB OTG MicroUSB connector
- Carefully insert a clip into the "Recovery" pin hole (near the HDMI connector) until a pushbutton clicks, and keep it pushed.
- Press the X7's Power button

Then, upon doing a "lsusb" on the PC you'll see the X7 in bootloader mode, listed as a nameless USB device.

You can check the partition table (as a list formatted like: partition_size@partition_offset(partition_name)) by issuing this command:

sudo ./rkflashtool r 0 1 | head -n 11

The partition parameters is what follows after mtdparts. On my X7's revision this looks like:

mtdparts=rk29xxnand:0x00002000@0x00002000(misc),0x00008000@0x00004000(kernel),0x00008000@0x00012000(boot),0x00010000@0x00020000(recovery),0x00020000@0x00030000(backup),0x00040000@0x00050000(cache),0x00800000@0x00090000(userdata),0x00002000@0x00890000(kpanic),0x00130000@0x00892000(system),-@0x009c5000(user)

So backing up recovery partition becomes (swapping size <=> offset):

sudo ./rkflashtool r 0x20000 0x10000 > NEO_X7_recovery.img


2) Second step would be to root Android, so you can reboot to recovery (i.e. Linux) anytime. Rooting the X7 is done as described in this post.



3) Now you want to compile your kernel with the options (.config) you prefer, just remember to use the latest kernel source, at the last line of the MINIX Developer Challenge announcement.

As a base for any hacking, the stock Neo X7 config is: /arch/arm/configs/box_3188_r2_defconfig

To compile your own kernel you can follow this post: Generic Linux Kernel building for RK devices.



4) Last step is flashing your shiny new kernel to the recovery partition of the X7. This is done with the following two commands:


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


5) In order to boot to Linux, you just need to insert an SD card with your Linux RFS (you can create your own RFS as described here) and then, you can either use this excellent "Autorun Linux" app, or install "Android Terminal Emulator" get inside it, type "su" and then "reboot recovery" every time.

That's it, happy hacking!




Regarding Android 4.4 KitKat


Yesterday Minix issued a brief message regarding the recently announced, supposed, Android 4.4 support on some RK3188 devices from other vendors [that do not release their kernel sources].

Since I have been myself, along with other well known developers in the RK Linux community, doing work on upgrading the RK kernel to newer versions (3.0.36+ is tremendously outdated), I can confirm Minix' point of view, that the supposed 4.4 support by those other vendors is indeed FAKE.

The leaked 4.4-supporting kernel is the same old 3.0.36+ kernel with just some drivers in different structures/places and the bare minimum to trick Android 4.4 into believing it is running a newer kernel.
Naturally this is a recipe for bad outcomes, instability and developer support dispersion.

It kinda feels like those MicroSD cards that are labelled 8 GB but are internally just 4 GB...

So, I really look forward to the official release of a real Android 4.4 and its kernel sources. Until then I think we are better off with a nice theme in our current and more stable Android Jelly Bean.



Sunday, December 1, 2013

OpenSUSE for Rockchip ARM devices



      Going on with the earlier post on creating your own MicroSD with the Linux RFS of your preference, here is the howto for installing OpenSUSE using the usual kernel and modules+firmware.
      Just in case, whatever your stick/box, you can use these very generic 3.0.36+ kernels for RK3066 or RK3188 (only missing internal Wifi).

       In my case I used the excellent Radxa Rock board, equipped with a quad-core RK3188, for the tests and found no problem booting it:

OpenSUSE on Rockchip RK3188 (Radxa Rock board)



     Of course, this has been made possible by OpenSUSE team's commitment to the ARM architecture, since they are one of the few that have put all the necessary efforts to have their distribution compiled for ARM CPUs.

     OpenSUSE's official wiki has one page dedicated to installing on a RK3066 device (MK808 [1]), though it is outdated since, among other things, it uses the old 3.0.8 kernel. However the guide was useful and I wanted to update it here.


Now the procedure, with the same captions as in the original post (for Linaro Ubuntu), for comparison:



Getting an up-to-date official distribution, for ARM
 
     You can check the latest ARM distribution at OpenSUSE by heading to this url:
http://download.opensuse.org/ports/armv7hl/distribution/openSUSE-current/images/

and downloading the "rootfs" suffixed .tbz file, which at the time of writing (Dec 2013) is this one:
http://download.opensuse.org/ports/armv7hl/distribution/openSUSE-current/images/openSUSE-12.3-ARM-XFCE-rootfs.armv7l-1.12.1-Build49.1.tbz




Getting the RFS into the MicroSD card (or flash)

Exactly the very same procedure as in original post, except that steps 4 and 6 are NOT to be done, and step 3 becomes:

3) Extract the downloaded ARM RFS in it:
tar xjfv /home/username/Downloads/openSUSE-12.3-ARM-XFCE-rootfs.armv7l-1.12.1-Build49.1.tbz 


And this last step is necessary (or else the root file system is mounted as read-only, preventing correct boot), open the /mnt/whatever_folder/etc/fstab in your linuxroot and add the following first line:
/dev/root / ext4 defaults,noatime 0 0



Getting a desktop environment

    You already have it. However I've found a problem: upon opening the "Install/Remove Software" you will likely stumble upon this fatal error:

"UI Syntax error. Couldn't load plug-in gtk-pkg. Check the logfile"
Solution is simple [2], open a terminal and type:
su -c "zypper in libyui-gtk-pkg4"
You'll be asked the root's password and the missing package installed, so now you can open the Install Software app.


Enjoy!




References:
[1] http://en.opensuse.org/HCL:MK808
[2] http://forums.opensuse.org/english/get-technical-help-here/applications/487505-opensuse-samsung-arm-chromebook-almost-works.html#post2561668

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!




Wednesday, October 23, 2013

DIY NAS with a RK3188 device (Radxa Rock)

I currently have a full-blown Linux PC noisy tower serving 3 SATA hard disks full of multimedia as a home server... that is some 80 Watts of power consumption, plus the noise, for just a few hours of use per week.

There must be a better solution for my home network file-sharing (also called NAS) needs!

So, come the Radxa Rock board, equipped with a Quad Core ARM CPU, the Rockchip RK3188, and 2 GB RAM, quite a beast actually (I'm currently blogging from it, and use it for almost all my PC needs).

And here is today's proof-of-concept RK3188 NAS happily serving files from my desk:

1st rev.: RK3188 functioning as NAS home fileserver (using Radxa Rock board)
UPDATE:
2nd rev.: Radxa Rock as a 3 hard disks NAS (11W idle, 33W with 2 disks streaming)

Now, if you want to bear with me on the technical side... I've been doing the math about data bandwidths for some time already and taken into account the Rockchip datasheet briefs to guess the best I/Os for the task:


Hard disk interface:


Let's face it, Rockchip SoCs don't have SATA ports, and other ARM SoC have at most one SATA port, afaik, and that still means an external power for the SATA device is necessary. That is not a solution for NAS, unless you can fit everything in just one hard disk.

So let's get over it and find the second best solution: USB 2.0 ports are the highest bandwidth inputs (to connect the hard disks). The Radxa Rock board has:

- Two full sized USB 2.0 ports, and a third one in the pins of the expansion connector. All these ports are sharing, through an integrated hub, one single USB bus coming from the RK3188.
- One Micro USB 2.0 OTG  port that is directly wired to the RK3188.

Ideally USB 2.0 would mean up to 480 Mbps raw throughput so, to get the best, we don't want to share it with other devices. Hence, we will be plugging our hard disk/s to the USB OTG port.

Thankfully the market is full of external hard disk enclosures that do a very good job at converting SATA to USB. And let's see what that means:

- SATA is currently doing 3 Gbps
- USB 2.0 is "just" 480 Mbps, here is a bottleneck, certainly, but is it?


Why USB 2.0 is fine instead of SATA

Does this sound like a let down? Really? Let's do the math:

Are you going to be streaming 1080p content over Wifi? That really leaves you with <300 Mbps, and most probably <150 Mbps, if you can maintain that incredible wireless speed.

But, let's see what 150 Mbps really means in today's high compression world:

150 Mbps / 8 bits per byte = ~19 MB/s and let's say your content is a 1h30m long movie...
19 MB/second * 90 minutes * 60 seconds/minute = 100 GB movie!

Is your movie larger than that? Then this solution is clearly not for you. For the rest of the world, let's go on:

You may rightly object: movies have well and bad compressed parts, fast action may mean a bandwidth spike!

Well, you are right, and that's why multimedia players use a technique called buffering! This mostly rids us of the problem.

So once we accept that it's OK to stream things at Megabit speeds, we may stop worrying about using SATA hard disks over USB.



Network interface:


As I/O, the Radxa Rock board has an integrated Fast Ethernet, that is connected directly to the RK3188 (through the usual RMII PHY interface). This means 100 Mbps so... people with movies of >66 GB may stop reading now.  ;-)

For the sake of this proof-of-concept, we will be using this 100 Mbps Ethernet port, although a better solution would be to have a Gigabit Ethernet adapter attached to a full sized USB 2.0 port, which would give us up to 480 Mbps of actual bandwidth.

Do not share the USB OTG port with the hard disk/s! The RK3188 (and the RK3066) has two physical USB 2.0 buses: the OTG and the "full sized", so use both as much as possible, instead of cramming all devices onto just one's bandwidth.




File-sharing Speed Testing:


I am using a bare Xubuntu Linux on the Radxa board so it is possible to connect to the SATA hard disk through FTPS out of the box.

The SATA II hard disk is in a external USB 2.0 enclosure and has a 1.5 TB NTFS partition and we will be using a FTPS server (slower than FTP). Not the best case for speed, but will let us see how well it can do on this not ideal setup.

So, first of all, let's test how fast the RK3188 itself can read files from it, by running this command on the connected [but unmounted] drive:
sudo hdparm -t /dev/sda
/dev/sda:
 Timing buffered disk reads:  90 MB in  3.03 seconds =  29.74 MB/sec
The repeated tests result always around and very close to 30 MB/second. That is some 240 Mbps, or 50% the theoretical maximum USB 2.0 speed.
Who is to blame? I fear in this case it's my old USB2SATA's fault, since doing the same speed test on an i7 top of the line PC yields some 33 MB/s.

Good, more of a worst case then, so let's do real life tests with actual multimedia files on the SATA disk served over Fast Ethernet by the Radxa Rock RK3188 board:

Streaming an 11 GB action movie (1080p) requires an average of 2 MB/s and is perfectly watchable on the remote PC, as if it were a local file.

Transferring a large file over Ethernet to another PC maintains a speed of 6.7 MB/s, that is a bit over 50 Mbps.

I've also tested transferring a file from the MicroSD card where Xubuntu runs, just to do a test without USB and SATA, the result is a constant speed of 7.2 MB/s.

For the sake of completeness, I too have tried this same raw transfer (FTPS from MicroSD) using a Gigabit Ethernet to USB 2.0 adapter, the result is a constant speed of 8 MB/s.
Better and more than enough for our purposes, but still below my expectations. Next thing will be to test with an FTP server, without the FTPS encryption burden!

Further details about these tests: the "intermediary" is a Gigabit switch that has been thoroughly tested at 1 Gbps speeds.

So it seems the RK3188 is perfectly able to cope with the task, even using a heavy encrypted FTPS server.



Conclusions for a faster NAS file-sharing solution


1) Use a Gigabit Ethernet to USB 2.0 adapter (and from a reliable source or you'll find yourself with a ridiculous USB 1.1 device able of <11 Mbps) and connect it to the full size USB port on your Rockchip board/stick.

2) Set up a simple FTP server for file-sharing, that makes sure your RK3188 can concentrate on reading the hard-disks through USB and the network protocols, instead of the heavyweight encryption for the FTPS. Even if you go wireless, Wifi already encrypts everything on the air!

3) Use Linux-friendly EXT4 partitions. NTFS is not bad, but will require more CPU to read/write (you'll see a process called "mount.ntfs" often). FAT what?

4) If you want to have a 4-disk NAS or even an 8-disks NAS, no problem! Just know you should still plug them all, through a USB hub, to the same USB port.

5) And the final tip to make a nice NAS solution:
sudo hdparm -B 50 /dev/sda
This wonderful command at NAS startup will take care of turning-off your hard disks when they are unused, saving power and hard-disk life, while keeping a 100% silent environment!


UPDATE: If the drive answers with:
HDIO_DRIVE_CMD failed: Input/output error
 APM_level = not supported
Then try this similar command:
sudo hdparm -S 20 -K 1 /dev/sda

(substitute /dev/sda in these commands with your actual /dev/sdX device)


Next step: a quad hard-disk NAS solution based on Rockchip ARMs for all my file serving needs!




Wednesday, October 16, 2013

Radxa Rock communicating with I2C devices

Since I'm a hardware tinkerer at heart, and my background is more on electronics than on software, the Radxa Rock board had a deeper interest for me.

This board has a lot of potential for all kind of low level electronics, thanks to its two expansion headers:

Expansion Headers from Radxa Rock schematics



As you can see there are two UARTs (number 3 is shared with some GPS pins), one I2C bus, two SPI buses (SPI1 on J8 is shared with GPS pins), a full 24 bits LCD display output (!!), one USB port (HOST_D*2), one audio Line In (LINE_L/R), as well as several other GPIO I/Os.



I then set out to test my latest kernel for booting Linux on the Radxa Rock to access one of the, for me, most interesting low level hardware buses: I2C.

This one is heavily used for low bandwidth (control/status, sensor data readings, EEPROMs, etc...) communications inter integrated circuits (I I C... I2C ;). This bus consists of just two lines: SCL (master clock) and SDA (bi-directional data), which makes it extremely handy.

And for this test, a handy old friend of mine: the BMP085 pressure sensor (featured on this blog's first post) inside a little PCB with an accelerometer chip, gyroscope chip, magnetometer compass chip, and our pressure and temperature sensor chip, the BMP085.

This is all called a 10-DOF or Ten Degrees of Freedom sensor board, since it allows for precise movement/position detection through "sensor fusion" (though I really dislike using nerdy "magic words").

So first's first, I wired the 10-DOF board to the Radxa's left expansion header (J8) in the following manner:
- PCB's VCC (5V) wired to J8 exp. header's pin 40 (DC5V)
- PCB's GND wired to J8 exp. header's pin 39 (GND)
- PCB's SDA wired to pin 32 (I2C0_SDA)
- PCB's SCL wired to pin 31 (I2C0_SCL)


The result looks like this:

Radxa Rock board bus I2C #0 connected to a 10 degrees-of-freedom sensor board


So, what to do to start communicating with the board? Well, since my kernel already has all the needed things built-in, you just have to follow these steps (shamelessly taken from this guide):

#install i2c-tools (user space) for talking to I2C buses/devices
sudo apt-get install i2c-tools
#insmod the I2C-dev module to allow user space access to I2C
sudo modprobe i2c-dev
#probe I2C bus 0, the one at expansion header J8
sudo i2cdetect -y 0

The result of this last command is the possibly detected I2C devices on bus 0 (remember the 10-DOF board has 4 devices sharing the same bus). In our case we do know the I2C address of the BMP085 (0x77), so we can talk to it directly.

Since I know the calibration parameters of my device (see AC* at first screenshot in this post) and their addresses, I can just compare to see if this is random data, or actually the BMP085 chip, being talked to from Linux running on the RK3188 of the Radxa Rock board:

Calibration parameter AC1, which for my 10-DOF board has a 2 byte value of 6746 (0x1A5A) is located at I2C registers 0xAA (MSB) and 0xAB (LSB), by reading the sensor's datasheet.

Let's dump the contents of the device at that address (the BMP085) to confirm we are talking to it:

#dump non-interactively (-y) contents of selected device (0x77)
#on given I2C bus (0) in byte read mode (b)
sudo i2cdump -y 0 0x77 b

Not really illustrating, but the result is:
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
80: a5 94 52 49 a4 27 77 a6 1e 26 1a 5a fb dd c7 bc    ??RI?'w??&?Z????
90: 7c 9e 60 2c 59 11 15 7a 00 37 80 00 d4 bd 09 80    |?`,Y??z.7?.????
a0: a5 94 52 49 a4 27 77 a6 1e 26 1a 5a fb dd c7 bc    ??RI?'w??&?Z????
b0: 7c 9e 60 2c 59 11 15 7a 00 37 80 00 d4 bd 09 80    |?`,Y??z.7?.????
c0: 00 00 bc 33 00 00 00 00 00 00 00 10 00 00 00 03    ..?3.......?...?
d0: 55 01 06 00 00 00 00 00 00 00 00 00 00 00 00 00    U??.............
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
f0: 00 00 00 00 00 00 80 00 00 00 00 00 00 00 00 00    ......?.........


And sure enough! you can find the values (1a and 5a) of this little example at the expected register addresses (0xAA and 0xAB).

RK3188 is communicating with the 10-DOF board through one I2C bus at the expansion header!

Radxa Rock meets the world of electronics!






Saturday, October 12, 2013

Doubts over Rockchip FB Vsync fix

Almost every owner of a RK3188 stick has noticed video problems, like stuttering or a lost frame every now and then, no matter its being a local file or just a small avi.

Some time ago phjanderson (from Freaktab forum) found a solution to this:
http://www.freaktab.com/showthread.php?5939-Fixing-RK3188-video-playback/page2&p=81489#post81489

It basically eliminated a blocking condition on a function on rk_fb.c, which also happened to apparently solve the stutter problem. This was called phjanderson's Vsync fix and lots of ROMs have added this patch since.

I then set out to test it on Linux along with my framebuffer fix (see https://github.com/Galland/3188-SRC-AP6210/commit/a3ddf7e46c4426e6cc67e09d7eee2a14baeea1f0 ) just to find that after a random amount of minutes after boot, there appeared a new thread called "fb-vsync" that utilized 100% of one of the 4 cores on the RK3188, regardless of the system being idle or never even opening a video.

To me, this is unacceptable since it forces the CPU to run at higher frequencies all the time, as well as consume lots more of power and a 25% performance penalty hit.

I initially thought it had something to do with Linux' screen usage or even with my framebuffer fix. However it did happen without the framebuffer fix, so I just let it out of my kernels.

However, I recently read on a forum ( http://www.rikomagic.co.uk/forum/viewtopic.php?p=15682&sid=e872d9b5e003da9082af7976a28fa50c#p15682 ) that Android people are seeing also the 25% CPU usage constant (1 core out of 4) due to this thread.

So I heavily suspect this patch is great for fixing the Vsync video stutter problems, but at the cost of losing 25% of the CPU performance, consuming more power all the time (+heat!), and thus reducing the component's life.

If you happen to have flashed a rooted ROM with Vsync fix and have an Android monitor installed (able to track system threads), please write a comment sharing if you've been able to see the thread in action.


UPDATE:

I'll try to explain a bit the code related to this problem.
Most of it is located in rk_fb.c where:
1) upon registering fb0 (the main framebuffer) a thread called "fb-vsync" is created.
2) This thread executes the function "rk_fb_wait_for_vsync_thread"
3) This function is an "infinite" loop that emits a "vsync" notification to user-space apps subscribed to it, whenever a Vsync happens, meanwhile it waits idle.

How does it wait for a Vsync?
Through the use of "wait_event_interruptible" with arguments:
   - waitqueue: this is the event queue we're hanging on: dev_drv->vsync_info.wait
   - condition:
!ktime_equal(timestamp, dev_drv->vsync_info.timestamp) && dev_drv->vsync_info.active

The 2nd part of the condition (dev_drv->vsync_info.active) should always be met since it is set to 1 just after creating this thread.
What about the 1st part? It compares:
a) variable "timestamp": which is constant!! and set to the value of "dev_drv->vsync_info.timestamp" as it was just before calling "wait_event_interruptible".
b) dev_drv->vsync_info.timestamp as it IS any time the waitqueue is awaken

Naturally this condition is meant to become true (and exit the wait event to send the "vsync" notification) at the next Vsync.

Why? Because "dev_drv->vsync_info.timestamp" is updated by the lcdc interrupt service routine, which at the same time wakes up our "wait_event_interruptible" above!

Then the !ktime_equal compares the "timestamp" variable that holds the PREVIOUSLY set vsync_info.timestamp (before the wait_event is triggered) with the CURRENT, just updated, vsync_info.timestamp.
Hence the condition may indeed become true.


What did phjanderson's fix do? It just made this wait event to always have a true condition, hence the "while" loop is constantly executing (no wait) and notifying a "vsync".

How does it interact with Galland's framebuffer fix? Note that in the lcdc isr, the fb fix excludes the wake_up_... call, so what it does is make the wait event above to never be woken up. Kind of the opposite to phjanderson's.

The union of both fixes is... unfortunate too :) so I just left out phjanderson's fix, since the isr changes are needed for the overall fb fix.