В предыдущей статье мы рассмотрели процесс сборки загрузчика. Теперь мы рассмотрим ядро Linux, исходные коды которого поддерживает компания StarFive в репозитории https://github.com/starfive-tech/linux. Кроме того, мы рассмотрим создание скриптов загрузки ядра (boot.scr) для U-Boot.
Компания StarFive одновременно ведет две версии ядра: 5.15.x и 6.1.x. Нас интересует стабильная ветка 6.1.x, поэтому мы возьмем snapshoot тега VF2_6.1_v3.8.2:
git clone https://github.com/starfive-tech/linux.git
cd linux
git archive --format=tar --prefix=linux-starfive-6.1.31-3.8.2/ 22e0315434b13cdde93ded101b567d5d1c4d5a2e | \
xz >../linux-starfive-6.1.31-3.8.2.tar.xz
cd ..
rm -rf linux
tar xJvf linux-starfive-6.1.31-3.8.2.tar.xz
Таким образом исходный код ядра, соответствующий тегу VF2_6.1_v3.8.2, мы имеем в каталоге ./linux-starfive-6.1.31-3.8.2/.
Как установить необходимый toolchain мы рассказали в предыдущей статье.
Конфигурационный файл для VisionFive2 starfive_visionfive2_defconfig находится в каталоге ./linux-starfive-6.1.31-3.8.2/arch/riscv/configs/ и для того, чтобы получить конфигурационный файл ./linux-starfive-6.1.31-3.8.2/.config, пригодный для последующего редактирования и многократного использования для наших нужд, выполним следующий скрипт (в каталоге ./linux-starfive-6.1.31-3.8.2/):
#!/bin/sh
JOBS=-j24
PKG_CONFIG_PATH= PKG_CONFIG_LIBDIR= \
make ${JOBS} ARCH=riscv CROSS_COMPILE="/opt/toolchains/riscv64-RV64GC-linux-glibc/1.9.8/bin/riscv64-rv64gc-linux-gnu-" \
KCFLAGS="-Wno-unused-variable -Wno-undef -Wno-unused-label -Wno-unused-function -Wno-address -Wno-discarded-qualifiers -Wno-int-conversion -Wimplicit-fallthrough=0 -Wformat=0" \
HOSTLDFLAGS="-L/lib64 -L/usr/lib64" \
starfive_visionfive2_defconfig
Теперь мы можем внести некоторые изменения в конфигурацию ядра, перед сборкой. Например, добавив следующие строки:
#
# Userland interfaces
#
CONFIG_INPUT_MOUSEDEV=y
CONFIG_INPUT_MOUSEDEV_PSAUX=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
CONFIG_INPUT_JOYDEV=m
CONFIG_INPUT_EVDEV=m
# CONFIG_INPUT_EVBUG is not set
мы обеспечим возможность использования мыши в терминале.
Кроме того, следует обратить внимание на драйвер графического ускорителя:
CONFIG_DRM_IMG=y
CONFIG_DRM_IMG_ROGUE=y
CONFIG_DRM_LEGACY=y
ведь SoC JH7110 имеет в своем составе GPU Imagination MG BXE-4-32 MC1.
После изменений файла ./linux-starfive-6.1.31-3.8.2/.config, для повторного конфигурирования исходного кода, необходимо выполнить команду make oldconfig:
#!/bin/sh
JOBS=-j24
PKG_CONFIG_PATH= PKG_CONFIG_LIBDIR= \
make ${JOBS} ARCH=riscv CROSS_COMPILE="/opt/toolchains/riscv64-RV64GC-linux-glibc/1.9.8/bin/riscv64-rv64gc-linux-gnu-" \
KCFLAGS="-Wno-unused-variable -Wno-undef -Wno-unused-label -Wno-unused-function -Wno-address -Wno-discarded-qualifiers -Wno-int-conversion -Wimplicit-fallthrough=0 -Wformat=0" \
HOSTLDFLAGS="-L/lib64 -L/usr/lib64" \
oldconfig
Полный скрипт сборки ядра может выглядеть, например, следующим образом:
#!/bin/sh
JOBS=-j24
PKG_CONFIG_PATH= PKG_CONFIG_LIBDIR= \
make ${JOBS} ARCH=riscv CROSS_COMPILE="/opt/toolchains/riscv64-RV64GC-linux-glibc/1.9.8/bin/riscv64-rv64gc-linux-gnu-" \
KCFLAGS="-Wno-unused-variable -Wno-undef -Wno-unused-label -Wno-unused-function -Wno-address -Wno-discarded-qualifiers -Wno-int-conversion -Wimplicit-fallthrough=0 -Wformat=0" \
HOSTLDFLAGS="-L/lib64 -L/usr/lib64" \
oldconfig
PKG_CONFIG_PATH= PKG_CONFIG_LIBDIR= \
make ${JOBS} ARCH=riscv CROSS_COMPILE="/opt/toolchains/riscv64-RV64GC-linux-glibc/1.9.8/bin/riscv64-rv64gc-linux-gnu-" \
KCFLAGS="-Wno-unused-variable -Wno-undef -Wno-unused-label -Wno-unused-function -Wno-address -Wno-discarded-qualifiers -Wno-int-conversion -Wimplicit-fallthrough=0 -Wformat=0" \
HOSTLDFLAGS="-L/lib64 -L/usr/lib64" \
modules_prepare
PKG_CONFIG_PATH= PKG_CONFIG_LIBDIR= \
make ${JOBS} ARCH=riscv CROSS_COMPILE="/opt/toolchains/riscv64-RV64GC-linux-glibc/1.9.8/bin/riscv64-rv64gc-linux-gnu-" \
KCFLAGS="-Wno-unused-variable -Wno-undef -Wno-unused-label -Wno-unused-function -Wno-address -Wno-discarded-qualifiers -Wno-int-conversion -Wimplicit-fallthrough=0 -Wformat=0" \
HOSTLDFLAGS="-L/lib64 -L/usr/lib64" \
Image
PKG_CONFIG_PATH= PKG_CONFIG_LIBDIR= \
make ${JOBS} ARCH=riscv CROSS_COMPILE="/opt/toolchains/riscv64-RV64GC-linux-glibc/1.9.8/bin/riscv64-rv64gc-linux-gnu-" \
KCFLAGS="-Wno-unused-variable -Wno-undef -Wno-unused-label -Wno-unused-function -Wno-address -Wno-discarded-qualifiers -Wno-int-conversion -Wimplicit-fallthrough=0 -Wformat=0" \
HOSTLDFLAGS="-L/lib64 -L/usr/lib64" \
Image.lzma
PKG_CONFIG_PATH= PKG_CONFIG_LIBDIR= \
make ${JOBS} ARCH=riscv CROSS_COMPILE="/opt/toolchains/riscv64-RV64GC-linux-glibc/1.9.8/bin/riscv64-rv64gc-linux-gnu-" \
KCFLAGS="-Wno-unused-variable -Wno-undef -Wno-unused-label -Wno-unused-function -Wno-address -Wno-discarded-qualifiers -Wno-int-conversion -Wimplicit-fallthrough=0 -Wformat=0" \
HOSTLDFLAGS="-L/lib64 -L/usr/lib64" \
modules
PKG_CONFIG_PATH= PKG_CONFIG_LIBDIR= \
make ${JOBS} ARCH=riscv CROSS_COMPILE="/opt/toolchains/riscv64-RV64GC-linux-glibc/1.9.8/bin/riscv64-rv64gc-linux-gnu-" \
KCFLAGS="-Wno-unused-variable -Wno-undef -Wno-unused-label -Wno-unused-function -Wno-address -Wno-discarded-qualifiers -Wno-int-conversion -Wimplicit-fallthrough=0 -Wformat=0" \
HOSTLDFLAGS="-L/lib64 -L/usr/lib64" \
dtbs
PKG_CONFIG_PATH= PKG_CONFIG_LIBDIR= \
make ${JOBS} ARCH=riscv CROSS_COMPILE="/opt/toolchains/riscv64-RV64GC-linux-glibc/1.9.8/bin/riscv64-rv64gc-linux-gnu-" \
KCFLAGS="-Wno-unused-variable -Wno-undef -Wno-unused-label -Wno-unused-function -Wno-address -Wno-discarded-qualifiers -Wno-int-conversion -Wimplicit-fallthrough=0 -Wformat=0" \
HOSTLDFLAGS="-L/lib64 -L/usr/lib64" \
modules_install DEPMOD=true INSTALL_MOD_PATH=`pwd`/_dist
Выполнив данный скрипт в каталоге ./linux-starfive-6.1.31-3.8.2/ мы получим образы ядра: ./linux-starfive-6.1.31-3.8.2/arch/riscv/boot/Image{,.lzma} и модули ./linux-starfive-6.1.31-3.8.2/_dist/lib/modules/6.1.31 для установки в каталог /lib/modules/ корневой файловой системы.
DeviceTree-файл ./linux-starfive-6.1.31-3.8.2/arch/riscv/boot/dts/starfive/jh7110-visionfive-v2.dtb, а также файл ./linux-starfive-6.1.31-3.8.2/arch/riscv/boot/dts/starfive/vf2-overlay/vf2-overlay-uart3-i2c.dtbo надо будет установить в каталог /boot/starfive/ корневой файловой системы.
Далее нам понадобится утилита mkimage, которая входит в состав исходных кодов U-Boot, необходимая для подписи образов.
Все необходимые адреса памяти для загрузки ядра, devicetree и скриптов можно найти в файле ./u-boot-2021.10-3.8.2-orig/include/configs/starfive-visionfive2.h:
#define CONFIG_EXTRA_ENV_SETTINGS \
"fdt_high=0xffffffffffffffff\0" \
"initrd_high=0xffffffffffffffff\0" \
"kernel_addr_r=0x40200000\0" \
"kernel_comp_addr_r=0x5a000000\0" \
"kernel_comp_size=0x4000000\0" \
"fdt_addr_r=0x46000000\0" \
"scriptaddr=0x43900000\0" \
"script_offset_f=0x1fff000\0" \
"script_size_f=0x1000\0" \
"pxefile_addr_r=0x45900000\0" \
"ramdisk_addr_r=0x46100000\0" \
"fdtoverlay_addr_r=0x4f000000\0" \
"loadaddr=0x60000000\0" \
. . .
Подписать образы Image и Image.lzma можно с помощью следующих комманд:
./u-boot-2021.10-3.8.2/tools/mkimage \
-A riscv -O linux -T kernel -C none -a 0x40200000 -e 0x40200000 \
-n 6.1.31 -d Image uImage
./u-boot-2021.10-3.8.2/tools/mkimage \
-A riscv -O linux -T kernel -C lzma -a 0x40200000 -e 0x40200000 \
-n 6.1.31 -d Image.lzma uzImage
Здесь мы используем значение переменной kernel_addr_r=0x40200000 и версию ядра 6.1.31. Полученные файлы uImage и uzImage необходимо скопировать в каталог /boot/ корневой файловой системы для того, чтобы загрузчик мог найти эти образы.
Загрузчик U-Boot использует скрипты /boot/boot.scr для того, чтобы получить информацио о том, какие образы надо загружать в пямять, по каким адресам должны располагаться эти образы и как передавать управление для последующей загрузки системы.
Мы приготовим три исходных скрипта для загрузки с SD-карты (mmc1), EMMC Flash (mmc0), а также NVME диска (nvme0):
boot.sdhc.script:
mmc dev 1
mmcinfo
ext4load mmc 1:2 ${kernel_comp_addr_r} /boot/uzImage
ext4load mmc 1:2 ${fdt_addr_r} /boot/starfive/jh7110-visionfive-v2.dtb
setenv bootargs 'earlycon=sbi console=ttyS0,115200n8 console=tty1 ro root=/dev/mmcblk1p2 rootwait rootfstype=ext4 consoleblank=0 no_console_suspend'
bootm ${kernel_comp_addr_r} - ${fdt_addr_r}
boot.emmc.script:
mmc dev 0
mmcinfo
ext4load mmc 0:2 ${kernel_comp_addr_r} /boot/uzImage
ext4load mmc 0:2 ${fdt_addr_r} /boot/starfive/jh7110-visionfive-v2.dtb
setenv bootargs 'earlycon=sbi console=ttyS0,115200n8 console=tty1 ro root=/dev/mmcblk0p2 rootwait rootfstype=ext4 consoleblank=0 no_console_suspend'
bootm ${kernel_comp_addr_r} - ${fdt_addr_r}
boot.nvme.script:
nvme device 0
nvme info
ext4load nvme 0:2 ${kernel_comp_addr_r} /boot/uzImage
ext4load nvme 0:2 ${fdt_addr_r} /boot/starfive/jh7110-visionfive-v2.dtb
setenv bootargs 'earlycon=sbi console=ttyS0,115200n8 console=tty1 ro root=/dev/nvme0n1p2 rootwait rootfstype=ext4 consoleblank=0 no_console_suspend'
bootm ${kernel_comp_addr_r} - ${fdt_addr_r}
И подпишем их с помощью утилиты mkimage:
./u-boot-2021.10-3.8.2/tools/mkimage -A $(ARCH) -T script -C none -n "Boot Script" -d boot.sdhc.script boot.sdhc.scr
./u-boot-2021.10-3.8.2/tools/mkimage -A $(ARCH) -T script -C none -n "Boot Script" -d boot.emmc.script boot.emmc.scr
./u-boot-2021.10-3.8.2/tools/mkimage -A $(ARCH) -T script -C none -n "Boot Script" -d boot.nvme.script boot.nvme.scr
Полученные скрипты: boot.sdhc.scr, boot.emmc.scr и boot.mvme.scr необходимо поместить в каталог /boot/ корневой файловой системы.
Для загрузки с SD-карты, необходимо создать символическую ссылку:
cd /boot
ln -sf boot.sdhc.scr boot.scr
Если мы правильно скопировали созданные нами образы, в результате мы будем иметь следующее дерево каталогов:
/boot/
├── boot.emmc.scr
├── boot.nvme.scr
├── boot.sdhc.scr
├── starfive/
│ ├── jh7110-visionfive-v2.dtb
│ └── vf2-overlay/
│ └── vf2-overlay-uart3-i2c.dtbo
├── uImage
└── uzImage
Здесь необходимо отметить, что в рассматриваемом нами случае, загрузочный носитель, будь то SD-карта или NVME диск, имеет два раздела:
bash-5.1# fdisk -l /dev/sdi
Disk /dev/sdi: 58.61 GiB, 62929764352 bytes, 122909696 sectors
Disk model: MassStorageClass
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: gpt
Disk identifier: 0A88052A-5572-5E43-B543-02CBC7D4290A
Device Start End Sectors Size Type
/dev/sdi1 2048 526335 524288 256M EFI System
/dev/sdi2 526336 36444159 35917824 17.1G Linux filesystem
На первом расположена fat32 файловая система, а U-Boot, расположенный в QSPI Nor Flash, предполагает загрузку со второго раздела, на котором расположена ext4 корневая файловая система операционной системы.
Если мы зазместим загрузчик GRUB на первом разделе:
efi/boot/bootriscv64.efi
то мы также сможем загружать операционную систему с помощью следующих команд (в терминале U-Boot):
VisionFive2 # fatload mmc 1:1 ${kernel_addr_r} efi/boot/bootriscv64.efi
VisionFive2 # bootefi ${kernel_addr_r}
Готовые образы файловых систем: visionfive2.efi32fs и visionfive2.ext4fs можно загрузить из каталога releases FTP-сервера https://ftp.radix.pro/, и с помощью скрипта write-efiboot-image по инструкции создать загрузочную SD-карту с операционной системой Radix cross Linux.
Информацию об установке и настройке RcL вы можете найти на страницах Download, Install, а также в разделе Devices, посвященном SBC VisionFive2.
Отметим здесь, что система Radix cross Linux имеет в своем составе все необходимые пакеты, как для создания собственного сервера, так и для разработки собственных програм с помощью таких средств как GCC-12.2.0, LLVM-16.0.2, QtCreator, Glade, Cambalache и многих других. Кроме того, в системе предустановлены Libreoffice-7.6.2.1, Firefox-118.0.1, Thunderbird-115.3.1, что позволяет использовать SBC VisionFive2 в качестве (old school) персональной машины. Полный перечень пакетов представлен в файле visionfive2.pkglist.
Johan_Palych
Однако - visionfive2.ext4fs 18390450176 (17G)
rcl Автор
Система не маленькая, ведь там куча компиляторов (GCC, LLVM), интерпретаторов, IDEs, LibreOffice, Firefox, Thunderbird. В общем все, что нужно для работы. Около 820-и пакетов.
Плюс локальный репозиторий пакетов для инсталляции без сети.