嵌入式开发板模拟器:QEMU

前两天看微信公众号时发现了一个嵌入式模拟器,感觉很不错,自己动手安装了一个,折腾了几天,下载一直是个问题,特此记录如下

模拟器大家应该都听说过,有的小伙伴打游戏也会安装模拟器,今天我们介绍的主角QMEU就是一个可以用在嵌入式的模拟器,如果你想学习嵌入式,但身边没有开发板,这时候你可以尝试使用它来模拟Linux内核的启动,当然它还可以模拟ARM、MIPS等各种CPU架构,本文主要介绍模拟ARM的启动流程

(一)环境介绍

        虚拟机:VMware

        Ubuntu 16.04LTS

(二)安装QEMU

我们常用的VMware和virtualBox只能在X86架构上,虚拟一台X86计算机,但是QEMU能用在X86架构下虚拟出ARM计算机。QEMU时一个支持跨平台的虚拟机,有两种模式:user mode和system mode,在system mode下能够模拟出整个计算机,可以在qemu上运行 操作系统,在user mode下,可以运行和当前平台指令集不同的可执行程序。例如可以用qemu在x86上运行ARM的可执行程序,但是两个平台必须是同一种操作系统,比如Linux。

由于本文介绍ARM版本,我们可以在Ubuntu里使用sudo apt install qemu-system-arm命令去安装,但是不太推荐此方法,Ubuntu里安装源更新比较慢,安装版本不确定,另外就是从官网(https://www.qemu.org/)下载源码包来安装,如果想了解更多,可以从阅读官网上相关信息。

(1)从官网下载好安装包,或者用我下载好的:qemu

wget https://download.qemu.org/qemu-5.1.0.tar.xz

(2)执行下面的命令

$: tar -xvJf qemu-5.0.1.tar.xz 
$: cd qemu-5.0.1
$: ./configure
$: make & make install //如果报错要安装两个文件:apt-get install libglib2.0-devapt-get install libpixman-1-dev

通过上面的安装了32位(qemu-system-arm)和64位(qemu-system-aarch64)的模拟器,使用help命令查看支持的开发板,这里面有很多我们的开发版选项,本文以vexpress-a9 (ARM Versatile Express for Cortex-A9) 为例进行讲解。

(三)编译操作系统

 (1)编译u-boot

      下载u-boot代码:


git clone https://gitlab.denx.de/u-boot/u-boot.git
//注意这个有时候会比较慢,找个合适的时间下载(比如早上),或者镜像上下载

下载完成后可以在u-boot的configs目录下查看配置文件,我们选择的vexpress-a9 配置文件是vexpress_ca9x4_defconfig,

make  vexpress_ca9x4_defconfig
make CROSS_COMPILE=arm-linux-gnueabihf- all//make的时候可能出错,按照出错提示百度相关错误,可能由于没有相关命令支持,例如我安装时提示flex找不到,执行apt-get install flex在make就成功了
//需要交叉编译工具的可以在这里下载http://releases.linaro.org/components/toolchain/binaries/
注意:如果指定交叉编译器的路径一定要使用绝对路径

 

(2)制作文件系统

以前都是使用busybox编译,然后手动创建跟文件目录,但是现在我们使用bulidroot可以很轻松容易的构建跟文件系统(这里感谢下文链接的作者提供了这么方便的工具)

buildroot下载

git clone git://git.buildroot.net/buildroot

 

上面下载的代码并不是真正下载跟文件系统,真正下载跟文件系统是在我们配置好后,编译时下载的。

  执行make menuconfig来配置选项:

然后在Target opions选择相应的目标平台,我们这里点进去选择arm(little-endian)即ARM架构小端模式

build options选项我这里不修改保持默认,有需要的可以自行修改

编译工具链toolchain选择外部,找到自己的编译工具链位置,具体参考我的配置情况

上面的配置要注意内核头文件和编译工具链版本一样,不知道的可以在相应选项上按h查看帮助信息

选择对应的控制台信息:

为了减少跟文件系统镜像,这里在filesystem images里面选择如下,意思是使压缩文件系统(lz4),内核启动时解析文件系统。

其他配置先保持默认,有需要我们再修改

执行make savedefconfig命令,就会生成新的 defconfig 文件,然后执行make命令(执行make时会连接网络下载相关资源,注意网络畅通)

(3)编译kernel

  代码下载:

git clone https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git

  不推荐使用上面的方法,下载太慢了,可以在网上直接搜相关镜像下载,这里我使用正点原子提供的kernel作为演示,使用imx的配置文件imx_v7_defconfig

然后把上面buildroot编译的文件系统拷贝过来

 cp /opt/buildroot/output/images/rootfs.cpio .make ARCH=arm  vexpress_defconfigmake ARCH=arm  menuconfig

make ARCH=arm CROSS_COMPILE=/交叉编译器路径/bin/arm-linux-gnueabihf-  -j8

注意:上面一定要指定架构为arm架构

(4)系统启动

下面我们模仿sd卡启动过程

制作sd卡镜像:

dd if=/dev/zero of=sd.img bs=4096 count=4096
mkfs.vfat sd.img

把编译好的 kernel zImage 和 dtb 文件拷贝到 sd.img 中

mount sd.img /mnt/ -o loop,rw
cp arch/arm/boot/zImage /mnt/
cp arch/arm/boot/dts/vexpress-v2p-ca9.dtb /mnt/
umount /mnt

启动qemu

qemu-system-arm -M vexpress-a9 -m 512M -kernel ../u-boot/u-boot -nographic  -sd sd.img

可以看到uboot启动了:

但是没有找到内核,我们还需要下面的操作

查看内核执行地址相对内存的偏移地址:0x8000

在 u-boot 命令行中输入bdinfo命令,可以查到这块开发板内存的起始地址:

//读取内核文件到开发板内存中
fatload mmc 0:0 0x62008000 zImage
fatload mmc 0:0 0x64008000 vexpress-v2p-ca9.dtb//启动内核
bootz 0x62008000 - 0x64008000

(四) 总结

  通过上面的操作我们完成了模拟内核启动的流程,有几个问题也折腾了好久说一下注意的几点:

(1)编译uboot、kernel时注意架构的选择

(2)在内核启动不成功,可能是sd.img没有制作成功

  当然qemu并不能完全替代开发板,更多的功能可以自己发掘哈哈~

 

参考文章:Linux利器:QEMU!用它模拟开发板能替代真开发板?

                  QEMU编译安装

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/531366.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

gcc: weak_alias如何使用

本文主要说明weak和alias是什么和如何使用它 __attribute__是用来说明函数的属性,weak和alias分别是两个属性。 (一)强符号和弱符号: 强符号:已经初始化的全局变量和未被weak修饰的函数弱符号:未初始化的全…

静态Include和动态Include测试并总结

主要代码 hjzgg.css .center-div{width:auto;margin-left: 40%;margin-right: 40%;display: block;position: absolute;top:0px;left:0px; }.text-div{margin-top: 80px; }.hjzgg-div{color:transparent;font-size:20px;font-weight: bold;letter-spacing:2px;-webkit-animatio…

linux终端常用快捷键

CTRLALTT 打开终端 CTRLD 关闭终端 CTRL SHIFT "" 放大终端字体 CTRL “-” 缩小终端字体 CTRL r 查找历史命令 CTRLu 删除光标前面所有内容 CTRLw 删除光标左边的单词 CTRL k 删除光标后面的所有内容 CTRLL 清除当前屏幕内容 CTRLa 光标移到开始位置 CTRLe 光标移到…

ueditor的配置和使用

ueditor下载好之后直接复制到项目的WebContent目录下,并将ueditor\jsp\lib下的jar包复制或者剪切到项目的lib目录下。先看一下效果,如下: 1.文件的上传 首先在ueditor/jsp目录下找到config.json文件,就拿Image上传来说吧。 "…

windows上搭建NFS服务器

在进行嵌入式开发的时候,我们常用的做法是搭建NFS服务器,然后使把文件系统、调试程序放在NFS服务器上,这样可以方便调试,以前都是在linux里面开启NFS服务器,今天来说下window里的nfs服务器–haneWin 一、软件安装和使…

计算机是如何启动的?从未上电到操作系统启动

计算机是如何启动的,网络上很多博文1都从 BIOS 程序的加载开始说起,有的也跳到 BIOS 程序加载 Bootloader 阶段。个人认为把这个过程称为操作系统是如何被加载并启动应该更加贴切一点。同时,也有计算机硬件大神的文章[1][5]详细分析计算机加电…

Hibernate注解

前言: 最近正在学习Hibernate通过注解(annotation)来管理映射关系,以前都是通过XML映射文件。下面拿个小例子说一下。 数据库物理模型: 数据库的描述: 一篇博客随笔可以分到不同的类中,一个类中…

js表单动态添加数据并提交

情景1&#xff1a;已经存在form对象了&#xff0c;动态为form增加对象并提交 function formAppendSubmit(){var myform$(#newArticleForm); //得到form对象var tmpInput$("<input typetext nameblogArticleForm.articleContent/>");tmpInput.attr("value&…

*++p和*p++的区别

首先你应该明白* 和 的优先级是相同的&#xff0c;而且他们的结合性是从又往左的 #include <stdio.h>int main(int argc ,char * argv[]) {int str[]{1,2,3,4,5,6,7,8,9,10};int *p str;int a *p;//a*p ,pp1即a1&#xff0c;p&str[1]int b *p;//pp1,b*p即p&s…

zyUpload+struct2完成文件上传

前言&#xff1a; 最近在写自己的博客网站&#xff0c;算是强化一下自己对s2sh框架的理解。期间遇到了很多问题&#xff0c;这些问题在写之前都考虑过&#xff0c;感觉也就是那样吧。但正真遇到了&#xff0c;也挺让人难受的。就利用zyUpload这个js插件实现文件的上传&#xff…

gbd的简单使用(一)

这篇文章将gdb的简单使用&#xff0c;通过此篇文章你能学习到使用gdb进行调试程序 在Linux中编写程序时&#xff0c;如何进行程序的debug工作呢&#xff1f;今天来介绍下gdb这个工具&#xff0c;可以在Linux下直接man gdb查看帮助信息 &#xff08;一&#xff09;gdb命令介绍 …

java发送内嵌图片邮件

前言&#xff1a; 博客系统中需要邮件服务的功能&#xff0c;以前写过类似的功能&#xff0c;不过功能太简单了&#xff0c;仅仅是发送文本内容&#xff0c;现在尝试一下发送内嵌图片邮件&#xff01; 准备工作&#xff1a; 请参考&#xff1a;http://www.cnblogs.com/hujunzhe…

调试跟踪利器---strace

通过这篇文章你会学习到strace的用法&#xff0c;strace可以帮助你高效地定位进程中的一些错误&#xff0c;关于strace的用处有很多&#xff0c;可以自行发掘 前面我们讲解了gdb调试程序,这篇文章介绍另一个调试跟踪工具strace&#xff0c;同样你可以在linux下执行man strace查…

MBR、DBR、FAT32基础小知识

MBR-------主引导记录 1.创建时间&#xff1a;由分区软件&#xff08;Fdisk/PartitionMagic/Windows 2000/Windows XP安装 工具等&#xff09;给 硬盘分区时建立的。 2.功能 &#xff1a;存放硬盘分区信息和引导系统时检查分区。 3.作用范围&#xff1a;MBR和虚拟MBR控制着整个…

java使用Executor(执行器)管理线程

一.一个实现了Runnable接口的类 class MyThread implements Runnable{private static int num 0;Overridepublic void run() {while(true){synchronized(MyThread.class){num;try{Thread.sleep(500);} catch(Exception e){System.out.println(e.toString());}System.out.print…

JMM和happens-before原则

JMM&#xff1a; Java Memory Model(Java内存模型)&#xff0c;围绕着在并发过程中如何处理可见性、原子性、有序性这三个特性而建立的模型。 可见性&#xff1a; JMM提供了volatile变量定义、final、synchronized块来保证可见性。  例如&#xff1a;线程a在将共享变量x1写入…

SD卡移植FAT32文件系统无MBR

问题&#xff1a;在研究SD卡和FAT32文件系统的时候&#xff0c;发现SD卡有的有MBR&#xff0c;有的没有MBR&#xff0c;这个为什么呢&#xff1f; 分析&#xff1a;MBR是主引导记录&#xff0c;是在给磁盘分区的时候建立的&#xff0c;我们的SD卡没有这个可能就是没有进行过分区…

java获取类的信息

关键技术剖析 1.java.lang.reflect包实现了java的反射机制&#xff0c;在使用反射机制时&#xff0c;需要导入该包。 2.Class类的forName方法能够根据类名加载类&#xff0c;获得类的Class对象。 Class类的getSuperclass方法获得父类的Class对象&#xff1b;getDeclaredFields方…

FAT32文件系统介绍

FAT32文件系统&#xff08;一&#xff09;为什么要有文件系统&#xff08;二&#xff09;FAT32文件系统组成&#xff08;三&#xff09;分步介绍各部分(1) 首先介绍一下MBR(2)DBR介绍(3)FAT表介绍(4) 数据区&#xff08;一&#xff09;为什么要有文件系统 文件系统是操作系统用…

java中动态代理实现机制

前言&#xff1a; 代理模式是常用的java设计模式&#xff0c;它的特征是代理类与委托类有同样的接口&#xff0c;代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类&#xff0c;以及事后处理消息等。代理类与委托类之间通常会存在关联关系&#xff0c;一个代理类…