weiqi7777

riscv linux在qemu上仿真

0
阅读(259) 评论(0)

经过几天的斗争,终于在qemu上,成功跑通了linux。下面将整个流程,记录下。

大致分为如下几步:

  1. 编译工具链
  2. 编译linux kernel
  3. 编译bootloader
  4. 编译跟文件系统
  5. 编译qemu
  6. 使用qemu,仿真kernel

看是有这么多步,挺麻烦的。如果真要自己做,那中间会有很多坑。

在这里,我们要感谢sifive工具的开源项目,freedom-u-sdk。该开源项目,把上面的几个步骤,全部都包括了。只需要2个命令,即可。

make

make qemu

该项目的githu地址如下:https://github.com/sifive/freedom-u-sdk

首先,先clone该项目,执行make。

执行make命令之后,就会自动的下载工具和代码,然后开始自动编译工具,如交叉编译工具链,跟文件系统等。

最后安装的工具,在版本库根目录下的 work/buildroot_initramfs/bost 目录下:

其实,这一套自动化下载,编译工具的流程,是根据buildroot这个工具来做的。官方地址是:https://buildroot.org

下面是该官网的介绍。

下载,安装完成之后,要修改下makefile,将以下代码全部注释掉:

注释掉如下的target:

  • $(buildroot_initramfs_wrkdir)/.config
  • $(buildroot_initramfs_tar)
  • buildroot_initramfs-menuconfig
  • $(buildroot_rootfs_wrkdir)/.config
  • (buildroot_rootfs_ext)
  • buildroot_rootfs-menuconfig
  • $(buildroot_initramfs_sysroot_stamp)

注释掉的目的是,防止之后执行make命令误操作,把下载的文件和编译好的工具删除,又重新下载和编译工具。

下载,安装之后。就可以启动qemu仿真linux kernel。执行如下命令:

make qemu

makefile中,对于qemu target实现如下:

.PHONY: qemu

qemu: $(qemu) $(bbl) $(vmlinux) $(initramfs)

    $(qemu) -nographic -machine virt -bios $(bbl) -kernel $(vmlinux) -initrd $(initramfs) \

        -netdev user,id=net0 -device virtio-net-device,netdev=net0

依赖于如下:

  • qemu工具,
  • bbl:riscv的bootloader
  • vmlinux:linux的可执行程序
  • initramfs:跟文件系统

make命令,首先是编译qemu,得到qemu可执行程序,接着编译riscv-pk,得到bbl。最后编译linux,得到vmlinux。initramfs之前的make阶段已经生成,因此这里不重新生成。

makefile最后,执行如下命令,启动qemu:

cd /home/lujun/work/sifive/freedom-u-sdk/work/linux && \

    /home/lujun/work/sifive/freedom-u-sdk/linux/usr/gen_initramfs_list.sh \

    -o /home/lujun/work/sifive/freedom-u-sdk/work/initramfs.cpio.gz -u 1000 -g 1000 \

    /home/lujun/work/sifive/freedom-u-sdk/conf/initramfs.txt \

    /home/lujun/work/sifive/freedom-u-sdk/work/buildroot_initramfs_sysroot

/home/lujun/work/sifive/freedom-u-sdk/work/riscv-qemu/prefix/bin/qemu-system-riscv64 -nographic -machine virt -bios /home/lujun/work/sifive/freedom-u-sdk/work/riscv-pk/bbl -kernel /home/lujun/work/sifive/freedom-u-sdk/work/linux/vmlinux -initrd /home/lujun/work/sifive/freedom-u-sdk/work/initramfs.cpio.gz \

    -netdev user,id=net0 -device virtio-net-device,netdev=net0

  • -machine virt: 指定qemu模拟平台是virt
  • -bios: 指定bootloader
  • -kernel: 指定kernel
  • -initrd: 指定份文件系统

这里要注意,qemu,一定要用这个freedom-u-sdk开源项目,编译得到的qemu,不能使用官方提供的最新的qemu(目前最新是4.0.0)。

lujun@lujun-host:~/work/linux/linux-arm$/home/lujun/work/sifive/freedom-u-sdk/work/riscv-qemu/prefix/bin/qemu-system-riscv64 --version

QEMU emulator version 3.1.50

Copyright (c) 2003-2018 Fabrice Bellard and the QEMU Project developers

这里使用的qemu版本是 3.1.50。用官方提供最新的qemu,会启动不了kernel。

下图是bbl执行的结果,打印logo,然后启动kernel。

最后出现登录界面,输入用户名和密码即可登录到linux。

这里,用户名是root,密码是 sifive。

以上就是在qemu上,跑riscv kernel的流程。要感谢sifive,将工作封装得这么简单与完美。

至于为什么需要几天,才在qemu上成功执行kernel,是以为之前就是按照本文开始的流程来做的,然后遇到了各种各样的问题。直到后面发现了sifive的这个开源项目。

其中遇到最大的问题,就是qemu工具版本的选择,不同版本的qemu,硬件描述不一样,使用选项也不一样,造成网上说的一些流程,在自己本机上却跑不起来。因此选择合适的qemu版本很重要。

后面说一下,怎么使用eclipse + riscv gdb,来连接qemu,调试kernel程序。