Building Linux kernel for my RISC-V SoC(RV32X SoC)

Tuesday, March 16, 2021

概要

自作のRISC-V SoC向けのLinuxカーネルのビルドフローをメモとして残す。 アーキテクチャはRV32IMAである。 特権モードは(M, S, U)をサポートしており、SV32ページングを実装している。 クロスコンパイラとしてriscv32-unknown-linux-gnu-gcc(version 10.1.0)がインストールされていることとする。

Build Linux Kernel

Linuxのレポジトリをクローンする。

バージョンはv5.11とする。

git clone https://github.com/torvalds/linux
git checkout v5.11

依存ツールをインストールする。

sudo apt install autoconf automake autotools-dev curl libmpc-dev libmpfr-dev libgmp-dev \
                 gawk build-essential bison flex texinfo gperf libtool patchutils bc \
				                  zlib1g-dev libexpat-dev git

コンフィグレーションを行う。

lib/Kconfig.debugmenu "Kernel hacking"の次の行に以下を追記する。 これで、Kernel hackingの設定項目にEnable Early PRINTKが追加される。

config EARLY_PRINTK                                                                                                                               
	bool "Enable Early PRINTK"

ARCH=riscvでRISC-Vをアーキテクチャとして指定する。 arch/$ARCH/configsにデフォルトのdefconfigが用意されている。 defconfigでデフォルトのコンフィグレーションをもとに.configを作る。 menuconfigでdefconfigした情報をもとに、手動でコンフィグレーションを行う。

cd linux
make ARCH=riscv CROSS_COMPILE=riscv32-unknown-linux-gnu- defconfig
make ARCH=riscv CROSS_COMPILE=riscv32-unknown-linux-gnu- menuconfig
Platform type -> Base ISA => RV32I
Platform type -> Symmetric Multi-Processing => off
Platform type -> supported PMU type => Base Performance Monitoring Unit => off
Platform type -> FPU support => off
Platform type -> Emit compressed instruction when building Linux => off (UEFI runtime supportのdepends、オフにする)
Boot options -> UEFI runtime support => off (Compress instruction emmitionを無効化できるようになる。)
Kernel features -> Timer frequency => いい感じにする
Networking support => off
Boot options -> Build-in kernel command line => earlycon=sbi
Kernel hacking -> ログレベルを最大にする。

defconfig

defconfigを保存する。

make savedefconfig
cp defconfig arch/riscv/configs/rv32xsoc_defconfig

defconfigを読み込み、.configを作成する。

make ARCH=riscv CROSS_COMPILE=riscv32-unknown-linux-gnu- rv32xsoc_defconfig
CONFIG_SYSVIPC=y
CONFIG_NO_HZ_IDLE=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_CGROUPS=y
CONFIG_CGROUP_SCHED=y
CONFIG_CFS_BANDWIDTH=y
CONFIG_CGROUP_BPF=y
CONFIG_NAMESPACES=y
CONFIG_USER_NS=y
CONFIG_CHECKPOINT_RESTORE=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_EXPERT=y
# CONFIG_SYSFS_SYSCALL is not set
CONFIG_BPF_SYSCALL=y
CONFIG_SOC_SIFIVE=y
CONFIG_SOC_VIRT=y
CONFIG_ARCH_RV32I=y
CONFIG_CMODEL_MEDANY=y
# CONFIG_RISCV_ISA_C is not set
# CONFIG_FPU is not set
CONFIG_CMDLINE="earlycon=sbi"
# CONFIG_EFI is not set
CONFIG_JUMP_LABEL=y
CONFIG_ARCH_MMAP_RND_BITS=17
# CONFIG_COMPAT_32BIT_TIME is not set
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_PAGE_REPORTING=y
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
# CONFIG_BLK_DEV is not set
CONFIG_BLK_DEV_SD=y
CONFIG_SCSI_VIRTIO=y
CONFIG_ATA=y
CONFIG_SATA_AHCI_PLATFORM=y
CONFIG_INPUT_MOUSEDEV=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SERIAL_EARLYCON_RISCV_SBI=y
CONFIG_HVC_RISCV_SBI=y
CONFIG_VIRTIO_CONSOLE=y
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_VIRTIO=y
# CONFIG_HWMON is not set
CONFIG_DRM=y
CONFIG_BACKLIGHT_CLASS_DEVICE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
# CONFIG_USB_SUPPORT is not set
# CONFIG_VIRTIO_MENU is not set
# CONFIG_VHOST_MENU is not set
# CONFIG_IOMMU_SUPPORT is not set
CONFIG_RPMSG_VIRTIO=y
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_AUTOFS4_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_KEYS=y
CONFIG_CRYPTO_DEV_VIRTIO=y
CONFIG_CRC_ITU_T=y
CONFIG_CRC7=y
CONFIG_EARLY_PRINTK=y
CONFIG_PRINTK_TIME=y
CONFIG_PRINTK_CALLER=y
CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15
CONFIG_CONSOLE_LOGLEVEL_QUIET=15
CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7
CONFIG_DYNAMIC_DEBUG=y
CONFIG_FRAME_WARN=2048
CONFIG_DEBUG_FS=y
CONFIG_DEBUG_PAGEALLOC=y
CONFIG_SCHED_STACK_END_CHECK=y
CONFIG_DEBUG_VM=y
CONFIG_DEBUG_VM_VMACACHE=y
CONFIG_DEBUG_VM_RB=y
CONFIG_DEBUG_VM_PGFLAGS=y
CONFIG_DEBUG_VIRTUAL=y
CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_SOFTLOCKUP_DETECTOR=y
CONFIG_WQ_WATCHDOG=y
CONFIG_DEBUG_TIMEKEEPING=y
CONFIG_DEBUG_RT_MUTEXES=y
CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
CONFIG_DEBUG_RWSEMS=y
CONFIG_DEBUG_ATOMIC_SLEEP=y
CONFIG_STACKTRACE=y
CONFIG_DEBUG_LIST=y
CONFIG_DEBUG_PLIST=y
CONFIG_DEBUG_SG=y
CONFIG_RCU_EQS_DEBUG=y
CONFIG_DEBUG_BLOCK_EXT_DEVT=y
# CONFIG_FTRACE is not set
# CONFIG_RUNTIME_TESTING_MENU is not set
CONFIG_MEMTEST=y

コンフィグレーションは以下のコマンドで削除できる。

make mrproper

Linuxのビルドを行う。

make CFLAGS="-march=rv32ima -mabi=ilp32" LDFLAGS="-march=rv32ima -mabi=ilp32" ARCH=riscv CROSS_COMPILE=riscv32-unknown-linux-gnu- all -j4

OpenSBIのPayloadとしてビルドする

cd rv32x_dev/software/opensbi
make CROSS_COMPILE=riscv32-unknown-elf- PLATFORM=rv32xsoc FW_PAYLOAD_PATH=~/linux/arch/riscv/boot/Image FW_FDT_PATH=~/rv32x_dev/software/bootrom/rv32xsoc.dtb

シミュレーターで実行

clear;./rv32x_simulation ../software/opensbi/build/platform/rv32xsoc/firmware/fw_payload.elf --no-sim-exit --no-log 2>/dev/null

References

LinuxRISC-VLinuxCPU

Booting linux kernel on my RISC-V part1

Next Synthesis Language