In order to be able to boot GNU/Linux on the Arrow SocKit we need a bootloader. If we run make we see that there is a target called uboot.

$  cross_compile_arrow_sockit
$  quartus20.1
------------------------------------------------
Altera Nios2 Command Shell

Version 20.1, Build 711
------------------------------------------------
$  eds20.1
------------------------------------------------
Intel FPGA Embedded Command Shell

Version 20.1 [Build 711]
------------------------------------------------
$  make
*****************************************
*                                       *
* Manage QuartusII/QSys design          *
*                                       *
*     Copyright (c) 2015                *
*     All Rights Reserved               *
*                                       *
*****************************************

*********************
* Target: help
*   Displays this info (i.e. the available targets)
*********************
* Target: preloader
*   Build Preloader BSP for this design into software/preloader directory
*********************
* Target: program_fpga
*   Quartus program sof to your attached dev board
*********************
* Target: program_qspi
*   Flash program preloader into QSPI Flash
*********************
* Target: qsys_edit
*   Launch QSys GUI
*********************
* Target: quartus_edit
*   Launch Quartus II GUI
*********************
* Target: scrub_clean
*   Restore design to its barebones state
*********************
* Target: sof
*   QSys generate & Quartus compile this design
*********************
* Target: tgz
*   Create a tarball with the barebones source files that comprise this design
*********************
* Target: uboot
*   Build U-Boot into software/preloader directory
*********************

So we try to build the target uboot.

$  make uboot

Unfortunately it fails but it gives us this useful output:

Please visit https://rocketboards.org/foswiki/Documentation/BuildingBootloader for instructions on how to build the bootloader.

It seams that something changed in version 19.1 and we need to clone the u-boot from github.

Compiling U-Boot

The following is based from RocketBoards.

Run bsp-create-settings with no user options to convert the handoff data into source code:

$  cd ~/arrow-sockit-ghrd/
$  bsp-create-settings \
> --type spl \
> --bsp-dir software/bootloader \
> --preloader-settings-dir hps_isw_handoff/sockit_ghrd_hps_0/ \
> --settings software/bootloader/settings.bsp

Retrieve the U-Boot source code by cloning the git tree, and checking out the supported branch:

$  cd software/bootloader
$  git clone https://github.com/altera-opensource/u-boot-socfpga
$  cd u-boot-socfpga
$  git checkout -b test-bootloader -t origin/socfpga_v2020.07

Run the qts_filter to take the sources from the handoff folder and the ones generated by bsp-create-settings, format them appropriately and copy them to the U-Boot source code:

$  ./arch/arm/mach-socfpga/qts-filter.sh cyclone5 ../../../ ../ ./board/altera/cyclone5-socdk/qts/

Configure and build U-Boot:

$  make socfpga_cyclone5_defconfig
$  make -j 24

Preparing the SD Card

The following is based on zangmans guide for de10-nano..

Create a directory structure for our work.

$  cd ~/arrow-sockit-ghrd/
$  mkdir sdcard
$  cd sdcard

Create an image and make it visible as a device. We make the image large enough to also hold the Linux kernel, the root file system and some other files that we will add in some later posts. You can make it another size if you like. A larger image will take longer to work with.

$  dd if=/dev/zero of=sdcard.img bs=1G count=3
3+0 records in
3+0 records out
3221225472 bytes (3.2 GB, 3.0 GiB) copied, 2.07561 s, 1.6 GB/s
$  sudo losetup --show -f sdcard.img
/dev/loop0

For now we are only interested in U-Boot so will only make the partition for U-Boot skipping the partitions for the Linux kernel and device tree and the root file system. Enter the sequence n, enter, p enter, 3, enter, enter, +1M, enter, t, enter, a2, enter, p, w ion fdisk.

$  sudo fdisk /dev/loop0

Welcome to fdisk (util-linux 2.36).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Device does not contain a recognized partition table.
Created a new DOS disklabel with disk identifier 0xeb7935ca.

Command (m for help): n
Partition type
   p   primary (0 primary, 0 extended, 4 free)
   e   extended (container for logical partitions)
Select (default p): p
Partition number (1-4, default 1): 3
First sector (2048-20479, default 2048):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-20479, default 20479): +1M

Created a new partition 3 of type 'Linux' and of size 1 MiB.

Command (m for help): t
Selected partition 3
Hex code or alias (type L to list all): a2
Changed type of partition 'Linux' to 'unknown'.

Command (m for help): p
Disk /dev/loop0: 10 MiB, 10485760 bytes, 20480 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
Disklabel type: dos
Disk identifier: 0xeb7935ca

Device       Boot Start   End Sectors Size Id Type
/dev/loop0p3       2048  4095    2048   1M a2 unknown

Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Re-reading the partition table failed.: Invalid argument

The kernel still uses the old table. The new table will be used at the next reboot or after you run partprobe(8) or partx(8).

Since this is a special partition type without any file system we use dd to write U-Boot with SPL to the partition. But first we update the loopback device. When we are done we can delete the loopback device.

$  sudo partprobe /dev/loop0
$  sudo dd if=../software/bootloader/u-boot-socfpga/u-boot-with-spl.sfp of=/dev/loop0p3 bs=64k seek=0 oflag=sync
13+1 records in
13+1 records out
852274 bytes (852 kB, 832 KiB) copied, 0,0744263 s, 11,5 MB/s
sudo losetup -d /dev/loop0

Now we use dd to write the image to an SD Card.

$  sudo dd if=sdcard.img of=/dev/your_sd_device bs=64K oflag=sync status=progress

Insert the SD Card into the SD Card slot on the SocKit. Configure BOOTSEL and CLKSEL jumpers as shown in the figure below. BOOTSEL[2:0] = 101, CLKSEL[1:0] = 00.

BOOTSEL and CLKSEL

Prepare PuTTY or another serial terminal emulator with baud rate of 115200, 8 data bits, 1 Stop bits, no parity and no flow control. The device will not be available until the board is powered up. The device will probably be /dev/ttyUSBX where X is a number. Power on the board and after ~one second open the terminal. If all where successfully we see U-Boot starting up. We need to be fast to stop U-Boor from trying to continue the boot, which will fail since we have not added the Linux kernel and the root file system yet. If we hit a button before the timeout we will be left in the U-Boot terminal. Here we can run many commands for example version to print the version. Running help will display all the commands. In the upcoming posts we will add the Linux kernel and a root file system and booting into GNU/Linux.

MMC:   dwmmc0@ff704000: 0
Loading Environment from MMC... *** Warning - bad CRC, using default environment

In:    serial
Out:   serial
Err:   serial
Model: Altera SOCFPGA Cyclone V SoC Development Kit
Net:
Warning: ethernet@ff702000 (eth0) using random MAC address - 6e:c8:07:a4:ab:1e
eth0: ethernet@ff702000
Hit any key to stop autoboot:  0
=> version
U-Boot 2020.07-08666-g9ad6dad583-dirty (Oct 21 2020 - 20:34:27 +0200)

arm-linux-gnueabihf-gcc (Linaro GCC 7.5-2019.12) 7.5.0
GNU ld (Linaro_Binutils-2019.12) 2.28.2.20170706