Obtaining the linux source

To start we first need the source files of linux so we can compile it. We will also use the --depth=1 option because we simple don’t need the massive history of linux on our disk.

git clone https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git --depth=1
cd linux

Configuring linux

First of we need the correct defconfig. To get the defconfig you need to run the make help command with the architecture of which you need the defconfig. In our case: riscv

ARCH=riscv make help

For the MAIX bit (Canaan Kendryte K210), at the time of writing, two options show up for targets: nommu_k210_defconfig and nommu_k210_sdcard_defconfig. Because we aren’t going to do anything with the sd-card on the kernel side(for now). We will select the nommu_k210_defconfig.

ARCH=riscv CROSS_COMPILE=riscv64-linux- make nommu_k210_defconfig

To edit the config use

ARCH=riscv CROSS_COMPILE=riscv64-linux- make menuconfig

Compiling linux

After the configuration we can compile the kernel.

ARCH=riscv CROSS_COMPILE=riscv64-linux- make -j$(nproc)

Uploading the kernel to the sd-card

Before we can upload the kernel to the sd-card we need to make a small FAT partition on the sd-card (The kernel will take up at most a few MB). If you don’t know how to do that. Go google it yourself. After you have the partition ready (I will assume in the rest of this blog that this partion is partition 0) you need to upload two files to the sd-card: the kernel and the device tree bindings (.dtb). These files are located at arch/riscv/boot/Image and arch/riscv/boot/dts/canaan/k210_generic.dtb respectively.

Now that the files are on the sd-card. Plug it into the MAIX bit and open een terminal (see how in previous chapter).

Booting the linux kernel

This part will be done in the u-boot shell. To check if the sd-card is detected type mmc list. This should list an sd card on the spi bus. If not try to rescan (mmc rescan) or reboot the MAIX bit. To check if the files are present on the sd-card type fatls mmc 0. This will list all files on the the first mmc device (see the mmc list). If everything is good to go, continue.

If everything is correct then u-boot should have some arguments in the enviroment. To see those type print. The two important arguments are: loadaddr and fdt_addr_r. If they aren’t there you should subtitute the arguments with the following values (In case of the MAIX bit): $loadaddr -> 0x80060000 and $fdt_addr_r -> 0x80400000.

After that we will need to load the to files to their respective locations and boot into linux. This will take three commands which we will attach to each other.

fatload mmc 0 $loadaddr Image
fatload mmc 0 $fdt_addr_r k210_generic.dtb
booti $loadaddr - $fdt_addr_r

Those three can be entered on their own or together. To put them together add && in between the commands like:

fatload mmc 0 $loadaddr Image && fatload mmc 0 $fdt_addr_r k210_generic.dtb && booti $loadaddr - $fdt_addr_r

After executing these commands you should be greeted with a nice kernel panic. This is expected, because we haven’t assigned a rootfs or an init. But congrats, you have booted linux. The next step is to load the mmc and make the rootfs.