Setup of development environment

NOTE: I was not able to get a USB hard disk to reliably work with the OLinuXino A10S. However, I was able to reliably use a SD card with the mentioned ARM computer for storage. Thus, I recommend that you substitute a SD card for the USB hard disk. Just insert that card in the SD card slot, and do the necessary adjustments in the steps below.

1] Create a VirtualBox VM for Debian 7.2.0 i386. I allocated 1024MB of RAM to it. As for the virtual hard drive space, I allocated 8GB. I also recommend that you disable audio support for the VM.
2] Download the Net Install ISO image for Debian 7.2.0 i386. Boot the mentioned ISO in the VirtualBox VM you've created. I used the "Install" option in the installer boot menu.
3] This set of instructions will work with everything deselected under "Software selection." You may select software to your taste during installation.
4] After the installation, the guest OS will automatically get an IP Address via DHCP.
5] As root in your guest OS:
# apt-get update
# apt-get upgrade
6] Install OpenSSH client and server software as root in your guest OS if this will make file transfers and access to your development environment convenient for you:
# apt-get install openssh-client openssh-server
7] As root in your guest OS:
# apt-get install ncurses-dev uboot-mkimage build-essential git
# cd ~
# wget http://www.malaya-digital.org/gcc-linaro-arm-linux-gnueabihf-4.7-2013.01-20130125_linux.tar.bz2
# tar xjfv gcc-linaro-arm-linux-gnueabihf-4.7-2013.01-20130125_linux.tar.bz2
8] Add toolchain directory to $PATH in your guest OS(You may want to add this to /etc/profile . Appending it will do.):
export PATH=/root/gcc-linaro-arm-linux-gnueabihf-4.7-2013.01-20130125_linux/bin:$PATH
9] Restart your guest OS as root:
# shutdown -r now

Compiling the kernel
1] In the development environment you've made above, login as root. Then get the kernel source code:
# cd ~
# git clone https://github.com/linux-sunxi/linux-sunxi
2] Note that I'm using the revision below(this is the latest revision for the 3.4.61 kernel):
# cd ~/linux-sunxi/
# git rev-parse --verify HEAD
01d42bfbd0ab3f42205ba1d3f266840bbf14098a
So, to checkout the mentioned revision:
# cd ~/linux-sunxi/
# git checkout 01d42bfbd0ab3f42205ba1d3f266840bbf14098a
3] Do a "make clean":
# cd ~/linux-sunxi
# make clean
4] Download a10s_defconfig:
# cd ~/linux-sunxi
# wget http://www.malaya-digital.org/a10s_defconfig
Move this file to ~/linux-sunxi/arch/arm/configs/ . These are to be done in your development environment as root:
# mv a10s_defconfig ~/linux-sunxi/arch/arm/configs/
5] Execute the following under the linux-sunxi directory in your development environment as root:
# cd ~/linux-sunxi/
# make ARCH=arm a10s_defconfig
6] Configure the kernel in your development environment as root:
# make ARCH=arm menuconfig

HINT: If you're having problems with Logitech wireless keyboards and mice, don't build this (for Linux 3.4.61):
Device Drivers->HID Devices->Special HID drivers->< > Logitech Unifying receivers full support

HINT: To verify OTG is enabled(for Linux 3.4.61):
Under Kernel Configuration, this must be built in the kernel:
Device Drivers->USB support->[*] SUNXI USB2.0 Dual Role Controller Support
Also, this must be built in the kernel, too:
Device Drivers->USB support->SUNXI USB2.0 Dual Role Controller Support->[*] SUNXI USB2.0 Manager
And make sure of the following:
Device Drivers->USB support->SUNXI USB2.0 Dual Role Controller Support->SUNXI USB2.0 Manager->USB0 Controller support (otg support)->(X) otg support

