Qemu的使用及一些开发板的模拟

介绍

Qemu可以对许多架构的CPU或开发板进行模拟。在我们没有开发板的时候,可以通过其进行一些开发板的模拟,便于学习。

安装

sudo apt-get install qemu
sudo apt install qemu-utils
# 使用不同架构的CPU,这个安装方式要再次安装相应命令
sudo apt install qemu-system-x86
sudo apt install qemu-system-arm
sudo apt install qemu-system-mips

如果需要源码(源码好像可以安装全部指令):

git clone git://git.qemu-project.org/qemu.git
或者
wget http://wiki.qemu-project.org/download/qemu-2.0.0.tar.bz2

使用

创建镜像文件

qemu-img create -f qcow2 test-vm-1.qcow2 10G

-f : 选项用于指定镜像的格式
qcow2 : 格式是 Qemu 最常用的镜像格式,采用来写时复制技术来优化性能
test-vm-1.qcow2 : 是镜像文件的名字
10G:镜像文件大小

镜像文件创建完成后,可使用 qemu-system-x86 来启动x86 架构的虚拟机(当然,其他架构也有相应的命令):

qemu-system-x86_64 test-vm-1.qcow2

因为没有安装操作系统,会出现下面的界面:

安装镜像命令:

qemu-system-x86_64 \-boot d \-cdrom ubuntu-16.04.7-desktop-amd64.iso \-hda test-vm-1.qcow2 \-m 2048

当然也可以把hda选项去掉仅仅做测试。

测试

其实不仅仅是x86-x64的架构的镜像,像arm等体系架构都可以使用qemu来模拟,不过命令不相同。

树莓派1代

树莓派CPU是arm架构的,所以下面使用arm相关的启动指令。
下载地址:
https://github.com/dhruvvyas90/qemu-rpi-kernel
实际使用两个文件:kernel-qemu-4.19.50-buster 、 versatile-pb-buster.dtb。前者是1代内核镜像,后者是versatile开发板类型的设备树(没有树莓派1代的开发版版本,这里用来替代,设备树描述的就是开发板的硬件信息)。
img镜像下载地址:
http://downloads.raspberrypi.org/raspbian_lite/images/
这里选择在2019-09-30目录下面的镜像,下载压缩包解压后得到2019-09-26-raspbian-buster-lite.img。
启动命令:

qemu-system-arm  \-M versatilepb \-cpu arm1176 \-drive format=raw,file=./pi/2019-09-26-raspbian-buster-lite.img \-net nic  \-net user,hostfwd=tcp::5022-:22 \-dtb ./pi/versatile-pb-buster.dtb \-kernel ./pi/kernel-qemu-4.19.50-buster \-append  "root=/dev/sda2 panic=1 rootfstype=ext4 rw" \-serial stdio \-usb
qemu-system-arm \-M versatilepb \-cpu arm1176 \-m 256 \-hda ./pi/2019-09-26-raspbian-buster-lite.img \-net user,hostfwd=tcp::5022-:22 \-dtb ./pi/versatile-pb-buster.dtb \-kernel ./pi/kernel-qemu-4.19.50-buster \-append 'root=/dev/sda2 panic=1' \-no-reboot

上面两条指令都可以正常启动系统,但是使用时会有些区别,感兴趣的可以自己测试一下。
下面以第一条指令的参数进行解释:

参数 说明
-M versatilepb 模拟的电路板,versatilepb
-cpu arm1176 cpu型号
-m 256 内存256M
-drive format=raw,file=<img_path> 加载的镜像格式和位置
-net user,hostfwd=tcp::5022-:22 网卡使用NAT模式,将主机的5022映射到虚拟机22口便于SSH
-dtb <dtb_path> 设备树文件
-kernel <path>
-append 附加命令,内核命令行
-serial stdio 将CMD命令行用作标准输入输出,可以通过CMD命令行对虚拟机发送命令,而不必使用虚拟机的显示和输入
-usb 支持usb

龙芯2K1000

默认下载(或qemu官方)的qemu内置支持的开发板没有龙芯的,需要使用龙芯提供的。
龙芯开放的Qemu源代码 : https://gitee.com/loongsonlab/qemu
安装:

cd <qemu-source-path>/
mkdir ./build
cd ./build
../configure --target-list=mipsel-softmmu,mips64el-softmmu --disable-werror
make

