I am using this blog post as a reference. In this one the boot process of Linux is like:
- Boot0
- OpenSBI
- U-Boot
- Kernel Linux
- Debian rootfs
The content of the SD card looks like:
dd if=sun20i_d1_spl/nboot/boot0_sdcard_sun20iw1p1.bin of=/dev/sdc bs=8192 seek=16
dd if=u-boot.toc1 of=/dev/sdc bs=512 seek=32800
There is another github repository that build custom images. It has all the steps in this guide but updated. And also another project similar to the last one.
But reviewing commits, and also this paragraph makes me think that the updated boot process looks something like:
- U-Boot SPL
- U-Boot
- Kernel Linux
- Debian rootfs
The different is that the U-Boot will generate a binary containing the U-Boot SPL and the U-Boot.
sudo apt install autoconf automake autotools-dev curl python3 libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev swig libssl-dev python3-distutils python3-dev
After trying for some time, it is not possible to use the new way, becuase it gives some errors. For this reason I am sticking to the original recipe.
How to make it work
I was able to build my own OS. The steps were to replicate the original post with some changes to make it compatible today. The U-boot part is the same, but instead of building Debian is necessary to build Ubuntu. The problem is that the Debian packages are not very stable and it crash when trying to install an essential package. Probably in going to be fixed in the future.
Riscv
export cwd=`pwd`
git clone https://github.com/riscv/riscv-gnu-toolchain
cd riscv-gnu-toolchain
git checkout df6ecbe4ddb2a1a261b44af822d22f1253d3f0e4
git submodule update --init --recursive
./configure --prefix=$cwd/riscv64-unknown-linux-gnu --with-arch=rv64gc --with-abi=lp64d
make linux -j `nproc`
export PATH=$cwd/riscv64-unknown-linux-gnu/bin:$PATH
cd ..
Boot0
Building the Boot0 binary:
git clone https://github.com/smaeul/sun20i_d1_spl
cd sun20i_d1_spl
git checkout 4da9c518c124d6f6123bf274e449514863df3646
make CROSS_COMPILE=$cwd/riscv64-unknown-linux-gnu/bin/riscv64-unknown-linux-gnu- p=sun20iw1p1 mmc
cd ..
The binary is located here: sun20i_d1_spl/nboot/boot0_sdcard_sun20iw1p1.bin
OpenSBI
git clone https://github.com/smaeul/opensbi
cd opensbi
git checkout d1-wip
make CROSS_COMPILE=$cwd/riscv64-unknown-linux-gnu/bin/riscv64-unknown-linux-gnu- PLATFORM=generic FW_PIC=y FW_OPTIONS=0x2
cd ..
The binary is located here: opensbi/build/platform/generic/firmware/fw_dynamic.bin
U-Boot
You can modify the dtb in arch/riscv/dts.
Use the same steps as the original post. The U-boot SPL doesnt work, i was not able to compile it for the lichee.
Build u-boot toc
Then you need to generate the toc file. Go back to the root folder, wher all the previous folders are:
Create a file licheerv_toc1.cfg
with the following contents:
[opensbi]
file = opensbi/build/platform/generic/firmware/fw_dynamic.bin
addr = 0x40000000
[dtb]
file = u-boot/arch/riscv/dts/sun20i-d1-lichee-rv-dock.dtb
addr = 0x44000000
[u-boot]
file = u-boot/u-boot-nodtb.bin
addr = 0x4a000000
and then execute:
./u-boot/tools/mkimage -T sunxi\_toc1 -d licheerv\_toc1.cfg u-boot.toc1
which produces the file: u-boot.toc1
Generate the u-boot script
It is necessary to create the u-boot script like the source article.
I was able to put custom dtb, but is necessary to update the u-boot script
Some notes of errors
After the next error you need to do:
E: Release signed by unknown key (key id 8D69674688B6CB36)
The specified keyring /usr/share/keyrings/debian-ports-archive-keyring.gpg may be incorrect or out of date.
You can find the latest Debian release key at https://ftp-master.debian.org/keys.html
This error is due to the packages are signed with a key that we dont have. We need to download the asc file from the maintainers and import it. The steps were like this, but the keys will change every year.
wget -O - https://www.ports.debian.org/archive_2024.key | sudo apt-key add -
gpg --export 6ED0E7B82643E131 | sudo tee /usr/share/keyrings/debian-ports-archive-keyring.gpg >/dev/null
wget -O - https://ftp-master.debian.org/keys/archive-key-12.asc | sudo apt-key add -
wget -O - https://ftp-master.debian.org/keys/archive-key-12-security.asc | sudo apt-key add -
gpg --export 6ED0E7B82643E131 > newkey.gpg
sudo debootstrap --arch=riscv64 --keyring ./newkey.gpg --components=main,contrib,non-free --include=debian-ports-archive-keyring,pciutils,autoconf,automake,autotools-dev,curl,python3,libmpc-dev,libmpfr-dev,libgmp-dev,gawk,build-essential,bison,flex,texinfo,gperf,libtool,patchutils,bc,zlib1g-dev,wpasupplicant,htop,net-tools,wireless-tools,ntpdate,openssh-client,openssh-server,sudo,e2fsprogs,git,man-db,lshw,dbus,wireless-regdb,libsensors5,lm-sensors,swig,python3-distutils,python3-dev,alien,fakeroot,dkms,libblkid-dev,uuid-dev,libudev-dev,libaio-dev,libattr1-dev,libelf-dev,python3-setuptools,python3-cffi,python3-packaging,libffi-dev,libcurl4-openssl-dev,python3-ply,iotop,tmux,psmisc,dbus-user-session,xorg,lightdm,openbox-lxde-session,lxde,vim,gnupg unstable rootfs http://deb.debian.org/debian
The previous command is the same as the original webpage… but by the time I am writting this there are essential packages that crash. It is not possible to build Debian. For that reason I decided to move to Ubuntu Jammy. I am going to use this as a reference following this guide.
sudo debootstrap --arch=riscv64 --foreign jammy ./temp-rootfs http://ports.ubuntu.com/ubuntu-ports
After having the rootfs, it is possible to execute a bash on the root folder, like sudo chroot rootfs /bin/bash
/debootstrap/debootstrap --second-stage
cat >/etc/apt/sources.list <<EOF
deb http://ports.ubuntu.com/ubuntu-ports jammy main restricted
deb http://ports.ubuntu.com/ubuntu-ports jammy-updates main restricted
deb http://ports.ubuntu.com/ubuntu-ports jammy universe
deb http://ports.ubuntu.com/ubuntu-ports jammy-updates universe
deb http://ports.ubuntu.com/ubuntu-ports jammy multiverse
deb http://ports.ubuntu.com/ubuntu-ports jammy-updates multiverse
deb http://ports.ubuntu.com/ubuntu-ports jammy-backports main restricted universe multiverse
deb http://ports.ubuntu.com/ubuntu-ports jammy-security main restricted
deb http://ports.ubuntu.com/ubuntu-ports jammy-security universe
deb http://ports.ubuntu.com/ubuntu-ports jammy-security multiverse
EOF
When you are inside and after the stage 2 you run:
apt install pciutils autoconf automake autotools-dev curl wget gnupg python3 libmpc-dev libmpfr-dev libgmp-dev build-essential bison flex texinfo libtool patchutils bc zlib1g-dev wpasupplicant htop net-tools wireless-tools ntpdate openssh-client openssh-server sudo git man-db lshw dbus wireless-regdb libsensors5 vim lm-sensors swig libssl-dev python3-distutils python3-dev alien fakeroot dkms libblkid-dev uuid-dev libudev-dev libaio-dev libattr1-dev libelf-dev python3-setuptools python3-cffi python3-packaging libffi-dev libcurl4-openssl-dev python3-ply iotop tmux psmisc dbus-user-session
apt-get install --no-install-recommends -y util-linux haveged openssh-server systemd kmod initramfs-tools conntrack ebtables ethtool iproute2 iptables mount socat ifupdown iputils-ping vim dhcpcd5 neofetch sudo chrony
I tested the ubuntu SO in the board, and it works, impressive :)
The user and password is obc:insightsat
Compress and put the SO in the SD
sudo XZ\_OPT="-9 -T8" tar -Jcf ../rootfs_20240312.tar.xz .
mount /dev/sdX2 /mnt/sdcard_rootfs
sudo tar xfJ ../rootfs_20240312.tar.xz -C /mnt/sdcard_rootfs
umount /mnt/sdcard_rootfs
Some things not working
I tried to compile linux as is stated in the blog and I couldnt. When is booting the kernel is not able to start the SO.
Using the precompiled kernel I am not able to have the put it working the wifi.
But there is the last solution, that is my last attempt becuase I am super bored doing this. Now is becoming to start being repetitive.
The last chance is to take everything that was working back then, and then modify the rootfs to fix it.
Fix precompiled OS
I extracted the rootfs, and then I did sudo chroot temp-rootfs /bin/bash
.
The main problem was the resolv.conf, and the apt link. I fixed it and then I installed the packages I needed.
Add the mcp251 linux driver
When compiling the kernel modules, it is the the debconfig file where it states which drivers are going to be installed. The mcp251x needs to be install by adding the next parameter CONFIG_CAN_MCP251X=y
and CONFIG_CAN=y
Third attempt
This time I am using:
- The compiler in ubuntu: gcc-riscv64-linux-gnu
Open SBI
curl -O -L https://github.com/riscv-software-src/opensbi/releases/download/v1.2/opensbi-1.2-rv-bin.tar.xz
...
cp opensbi-1.2-rv-bin/share/opensbi/lp64/generic/firmware/fw_dynamic.bin output
U-Boot
make CROSS_COMPILE=riscv64-linux-gnu- lichee_rv_dock_defconfig
make CROSS_COMPILE=riscv64-linux-gnu- ARCH=riscv OPENSBI=${cwd}/output/fw_dynamic.bin -j `nproc`
cd ..
cp u-boot_sunxi_licheerv/u-boot-sunxi-with-spl.bin output
Linux
You need to modify the defconfig. The mcp251x needs to be install by adding the next parameter CONFIG_CAN_MCP251X=y
and CONFIG_CAN=y
.
mkdir -p linux-build/arch/riscv/configs
cp licheerv_linux_defconfig linux-build/arch/riscv/configs/licheerv_defconfig
make ARCH=riscv -C linux_sunxi_licheerv O=$cwd/linux-build licheerv_defconfig
make -j `nproc` -C linux-build ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- V=1
KERNEL_RELEASE=`make ARCH=riscv -C linux-build -s kernelrelease`
cp linux-build/arch/riscv/boot/Image output
cp linux-build/arch/riscv/boot/Image.gz output
rootfs
sudo debootstrap --arch=riscv64 --foreign jammy ./rootfs http://ports.ubuntu.com/ubuntu-ports
sudo chroot rootfs /bin/bash
/debootstrap/debootstrap --second-stage
cat >/etc/apt/sources.list <<EOF
deb http://ports.ubuntu.com/ubuntu-ports jammy main restricted
deb http://ports.ubuntu.com/ubuntu-ports jammy-updates main restricted
deb http://ports.ubuntu.com/ubuntu-ports jammy universe
deb http://ports.ubuntu.com/ubuntu-ports jammy-updates universe
deb http://ports.ubuntu.com/ubuntu-ports jammy multiverse
deb http://ports.ubuntu.com/ubuntu-ports jammy-updates multiverse
deb http://ports.ubuntu.com/ubuntu-ports jammy-backports main restricted universe multiverse
deb http://ports.ubuntu.com/ubuntu-ports jammy-security main restricted
deb http://ports.ubuntu.com/ubuntu-ports jammy-security universe
deb http://ports.ubuntu.com/ubuntu-ports jammy-security multiverse
EOF
apt-get update
apt-get install --no-install-recommends -y util-linux haveged openssh-server systemd kmod initramfs-tools conntrack ebtables ethtool iproute2 iptables mount socat ifupdown iputils-ping vim dhcpcd5 neofetch sudo chrony
Install kernel modules
6.1.0-rc3-ge56c43a61610
sudo make modules_install ARCH=riscv INSTALL_MOD_PATH=../rootfs KERNELRELEASE=$KERNEL_RELEASE
rtl
make -j `nproc` ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- KSRC=$cwd/linux-build modules
sudo install -D -p -m 644 rtl8723ds/8723ds.ko rootfs/lib/modules/$KERNEL_RELEASE/kernel/drivers/net/wireless/8723ds.ko
sudo depmod -a -b rootfs $KERNEL_RELEASE
sudo sh -c 'echo "8723ds" >> rootfs/etc/modules'
Some things in the OS
sudo chroot rootfs /bin/bash
passwd root # rootpwd
Content of rootfs/etc/fstab
<device> <dir> <type> <options> <dump> <pass>
LABEL=boot /boot ext2 rw,defaults,noatime 0 1
LABEL=root / ext4 rw,defaults,noatime 0 2
It worked!
This way of compiling the OS just work. Perfect!
Same as before but with the changes of dts
The only difference is to generate the uboot, that is going to be like:
make CROSS_COMPILE=riscv64-linux-gnu- lichee_rv_can_defconfig
make CROSS_COMPILE=riscv64-linux-gnu- ARCH=riscv OPENSBI=${cwd}/output/fw_dynamic.bin -j `nproc`
cd ..
cp u-boot_sunxi_licheerv/u-boot-sunxi-with-spl.bin output
Then when boots up
$ sudo ip link set can0 up type can bitrate 500000
$ sudo ifconfig can0 up
$ cansend can0 5A1#00.01.02.03.04
And then it just work :) It works perfectly :))))))