Altera’s tools for generating U-boot and Linux are a bit messy, outdated at best. For example, last time I checked their auto-generated U-boot dates back to 2014. Let’s try to build and run an up-to-date version of U-boot and Linux.
First, clone the repository.
git clone https://github.com/u-boot/u-boot.git
A variety of defconfigs exist for different boards.
[xrn@a23pc07 u-boot]$ find . -iname "socfpga*defconfig" ./configs/socfpga_sockit_defconfig ./configs/socfpga_de10_nano_defconfig ./configs/socfpga_is1_defconfig ./configs/socfpga_cyclone5_defconfig ./configs/socfpga_stratix10_defconfig ./configs/socfpga_de1_soc_defconfig ./configs/socfpga_de0_nano_soc_defconfig ./configs/socfpga_dbm_soc1_defconfig ./configs/socfpga_sr1500_defconfig ./configs/socfpga_socrates_defconfig ./configs/socfpga_arria5_defconfig ./configs/socfpga_vining_fpga_defconfig ./configs/socfpga_arria10_defconfig
For example, building U-boot for the Altera’s Cyclone V development kit:
make ARCH=arm CROSS_COMPILE=/opt/toolchain/gcc-linaro-7.2.1-2017.11-x86_64_arm-eabi/bin/arm-eabi- socfpga_cyclone5_defconfig make ARCH=arm CROSS_COMPILE=/opt/toolchain/gcc-linaro-7.2.1-2017.11-x86_64_arm-eabi/bin/arm-eabi- -j8
This will result in a u-boot-with-spl.sfp file being created.
The SoCFPGA boot ROM will look for a partition of type 0xa2 and execute it. This is where U-boot must be copied. The two other partitions will contain an ext4 filesystem with the rootfs and a FAT32 filesystem with the Linux kernel and its device tree. With the help of fdisk, partition the SD card (or eMMC) correctly. The following shows an example on a 16 GB SD card.
Note: it is advised that U-boot resides on the first partition.
Command (m for help): p Disk /dev/sdj: 15.9 GB, 15931539456 bytes 64 heads, 32 sectors/track, 15193 cylinders, total 31116288 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: 0xcedaa4bc Device Boot Start End Blocks Id System /dev/sdj1 2048 99703 48828 a2 Unknown /dev/sdj2 99704 490328 195312+ 83 Linux /dev/sdj3 490329 31116287 15312979+ b W95 FAT32
Then, proceed to format the Linux and FAT32 partitions with mkfs. The 0xa2 partition doesn’t need any kind of formatting. Instead, we can perform a low-level copy of U-boot with the help of dd.
dd if=u-boot-with-spl.sfp of=/dev/sdj1 sync
Try it out, you should be greeted by a nice and up-to-date U-boot prompt.
U-Boot 2019.04-rc2-00032-g97f9830849 (Feb 21 2019 - 16:59:05 +0100) CPU: Altera SoCFPGA Platform FPGA: Altera Cyclone V, SE/A6 or SX/C6 or ST/D6, version 0x0 BOOT: SD/MMC External Transceiver (1.8V) DRAM: 1 GiB MMC: dwmmc0@ff704000: 0 Loading Environment from MMC... OK In: serial Out: serial Err: serial Model: Altera SOCFPGA Cyclone V SoC Development Kit Net: Error: ethernet@ff702000 address not set. eth-1: ethernet@ff702000 Hit any key to stop autoboot: 0 =>
Building Linux is not difficult either. The same defconfig is used by every board of the socfpga family. Only the device tree will show minor changes.
make ARCH=arm CROSS_COMPILE=/opt/toolchain/gcc-linaro-7.2.1-2017.11-x86_64_arm-eabi/bin/arm-eabi- socfpga_defconfig make ARCH=arm CROSS_COMPILE=/opt/toolchain/gcc-linaro-7.2.1-2017.11-x86_64_arm-eabi/bin/arm-eabi- -j8 make ARCH=arm CROSS_COMPILE=/opt/toolchain/gcc-linaro-7.2.1-2017.11-x86_64_arm-eabi/bin/arm-eabi- socfpga_cyclone5_socdk.dtb
When you look at them, every socfpga board’s device tree includes the same socfpga_cyclone5.dtsi file. Adapting an existing device tree to a new socfpga board is easy and is generally just a matter of activating the right nodes with a status = “okay” string. Here are all the supported boards so far:
[xrn@a23pc07 linux]$ find . -iname "*socfpga*dts" ./arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts ./arch/arm/boot/dts/socfpga_cyclone5_socrates.dts ./arch/arm/boot/dts/socfpga_cyclone5_sockit.dts ./arch/arm/boot/dts/socfpga_arria10_socdk_qspi.dts ./arch/arm/boot/dts/socfpga_cyclone5_de0_nano_soc.dts ./arch/arm/boot/dts/socfpga_cyclone5_socdk.dts ./arch/arm/boot/dts/socfpga_cyclone5_vining_fpga.dts ./arch/arm/boot/dts/socfpga_cyclone5_sodia.dts ./arch/arm/boot/dts/socfpga_arria10_socdk_nand.dts ./arch/arm/boot/dts/socfpga_arria10_socdk_sdmmc.dts ./arch/arm/boot/dts/socfpga_vt.dts ./arch/arm/boot/dts/socfpga_cyclone5_mcvevk.dts ./arch/arm/boot/dts/socfpga_arria5_socdk.dts
Use Buildroot to create a rootfs tailored to your needs.
Untar your rootfs to the ext4 partition. Copy your zImage and socfpga_cyclone5_socdk.dtb to your SD card’s FAT32 partition. Start U-boot and run your kernel with the following command. You will successfully boot into your new kernel!
setenv bootargs console=ttyS0,115200 root=/dev/mmcblk0p3 rw rootwait; fatload mmc 0:2 0x10000 zImage; fatload mmc 0:2 0x1000 socfpga_cyclone5_socdk.dtb; bootz 0x10000 - 0x1000
Clear and concise. Quite a difference to the bunch of other sites full of crap. Thank you!
How do you know which address to load kernel and FDT into?