Getting Started with BananaPI Linux
Single board computers have been very popular in the community due to their low price and high flexibility and Banana Pi board, which is powered by Allwinner A20, is no exception. In this blog post you will find everything you need to prepare a Banana Pi Linux image from scratch.
Board setup
I have a Banana Pi (Foxconn Super Pi clone actually) with a 5″ capacitive touchscreen which is connected to RGB pins with an adapter board. Find the scheme and details of the board here. For internet connectivity i use TL-WN725N (v3) wifi dongle that has RTL8188EU chip.
Build environment
Build OS
To make everything clear, it is important to prepare the same working environment as instructed here. So I started on a fresh Ubuntu 16.04.3 64bit installation and you should do the same (VMware is also possible).
Required packages
On the version of Ubuntu I am currently using have some problems installing the packages and this is why I use aptitude to solve the dependency problems.
1 2 |
sudo apt-get update sudo apt-get install aptitude |
Now run the following to prepare the environment.
1 |
sudo aptitude install build-essential u-boot-tools binutils-arm-linux-gnueabihf gcc-4.8-arm-linux-gnueabihf-base g++-4.8-arm-linux-gnueabihf gcc-arm-linux-gnueabihf cpp-arm-linux-gnueabihf libusb-1.0-0-dev git wget fakeroot kernel-package zlib1g-dev libncurses5-dev device-tree-compiler libssl-dev |
Here aptitude solves the problems and we must choose where no package stays “not installed”. The solution below works perfect for me.
If everything is ready, let’s go ahead to the image building.
Banana Pi BSP building
The most important parts are Uboot bootloader and kernel building. Run the following to get the repositories for u-boot v2016.09, stable Linux Mainline Kernel v4.15 and firmware files that are necessary for some drivers to operate.
1 2 3 |
git clone git://git.denx.de/u-boot.git --depth 1 -b v2016.09 git clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git --depth 1 -b v4.15 git clone git://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git --depth 1 |
U-boot compilation
The required GCC is version 4.8 for this version of u-boot. This is why we need to hack the Makefile.
1 2 |
sed -i 's/$(CROSS_COMPILE)gcc-4.8/$(CROSS_COMPILE)gcc/g' ~/u-boot/Makefile sed -i 's/$(CROSS_COMPILE)gcc/$(CROSS_COMPILE)gcc-4.8/g' ~/u-boot/Makefile |
Now is the part for LCD and touch settings. Note that the configuration is given for the adapter board of which details are given above.
1 2 3 4 5 6 7 |
cat<<END >> ~/u-boot/configs/Bananapi_defconfig CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:24,pclk_khz:30000,le:40,ri:40,up:29,lo:13,hs:48,vs:3,sync:3,vmode:0" # CONFIG_VIDEO_LCD_BL_PWM_ACTIVE_LOW is not set CONFIG_VIDEO_LCD_POWER="PH12" CONFIG_VIDEO_LCD_BL_EN="PH8" CONFIG_VIDEO_LCD_BL_PWM="PB2" END |
Finally, run the following to compile the bootloader.
1 2 3 4 5 6 |
cd ~/u-boot export CROSS_COMPILE=arm-linux-gnueabihf- make clean make Bananapi_defconfig make -j8 |
If everything is fine, you can find the u-boot image at ~/u-boot/u-boot-sunxi-with-spl.bin.
Linux mainline kernel for BananaPi
Mainline kernel compilation takes place with respect to defconfig file. Place the this bpi_defconfig file to path: ~/linux-stable/arch/arm/configs/bpi_defconfig without file extension.
Edit the device tree file at: ~/linux-stable/arch/arm/boot/dts/sun7i-a20-bananapi.dts for touchscreen settings. Add the following after i2c2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
&i2c3 { status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&i2c3_pins_a>; edt: edt-ft5x06@38 { compatible = "edt,edt-ft5x06", "edt,edt-ft5206"; reg = <0x38>; pinctrl-names = "default"; pinctrl-0 = <&edt_ft5x06_pins_a &edt_ft5x06_pins_b>; interrupt-parent = <&pio>; interrupts = <7 9 IRQ_TYPE_EDGE_FALLING>; touchscreen-size-x = <800>; touchscreen-size-y = <480>; //touchscreen-inverted-x; //touchscreen-inverted-y; //touchscreen-swapped-x-y; }; }; |
Then add the following into section pio:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
edt_ft5x06_pins_a: ft5@0 { // interrupt pins = "PH9"; function = "irq"; drive-strength = <20>; bias-pull-up; }; edt_ft5x06_pins_b: ft5@1 { // reset-gpios pins = "PH7"; function = "gpio_out"; drive-strength = <20>; bias-pull-up; output-high; }; |
To activate ft5x06 touchscreen and RTL8188EU wifi driver:
1 2 3 |
sed -i 's/# CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set/CONFIG_TOUCHSCREEN_EDT_FT5X06=y/g' ~/linux-stable/arch/arm/configs/bpi_defconfig sed -i 's/CONFIG_RTLWIFI_USB=m/CONFIG_RTLWIFI_USB=y/g' ~/linux-stable/arch/arm/configs/bpi_defconfig sed -i 's/CONFIG_R8188EU=m/CONFIG_R8188EU=y/g' ~/linux-stable/arch/arm/configs/bpi_defconfig |
Now everything is ready for compilation.
1 2 3 4 5 6 7 8 9 |
cd ~/linux-stable export ARCH=arm export CROSS_COMPILE=arm-linux-gnueabihf- make clean make bpi_defconfig make -j8 dtbs make -j8 uImage modules LOADADDR=0x40008000 INSTALL_MOD_PATH=output make -j8 modules_install INSTALL_MOD_PATH=output |
After successful compilation device-tree binary can be found at ~/linux-stable/arch/arm/boot/dts/sun7i-a20-bananapi.dtb, kernel image file (uImage) is located at ~/linux-stable/arch/arm/boot/uImage and modules are under ~/linux-stable/output/.
Boot script preparation
Boot script is the file that informs u-boot about the necessary settings, kernel and dtb locations. Run this.
1 2 3 4 5 6 |
cat <<END > ~/boot.cmd setenv bootargs console=ttyS0,115200 console=tty0 consoleblank=0 loglevel=2 root=/dev/mmcblk0p2 rootwait panic=10 load mmc 0:1 0x43000000 sun7i-a20-bananapi.dtb load mmc 0:1 0x42000000 uImage bootm 0x42000000 - 0x43000000 END |
To enable more boot messages you can also use the following but it impacts the performance.
1 |
setenv bootargs console=ttyS0,115200 console=tty0 consoleblank=0 loglevel=8 initcall_debug verbose debug root=/dev/mmcblk0p2 rootwait panic=10 |
The created boot.cmd must be converted into boot.scr with the following tool.
1 |
sudo mkimage -C none -A arm -T script -d ~/boot.cmd ~/boot.scr |
RootFs for BananaPi
There are several ways to create a rootfs but obtaining one is a fast and the most reliable option for a start. Linaro provides rootfs for several distributions and versions and here is a Debian rootfs that works fine.
1 |
wget https://releases.linaro.org/debian/images/alip-armhf/16.04/linaro-jessie-alip-20160428-22.tar.gz -P ~/ |
Bootable SD card preparation
Environment setup
Here we have u-boot, boot script, device-tree-binary, uImage and rootfs in hand. Next step is gathering all together to create our bootable Banana Pi SDcard. First, define the source paths and directories.
1 2 3 4 5 |
export uboot=~/u-boot/u-boot-sunxi-with-spl.bin export uimage=~/linux-stable/arch/arm/boot/uImage export dts=~/linux-stable/arch/arm/boot/dts/sun7i-a20-bananapi.dtb export bsp=~/linux-stable/output/ export firmware=~/linux-firmware/* |
Plug your 4GB+ card to the machine (or virtual machine) and find the drive letter using lsblk. Export the card and p variables similar to one of the examples below.
1 2 |
export card=/dev/sdb export p= |
1 2 |
export card=/dev/mmcblk1 export p=p |
Card partitions
Now we need to prepare the SD card partitions.
1 2 |
mkdir ~/mnt sudo rm -rf ~/mnt/* |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
umount ${card} umount ${card}${p}1 umount ${card}${p}2 sudo fdisk ${card} <<END o n +32M n w END umount ${card} umount ${card}${p}1 umount ${card}${p}2 sudo mkfs.vfat ${card}${p}1 sudo mkfs.ext4 ${card}${p}2<<END y END |
Run the following commands to write u-boot to the disk.
1 2 |
sudo dd if=/dev/zero of=${card} bs=1k count=1023 seek=1 sudo dd if=${uboot} of=${card} bs=1024 seek=8 |
Partition-1 (boot partition)
Copy the contents to the card.
1 2 3 4 5 6 |
sudo mount ${card}${p}1 ~/mnt sudo cp boot.scr ~/mnt/ sudo cp ${uimage} ~/mnt/ sudo cp ${dts} ~/mnt/ sudo umount ~/mnt |
Partition-2 (rootfs partition)
Copy the contents to the card.
1 2 3 4 5 6 |
sudo mount ${card}${p}2 ~/mnt sudo tar --strip-components=1 -xzpf ~/linaro-jessie-alip-20160428-22.tar.gz -C ~/mnt sudo cp -r ${bsp}/* ~/mnt/ sudo mkdir -p ~/mnt/lib/firmware/ sudo cp -r ${firmware} ~/mnt/lib/firmware/ |
Partition table
Some final touches are necessary for the card to work properly. First we need to create /etc/fstab file.
1 2 3 4 5 |
sudo sh -c 'cat<<END > ~/mnt/etc/fstab proc /proc proc defaults 0 0 /dev/mmcblk0p1 /boot vfat defaults,rw 0 2 /dev/mmcblk0p2 / ext4 defaults,noatime 0 1 END' |
Network settings
This part is for network connectivity. By default NetworkManager takes care of the network and enables DHCP on eth0 but in example if you want to assign a static ip address to your board, use the following part after changing the settings and uncommenting necessary lines. If you have no idea, ignore the following.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
sudo sed -i 's/managed=false/managed=true/g' ~/mnt/etc/NetworkManager/NetworkManager.conf sudo sh -c "echo manual > ~/mnt/etc/init/network-manager.override" sudo sh -c 'cat<<END > ~/mnt/etc/network/interfaces auto lo iface lo inet loopback #auto eth0 #allow-hotplug eth0 #iface eth0 inet dhcp #iface eth0 inet static #address 192.168.137.208 #netmask 255.255.255.0 #gateway 192.168.137.1 #auto wlan0 #allow-hotplug wlan0 #iface wlan0 inet dhcp # wpa-ssid YOUR_WIFI_NAME # wpa-psk YOUR_PASSWORD END' |
Keyboard settings
To change the default keyboard layout, one can use the following part with the desired language.
1 2 |
sudo sed -i 's/XKBLAYOUT="us"/XKBLAYOUT="tr"/g' ~/mnt/etc/default/keyboard sudo sed -i 's/XKBLAYOUT=us/XKBLAYOUT=tr/g' ~/mnt/usr/share/console-setup/keyboard |
Other settings
The following lines are also required.
1 2 3 4 5 |
sudo sh -c "echo BananaPI > ~/mnt/etc/machine-id" sudo ssh-keygen -q -t rsa -f ~/mnt/etc/ssh/ssh_host_rsa_key -C '' -N '' # Bugfix for Linaro sudo chmod +x ~/mnt/usr/lib/dbus-1.0/dbus-daemon-launch-helper |
Now finalize the partition.
1 2 3 4 5 |
sudo umount ~/mnt sudo sync sudo rm ~/boot.cmd sudo rm ~/boot.scr sudo rm -rf ~/mnt |
First boot
Assuming you have done every step correctly, the next thing to do is plugging the SDcard to your BananaPi and see the result of your patience ?
Final words
This tutorial explains the most basic steps to compile a mainline kernel and u-boot then using an instant rootfs from Linaro project. The next step would be preparing a rootfs using debootstrap or preparing a bootable image file rather than writing directly to the card. I will try to add new titles to this post when i find time. Keep informed and have fun ?