Copyright © Shanghai StarFive Technology Co., Ltd., 2021. All rights reserved.
Information in this document is provided "as is," with all faults. Contents may be periodically updated or revised due to the product development. Shanghai StarFive Technology Co., Ltd. (hereinafter “StarFive”) reserves the right to make changes without further notice to any products herein.
StarFive expressly disclaims all warranties, representations, and conditions of any kind, whether express or implied, including, but not limited to, the implied warranties or conditions of merchantability, fitness for a particular purpose and non-infringement.
StarFive does not assume any liability rising out of the application or use of any product or circuit, and specifically disclaims any and all liability, including without limitation indirect, incidental, special, exemplary, or consequential damages.
All material appearing in this document is protected by copyright and is the property of StarFive. You may use this document or any part of the document for internal or educational purposes only, provided you do not modify, edit or take out of context the information in this document in any manner. Information contained in this document may be used, at your sole risk, for any purposes. StarFive authorizes you to copy this document, provided that you retain all copyright and other proprietary notices contained in the original materials on any copies of the materials and that you comply strictly with these terms. This copyright permission does not constitute an endorsement of the products or services.
This document mainly describes how to compile firmware, u-boot, Linux Kernel and make file systems.
Version | Released | Revision |
---|---|---|
V1.0 | 2021-12-08 | The first official release. |
V1.1 | 2022-02-17 | Updated the command in step 12 in the Method 1: Using Micro-SD Card section. |
Make sure that the following hardware are prepared for the operation described in this manual:
VisionFive
Micro-SD card (16GB or more)
PC with Linux OS
USB to Serial Converter
Ethernet cable
Power adapter
USB Type-C cable
Information:
In this guide, Ubuntu 18.04 LTS is installed on the host PC.
Alternatively, if you are interested in compiling bootloader and ddr init from source code, you can follow the guideline in this chapter.
To prepare a compilation environment, perform the following steps:
Steps:
Visit this link and download the latest version of riscv64-unknown-elf-toolchain-xxx according to your operating system.
Unzip the downloaded toolchain by typing the following:
tar -xzvf <Toolchain_Name>
Information:
<Toolchain_Name>
refers to the name of the downloaded toolchain in the previous step. For example,riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14.tar.gz
.
Open .bashrc
file by typing the following:
gedit ~/.bashrc
Add the following line, save and exit:
export PATH=$PATH:<Unzipped_Compiler_Path>/bin
Information:
<Unzipped_Compiler_Path>
refers to the location of the unzipped compiler. For example,/home/yingpeng/Downloads/riscv64-unknown-elf-toolchain-xxx/
.
Example:
export PATH=$PATH:/home/yingpeng/Downloads/riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14/bin
Type the following to make the change effective:
source ~/.bashrc
Command Example and Result:
The following figure shows an example command and the result:
Figure - Example Output
To compile Bootloader, perform the following steps:
Steps:
Clone the repo from GitHub.
git clone https://github.com/starfive-tech/JH7100_secondBoot.git
Go into the build directory.
cd JH7100_secondBoot/build
Compile bootloader.
make
Result:
You will see the following output if the compilation is successful.
Figure - Example Output
To compile ddr init, perform the following:
Steps:
Clone the repo from GitHub.
git clone https://github.com/starfive-tech/JH7100_ddrinit.git
Go into build directory.
cd JH7100_ddrinit/build
Compile ddr init.
make
Result:
You will see the following output if the compilation is successful.
Figure - Example Output
Information:
Refer to Appendix B: Updating Firmware and u-boot section in VisionFive_Single_Board_Computer_Quick_Start_Guide to flash bootloader and ddr init.
You can follow the steps below to set up your own cross-compile.
Steps:
Install the riscv64-linux-gnu-gcc compiler from Ubuntu packages.
sudo apt update
sudo apt upgrade
sudo apt install gcc-riscv64-linux-gnu
Check the version of the riscv64-linux-gnu-gcc.
riscv64-linux-gnu-gcc -v
Result:
The output will be as follows:
Figure - Example Output
Follow the steps below to compile the u-boot for VisionFive.
Steps:
Locate to your desired directory to store the u-boot files. For example, the home directory.
Example:
cd ~ # home directory
Download the source code for u-boot compilation.
git clone https://github.com/starfive-tech/u-boot
Switch to the code branch by executing the following command:
cd u-boot
git checkout -b JH7100_upstream origin/JH7100_upstream
git pull
Type the following to compile u-boot under the u-boot directory.
make <Configuration_File> ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu-
make u-boot.bin u-boot.dtb ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu-
Information:
Configuration_File:
- For VisionFive, the file is
starfive_jh7100_visionfive_smode_defconfig
.- For Starlight, the file is
starfive_jh7100_starlight_smode_defconfig
.
Result:
There will be these 2 files generated after compilation inside the u-boot directory: u-boot.bin
and u-boot.dtb
.
Figure - Example Output
Information:
Bothu-boot.dtb
andu-boot.bin
will be used later for OpenSBI compilation.
OpenSBI stands for Open-source Supervisor Binary Interface and it is an open-source implementation of the RISC-V Supervisor Binary Interface. It is a RISC-V specific runtime service provider and it is typically used in boot stage following ROM and LOADER. A typical boot flow is as follows:
Figure Typical Boot Flow
Follow the steps below to compile OpenSBI for VisionFive.
Steps:
Locate to your desired directory to store the OpenSBI files. For example, the home directory.
Example:
cd ~ # home directory
Download the source code for OpenSBI compilation.
git clone https://github.com/riscv/opensbi.git
Inside opensbi directory, type the following to compile openSBI.
cd opensbi
make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- PLATFORM=generic FW_PAYLOAD_PATH={U-BOOT_PATH}/u-boot.bin FW_FDT_PATH={U-BOOT_PATH}/u-boot.dtb
Information:
Modify the {U-BOOT_PATH} to the path of u-boot from before.
Result:
After compilation, the file fw_payload.bin will be generated in the directory opensbi/build/platform/generic/firmware
and the size is larger than 2M.
Figure - Example Output
Navigate to the directory containing fw_payload.bin
.
cd opensbi/build/platform/generic/firmware
Copy the file fw_payload.bin
to a different location.
cp fw_payload.bin ~/Desktop/payload/
Navigate to the location where fw_payload.bin is copied and execute the following to install an image conversion tool.
cd ~/Desktop/payload/
sudo apt install subversion
svn export https://github.com/starfive-tech/freelight-u-sdk.git/branches/starfive/fsz.sh
Information:
Here is the source code.
Change the user rights of the tool.
chmod 777 fsz.sh
Convert the file from fw_payload.bin
to fw_payload.bin.out
.
./fsz.sh fw_payload.bin fw_payload.bin.out
Figure - Example Output
Information:
You will see a new file namedfw_payload.bin.out
generated. Refer to Appendix B: Updating Firmware and u-boot section in VisionFive_Single_Board_Computer_Quick_Start_Guide to flash u-boot.
Follow the following steps to compile Linux Kernel for VisionFive.
Locate to your desired directory to store the Linux Kernel files. For example, the home directory.
Example:
cd ~ # home directory
Download the source code for Linux Kernel.
git clone https://github.com/starfive-tech/linux
Type the following to set the default configuration settings for compiling Linux Kernel.
cd linux
make CROSS_COMPILE=riscv64-linux-gnu- ARCH=riscv visionfive_defconfig
Type the following to set additional configuration settings for compiling Linux Kernel.
make CROSS_COMPILE=riscv64-linux-gnu- ARCH=riscv menuconfig
Compile the Linux Kernel.
make CROSS_COMPILE=riscv64-linux-gnu- ARCH=riscv -jx
Information:
Here you need to change the-jx
value according to the number of cores in your CPU. If your CPU has 8 cores, change this to-j8
. This process will take some time and therefore please wait patiently.
Result:
The kernel image will be generated inside the directory linux/arch/riscv/boot
as Image.gz.
Figure - Example Output
The dtb files will be generated inside the directory linux/arch/riscv/boot/dts/starfive
Figure - Generated dtb Files
The Image.gz
and .dtb
files will be used later in this guide when we try to move rootfs, dtb and kernel to VisionFive. Different boards use different dtb files, and for the detailed information, refer to the dtb Files table in StarFive_40-Pin_GPIO_Header_User_Guide.
Steps:
Visit StarFive's official GitHub to download the latest operating system.
Flash the latest operating system to the Micro-SD card. For details, see Flash Fedora OS to a Micro-SD Card section in VisionFive_Single_Board_Computer_Quick_Start_Guide.
To add new file, perform the following steps:
Note:
If there is no update, no need to add the new file.
Compile the file under the linux directory with the following command:
make CROSS_COMPILE=riscv64-linux-gnu- ARCH=riscv INSTALL_PATH=<ROOTFS_PATH> zinstall -<jx>
Information:
<ROOTFS_PATH>
: This is a user-defined directory where the vmliunz files will be generated.<jx>
: It refers to the number of cores in your CPU. If your CPU has 8 cores, change this to -j8.
Example Command and Output:
Figure - Example Command and Output
Result:
vmliunz files will be generated under the ROOTFS_PATH
.
(Optional) Compile the file under the linux path with the following command:
make CROSS_COMPILE=riscv64-linux-gnu- ARCH=riscv INSTALL_MOD_PATH=<ROOTFS_PATH> modules_install -jx
Information:
- If you need to add new modules, this step is required.
<ROOTFS_PATH>
: This is a user-defined directory where the modules will be generated.<jx>
: It refers to the number of cores in your CPU. If your CPU has 8 cores, change this to -j8.
Example Command and Output:
Figure - Example Command and Output
Result:
The module files will be generated under the ROOTFS_PATH
.
View the files generated under ${ROOTFS_PATH}
. The following is an example:
Figure - Example
Add the new file:
Sub-steps:
View the SD-card information.
df -h
Figure - Example SD Card Information
Copy the kernel file to the Micro-SD card. Please operate under the path of ${ROOTFS_PATH}
.
sudo cp vmlinuz-5.16.0-rc2-visionfive-g6e924cb10a60 /media/<User_Name>/__boot/ && sync
Information:
<User_Name>
is your username, for example, yingpeng.
(Optional) Copy the modules file to the Micro-SD card. Please operate under the path of ${ROOTFS_PATH}
.
sudo cp -r lib/modules/5.16.0-rc2-visionfive-g6e924cb10a60/ /media/<User_Name>/__/lib/modules && sync
Information:
- If you have compiled modules in the Compile Module step, and you need to add these modules, this step is required.
<User_Name>
is your username, for example, yingpeng.
Perform the following step to update the grub.cfg
file:
cd /media/<UserName>/__boot/
sudo gedit grub.cfg
Information:
<User_Name>
is your username, for example, yingpeng.
Add the following command lines, save and exit:
menuentry '<Configuration_Item_Name_on_Menu>' {
linux /<Newly_Compiled_vmlinuz_file> ro root=UUID=59fcd098-2f22-441a-ba45-4f7185baf23f rhgb console=tty0 console=ttyS0,115200 earlycon rootwait stmmaceth=chain_mode:1 selinux=0 LANG=en_US.UTF-8
devicetree /dtbs/5.16.0-rc2+/starfive/<dtb_File_Name>
initrd /initramfs-5.16.0-rc2+.img
}
Information:
In these commands:
<Configuration_Item_Name_on_Menu>
: The configuration name displayed on the menu. For example,My Fedora vmlinux-5.16.0-rc2 visionfive
.<Newly_Compiled_vmlinuz_file>
: The vmlinuz file name that is newly compiled in the previous steps. For example,vmlinuz-5.16.0-rc2-visionfive-g6e924cb10a60
.<dtb_File_Name>
: Different boards use different dtb files, and for the detailed information, refer to the dtb Files table in StarFive_40-Pin_GPIO_Header_User_Guide.
Example:
The following are the example commands:
menuentry 'My Fedora vmlinux-5.16.0-rc2 visionfive' {
linux /vmlinuz-5.16.0-rc2-visionfive-g6e924cb10a60 ro root=UUID=59fcd098-2f22-441a-ba45-4f7185baf23f rhgb console=tty0 console=ttyS0,115200 earlycon rootwait stmmaceth=chain_mode:1 selinux=0 LANG=en_US.UTF-8
devicetree /dtbs/5.16.0-rc2+/starfive/jh7100-starfive-visionfive-v1.dtb
initrd /initramfs-5.16.0-rc2+.img
}
Verification:
The following steps are provided to verify if the configuration is successful:
Pull out the card from the PC and insert it into the VisionFive board. The system will start normally after power-on.
You can find the defined configuration item, for example, My Fedora vmlinux-5.16.0-rc2 visionfive
, on the menu, as shown below:
Figure - Example Interface
After the system starts successfully, you can see the version of the new vmlinuz file:
Figure - Example Output
Follow the following steps to make the file system.
Steps:
Create the directory structure.
mkdir rootfs
cd rootfs
mkdir dev usr bin sbin lib etc proc tmp sys var root mnt
Download the busybox source code outside the rootfs directory.
git clone https://git.busybox.net/busybox
Navigate to the extracted location and enter busybox configuration.
cd busybox
make CROSS_COMPILE=riscv64-linux-gnu- ARCH=riscv menuconfig
Figure - Busybox Configuration
Navigate to Settings > Build Options and check Build static binary (no shared libs) by pressing Y.
Under Build Options, select cross compiler prefix and type the following to specify the compiler.
riscv64-linux-gnu-
Under Installation Options > Destination path for make install
, change the path to the path of the rootfs file directory (this is the installation location of the compiled busybox).
Example:
/home/user/rootfs
Exit from the busybox configuration window and save the configuration.
Compile busybox.
make ARCH=riscv
Install busybox.
make install
Navigate to the rootfs/etc directory created before, create a file called inittab and open it using vim text editor.
cd rootfs/etc
vim inittab
Copy and paste the following content inside the inittab
file.
::sysinit:/etc/init.d/rcS
::respawn:-/bin/login
::restart:/sbin/init
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
::shutdown:/sbin/swapoff -a
Create a file called profile inside rootfs/etc and open it using vim text editor.
vim profile
Copy and paste the following content inside the profile file.
# /etc/profile: system-wide .profile file for the Bourne shells
echo
#echo -n "Processing /etc/profile... "
# no-op
# Set search library path
#echo "Set search library path in /etc/profile"
export LD_LIBRARY_PATH=/lib:/usr/lib
# Set user path
#echo "Set user path in /etc/profile"
PATH=/bin:/sbin:/usr/bin:/usr/sbin
export PATH
# Set PS1
#Note: In addition to the SHELL variable, ash supports \u, \h, \W, \$, \!, \n, \w, \nnn (octal numbers corresponding to ASCII characters)
#And \e[xx;xxm (color effects), etc.
#Also add an extra '\' in front of it!
#echo "Set PS1 in /etc/profile"
export PS1="\\e[00;32m[$USER@\\w\\a]\\$\\e[00;34m"
#echo "Done"
Create a file called fstab inside rootfs/etc and open it using vim text editor.
vim fstab
Copy and paste the following content inside the fstab file.
proc /proc proc defaults 0 0
none /tmp tmpfs defaults 0 0
mdev /dev tmpfs defaults 0 0
sysfs /sys sysfs defaults 0 0
Create a file called passwd inside rootfs/etc and open it using vim text editor.
vim passwd
Copy and paste the following content inside the passwd file.
root:x:0:0:root:/root:/bin/sh
Create a file called group inside rootfs/etc and open it using vim text editor.
vim group
Copy and paste the following content inside the group file.
root:x:0:root
Create a file called shadow inside rootfs/etc and open it using vim text editor.
vim shadow
Copy and paste the following content inside the shadow file.
root:BAy5qvelNWKns:1:0:99999:7:::
Create a directory called init.d
inside rootfs/etc
and navigate inside it.
mkdir init.d
cd init.d
Create a file called rcS inside rootfs/etc/init.d and open it using vim text editor.
vim rcS
Copy and paste the following content inside the rcS
file.
#! /bin/sh
#echo "----------mount all"
/bin/mount -a
#echo "----------Starting mdev......"
#/bin/echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
echo "********************************************************"
echo " starfive mini RISC-V Rootfs"
echo "********************************************************"
Navigate to the rootfs/dev
directory created before and execute the following.
1 cd rootfs/dev
2 sudo mknod -m 666 console c 5 1
3 sudo mknod -m 666 null c 1 3
Create a soft link in the root directory of rootfs.
1 cd rootfs/
2 ln -s bin/busybox init
Modify the permissions of all files in the rootfs directory.
sudo chmod 777 -R *
Execute the following command in the rootfs directory to generate rootfs.cpio.gz (cpio file system package) in a different directory.
1 cd rootfs
2 find . | cpio -o -H newc | gzip > /home/user/Desktop/rootfs.cpio.gz
Information:
After you successfully run the command above, you will see a file namedrootfs.cpio.gz
on your Desktop. This directory can be any directory you want. If your CPU has 8 cores, change this to-j8
. This process will take some time and therefore please wait patiently.
Start by moving the previously compiled rootfs file system package, kernel and dtb images into a single directory.
Figure - Example Interface
<dtb_File_Name>
: Different boards use different dtb files, and for the detailed information, refer to the dtb Files table in StarFive_40-Pin_GPIO_Header_User_Guide.
Steps:
Insert a micro-SD card to the host PC.
Type the following to see the location of the connected micro-SD card.
lsblk
For example, it's /dev/sdb
.
Figure - Example
Type the following to enter the partition configuration.
sudo gdisk /dev/sdb
Example Output:
Figure - Example Output
Delete the original partition and then create a new partition by entering the following respectively.
d--->o--->n--->w--->y
Information:
Press Enter to keep some settings to default in this configuration.
Format the micro-SD card and create the file system.
sudo mkfs.vfat /dev/sdb1
Remove the micro-SD card from PC and plug again to mount it.
Enter the following to check whether it gets mounted.
df -h
You will see an output as follows and take a note of the mount location.
Figure - Example Output
Navigate to the directory containing the 3 images as before.
Example:
cd Desktop/compiled
Copy the files to the micro-SD card by typing the following.
sudo cp Image.gz <Mount_Location>
sudo cp rootfs.cpio.gz <Mount_Location>
sudo cp <dtb_File_Name> <Mount_Location>
sync
Information:
<Mount_Location>
: is the mount location as shown above.<dtb_File_Name>
: Different boards use different dtb files, and for the detailed information, refer to the dtb Files table in StarFive_40-Pin_GPIO_Header_User_Guide.
Example:
The following are the example commands:
sudo cp Image.gz /media/user/6411-3C3F/
sudo cp rootfs.cpio.gz /media/user/6411-3C3F/
sudo cp jh7100-starfive-visionfive-v1.dtb /media/user/6411-3C3F/
sync
Remove the micro-SD card from PC, insert into VisionFive and turn it on.
Open minicom while USB to Serial Adapter is connected between VisionFive and PC, and wait until the board enters u-boot mode. You will see the following output when it is in u-boot mode.
Figure - Example Output
Enter the following commands.
setenv kernel_comp_addr_r 0x90000000;setenv kernel_comp_size 0x10000000;setenv kernel_addr_r 0x84000000;setenv fdt_addr_r 0x88000000;setenv ramdisk_addr_r 0x88300000
fatls mmc 0:1
fatload mmc 0:1 ${kernel_addr_r} Image.gz
fatload mmc 0:1 ${fdt_addr_r} jh7100-starfive-visionfive-v1.dtb
fatload mmc 0:1 ${ramdisk_addr_r} rootfs.cpio.gz
booti ${kernel_addr_r} ${ramdisk_addr_r}:${filesize} ${fdt_addr_r}
Log in by typing the following credentials.
Connect an Ethernet Cable from the RJ45 port of VisionFive to a router, connect serial adapter cable and power on the board.
Information:
Make sure the host PC is also connected to the same router using Ethernet or Wi-Fi.
Open minicom and wait until the board enters u-boot mode. You will see the following output when it is in u-boot mode.
Figure - Example Output
Enter the following commands to set u-boot environment variables.
setenv serverip 192.168.120.12;setenv ipaddr 192.168.120.200;setenv hostname starfive;setenv netdev eth0;setenv kernel_comp_addr_r 0x90000000;setenv kernel_comp_size 0x10000000; setenv bootargs console=ttyS0,115200 earlycon=sbi root=/dev/ram0 stmmaceth=chain_mode:1 loglevel=8
Information:
Generally, the default IP of a router is 192.168.120.1. In this case, use the server IP as the IP assigned by the DHCP server of the router and use the VisionFive IP as 192.168.120.xxx. However, if your router IP is different (e.g.: 192.168.2.1), the server and VisionFive should follow the IP format of 192.168.2.xxx.
Check the connectivity by pinging the host PC from VisionFive.
Example:
ping 192.168.120.12
Result:
If you see the following output, the host PC and VisionFive has established a communication on the same network.
Figure - Example Output
Install a tftp server on the Host PC.
sudo apt-get update
sudo apt install tftpd-hpa
Check the status of the server.
sudo systemctl status tftpd-hpa
Execute the following to enter the tftp server configuration.
sudo nano /etc/default/tftpd-hpa
Configure the tftp server as follows.
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/home/user/Desktop/compiled"
TFTP_ADDRESS=":69"
TFTP_OPTIONS="--secure"
Information:
TheTFTP_DIRECTORY
is the directory that we created before with all the 3 images (Image.gz
,jh7100-starfive-visionfive-v1.dtb
,rootfs.cpio.gz
).
Restart the tftp server.
sudo systemctl restart tftpd-hpa
Type the following inside the u-boot mode of VisionFive to download the files from the tftp server of the host PC and start the kernel.
tftpboot ${fdt_addr_r} <dtb_File_Name>;tftpboot ${kernel_addr_r} Image.gz;tftpboot ${ramdisk_addr_r} rootfs.cpio.gz;booti ${kernel_addr_r} ${ramdisk_addr_r}:${filesize} ${fdt_addr_r}
<dtb_File_Name>
: Different boards use different dtb files, and for the detailed information, refer to the dtb Files table in StarFive_40-Pin_GPIO_Header_User_Guide.
Example:
The following command is an example for VisionFive:
tftpboot ${fdt_addr_r} jh7100-starfive-visionfive-v1.dtb;tftpboot ${kernel_addr_r} Image.gz;tftpboot ${ramdisk_addr_r} rootfs.cpio.gz;booti ${kernel_addr_r} ${ramdisk_addr_r}:${filesize} ${fdt_addr_r}
Log in with the following credentials.