HINT: To verify Ethernet is enabled(for Linux 3.4.61):
Under Kernel Configuration, this must be built in the kernel:
Device Drivers->Network device support->Ethernet driver support-><*> Allwinner Ethernet MAC support
7] Note that before compiling kernel, you have to patch it:
Download the patch hcd_axp-md.patch from http://www.malaya-digital.org/hcd_axp-md.patch:
# cd ~/linux-sunxi/
# wget http://www.malaya-digital.org/hcd_axp-md.patch
Copy files:
# cp drivers/usb/sunxi_usb/hcd/hcd0/sw_hcd0.c drivers/usb/sunxi_usb/hcd/hcd0/sw_hcd0a.c
# cp drivers/usb/sunxi_usb/hcd/hcd0/sw_hcd0.c drivers/usb/sunxi_usb/hcd/hcd0/sw_hcd0b.c
Apply the patch:
# patch -p0 < hcd_axp-md.patch
Copy a file again:
# cp drivers/usb/sunxi_usb/hcd/hcd0/sw_hcd0a.c drivers/usb/sunxi_usb/hcd/hcd0/sw_hcd0.c
8] Edit ~/linux-sunxi/arch/arm/plat-sunxi/include/plat/i2c.h . Find "I2C0_TRANSFER_SPEED". Define "100000" for I2C1_TRANSFER_SPEED and up. These are to be done in your development environment as root. For example, the desired edit is:

#define I2C0_TRANSFER_SPEED (400000)
#define I2C1_TRANSFER_SPEED (100000)
#define I2C2_TRANSFER_SPEED (100000)
#define I2C3_TRANSFER_SPEED (100000)
#define I2C4_TRANSFER_SPEED (100000)
9] To maximize available memory, edit .config and look for the line having "CONFIG_CMDLINE". Then edit the line to become::
CONFIG_CMDLINE="mem=448M@0x40000000 console=ttyS0,115200 sunxi_ve_mem_reserve=0 sunxi_g2d_mem_reserve=0 sunxi_no_mali_mem_reserve sunxi_fb_mem_reserve=8"
10] Look for CONFIG_SUNXI_MALI_RESERVED_MEM, CONFIG_MALI, and CONFIG_MALI400 in .config . Set them to "n" :
CONFIG_SUNXI_MALI_RESERVED_MEM=n
CONFIG_MALI=n
CONFIG_MALI400=n

11] You can now compile the kernel and its modules in your development environment as root.
# cd ~/linux-sunxi/
# make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j4 uImage
# make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j4 INSTALL_MOD_PATH=out modules
# make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j4 INSTALL_MOD_PATH=out modules_install
12] In your development environment, your kernel will be "~/linux-sunxi/arch/arm/boot/uImage". And your modules will be found at "~/linux-sunxi/out/lib/modules/3.x.xx" where 3.x.xx is kernel version (eg: "3.4.61+").

Compiling Uboot (Copied from http://olimex.wordpress.com/2013/06/19/building-linux-for-a10s-from-scratch/ and http://olimex.wordpress.com/2013/10/28/building-debian-sd-card-for-linux-with-kernel-3-4-from-scratch-for-a10s-olinuxino-micro/ with some modifications)
The Allwinner Linux-Sunxi community uboot is maintained by Henrik Nordstrom aka hno on Freenode irc. You can find him in #linux-sunxi or #olimex channels. If something with uboot is broken, he is your man.

1] Download the uboot sources from GitHub repository.
# cd ~
# git clone https://github.com/linux-sunxi/u-boot-sunxi

After the download, you should have a new directory.

# cd ~/u-boot-sunxi/
2] Note that the revision below was used for this document.
root@debian:~/u-boot-sunxi# git rev-parse --verify HEAD
09ef3a640a3eb58e66eedcf239193e2ab548e730

So, to use the mentioned revision:

root@debian:~/u-boot-sunxi# git checkout 09ef3a640a3eb58e66eedcf239193e2ab548e730

3] With the following command, you can start the uboot build:

# cd ~/u-boot-sunxi/
# make distclean CROSS_COMPILE=arm-linux-gnueabihf-
# make a10s-olinuxino-m CROSS_COMPILE=arm-linux-gnueabihf-
4] At the end of the process, you can check if everything is OK by:

# ls u-boot-sunxi-with-spl.bin
If you got this file, well done so far.

Format and setup the SD-card (Copied from http://olimex.wordpress.com/2013/06/19/building-linux-for-a10s-from-scratch/ with some modifications)
We suggest that you use a 4GB class 10 micro SD card. But you can use any micro SD card between 2GB and 16GB.

Also, please make sure you have a micro SD card that is "clean." By "clean," I mean that this card was not set yet before for an ARM computer. If your micro SD card is not clean, there is a good chance that it will not boot. To clean by erasing the partition table and labels (Substitute "/dev/mmcblkX" appropriately for your micro SD card):

# dd if=/dev/zero of=/dev/mmcblkX bs=1M count=10

First, we have to make the correct card partitions. This is done with fdisk.

1] Plug the micro SD card into your SD card reader. Then, enter in the terminal:

