目录
一.编译qemu 运行opensbi+kernel+rootfs
1.编译qemu-9.1.1
2.安装riscv64编译器
3. 编译opensbi
4.编译kernel
5.编译rootfs
设备驱动开发流程
1.安装 RISC-V 交叉编译工具链
2.驱动开发准备
3.编写简易中断控制器驱动(PLIC)
4.配置内核编译选项
5.编译并测试驱动
一.编译qemu 运行opensbi+kernel+rootfs
1.编译qemu-9.1.1
打开qemu官网https://www.qemu.org/,下载qemu-9.1.1.tar.xz
root@ser004576790432:~# mkdir risc-v
root@ser132653590900:~/risc-v# wget https://download.qemu.org/qemu-9.1.0.tar.xz
安装依赖并执行安装:
root@ser132653590900:~/risc-v/qemu-9.1.0/build# apt-get install build-essential gcc g++ make pkg-config
root@ser132653590900:~# apt-get install libglib2.0-dev libpixman-1-dev libslirp-dev zlib1g-dev \
libfdt-dev libsdl2-dev libgtk-3-dev ninja-build git
root@ser004576790432:~/risc-v# apt install --reinstall policykit-1
root@ser004576790432:~/risc-v# systemctl enable --now polkit.service
root@ser132653590900:~/risc-v/qemu-9.1.0/#apt-get install python3-venv python3-pip python3-dev
root@ser132653590900:~/risc-v/qemu-9.1.0/# python3 -m pip install tomli
root@ser004576790432:~/risc-v/qemu-9.1.0# mkdir build
root@ser004576790432:~/risc-v/qemu-9.1.0# cd build/
root@ser004576790432:~/risc-v/qemu-9.1.0/build# ../configure --enable-slirp --target-list=riscv64-softmmu
root@ser132653590900:~/risc-v/qemu-9.1.0/build# make -j12
root@ser132653590900:~/risc-v/qemu-9.1.0/build# make install
root@ser132653590900:~/risc-v/qemu-9.1.0/build# ./qemu-system-riscv64 --version
QEMU emulator version 9.1.0
Copyright (c) 2003-2024 Fabrice Bellard and the QEMU Project developers
2.安装riscv64编译器
root@ser132653590900:~/risc-v# sudo apt install gcc-riscv64-linux-gnu g++-riscv64-linux-gnu -y
3. 编译opensbi
root@ser132653590900:~/risc-v# git clone https://github.com/riscv-software-src/opensbi.git -b v1.5.1
cd opensbi
make CROSS_COMPILE=riscv64-linux-gnu- PLATFORM=generic all -j12
4.编译kernel
wget https://mirrors.ustc.edu.cn/kernel.org/linux/kernel/v6.x/linux-6.6.1.tar.gz
tar xf linux-6.6.1.tar.xz
cd linux-6.6.1
make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- defconfig
#提前安装依赖
apt-get install -y flex bison libssl-dev libelf-dev bc make
make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- -j12
5.编译rootfs
root@ser132653590900:~/risc-v# wget https://buildroot.org/downloads/buildroot-2024.11.2.tar.xz
root@ser132653590900:~/risc-v# tar xf buildroot-2024.11.2.tar.xz
root@ser132653590900:~/risc-v# cd buildroot-2024.11.2/
root@ser132653590900:~/risc-v/buildroot-2024.11.2# apt-get install libncurses-dev
root@ser132653590900:~/risc-v# tar xf buildroot-2024.11.2.tar.xz
root@ser132653590900:~/risc-v# cd buildroot-2024.11.2/
root@ser132653590900:~/risc-v/buildroot-2024.11.2# make menuconfig
修改完成保存退出。
更换kernel的源地址:
root@ser004576790432:~/risc-v/buildroot-2024.11.2# vi .config
BR2_KERNEL_MIRROR="https://mirrors.ustc.edu.cn/kernel.org/"
#中科大镜像
配置之后进行编译:
#安装依赖
apt-get install unzip
root@ser132653590900:~/risc-v/buildroot-2024.11.2# FORCE_UNSAFE_CONFIGURE=1 make -j$(nproc)
编译时间较长。
编译完成后进行测试:
root@ser004576790432:~/risc-v# vi run.sh
#!/bin/bash
qemu-system-riscv64 \
-M virt \
-smp 4 \
-m 4G \
-kernel linux-6.11.4/arch/riscv/boot/Image \
-initrd buildroot-2024.11.2/output/images/rootfs.cpio \
-append "root=/dev/ram" \
-display none \
-serial stdio \
-device virtio-scsi-device \
-device virtio-net-pci,netdev=net0 \
-netdev user,id=net0
root@ser004576790432:~/risc-v# chmod +x run.sh
root@ser004576790432:~/risc-v# sh run.sh
设备驱动开发流程
1.安装 RISC-V 交叉编译工具链
## riscv64-unknown-elf-gcc 是 裸机(Bare-metal)工具链,默认不支持动态链接和 Linux 内核的某些特性, 使用了针对裸机(bare-metal)的 RISC-V 工具链riscv64-unknown-elf-来编译 Linux 内核,会导致动态链接和共享库支持缺失
建议换成gcc-riscv64-linux-gnu
apt-get install gcc-riscv64-linux-gnu
2.驱动开发准备
# 进入内核源码目录
cd risc-v/linux-6.6.1
# 创建驱动代码目录
mkdir drivers/mydrivers
3.编写简易中断控制器驱动(PLIC)
创建文件 drivers/mydrivers/plic_driver.c:
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
static irqreturn_t plic_irq_handler(int irq, void *dev_id) {
printk(KERN_INFO "PLIC Interrupt Received!\n");
return IRQ_HANDLED;
}
static int plic_probe(struct platform_device *pdev) {
int irq = platform_get_irq(pdev, 0);
if (request_irq(irq, plic_irq_handler, 0, "plic-mydriver", NULL)) {
dev_err(&pdev->dev, "Failed to request IRQ %d\n", irq);
return -EIO;
}
return 0;
}
static const struct of_device_id plic_ids[] = {
{ .compatible = "riscv,plic0" },
{ /* sentinel */ }
};
static struct platform_driver plic_driver = {
.driver = {
.name = "plic-mydriver",
.of_match_table = plic_ids,
},
.probe = plic_probe,
};
module_platform_driver(plic_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
4.配置内核编译选项
编辑 arch/riscv/configs/defconfig:
CONFIG_MYDRIVERS_PLIC=y
创建 drivers/mydrivers/Kconfig:
config MYDRIVERS_PLIC
tristate "My PLIC Interrupt Driver"
default y
help
Simple PLIC interrupt controller driver.
修改 drivers/mydrivers/Makefile:
obj-$(CONFIG_MYDRIVERS_PLIC) += plic_driver.o
5.编译并测试驱动
cd risc-v/linux-6.6.1
make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- distclean
make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- defconfig
# 使用 Linux 工具链重新编译
make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- -j$(nproc)
#启动测试
qemu-system-riscv64 -M virt -kernel arch/riscv/boot/Image -initrd ../buildroot-2024.11.2/output/images/rootfs.cpio -append "root=/dev/ram console=ttyS0" -nographic -serial mon:stdio
检查验证: