The goal is to upgrade the Linux on Altera's DE0-Nano-SOC FPGA development board. To challenge us even further, the board confusingly also branded as the Atlas SoC board. The boards provided Linux version is from 2013, woefully outdated, and a stripped-down version. It comes with busybox instead of full commands, lacks all local development tools, and is requiring off-system cross-compiling.
root@socfpga:~# cat /etc/version 201309272205 root@socfpga:~# cat /etc/issue Poky 8.0 (Yocto Project 1.3 Reference Distro) 1.3 \l root@socfpga:~# uname -r 3.13.0-00298-g3c7cbb9-dirty
On the bright side, the minimal linux image coming with Altera's DE0-Nano-SOC FPGA development board uses only 189MB.
root@socfpga:~# df -h / Filesystem Size Used Available Use% Mounted on /dev/root 975.9M 188.7M 736.0M 20% /
With the hardware being somewhat comparable to popular Raspberry Pi or Beagleboard platforms, DE0-SoC boards are missing the platform support convenience that comes with a adopted Linux distribution for the specific Altera platform.
Original SD card partioning:
root@socfpga:~# fdisk -l /dev/mmcblk0
Disk /dev/mmcblk0: 64.0 GB, 64021856256 bytes
4 heads, 16 sectors/track, 1953792 cylinders, total 125042688 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: 0xd68e23ba
Device Boot Start End Blocks Id System
/dev/mmcblk0p1 2121728 3799447 838860 b W95 FAT32
/dev/mmcblk0p2 14336 2111487 1048576 83 Linux
/dev/mmcblk0p3 2048 4095 1024 a2 Unknown
Partition table entries are not in disk order
http://eewiki.net/display/linuxonarm/DE0-Nano-SoC+Kit, courtesy of Robert Nelson.
This approach requires approx 8-10 GB disk space.
First we need a ARM cross-compiler. Linaro provides one that is frequently used:
wget https://releases.linaro.org/components/toolchain/binaries/latest/arm-linux-gnueabihf/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf.tar.xz
tar xf gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf.tar.xz
export CC=`pwd`/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-
fm@lts1604:/srv/app/bc/ubuntu$ ${CC}gcc --version
arm-linux-gnueabihf-gcc (Linaro GCC 6.2-2016.11) 6.2.1 20161016
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Next we need a Boot loader that can jump-start the OS.
git clone https://github.com/u-boot/u-boot fm@lts1604:/srv/app/bc/ubuntu$ cd u-boot/ fm@lts1604:/srv/app/bc/ubuntu/u-boot$ ls api board common configs doc dts fs Kbuild lib MAINTAINERS net README snapshot.commit tools arch cmd config.mk disk drivers examples include Kconfig Licenses Makefile post scripts test fm@lts1604:/srv/app/bc/ubuntu/u-boot$ git checkout v2017.01 -b tmp Switched to a new branch 'tmp'
Now we patch it for the DE0-Nano-SoC board:
wget -c https://rcn-ee.com/repos/git/u-boot-patches/v2017.01/0001-de0_nano-fixes.patch fm@lts1604:/srv/app/bc/ubuntu/u-boot$ patch -p1 < 0001-de0_nano-fixes.patch patching file include/configs/socfpga_de0_nano_soc.h
Finally we compile the Boot Loader:
fm@lts1604:/srv/app/bc/ubuntu/u-boot$ make ARCH=arm CROSS_COMPILE=${CC} distclean
fm@lts1604:/srv/app/bc/ubuntu/u-boot$
fm@lts1604:/srv/app/bc/ubuntu/u-boot$ make ARCH=arm CROSS_COMPILE=${CC} socfpga_de0_nano_soc_defconfig
HOSTCC scripts/basic/fixdep
HOSTCC scripts/kconfig/conf.o
SHIPPED scripts/kconfig/zconf.tab.c
SHIPPED scripts/kconfig/zconf.lex.c
SHIPPED scripts/kconfig/zconf.hash.c
HOSTCC scripts/kconfig/zconf.tab.o
HOSTLD scripts/kconfig/conf
#
# configuration written to .config
#
fm@lts1604:/srv/app/bc/ubuntu/u-boot$
fm@lts1604:/srv/app/bc/ubuntu/u-boot$ make ARCH=arm CROSS_COMPILE=${CC} u-boot-with-spl.sfp
scripts/kconfig/conf --silentoldconfig Kconfig
CHK include/config.h
UPD include/config.h
CFG u-boot.cfg
GEN include/autoconf.mk
GEN include/autoconf.mk.dep
CFG spl/u-boot.cfg
GEN spl/include/autoconf.mk
CHK include/config/uboot.release
UPD include/config/uboot.release
...
LD spl/u-boot-spl
OBJCOPY spl/u-boot-spl-nodtb.bin
FDTGREP spl/u-boot-spl.dtb
CAT spl/u-boot-spl-dtb.bin
COPY spl/u-boot-spl.bin
MKIMAGE spl/u-boot-spl.sfp
OBJCOPY u-boot-nodtb.bin
CAT u-boot-dtb.bin
COPY u-boot.bin
MKIMAGE u-boot.img
SOCBOOT u-boot-with-spl.sfp
Now we build a Kernel:
fm@lts1604:/srv/app/bc/ubuntu$ git clone https://github.com/RobertCNelson/socfpga-kernel-dev Cloning into 'socfpga-kernel-dev'... remote: Counting objects: 283, done. remote: Total 283 (delta 0), reused 0 (delta 0), pack-reused 283 Receiving objects: 100% (283/283), 804.01 KiB | 348.00 KiB/s, done. Resolving deltas: 100% (187/187), done. Checking connectivity... done. fm@lts1604:/srv/app/bc/ubuntu$ cd socfpga-kernel-dev/ fm@lts1604:/srv/app/bc/ubuntu/socfpga-kernel-dev$ git checkout origin/v4.6.x -b tmp Branch tmp set up to track remote branch v4.6.x from origin. Switched to a new branch 'tmp' fm@lts1604:/srv/app/bc/ubuntu/socfpga-kernel-dev$ vi version.sh fm@lts1604:/srv/app/bc/ubuntu/socfpga-kernel-dev$ ./build_kernel.sh
Finally we get a pre-arranged minimal filesystem:
wget -c https://rcn-ee.com/rootfs/eewiki/minfs/ubuntu-16.04.1-minimal-armhf-2017-01-14.tar.xz
Write it all to SD card.
Clear out old partition table:
dd if=/dev/zero of=/dev/sdc bs=1M count=64
Write new partition table:
/dev/sdc1 1M Boot Loader /dev/sdc2 remaining space Linux
sfdisk /dev/sdc <<-__EOF__ 1M,1M,0xA2, ,,,- __EOF__
Write boot loader to /dev/sdc1:
dd if=u-boot/u-boot-with-spl.sfp of=/dev/sdc1
Format Linux partition:
mkfs.ext4 -L rootfs /dev/sdc2
Write file system to Linux partition:
tar xfvp ./*-*-*-armhf-*/armhf-rootfs-*.tar -C /media/fm/rootfs
Set uname_r in boot/uEnv.txt:
root@lts1604:/srv/app/bc/ubuntu# export kernel_version=4.6.5-socfpga-r1
root@lts1604:/srv/app/bc/ubuntu# sh -c "echo 'uname_r=${kernel_version}' > /media/fm/rootfs/boot/uEnv.txt"
root@lts1604:/srv/app/bc/ubuntu# cat /media/fm/rootfs/boot/uEnv.txt
uname_r=4.6.5-socfpga-r1
Copy kernel image:
root@lts1604:/srv/app/bc/ubuntu# cp -v ./socfpga-kernel-dev/deploy/${kernel_version}.zImage /media/fm/rootfs/boot/vmlinuz-${kernel_version}
'./socfpga-kernel-dev/deploy/4.6.5-socfpga-r1.zImage' -> '/media/fm/rootfs/boot/vmlinuz-4.6.5-socfpga-r1'
Copy device tree binaries:
root@lts1604:/srv/app/bc/ubuntu# mkdir -p /media/fm/rootfs/boot/dtbs/${kernel_version}/root@lts1604:/srv/app/bc/ubuntu# tar xfv ./socfpga-kernel-dev/deploy/${kernel_version}-dtbs.tar.gz -C /media/fm/rootfs/boot/dtbs/${kernel_version}/
./socfpga_arria10_socdk_nand.dtb
./socfpga_arria10_socdk_qspi.dtb
./socfpga_arria10_socdk_sdmmc.dtb
./socfpga_arria10_swvp.dtb
./socfpga_arria5_socdk.dtb
./socfpga_cyclone5_de0_sockit.dtb
./socfpga_cyclone5_mcvevk.dtb
./socfpga_cyclone5_socdk.dtb
./socfpga_cyclone5_sockit.dtb
./socfpga_cyclone5_socrates.dtb
./socfpga_cyclone5_trcom.dtb
./socfpga_vt.dtb
Copy Kernel modules:
tar xfv ./socfpga-kernel-dev/deploy/${kernel_version}-modules.tar.gz -C /media/rootfs/
Create Filesystem table:
sh -c "echo '/dev/mmcblk0p2 / auto errors=remount-ro 0 1' >> /media/rootfs/etc/fstab"
Specify device IP in /etc/network/interfaces:
# /etc/network/interfaces -- configuration file for ifup(8), ifdown(8)
# The loopback interface
auto lo
iface lo inet loopback
# Wireless interfaces
iface wlan0 inet dhcp
wireless_mode managed
wireless_essid any
wpa-driver wext
wpa-conf /etc/wpa_supplicant.conf
iface atml0 inet dhcp
# Wired or wireless interfaces
auto eth0
iface eth0 inet static
address 192.168.99.3
netmask 255.255.255.0
dns-nameservers 192.168.179.1
iface eth1 inet dhcp
# Ethernet/RNDIS gadget (g_ether)
# ... or on host side, usbnet and random hwaddr
iface usb0 inet static
address 192.168.7.2
netmask 255.255.255.0
network 192.168.7.0
gateway 192.168.7.1
# Bluetooth networking
iface bnep0 inet dhcp
Sync and umount the sdcard. Its now ready to boot. After boot, the login will prompt for username ubuntu with password temppwd. The remaining work includes setting up DNS, routing, adding Ubuntu repositories to /etc/apt/sources.list. And finally, we are able to run apt-get update / apt-get upgrade / apt-get install.
root@arm:/home/fm# df -h / Filesystem Size Used Avail Use% Mounted on /dev/root 59G 1.4G 55G 3% /