编译依赖库:

Python
libpixman-1-dev

编译时链接报了stime未定义的错误,解决办法:

/* qemu-version/linux-user/syscall.c中 */
将
return get_errno(stime(&host_time));
修改为:
return get_errno(clock_settime(CLOCK_REALTIME, &host_time));

运行pmon,注意下面的pmon镜像是最终的(这里包含设备树,否则无法正常启动):

./mips64el-softmmu/qemu-system-mips64el    \-M ls2k \-m 256  \-smp 1  \-serial stdio   \-bios ../../../ls2k/gzrom-dtb.bin \-net nic \-nic user,net=192.168.1.55/24,host=192.168.1.5,tftp=/srv/tftp

运行结果:

简单的测试指令:

@todo 制作内核镜像、文件系统启动操作系统。

vexpress-a9

  1. 内核下载和编译
# 安装交叉编译链工具,有的话直接引入或忽略
# 32位
sudo apt install gcc-arm-linux-gnueabi
# 64位
sudo apt-get install gcc-aarch64-linux-gnu# 获取内核镜像,其它版本也可以,一般都有vexpress的默认配置,速度慢的话可以windows下直接访问网站下载
wget https://mirror.bjtu.edu.cn/kernel/linux/kernel/v5.x/linux-5.10.tar.xz
# 解压
tar xf linux-5.10.tar.xz
cd  linux-5.10
# 配置,要指定ARCH=arm(也可以设置环境变量),才会从arm架构中找配置文件
make ARCH=arm  vexpress_defconfig
# 编译,可以使用参数zImage,modules,dtbs编译指定的部分,默认全部编译
make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm -j8
# 生成的文件位于arch/arm/boot下
# qemu单独启动kernel
# 因为没有文件系统会报错
qemu-system-arm \-M vexpress-a9 \-m 512M \-kernel ./arch/arm/boot/zImage \-dtb  ./arch/arm/boot/dts/vexpress-v2p-ca9.dtb \-nographic  \-append "console=ttyAMA0"
  1. 文件系统下载和制作
