Installing a customized Debian on the Cubieboard

Forward: http://abhinavgupta2812.wordpress.com/2013/08/24/installing-a-customized-debian-on-the-cubieboard/

A few weeks back, I had the chance of working with this new family of ARM based System on Chip (SoC) chipset from this company called Allwinner Technologies and are the two most famous development boards based on the Allwinner A10 chipset. And from its specifications, I can assure you, they are far more powerful and customizable than Raspberry Pi and BeagleBoards. If you want an in detailed comparison between CubieBoard and Raspberry Pi, you can have a look at Alexandre’s blog. As Alexandre has pointed out rightly in his blog, the CubieBoard community is very young and the support is as good as zero. Hence this post is going to be an in-detail procedure on how to install a customizable version of a headless Debian on the CubieBoard. And maybe later, I might have some posts on how to interface with daughter controllers or something like using the board to set up a dedicated server.The CubieBoard comes with a stock Android ICS on its NAND flash memory. However, there is a provision to boot from SD card. Hence we create a boot-able SD card for using the OS of our choice. This involves four steps:

  1. Partitioning the SD card (Preferred SD card size = 4GB)
  2. Installing the bootloader
  3. Installing the kernel files and the script.bin
  4. Installing a proper root file-system

A lot of out-of-the-box images for SD cards exist, but if you use them, you won’t be able to customize the GPIOs for your specific purpose. Hence we will manually do each step and look at the flexibilities it provides. To keep the post simple and short, I won’t be discussing how to build the tool-chains and kernel images in this post and use the kernel images I created myself instead. I will have separate posts for building the kernel images and the pin binaries.The first and foremost requirement is to have Linux on your host machine (Laptop/Desktop).  I am not sure about Mac systems, but I am guessing that should be fine as well. But Windows is a strict no-no.

Partitioning the SD card:

The first MB of the SD card contains the partition table along with the bootloader binaries for booting. The next partition contains the kernel Images and the boot.scr files. The biggest partition contains the rootfs which takes around more than 2GB space. Thus it is best to use a 4GB SD card.Now assuming that you have installed the sfdisk tools and your card is connected to the host machine, we begin with checking the partition table and the physical characteristics of the SD card, such as bytes per sector. Here we assume that the card is named sdd in the /dev/ folder. To know the name of your SDcard, run the command

home@user:~ sudo ls -la /dev/sd*  

This will list all the disk type devices connected to your machine and you can read the name from there. After running

home@user:~ fdisk -l  

This is waht you should see:

Disk /dev/sdd : 3965 MB, 3965190144 bytes 122 heads, 62 sectors /track , 1023 cylinders, total 7744512 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical /physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0xb4e92fdc  Device Boot    Start      End      Blocks      Id      System /dev/sdd1      2048      34815     16384       83      Linux /dev/sdd2     34816    7744511   3854848       83      Linux  

Notice how sdd1 starts at 2048 sector. As the byte per sectors is 512, 2048 sector means that the partition sdd1 starts at 1MB. Usually the first  1MB space in a memory device is reserved for the Master Boot Record (MBR), the partition table and in case the memory device is bootable, the Initial Program Loader (IPL) and the Secondary Program Loader (SPL), also known as the bootloader binaries. Resetting the first 1MB of the SDcard ‘formats’ it.  to do that you need to run the following command:

home@user:~ dd if = /dev/zero of= /dev/sdd bs=1M count=1  

This writes zeroes for the byte size (bs) of 1MB, starting from the first sector itself. Thus rewriting over the entire column and subsequently formatting the entire card. If you run

home@user:~ fdisk -l  

now, it will show no partition table exists. Now we will use the sfdisk tools to make our partitions.Most SD cards have similar properties as the one shown above, i.e bytes per sector is usually 512. Using this information, we calculate the number of sectors for our partitions and start from sector 1MB (Since the first MB is preserved for the above mentioned reasons). The following commands create a 64MB fat partitions and the rest is used as an ext4 partition.

home@user:~$ sfdisk -uS /dev/sdd 2048,131072,c  
#Here it tells you to define sdd1 131073,
,L` `#Here it tells you to define sdd2\. Being the last partition,``just press enter twice to` `exit`</td>

Now we format these partition appropriately by running the following commands:

home@user:~$ mkfs.vfat /dev/sdd1  
home@user:~$ mkfs.ext4 /dev/sdd2  
home@user:~sync  