# ls /dev/sd
Then press TAB twice. You will see a list of your sd devices like sda, sdb, sdc, etc. Note that some of these devices may be your hard disk, so make sure you know which one is your micro SD card before you proceed. You can damage your HDD if you choose the wrong sd device. You can do this by unplugging your micro SD card reader, and identify which ?sd? devices was removed from the list.

2] Once you know which device is your micro SD card, use this text instead of the sdX name in the references below:

# fdisk -u=sectors /dev/sdX
Then do these steps:

2a] This will list your partitions:
p

2b] If there are already partitions on your card, do:
d 1
If you have more than one partitition, delete them all.

2c] Create the first partition. It should start from 2048 and end at 34815:
n p 1

2d] Create the second partition:
n p 2 enter enter

2e] List the created partitions:
p

If you did everything correctly on a 4GB card, you should see something like:

Disk /dev/sdX: 3980 MB, 3980394496 bytes
123 heads, 62 sectors/track, 1019 cylinders, total 7774208 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: 0x00000000

Device Boot Start End Blocks Id System
/dev/sdg1 2048 34815 16384 83 Linux
/dev/sdg2 34816 7774207 3869696 83 Linux

2f] Write changes to the micro SD card.
w

3] Now, we have to format the file system on the card:

The first partition should be vfat as this is the FS which the Allwinner bootloader understands.

# mkfs.vfat /dev/sdX1

4] The second partition should be a normal Linux EXT4 FS:

# mkfs.ext4 /dev/sdX2

Installing the kernel, Debian mini root filesystem, and kernel modules
1] Proceed to copy the "~/linux-sunxi/arch/arm/boot/uImage" kernel you've compiled in the development environment into the first filesystem of the micro SD card.
Mount the first partition:
# mkdir /mnt/olinuxino0
# mount /dev/sdX1 /mnt/olinuxino0 # Substitute the appropriate value for X in /dev/sdX1

Then copy the kernel uImage to the first filesystem of the micro SD card.
# cp uImage /mnt/olinuxino0 # Get the uImage file from the environment you've compiled the kernel.
2] Copy the script.bin file in /mnt/olinuxino0 . The mentioned file can be found here: https://drive.google.com/file/d/0B-bAEPML8fwlYkItdU1TTm1VN0E/edit?usp=sharing
--OR--
If you need to compile your own script.bin, you can get the fex files here in a scripts_A10s.7z archive: https://drive.google.com/file/d/0B-bAEPML8fwlY3llVDJxelY3d28/edit?usp=sharing
3] Unmount /mnt/olinuxino0 :
# umount /mnt/olinuxino0
4] Mount the second partition:
# mkdir /mnt/olinuxino1
# mount /dev/sdX2 /mnt/olinuxino1 # Substitute the appropriate value for X in /dev/sdX1
5] Extract the debian_34_fs_a10s.tgz root filesystem in /mnt/olinuxino1 . Debian root filesystem can be found here: https://drive.google.com/file/d/0B-bAEPML8fwlR0N2MEJ5WExYM1U/edit?usp=sharing
6] Proceed to copy the generated kernel modules ("~/linux-sunxi/out/lib/modules/3.x.xx" in the development environment where you've compiled the kernel) in the second filesystem of the micro SD card.

If the /mnt/olinuxino1/lib/modules directory does not exist, create it. Also, if a /mnt/olinuxino1/lib/modules/3.4.61+ directory exists, delete it.
# mkdir /mnt/olinuxino1/lib/modules
# cp -rf 3.x.xx+ /mnt/olinuxino1/lib/modules # Get the modules directory from the environment you've compiled the kernel.
7] Unmount /mnt/olinuxino1 :
# umount /mnt/olinuxino1

Write Uboot (Copied from http://olimex.wordpress.com/2013/06/19/building-linux-for-a10s-from-scratch/ with some modifications)

1] Note that you have to write u-boot-sunxi-with-spl.bin in /dev/sdX (not sdX1 or sdX2).

# dd if=u-boot-sunxi-with-spl.bin of=/dev/sdX bs=1024 seek=8
# sync

Hints:

1] Edit your the /etc/network/interfaces file in your SD card to assign a static IP address:
# interfaces(5) file used by ifup(8) and ifdown(8)
auto lo eth0
iface lo inet loopback

#auto eth0
#iface eth0 inet dhcp
# address 192.168.1.254
# netmask 255.255.255.0
# gateway 192.168.1.1

#auto eth0
iface eth0 inet static
address 192.168.1.253
netmask 255.255.255.0
gateway 192.168.1.254