# busybox下载
wget https://busybox.net/downloads/busybox-1.32.0.tar.bz2
# 解压
tar jxf busybox-1.32.0.tar.bz2
cd busybox-1.32.0
# 使用默认配置
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- defconfig
# 编译
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j4
# 安装,默认安装当前的__install文件夹下
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- install
# 至此文件系统的编译已完成,剩下的任务是设置文件系统的内容
# 建立文件夹存放操作系统,然后拷贝需要的文件到里面
mkdir rootfs
cp -ra _install/* rootfs/
# (里面的 *.a 其实可以删掉,只用 .so)
mkdir -p rootfs/lib
cp -ra /usr/arm-linux-gnueabi/lib/* rootfs/lib/
cd rootfs
# 全是空文件夹
mkdir dev proc sys tmp root var mnt
# 制作设备节点,一些设备的节点号是固定的,参看 ubuntu 主机中的
cd dev
sudo mknod -m 666 tty1 c 4 1
sudo mknod -m 666 tty2 c 4 2
sudo mknod -m 666 tty3 c 4 3
sudo mknod -m 666 tty4 c 4 4
sudo mknod -m 666 console c 5 1
sudo mknod -m 666 null c 1 3
  1. 制作根文件系统镜像
# 有点不明白,感觉直接把文件当成一个磁盘来用了,待研究
# 新建一个文件夹进行操作
# 64M空间,空间不够也可以把它改大点
dd if=/dev/zero of=a9rootfs.ext3 bs=1M count=64
mkfs.ext3 a9rootfs.ext3
sudo mount -t ext3 a9rootfs.ext3 /mnt -o loop
sudo cp -ra ../busybox-1.32.0/rootfs/* /mnt
sudo chown -R root.root /mnt/*
sudo umount /mnt
qemu-system-arm \-M vexpress-a9 \-m 512M \-kernel ./arch/arm/boot/zImage \-dtb  ./arch/arm/boot/dts/vexpress-v2p-ca9.dtb \-nographic \-append "init=/linuxrc root=/dev/mmcblk0 rw console=ttyAMA0" \-sd ../rootfs/a9rootfs.ext3
# 报错:end Kernel panic - not syncing: Requested init /linuxrc failed (error -8)
# 查看错误码-8,为执行文件格式错误,文件系统bin下程序在x64虚拟机上也可以运行,原因是编译时未指定交叉编译链
# 激动!!!重新编译后,可以正常启动,进到终端
# 文件系统还可以再优化
# 图形界面启动
qemu-system-arm \-M vexpress-a9 \-m 512M \-kernel ./arch/arm/boot/zImage \-dtb  ./arch/arm/boot/dts/vexpress-v2p-ca9.dtb \-append "init=/linuxrc root=/dev/mmcblk0 rw console=tty0" \-sd ../rootfs/a9rootfs.ext3

  1. u-boot编译
wget https://ftp.denx.de/pub/u-boot/u-boot-2022.04.tar.bz2
tar xjf u-boot-2022.04.tar.bz2
cd u-boot-2022.04
make ARCH=arm vexpress_ca9x4_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- all
# 报错:fatal error: openssl/evp.h: No such file or directory
# 安装下面的库
sudo apt-get install libssl-dev
# 生成的u-boot为可执行文件,u-boot.bin为二进制文件
# 单独启动u-boot
qemu-system-arm \-M vexpress-a9 \-m 512M \-kernel ./u-boot \-nographic
# 制作多分区的SD卡(文件模拟的)
# 这里要使用uImage进行启动,所以内核要重新编译一下
# uImage也可以用mkimage工具生成,下面的命令其实也是用mkimage工具
# uImage是u-boot的专用的启动镜像,可以由不同格式的u-boot镜像通过工具生成,只是加了一个文件头便于启动
sudo apt install u-boot-tools
make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm  LOADADDR=0x60003000 uImage -j8
# 一个分区存放kernel,一个分区存放镜像
# 前面分区放置文件系统镜像的时候其实是创建回环设备,用文件模拟块设备
# 使用losetup可以查看所有的回环设备,我们把它直接当成SD卡就行
# 这里只是把文件名字叫做SD,可以用任何名字
# dd if=/dev/zero of=SD  bs=1M count=64
# 回环设备名字不能重复,使用未使用的名字
# sudo losetup /dev/loop15 SD
dd if=/dev/zero of=SD  bs=1M count=64
sudo parted SD --script -- mklabel msdos
# 这里和2048对齐一下,减少一个警告
sudo parted SD --script -- mkpart primary fat32 2048s 40956s
sudo parted SD --script -- mkpart primary ext4 40960s -1# 建立映射,然后格式化两个分区
sudo losetup --show /dev/loop15 SD
# sudo apt install kpartx
sudo kpartx -va /dev/loop15
sudo mkfs.vfat /dev/mapper/loop15p1
sudo mkfs.ext4 /dev/mapper/loop15p2​
# 拷贝内核zImage、vexpress-v2p-ca9.dtb到第一个分区
sudo mount /dev/mapper/loop15p1 /mnt
sudo cp ../linux-5.10/arch/arm/boot/uImage  /mnt
sudo cp ../linux-5.10/arch/arm/boot/dts/vexpress-v2p-ca9.dtb /mnt
# 拷贝文件系统内的所有文件到第二个分区
sudo mount /dev/mapper/loop15p2 /media
sudo cp -r ../busybox-1.32.0/rootfs/* /media
sudo chown -R root.root /media/*
# 卸载
sudo umount /mnt
sudo umount /media​
# u-boot启动SD卡中的kernel和文件系统
qemu-system-arm \-M vexpress-a9 \-m 512M \-kernel ./u-boot-2022.04/u-boot \-nographic \-append "root=/dev/mmcblk0 console=ttyAMA0" \-sd ./rootfs/SD# 启动
fatls mmc 0:1
fatload mmc 0:1 60003000 uImage
fatload mmc 0:1 60500000 vexpress-v2p-ca9.dtb
setenv bootargs 'init=/linuxrc root=/dev/mmcblk0p2 rw rootwait earlyprintk console=ttyAMA0'
bootm 60003000 - 60500000# tips
这里对文件系统的修改会保存

# u-boot tftp网络启动内核
qemu-system-arm \-M vexpress-a9 \-m 512M \-kernel ./u-boot-2022.04/u-boot \-nographic \-append "root=/dev/mmcblk0 console=ttyAMA0" \-sd ./rootfs/SD \-net nic \-nic user,net=192.168.1.55/24,host=192.168.1.5,tftp=/srv/tftp# 启动
# 测试网络
setenv ipaddr 192.168.1.56
ping 192.168.1.5
# tftpboot 加载镜像
setenv serverip 192.168.1.5
tftpboot 60003000 uImage
tftpboot 60500000 vexpress-v2p-ca9.dtb
setenv bootargs 'init=/linuxrc root=/dev/mmcblk0p2 rw rootwait earlyprintk console=ttyAMA0'
bootm 60003000 - 60500000# 其它
内核下使用ifconfig时提示缺少文件,创建即可(可以使用touch命令),然后直接设置eth0网卡的ip,就应该和主机之间就可以进行网络通信了。

说明:无论是从SD卡启动,还是网络启动,过程都是一样的,都是将内核镜像加载到内存,然后启动(其它启动方式大同小异),区别在于下载内核镜像的位置。这里文件系统在bootargs里面指定,位于SD卡中,也可以使用网络挂载文件系统。

realview-pbx-a9

使用华为liteOS。

  1. 代码
git clone https://gitee.com/LiteOS/LiteOS.git
  1. 开发环境搭建
    见官方教程:
    https://support.huaweicloud.com/LiteOS/index.html
    建议仔细阅读教程,有一些需要测试的地方。

  2. 编译

# 配置
cp tools/build/config/realview-pbx-a9.config .config
# 选择提供的 Demo
make menuconfig
# Demos → Kernel Demo ,Enable Kernel Demo
# Kernel Demo Entry,DemoEntry,Run Kernel Task Demo# 清理工程
make clean
make

在Huawei_LiteOS根目录下执行make命令即可完成工程编译,编译结果会在屏幕上输出。生成的系统镜像文件、反汇编等文件在out/realview-pbx-a9目录中,库文件在out/realview-pbx-a9/lib目录中,中间文件在out/realview-pbx-a9/obj目录中。因在步骤 3 中使能了“Kernel Task Demo”,所以在保存库文件的lib目录中会有相应的库文件libkernel_demo.a。

qemu-system-arm \-machine realview-pbx-a9 \-smp 4 \-m 512M \-kernel out/realview-pbx-a9/Huawei_LiteOS.bin \-nographic

错误记录

1.fatal error: linux/compiler-gcc9.h: No such file or directory
原因:gcc版本和内核版本不匹配
解决办法:
更换内核版本
2. multiple (or no) load addresses: This is incompatible with uImages
解决办法:
指定LOADADDR参数
3. “mkimage” command not found
安装u-boot-tools
4. 卡在Start Kernel …
修改生成uImage时的LOADADDR地址为0x60003000,为什么是这个不清楚。

测试环境

  1. windows 10 下使用虚拟机Linux ubuntu 5.11.0-27-generic进行测试。

参考文章:

  1. QEMU仿真树莓派1和3B-保姆级教程
  2. QEMU 3.1.0安装手记
  3. 龙芯杯无开发板如何开发和调试linux
  4. qemu模拟arm嵌入式环境
  5. Ubuntu通过apt-get安装指定版本和查询指定软件有多少个版本
  6. 搭建基于qemu的仿真环境与应用
  7. Kernel panic - not syncing: Requested init /linuxrc failed (error -13)
  8. mount -o loop 解释
  9. linux创建回环设备的方法
  10. QEMU模拟器realview-pbx-a9

Qemu使用及常见开发板的模拟相关推荐

  1. 鸿蒙开发板Hi3861模拟SPI驱动JLX12864_LCD(UC1701X)_基于code-2.0

    鸿蒙开发板驱动晶联讯LCDjlx12864_lcd_hi3861源码-C文档类资源-CSDN下载鸿蒙开发板驱动晶联讯LCDjlx12864_lcd_hi3861源码博文介绍https://t更多下载资 ...

  2. 鸿蒙开发板Hi3861模拟SPI驱动12864LCD_ST7920_基于code-2.0-CANARY

    鸿蒙开发板Hi3861模拟SPI驱动12864LCD_ST7920源码.rar-C文档类资源-CSDN下载鸿蒙开发板Hi3861模拟SPI驱动12864LCD_ST7920源码.rar博文链接:htt ...

  3. 使用Arduino开发板连接模拟pH传感器

    在化学中,pH是用于指定水基溶液的酸性或碱性的标度.酸性溶液的pH值较低,而碱性溶液的pH值较高.因此,Ph传感器具有确定任何溶液的Ph的能力,即可以判断该物质本质上是酸性.碱性还是中性.通过了解pH ...

  4. 基于QEMU的ARM Cortex-A9开发板Vexpress-ca9的Linux内核的编译和运行

    宿主机:Ubuntu16.04 x64(Linux内核4.4.0) 交叉编译工具链:gcc-arm-linux-gnueabi arm-linux-gcc:4.4.3 QEMU:2.5.0 Linux ...

  5. Linux利器:QEMU!用它模拟开发板能替代真开发板?

    不想错过我的推送,记得右上角-查看公众号-设为星标,摘下星星送给我! QEMU,搞嵌入式开发的一定不陌生,最近各大群里都讨论疯了,说它是Linux利器一点也不夸张.它是一款知名的而且开源的模拟器(官网 ...

  6. 实现Qemu aarch32虚拟开发板ping www.baidu.com

    环境 Qemu: 2.8.0 开发板: vexpress-ca9 概述 如果要玩物联网,至少应该让开发板实现联网,让qemu支持联网在之前的博文中已经有介绍了,但是如果只能在自己的局域网内玩耍就太没意 ...

  7. linux 开发板模拟u盘,S5P4418开发板Linux下实现模拟U盘教程飞凌嵌入式

    飞凌嵌入式ARMCortex-A9 S5P4418开发板上能否满足U盘的功能?其实可通过修改内核配置和文件系统相关内容,在OK4418开发板上实现模拟U盘功能,模拟U盘可以帮助我们实现开发板与Wind ...

  8. MicroPython支持的开发板:高性能、低成本创客首选

    Python的开放.简洁.黏合正符合了现发展阶段对大数据分析.可视化.各种平台程序协作产生了快速的促进作用.自Python3的发布到现在已有五六年的时间,从刚发布的反对声音到慢慢被接受与喜欢经过了太漫 ...

  9. python 开发版-高性能、低成本、支持MicroPython开发板有哪些?

    Python的开放.简洁.黏合正符合了现发展阶段对大数据分析.可视化.各种平台程序协作产生了快速的促进作用.自Python3的发布到现在已有五六年的时间,从刚发布的反对声音到慢慢被接受与喜欢经过了太漫 ...

最新文章

  1. 【转】HashMap和HashSet的区别
  2. 解决sharepoint2010的多行文本框的插入图片—【从sharepoint】的disabled问题
  3. 7-49 数组乱炖 (10 分)
  4. Node中使用mysql模块遇到的问题
  5. leetcode刷题 74.搜索二维矩阵
  6. pytorch卷积可视化_使用Pytorch可视化卷积神经网络
  7. 读取数量不定的输入数据
  8. Qt中的角度和正方向描述清单
  9. 论文浅尝 | 当知识图谱遇上零样本学习——零样本学习综述
  10. php mysql 秒杀_redis+PHP实现高并发下秒杀数据入库的问题
  11. 和华为杯_华为P50超大杯确认!居中挖孔屏+鸿蒙OS系统:外观颜值感人
  12. 渗透测试入门6之权限提升
  13. @dynamic 模拟NSManagedObject类的内部实现,AFN的非常规用法
  14. 如何打造自己强大的气场?
  15. deap dataset的不同分类模型的实现(2)-认识数据
  16. 【GPT2】Language Models are Unsupervised Multitask Learners
  17. html自动刷新插件谷歌,Super Auto Refresh:定时自动重新刷新网页
  18. 应用系统云原生架构衡量指标
  19. Tacotron2 NVIDIA版本使用Biao-Bei数据集
  20. 大数据时代的新闻变革

热门文章

  1. linux定时任务提示没权限,Linux添加定时任务提示权限不够
  2. 经验分享| 文献调研 - ResearchRabbit
  3. STC16f40k128——时钟系统
  4. 计算机实训报告英语,中英文打字实训的总结报告
  5. python将图像转化为灰度图像_使用numpy将图像转换为灰度
  6. 小苏的Shell编程笔记之三--数组和算术运算
  7. 【19】核心易中期刊推荐——人工智能 | 遥感信息处理
  8. Spring AOP 的底层实现
  9. BigDecimal 的divide()
  10. python 3 or 5的值_python表达式3or5的值为_表达式 3 or 5 的值为