In the last post we compiled the boot loader and booted into U-Boot. Now we will continue by building the Linux kernel and adding it to the SD Card.

First we clone the kernel from github, list the branches and checkout the branch we would like to build.

$  git clone https://github.com/altera-opensource/linux-socfpga.git
$  cd linux-socfpga
$  git branch -a
$  git checkout -b sockit-5.8 remotes/origin/socfpga-5.8

When that is done we configure the kernel. I did not make any changes in menuconfig. But here you can configure the kernel to your need.

$  make ARCH=arm socfpga_defconfig
$  make ARCH=arm menuconfig

When you are satisfied with your configuration save it and exit menuconfig. We can now build the kernel image.

$  cross_compile_arrow_sockit
$  make ARCH=arm LOCALVERSION=zImage -j12

We now have a compressed kernel image located in arch/arm/boot/zImage. We need to add this file to the SD card but first we need to create an partition for it. We are going add the new partition to the image file we created for U-Boot. Enter the sequence p, n, enter, p, enter, 1, enter, enter, +256M, enter, t, enter, 1 enter, b, enter, p, w in fdisk.

$  cd ~/arrow-sockit-ghrd/sdcard
$  sudo losetup --show -f sdcard.img
$  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.


Command (m for help): p
Disk /dev/loop0: 3 GiB, 3221225472 bytes, 6291456 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: 0x039cfc37

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

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

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

Command (m for help): t
Partition number (1,3, default 3): 1
Hex code or alias (type L to list all): b

Changed type of partition 'Linux' to 'W95 FAT32'.

Command (m for help): p
Disk /dev/loop0: 3 GiB, 3221225472 bytes, 6291456 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: 0x039cfc37

Device       Boot Start    End Sectors  Size Id Type
/dev/loop0p1       4096 528383  524288  256M  b W95 FAT32
/dev/loop0p3       2048   4095    2048    1M a2 unknown

Partition table entries are not in disk order.

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).

This partition should be formatted as a FAT file system.

$  sudo partprobe /dev/loop0
$  sudo mkfs -t vfat /dev/loop0p1

Now we can mount the partition and put the Linux kernel on it. We are also going to put the device tree blob on this partition. This blob will inform the kernel about the HW during boot.

$  mkdir part1
$  sudo mount /dev/loop0p1 part1
$  sudo cp ~/linux-socfpga/arch/arm/boot/zImage part1/
$  sudo cp ~/linux-socfpga/arch/arm/boot/dts/socfpga_cyclone5_sockit.dtb part1/

We also need to create a config file for the extlinux bootloader.

$  sudo mkdir part1/extlinux
$  sudo emacs part1/extlinux/extlinux.conf

The content of part1/extlinux/extlinux.conf should be.

LABEL Linux Default
KERNEL ../zImage
FDT ../socfpga_cyclone5_sockit.dtb
APPEND root=/dev/mmcblk0p2 rw rootwait earlyprintk console=ttyS0,115200n8

Now we can write the image to an SD card and try it.

$  sudo umount part1
$  sudo losetup -d /dev/loop0
$  sudo dd if=sdcard.img of=/dev/your_sd_device bs=64K status=progress oflag=sync

We insert the card into the SocKit, power it up and open a serial terminal as we did when we only had U-boot on the SD card. We see that the boot was not successfully, which was to be expected since we have not yet added a root file system. However we see that the extlinux.conf file was found and was used which in turn used the DTB and started the kernel. In the next post we will add a Linux file system and continue to boot a full GNU/Linux system.

U-Boot 2020.07-08666-g9ad6dad583-dirty (Oct 21 2020 - 20:34:27 +0200)

CPU:   Altera SoCFPGA Platform
FPGA:  Altera Cyclone V, SE/A6 or SX/C6 or ST/D6, version 0x0
BOOT:  SD/MMC Internal Transceiver (3.0V)
       Watchdog enabled
DRAM:  1 GiB
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 - f2:5a:89:30:74:1a
eth0: ethernet@ff702000
Hit any key to stop autoboot:  0
switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...
Found /extlinux/extlinux.conf
Retrieving file: /extlinux/extlinux.conf
146 bytes read in 5 ms (28.3 KiB/s)
1:      Linux Default
Retrieving file: /extlinux/../zImage
5300888 bytes read in 363 ms (13.9 MiB/s)
append: root=/dev/mmcblk0p2 rw rootwait earlyprintk console=ttyS0,115200n8
Retrieving file: /extlinux/../socfpga_cyclone5_sockit.dtb
27367 bytes read in 9 ms (2.9 MiB/s)
## Flattened Device Tree blob at 02000000
   Booting using the fdt blob at 0x2000000
   Loading Device Tree to 09ff6000, end 09fffae6 ... OK

Starting kernel ...

.
.
.

 2.219402] ---[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(179,2) ]---