#auto wlan2
#iface wlan2 inet dhcp
#wpa-ssid YourSSID
#wpa-psk YourPass

2] Also, you may want to configure in some DNS servers into the SD card. Edit the /etc/resolv.conf file in your SD card(the servers provided here are from opendns.com):
nameserver 208.67.222.222
nameserver 208.67.220.220

NB: When you boot OLinuXino using the micro SD card with Debian Lenny, the "root" user has the password "olimex" by default.

Preparation of your OLinuXino's OS:

1] Make sure your OLinuXino is connected to your network. Boot your OLinuXino. The following operations (unless otherwise specified) in this section are to be done as root in your OLinuXino's OS.
2] Stop unnecessary services:
# chmod 775 /etc/init.d/exim4
# /etc/init.d/exim4 stop
# insserv -r exim4

3] Do an update and purging:
# apt-get update
# apt-get purge lightdm .*x11.* alsa.* sudo mpg123.* mpg321.* mplayer.* vlc.* perl python
# apt-get autoremove
# apt-get upgrade

4] Reconfigure your timezone, if necessary:
# dpkg-reconfigure tzdata

5] To change hostname:
Edit /etc/hostname and write your hostname there in one line

6] Shutdown your OLinuXino.
# shutdown -h now

7] Attach your printer to the USB-OTG port. Then attach a good and powered USB hard disk drive to the USB 2.0 port(the USB hard disk drive must be powered as the OLinuXino A10S USB 2.0 port won't give adequate current). Don't forget to turn on your printer and powered USB hard disk drive. Turn your OLinuXino A10S on.
8] Install Swat, Samba, and CUPS:
# apt-get install swat cups

9] Edit cupsd.conf:
# cd /etc/cups
# cp -p cupsd.conf cupsd.conf.orig
# vi cupsd.conf

* Change:
Listen localhost:631
* To:
Listen 192.168.1.253:631 # Substitute the IP you've assigned for the OLinuXino A10S.

* Look for the following:
# Restrict access to the server...
<Location />
Order allow,deny
</Location>

# Restrict access to the admin pages...
<Location /admin>
Order allow,deny
</Location>

* Make the following changes on the text you looked for:
# Restrict access to the server...
<Location />
Order allow,deny
Allow from 192.168.1.*
</Location>

# Restrict access to the admin pages...
<Location /admin>
Order allow,deny
Allow from 192.168.1.*
</Location>

10] Restart CUPS:
# /etc/init.d/cups restart

11] Use a web browser from a computer (other than your OLinuXino) in your network to go to the CUPS admin page(Use root as the user, and use your root password at authentication.):
https://192.168.1.253:631/admin

Make sure the following are ticked:
Allow remote administration
Share printers connected to this system

Click "Change Settings" if you've made changes.

12] Click "Add Printer" under Printers. Use the root user and its password when CUPS asks you to authenticate. Your printer should be listed under "Local Printers." Choose it, then click "Continue." Tick the "Share This Printer" tick box. Click "Continue." Make the appropriate choices in the next pages.

13] Edit /etc/rc.local . Put the following before "exit 0". This assumes that there is only 1 partition in the external USB hard disk. I used ext4 as the file system.
mount /dev/sda1 /home

14] Remove "colord". Shutdown your OLinuXino, and then turn it back on:
# apt-get remove colord
# shutdown -h now

15] From the commandline in your OLinuXino, create a Samba user:
# useradd -d /home/share -s /bin/false share
# mkdir /home/share
# chown share:users /home/share
# smbpasswd -a share

16] Use a computer (other than your OLinuXino) in your network to go to the SWAT admin page(Use root as the user, and use your root password at authentication.):
http://192.168.1.253:901

Click "Printers".
Select your printer in the drop down box to the right of the "Choose Printer" button. Then click the "Choose Printer" button. Set "Guest OK" to "Yes". Click "Commit Changes".

Click Shares.
Put a share name (eg: "Share") on the field to the right of the "Create share" button.
Click the "Create share" button.
Put your username(eg: "share") as a valid user.
Change Read Only to No, and Available to Yes.
Place your Path (eg: "/home/share").
Click Commit Changes.

Click the Status button.
Click the "Restart All" button.

17] You should have a working system now. 🙂

HINT: Disable advanced printing features in your Windows clients to make tasks like PDF printing possible. To do this, right click your printer icon, click "Printer properties," and then click the "Advanced" tab. Untick "Enable advanced printing features".