User:Vitali/Create a bootable Debian/Linux SDCard for the Pine64/Star64 from scratch
Introduction
This guide is for advance users only. In the process we will build every part necessary to boot the star64 until the kernel from source. For people interested to just get the star64 to boot I would recommend to search for a guide using a SDCard image.
This guide is a compilation of mostly already available information but this guide tries to glue all the parts together to make them work. All original sources are linked for reference.
By following this guide you will compile u-boot/spl
, u-boot
, opensbi
and the linux kernel
for the pine64/star64 and create a bootable SDCard by creating and populating the necessary partitions on the SDCard. Finally the precompiled official unstable Debian
riscv64 port will be installed to the rootfs partition on the SDCard. By using qemu
and systemd-nspawn
we will be able to execute debootstrap
to install a foreign architecture (e.g. install riscv64
while running debootstrap
on a amd64
host). Also minimal configuration of the rootfs is done on the host computer. All commands are documented in a way to be easy repeatable and will produce a ready to boot and configured SDCard image. You can of course modify configurations done on the host to your preference.
In contrast to methods using buildroot
or yocto
this guide is compiling each component separately. And the advantage of using debian
is that you will have access to thousands of precompiled debian
packages.
Preparation
Install qemu
, systemd-nspawn
and a riscv compiler
.
sudo apt install gcc-riscv64-linux-gnu systemd-container qemu debootstrap pwgen
Optional: Create .env file with your environment settings. Or Just set them directly.
nano .env
# cross compiler
CROSS_COMPILE=riscv64-linux-gnu-
# where to store apt cache, for faster installs
APT_CACHE_DIR=/tmp/apt/cache
# arbitrary path where the rootfs will be mounted at
ROOTFS=/tmp/star64/rootfs
# SDCard dev path
USBDEV=/dev/sdX
# hostname of the target, can be left empty
MNAME=
# username you are logged in your host system this name will be also used to create a new user on the newly created rootfs.
USER=$USER
test "$USER" = root && { echo "USER can't be root"; exit; }
PASSWORD=$(pwgen -1)
AUTHORIZED_KEY=$(ssh-keygen -f /home/$USER/.ssh/id_ed25519 -y)
# define helper functions
function star64_mount() {
mkdir -p ${ROOTFS?}/
sudo -E mount ${USBDEV:?}4 ${ROOTFS?}/
sudo mkdir -p ${ROOTFS?}/boot
sudo -E mount -o umask=0000 ${USBDEV:?}3 ${ROOTFS?}/boot
}
function star64_unmount() {
sudo umount ${ROOTFS?}/boot
sudo umount ${ROOTFS?}/
}
source .env
Connect Serial Cable
It is a good idea to first make sure the serial connection is working. Make sure the boot switches are set to boot from UART.
PINE64 STAR64 BOOT UART ┌──┐ GOIO_0 1 │X │ GPIO_1 2 │X │ └──┘ H L
Connect and monitor the serial port as stated in the Troubleshooting Section: Serial / UART. You should see repeatably printing of ‘C’. After making sure the serial works we can change it to SDCard boot mode.
PINE64 STAR64 BOOT SDCARD ┌──┐ GOIO_0 1 │ X│ GPIO_1 2 │X │ └──┘ H L
Build
Build each of the following projects. Make sure to navigate back into your base project directory (e.g. /tmp/star64
) if you proceed to build the next project. After completing this guide it should at least contain the directories: linux opensbi Tools u-boot
.
- Build tools
- Build OpenSBI
- Build U-Boot
- Partition the SDCard
- Build the Linux kernel
- Debootstrap the Debian riscv64 rootfs
- Copy the Linux kernel to SDCard
Build tools
Build spl_tool.
git clone --depth 1 https://github.com/starfive-tech/Tools.git
make -C Tools/spl_tool
Build OpenSBI
git clone --depth 1 https://github.com/riscv/opensbi.git
cd opensbi
make CROSS_COMPILE=${CROSS_COMPILE?} PLATFORM=generic FW_TEXT_START=0x40000000 FW_OPTIONS=0 -j
For more insight about the u-boot boot process you can find more useful information in the u-boot visionfive2 docs.
Build U-Boot
Make sure to build Tools and openSBI before proceeding.
The upsteam u-boot builds the u-boot.itb
automatically by using openSBIs fw_dynamic.bin. But the upstream u-boot does not boot properly (Last checked: 26-05-23)… Therefore we use the fw_payload.bin method with the starfive/u-boot.
git clone --depth 1 -b Star64 https://github.com/Fishwaldo/u-boot.git
cd u-boot
CROSS_COMPILE=${CROSS_COMPILE?} make pine64_star64_defconfig
CROSS_COMPILE=${CROSS_COMPILE?} make OPENSBI=../opensbi/build/platform/generic/firmware/fw_dynamic.bin -j
make -C ../opensbi CROSS_COMPILE=${CROSS_COMPILE?} PLATFORM=generic \
FW_FDT_PATH=../u-boot/arch/riscv/dts/pine64_star64.dtb \
FW_PAYLOAD_FDT_ADDR=0x40080000 \
FW_PAYLOAD_OFFSET=0x00100000 \
FW_PAYLOAD_PATH=../u-boot/u-boot.bin \
FW_TEXT_START=0x40000000
ln -s ../../opensbi/build/platform/generic/firmware/fw_payload.bin ../Tools/uboot_its/
tools/mkimage -f ../Tools/uboot_its/visionfive2-uboot-fit-image.its -A riscv -O u-boot -T firmware u-boot.itb
Create a SPL header as stated in u-boot visionfive2 docs and spl_tool:
../Tools/spl_tool/spl_tool -c -f spl/u-boot-spl.bin
Update with Linux
If you alreay have Linux running on the star64 and want to update u-boot
you can do that like that:
scp u-boot.itb ${MNAME?}:/tmp
ssh ${MNAME?} sudo dd if=/tmp/u-boot.itb of=/dev/mmcblk1p2
More infos on the u-boot build process with gcc. I strongly recommend to read JH7110Boot User Guide for more information on the boot process.
Partition the SDCard
After build OpenSBI and U-Boot from above we can proceed to setup the partitions for the SDCard and write u-boot-spl into the SPL
-partition and u-boot into the UBOOT
-partition.
# Set the SDCard dev path (content will be lost)
sudo su # continue with caution!
source .env
fdisk -l ${USBDEV:?} # make sure its in fact the right drive
lsblk ${USBDEV:?} -n | grep -q part && \
{ echo "delete partitions with 'wipefs --all ${USBDEV:?}' first"; exit; }
sfdisk ${USBDEV:?} <<EOF
label: gpt
: start=4096, size=2MiB, name=SPL, type=2E54B353-1271-4842-806F-E436D6AF6985
: size=4MiB, name=UBOOT, type=BC13C2FF-59E6-4262-A352-B275FD6F7172
: size=512MiB, name=BOOT, type=EBD0A0A2-B9E5-4433-87C0-68B6B72699C7
: name=SYSTEM, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4
EOF
mkfs.vfat -F 32 ${USBDEV:?}3
mkfs.ext4 -E lazy_itable_init=0,lazy_journal_init=0 ${USBDEV:?}4
# if you install on eMMC: execute:
# Tools/spl_tool/spl_tool --fix-imghdr -f ${USBDEV:?}
dd if=u-boot/spl/u-boot-spl.bin.normal.out of=${USBDEV:?}1
dd if=u-boot/u-boot.itb of=${USBDEV:?}2
You can find more about the partition layout on JH7110_Boot_UG Page 8 Table1-3 SD/eMMC Boot Address Allocation and u-boot/visionfive2: create bootable image: flashing
Build the Linux kernel
# alternative: https://github.com/starfive-tech/linux/tree/JH7110_VisionFive2_upstream
git clone --depth 1 -b Star64_devel https://github.com/Fishwaldo/Star64_linux.git linux
cd linux/
ARCH=riscv CROSS_COMPILE=${CROSS_COMPILE?} make pine64_star64_defconfig
# if you need any extra symbols for your kernel
ARCH=riscv CROSS_COMPILE=${CROSS_COMPILE?} make xconfig
# or by command line
ARCH=riscv CROSS_COMPILE=${CROSS_COMPILE?} scripts/config \
-m ATA \
-m SATA_AHCI \
-m ATA_GENERIC
# set new defaults if changed by command line
ARCH=riscv CROSS_COMPILE=${CROSS_COMPILE?} make olddefconfig
ARCH=riscv CROSS_COMPILE=${CROSS_COMPILE?} make -j14
Copy the Linux kernel to SDCard
Make sure to build the Linux kernel and Partition the SDCard before proceeding.
star64_mount
cp -v linux/arch/riscv/boot/Image.gz ${ROOTFS?}/boot
# cp initramfs.cpio.gz ${ROOTFS?}/boot # don't have one...
cp -v linux/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dtb ${ROOTFS?}/boot
sudo ARCH=riscv CROSS_COMPILE=${CROSS_COMPILE?} \
INSTALL_MOD_PATH=${ROOTFS?}/usr \
INSTALL_PATH=${ROOTFS?}/boot \
INSTALL_HDR_PATH=${ROOTFS?}/usr \
make -C linux install modules_install headers_install
star64_unmount
Update with Linux
If you already have Linux running on the star64 and want to update the linux
kernel you can do that like that:
rsync --rsync-path='sudo rsync' arch/riscv/boot/Image.gz ${MNAME?}:/boot
sudo ARCH=riscv CROSS_COMPILE=${CROSS_COMPILE?} \
INSTALL_MOD_PATH=/tmp/modules \
make modules_install
rsync -rv --rsync-path='sudo rsync' /tmp/modules/lib/modules/ ${MNAME?}:/lib/modules
Debootstrap the Debian riscv64 rootfs
Make sure to setup binfmt. Check if it is available with mount | grep binfmt_misc
and cat /proc/sys/fs/binfmt_misc/qemu-riscv64
.
Copy and past the star64_install_debian
function into bash and execute it or create a script file from that function. You can also execute them one by one if you prefer.
You can also just run the debootstrap
command and setup Debian on your own. But at least set a root password so you can login over serial.
For reference read debootstrap.
Alternatively if you dont want to use qemu
and systemd-nspawn
you can just follow the Star64: Armbian Installation guide instead of debootsraping
Debian
.
#switch to root
sudo su
source .env
function star64_install_debian() {
MNAME=${MNAME:-"star64-$(pwgen 4 -1 -A)"}
mkdir -p ${APT_CACHE_DIR:-/tmp/apt/cache}
debootstrap --foreign --cache-dir=/mnt/data/tmp/apt-riscv --arch=riscv64 --no-check-gpg --include=debian-ports-archive-keyring,usrmerge,openssh-server,htop,vim,nano,tcpdump,sudo,curl,wget,iputils-ping,fdisk,gdisk,pciutils,usbutils,screen,rsync,firmware-linux-free unstable ${ROOTFS?} http://deb.debian.org/debian-ports
cp /usr/bin/qemu-riscv64 ${ROOTFS?}/usr/bin/
chroot ${ROOTFS?} /debootstrap/debootstrap --second-stage
NSPAWN="systemd-nspawn -M $MNAME -D ${ROOTFS?} --quiet --no-pager"
# ${NSPAWN?} sed -i 's/main/main non-free/g' /etc/apt/sources.list
# ${NSPAWN?} apt update
# ${NSPAWN?} apt install -y firmware-linux-nonfree
PASSWORD=${PASSWORD:-$(pwgen 8 -1 -A)}
echo "Your root/$USER password is set to $PASSWORD"
${NSPAWN?} useradd --shell /bin/bash --create-home ${USER:-user}
${NSPAWN?} sh -c "echo root:$PASSWORD | chpasswd"
${NSPAWN?} sh -c "echo ${USER:-user}:$PASSWORD | chpasswd"
echo "$MNAME" > ${ROOTFS?}/etc/hostname
echo "127.0.0.1 $MNAME" >> ${ROOTFS?}/etc/hosts
echo "${USER:-user} ALL=(ALL) NOPASSWD:ALL" > ${ROOTFS?}/etc/sudoers.d/${USER:-user}
install -o 1000 -g 1000 -d -m 0700 ${ROOTFS?}/home/${USER:-user}/.ssh/
install -o 1000 -g 1000 -m 0644 <(echo "$AUTHORIZED_KEY") ${ROOTFS?}/home/${USER:-user}/.ssh/authorized_keys
mkdir -p ${ROOTFS?}/boot
test -b ${USBDEV:-''} && {
echo "PARTUUID=$(blkid ${USBDEV:?}4 --output value | tail -1) / ext4 defaults,noatime 0 0" >> ${ROOTFS?}/etc/fstab
echo "PARTUUID=$(blkid ${USBDEV:?}3 --output value | tail -1) /boot vfat defaults,noatime 0 0" >> ${ROOTFS?}/etc/fstab
echo "none /tmp tmpfs defaults,noatime 0 0" >> ${ROOTFS?}/etc/fstab
}
${NSPAWN?} sh -c "
systemctl enable networking
systemctl enable systemd-networkd.service
systemctl enable ssh
"
cat > ${ROOTFS?}/etc/systemd/network/20-dhcp-all.network <<EOF
[Match]
Name=*
[Network]
DHCP=yes
EOF
echo "nameserver 1.1.1.1" > ${ROOTFS?}/etc/resolv.conf
echo "nameserver 8.8.8.8" >> ${ROOTFS?}/etc/resolv.conf
test -d ssh_host && {
sudo rsync --chown=root:root -vr ssh_host/etc/ssh/ ${ROOTFS?}/etc/ssh/
sudo chmod 600 ${ROOTFS?}/etc/ssh/ssh_host_*
sudo chmod +r ${ROOTFS?}/etc/ssh/ssh_host_*.pub
}
}
star64_mount
star64_install_debian
tee ${ROOTFS?}/boot/vf2_uEnv.txt <<'EOF'
bootargs=console=ttyS0,115200 rootwait earlycon=sbi root=/dev/mmcblk1p4 rw
distro_bootcmd=fatload mmc 1:3 0x60200000 Image.gz; \
fatload mmc 1:3 ${fdt_addr_r} jh7110-pine64-star64.dtb \
unzip 0x60200000 ${kernel_addr_r}; \
booti ${kernel_addr_r} - ${fdt_addr_r}
EOF
star64_unmount
Troubleshooting
Project versions used (last git commit hash)
- linux: 7943fd6427b0abd25e1af2756e061a112bde8711
- opensbi: d4c46e0ff1b0ead9d5a586e1a19a00a92160206d
- Tools: 693661d4ba314424f76c06da1bbb799e9b534c9f
- u-boot: 172b47f62039605d6806fa96bd403c21cda28996
Serial / UART
PINE64 STAR64 UART ┌─────┐ 3.3V │ 1 2│ 5V SDA1 │ 3 4│ 5V SCL1 │ 5 6│ GND GPIO55 │ 7 8│ TXD GND │ 9 10│ RXD
Use screen /dev/ttyUSB0 115200
to monitor serial port.
JTAG
Connect a JTAG adapter to GPIO Star64 schematic p. 18 J5 and Match it with the configuration as of in starfive-tech/u-boot: board: starfive_visionfive2.c#L354. Also see: - visionfive jtag port - JH7110 GPIO AF
PINE64 STAR64 JTAG │33 34│ GND GPIO63 TMS │35 36│ nTRST GPIO36 GPIO60 TCK │37 38│ TDI GPIO61 GND │39 40│ TDO GPIO44 └─────┘
Openocd
You can use the visionfive2 openocd config.
mkdir -p openocd/
nano openocd/starfive-visionfive2.cfg
openocd -f interface/ftdi/um232h.cfg -f openocd/starfive-visionfive2.cfg
BOOT fail,Error is 0xffffffff
If you get the BOOT fail,Error is 0xffffffff
error just press the reset key again. This error keeps ocurring if powering the star64 on. But pressing reset will make the star64 boot normally.