Installing the kernel image and filesystem on the card:

Now that we have the card partitioned according to our needs, its time to set up the card by putting the appropriate files in their respective partitions. I have prepared three versions of kernel files and the bootloaders for the CubieBoard board. You can get these files from hereA brief explanation of the files in this repository:

  1. Bootloader : This directory contains the bootloader files for the CubieBoard
  2. kernelsunxi3_* : These directories are the different kernel versions

  3. lib : This directory contains the firmware for that specific kernel version

  4. uImage : The actual kernel image file

  5. script.bin : The files that specifies the functionality of each pin.

So the flexibility provided here is that you can make your own script files and hence specify every pin’s function. Furthermore, you can write your own patches for the kernel and make custom images depending on what you desire. How to do generate custom files for these will be shown in later posts.We should now have 2 partitions. One 64M in vfat format, and another in ext4. We also need to make this bootable, so lets blat in the IPL and SPL to the SD at the appropriate places. These files are in the directory named “bootloader” in the link given above.Write spl ->8k and then write uBoot ->32k on the SD card.

home@user:~ dd if =sunxi-spl.bin of= /dev/sdd bs=1024 seek=8  
home@user:~ dd if =u-boot.bin of= /dev/sdd bs=1024 seek=32  

Now create a folder on your linux machine and mount both the partitions there. Do the following assuming that you are the superuser (sudo su):

home@user:~$ mkdir /mnt  
home@user:~$ mkdir /mnt/boot  
home@user:~$ mkdir /mnt/rootfs  
home@user:~$ mount -t auto /dev/sdd1 /mnt/boot  
home@user:~$ mount -t auto /dev/sdd /mnt/rootfs  
home@user:~$ cd /mnt/boot  

Now, create a file in the /mnt/boot directory named boot.cmd and write the
following in it:

setenv bootargs console=ttyS0,115200 console=tty0 noinitrd init=/init root=/dev/sdd2  
rootfstype=ext4 rootwait panic=10 ${extra}  
fatload mmc 0 0x43000000 script.bin  
fatload mmc 0 0x48000000 kernel.img  
bootm 0x48000000  

The first line calls the kernel, and passes parameters onto it. You’ll note that I setup 2 consoles, one on tty0 and another on ttyS0. I like to have both a serial and a display console on kernel bootup. Now we need to compile it, to do that, run the following:

mkimage -C none -A arm -T script -d boot.cmd boot.scr  

Next step is to copy the kernel image and the script file. Assuming you are in the folder kernelsunxi3-- (Depending on your choice of kernel version)

home@user:~$ cp uImage /mnt/boot  
home@user:~$ cp script.bin /mnt/boot  

Now we have all the pre boot binaries, bootloaders, kernel image and the script.bin files all loaded on to the SD card. Now we come to the last part, uploading the file system. I prefer the newest version of the Debain filesystem as it more flexible and light in nature. Now you need to download the tar file of the filesystem and unpack it at the place where your second partition is mounted
(i.e /mnt/rootfs).

home@user:~$ cd /tmp  
home@user:~$ axel http://dl.cubieforums.com/loz/rootfs/debian-unstable-armhf.tar.bz2  
home@user:~$ cd /mnt/rootfs  
home@user:~$ unp /tmp/debian-unstable-armhf.tar.bz2  

This will unpack the Debain filesystem on the second partition. After this, you need to copy the compiled drivers, firmware etc to the appropriate place in the rootfs. This is an absolutely necessary step as any changes in the driver files wont take effects if they are not copied to the appropriate places in the file system. Here is an example snippet of this (Assuming again that the user is in the kernelsunxi3--):

home@user:~$ mkdir -p /rootfs/lib/modules  
home@user:~$ rm -rf /rootfs/lib/modules/  
home@user:~$ cp -r lib /rootfs/  
Now just unmount the the SD card:  
home@user:~$ umount /mnt/boot  
home@user:~$ umount /mnt/rootfs  

Now just unmount the the SD card:

In case it says, it is busy, open a new instance of the terminal and run. It will surely work. After this, just boot up your cubieboard with this SD card. Use GNU screen command to see the boot sequence (Use this link for reference of TTL-USB Connections and using GNU screen). If the boot is successful, it will ask you for login and password. They are root and password respectively.