用 qemu 模拟 arm 内核

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/leishengsheng/article/details/80184319

前情

基于手上没有板子,想想试试 qemu 的模拟功能,这里可能并不会有一个流程化的过程,这方面的技术步骤网上还是有很多资源的,没必要再写了,主要是把自己的一些问题,主要的内容有个记录

记录

安装 qemu

ubuntu 系统 下用 apt install qemu-xx ,tab 键就可以发现应该安装什么,安装后命令行会有 qemu-开头的命令,qemu-ARCH 是模拟软件运行的,qemu-system-ARCH 是模拟系统运行的,这里主要用 qemu-system-arm, qemu-system-aarch64,其中 arm是对32bit 的模拟,aarch64是对 64bit 的模拟。

编译器

arm的编译器可以直接下载,用 apt install gcc-arm-linux-gnueabi gcc-arm-none-eabi 其中前面一个是用于编译 linux 相关系统的,后一个主要用于编译祼机系统。 如果需要 g++ 也是一样的安装,只是只有 arm-linux-gnueabi版本

编译 busybox

  • 要编译 static 版本
  • 我没有测试 32bit 版本,选择 64bit 版本,在编译过程中遇到了 32bit 编译失败的问题,现象已经不在了,当时应该是编译器版本低的原因,然后就使用 64bit 的
  • 编译命令 make -j 4 ARCH=arm64 CROSS_COMPILE=arm-linux-gnueabi-
  • 编译完安装默认是在当前目录的 _install 目录下

制作最小文件系统

  • 基于 _install 目录,创建 dev, etc/init.d 目录
  • dev 下面创建 mknod console c 5 1, mknod null c 1 3
  • 还有几个要准备的文件是 etc/inittab, etc/init.d/rcS, etc/fstab,文件内容参见 文后列表

编译内核

  • 下载内核源码
  • make defconfigarm64 只有这个选项可以用,不像 arm 里面有很多,当前可以执行后再自己配置
  • General Setup --> Initial RAM filesytem and RAM disk -> (_install) Initramfs source file(s) 这个要记得加上 busybox 生成的目录位置
  • make ARCH=arm64 CROSS_COMPILE=arm-linux-gnueabi- 不是最小内核,编译时间有点长
  • 我当时加上 -j4 编译的时候会有错,也没有去找原因,可能并发编译哪里的依赖没控制 好吧

运行

  • qemu 运行的命令 qemu-system-aarch64 -machine virt -cpu cortex-a57 -m 2048 -smp 2 -kernel Image -machine type=virt --nographic --append "rdinit=linuxrc console=ttypAMA0",运行过程中,我的出现 kernel panic 什么 init= 这个没有指定,最后测试将 _install 目录下的 linuxrc 更名为 init 即可,具体原因还没到内核源码中去查找
  • 其中 --nographic 是为了输出 ,也可以换成 -serial stdio ,这样为多开一个窗口,将窗口关闭就可以关闭运行中的系统,否则出现 kernel panic 的现象就只能能过 kill 来关闭,麻烦。

用独立文件系统

  • 如果使用上面的方法,文件系统有更新需要重新编译内核,于是换一种方法,把文件系统独立出来
  • 制作文件系统镜像,最简单的方法
  • dd if=/dev/zero of=rootfs.img bs=1M count=512 我为了把内核模块都放进去,做的比较大一些
  • mkfs.ext4 rootfs.img 格式化
  • mount rootfs.img b 挂载后,将 _install 下的内容都放到 b 目录下
  • 使用命令 qemu-system-aarch64 -machine virt -cpu cortex-a57 -m 2048 -smp 2 -kernel Image -machine type=virt --nographic --append "root=/dev/vda rw console=ttypAMA0" -hda rootfs.img 来运行
  • 其中 /dev/vda 可能 会不一样,我一开始用的 sda 根据内核的错误提示,发现加载后是 vda 于是用了这个
  • 当有问题时可以用 gdbdebug 内核
  • 运行 arm-xxxgdb Image 之后在提示符下输入 target remote localhost:1234 就可以开始调试,具体还没怎么用,就不说了,记得 qemu 命令要加 -s -S 使能调试功能
  • 用这种模式时,在 _install 目录下要先建好 /proc, /tmp /sys 目录,写在脚本中没有效果
  • 当然 gdb 要安装 ,跟安装 gcc 差不多

测试 u-boot

  • 下载 u-boot 编译
  • 整个过程跟内核 差不多
  • 我在编译好之后,qemu-system-aarch64 -M virt -kernel u-boot -serial stdio 来运行,出现了没有打印,用 gdb 调试,调试也看不出什么,再关闭后发现 u-boot 的打印了,具体的以后再研究。
  • 之后 u-boot 编译为 raspberry 版本之后,一直没有提示,调试之后也没有,具体原因还在看,就不说了

文件参考

部分文件内容来自 《奔跑吧,Linux 内核》

etc/init.d/rcS

mkdir -p /proc
mkdir -p /tmp
mkdir -p /sys
mkdir -p /mnt
/bin/mount -a
mkdir -p /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s

etc/inittab

::sysinit:/etc/init.d/rcS
::respawn:-/bin/sh
::askfirst:-/bin/sh
::ctrlaltdel:/bin/umount -a -r

etc/fstab

proc /proc proc defaults 0 0
tmpfs /tmp tmpfs defaults 0 0 
sysfs /sys sysfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0
debugfs /sys/kernel/debug debugfs defaults

猜你喜欢

转载自blog.csdn.net/leishengsheng/article/details/80184319