qemu的学习

qemu搭建arm开发环境

第一部分

第一步

Windows下QEMU安装文件:链接:https://pan.baidu.com/s/1mLw4pqdp9Q8JxYkrXRfbbg 提取码:3qq4

下载上述两个文件,并安装QEMU后,运行如下命令:

1
"C:\Program Files\qemu\qemu-system-arm.exe" -M versatilepb -m 16 -kernel vmlinuz-qemu-arm-2.6.20 -append "clocksource=pit quiet rw"

一堆企鹅

qemu.PNG

第二步

ubuntu 18 文件系统下载地址如下:链接:https://pan.baidu.com/s/1qYmiqvL6nPx3LY8gDIylIw 提取码:68lc

内核与DTB文件下载地址如下:链接:https://pan.baidu.com/s/1WmRMtAxddu69SbaUqRma8Q 提取码:up22

下载上述文件,解压缩文件系统,和内核文件以及DTB文件放在同一个目录,然后运行如下命令:

1
"C:\Program Files\qemu\qemu-system-arm.exe" -M vexpress-a9 -m 1024M -kernel zImage -dtb vexpress-v2p-ca9.dtb -append "root=/dev/mmcblk0 rw console=ttyAMA0" -sd rootfsubuntu18lxde.ext3 -serial stdio -smp 4

结果

qemu2.PNG

第二部分

第一步

启动ubuntu

用户cxy 密码123456

结果

ubuntu1.PNG

第二步/这部分根据实际情况

建立文件夹并解压缩gcc文件

1
2
3
4
5
6
cxy@ubuntu:~/Desktop/src$ ls
arm-linux-gcc-4.6.4-arm-x86_64.tar.bz2
cxy@ubuntu:~/Desktop/src$ mkdir tmp
cxy@ubuntu:~/Desktop/src$ cd tmp
cxy@ubuntu:~/Desktop/src/tmp$ tar jxvf ../arm-linux-gcc-4.6.4-arm-x86_64.tar.bz2

下载成功后,解压缩,然后将opt/TuxamitoSoftToolchains/arm-arm1176jzfssf-linux-gnueabi/gcc-4.6.4下的所有文件复制到新建的目录/usr/local/arm/gcc-4.6.4/下面.

1
2
3
4
5
6
7
8
9
sudo mkdir /usr/local/arm/gcc-4.6.4/

mkdir tmp

cd tmp

tar jxvf ../arm-linux-gcc-4.6.4-arm-x86_64.tar.bz2

sudo cp -rf opt/TuxamitoSoftToolchains/arm-arm1176jzfssf-linux-gnueabi/gcc-4.6.4/* /usr/local/arm/gcc-4.6.4/

第三步

配置环境变量

1
2
export PATH=$PATH:/usr/local/arm/gcc-4.6.4/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/arm/gcc-4.6.4/lib

第四步

执行命令

1
arm-none-linux-gnueabi-gcc --version

若出现下面,则成功。

1
2
3
4
arm-none-linux-gnueabi-gcc (crosstool-NG hg+unknown-20130521.154019 - tc0002) 4.6.4
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
已成功实现

gcc1.PNG

第五步:下载编译内核部分

内核下载官网:https://www.kernel.org/,我选择了linux-4.4.229这个版本,你也可以选择其他版本,其他版本的编译过程也是类似的.如果官网下载比较慢的话,可以从下面这里下载:

链接:https://pan.baidu.com/s/1NFGSYQWZlgVuAy6yXu-xpQ
提取码:g00g

使用命令tar xvf linux-4.4.229.tar.xz解压缩

进入解压后目录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ls arch/arm/configs/

acs5k_defconfig cns3420vb_defconfig ezx_defconfig ixp4xx_defconfig moxart_defconfig nuc960_defconfig raumfeld_defconfig spear3xx_defconfig viper_defconfig
acs5k_tiny_defconfig colibri_pxa270_defconfig footbridge_defconfig jornada720_defconfig multi_v5_defconfig omap1_defconfig realview_defconfig spear6xx_defconfig vt8500_v6_v7_defconfig
am200epdkit_defconfig colibri_pxa300_defconfig h3600_defconfig keystone_defconfig multi_v7_defconfig omap2plus_defconfig realview-smp_defconfig spitz_defconfig xcep_defconfig
assabet_defconfig collie_defconfig h5000_defconfig ks8695_defconfig mv78xx0_defconfig orion5x_defconfig rpc_defconfig stm32_defconfig zeus_defconfig
at91_dt_defconfig corgi_defconfig hackkit_defconfig lart_defconfig mvebu_v5_defconfig palmz72_defconfig s3c2410_defconfig sunxi_defconfig zx_defconfig
axm55xx_defconfig davinci_all_defconfig hisi_defconfig lpc18xx_defconfig mvebu_v7_defconfig pcm027_defconfig s3c6400_defconfig tct_hammer_defconfig
badge4_defconfig dove_defconfig imote2_defconfig lpc32xx_defconfig mxs_defconfig pleb_defconfig s5pv210_defconfig tegra_defconfig
bcm2835_defconfig ebsa110_defconfig imx_v4_v5_defconfig lpd270_defconfig neponset_defconfig prima2_defconfig sama5_defconfig trizeps4_defconfig
bcm_defconfig efm32_defconfig imx_v6_v7_defconfig lubbock_defconfig netwinder_defconfig pxa168_defconfig shannon_defconfig u300_defconfig
cerfcube_defconfig em_x270_defconfig integrator_defconfig magician_defconfig netx_defconfig pxa255-idp_defconfig shmobile_defconfig u8500_defconfig
clps711x_defconfig ep93xx_defconfig iop13xx_defconfig mainstone_defconfig nhk8815_defconfig pxa3xx_defconfig simpad_defconfig versatile_defconfig
cm_x2xx_defconfig eseries_pxa_defconfig iop32x_defconfig mini2440_defconfig nuc910_defconfig pxa910_defconfig socfpga_defconfig vexpress_defconfig
cm_x300_defconfig exynos_defconfig iop33x_defconfig mmp2_defconfig nuc950_defconfig qcom_defconfig spear13xx_defconfig vf610m4_defconfig

上面为支持的内核

versatile_defconfig和vexpress_defconfig都是比较常见的qemu支持的内核版本

在解压内核的根目录,执行如下命令来配置内核将要编译的平台:

make vexpress_defconfig

根据你安装的交叉编译器的版本,执行如下命令开始编译内核:

ARM=arm CROSS_COMPILE=arm-linux-gnueabi- make -j16

或者

ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- make -j16

上述命令中ARCH=arm是指定编译的CPU架构是arm,而CROSS_COMPILE=arm-none-linux-gnueabi是指定交叉编译工具,最后的-j16是使用16个线程进行编译,通常选择你当前电脑CPU数量的二倍.

没有出现提示错误一般就编译成功了,常见编译后会出现类似如下的信息:

AS arch/arm/boot/compressed/piggy.gzip.o
LD arch/arm/boot/compressed/vmlinux
OBJCOPY arch/arm/boot/zImage
Kernel: arch/arm/boot/zImage is ready

成功完成

第六步用QEMU启动内核

内核文件arch/arm/boot/zImage就是我们最后编译成功的内核文件.我们来尝试启动一下这个内核.命令中-M指定内核运行的平台,-m指定内存大小,-kernel指定内核文件,-dtb指定设备树定义文件.

qemu-system-arm -M vexpress-a9 -m 512M -kernel arch/arm/boot/zImage -dtb arch/arm/boot/dts/vexpress-v2p-ca9.dtb

四个企鹅.PNG

使用如下命令来指定内核日志输出的端口.其中-append指定内核启动的参数(后续在uboot启动的时候,也可以在uboot指定这个参数,我们在这里把内核输出console指定到了ttyAMA0这个串口),-serail设定串口转发到host机标准输入输出控制台(也就是你当前打命令的地方)

qemu-system-arm -M vexpress-a9 -m 512M -kernel arch/arm/boot/zImage -dtb arch/arm/boot/dts/vexpress-v2p-ca9.dtb -append “root=/dev/mmcblk0 rw console=ttyAMA0” -serial stdio

一个企鹅2背后.PNG

一个企鹅2.PNG

第三部分(24日下午)

第七步busybox下载与编译

官方下载地址:https://busybox.net/downloads/,我们选择下载了busybox-1.21.0.tar.bz2

如果下载比较慢可以从这里下载:

链接:https://pan.baidu.com/s/1rtNI5_lmIMx58McGIzaUWQ
提取码:lnf4

下载后首先解压缩:

tar xjf busybox-1.21.0.tar.bz2

解压完成后,进入解压缩后的目录执行下面命令完成最初基本配置

make defconfig ARCH=arm

image-20200726212134208.png

运行成功后,当前目录会出现一个.config的文件.为了日后运行方便,我们需要手工改成静态编译

你可以直接编辑.config将# CONFIG_STATIC is not set这句话改为CONFIG_STATIC=y

image-20200726212240994.png

再执行如下命令进行编译:

ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- make install

成功

_install.PNG

第八步做一个文件系统

做一个最简单的文件系统image

1
2
3
4
5
6
7
dd if=/dev/zero of=rootfs.ext3 bs=1M count=200
mkfs.ext3 rootfs.ext3
sudo mount -t ext3 rootfs.ext3 mnt
cd mnt
cp -rf busybox-1.21.0/_install/* .
cd ..
sudo umount mnt

这个rootfs.ext3就是最简单的文件系统image了.

成功

rootfs.PNG

第九步QEMU启动内核加BusyBox

运行下面的命令

qemu-system-arm -M vexpress-a9 -m 1024M -kernel zImage -dtb vexpress-v2p-ca9.dtb -append “root=/dev/mmcblk0 rw console=ttyAMA0 init=/sbin/init” -sd rootfs.ext3 -smp 4 -serial stdio

启动成功,

四个企鹅.PNG

仔细看日志会发现:

can’t run ‘/etc/init.d/rcS’: No such file or directory

can’t open /dev/tty2: No such file or directory
can’t open /dev/tty4: No such file or directory

修改文件系统

从日志上看,加载文件系统已经成功了!但是启动/etc/init.d/rcS文件失败了,而且缺少/dev目录.所以我们需要稍微修改一下我们的文件系统

1
2
3
sudo mount rootfs.ext3 mnt
cd mnt
sudo mkdir proc sys dev etc etc/init.d

然后建立一个名为etc/init.d/rcS文件

1
2
3
4
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
/sbin/mdev -s

给这个文件加上可执行权限,然后解除挂载

1
2
3
sudo chmod +x etc/init.d/rcS
cd ..
sudo umount mnt

再次启动文件系统

四个企鹅2.PNG

成功

qemu搭建arm开发环境2

准备

先对之前的步骤部分又执行了一遍

1
"C:\Program Files\qemu\qemu-system-arm.exe" -M versatilepb -m 16 -kernel vmlinuz-qemu-arm-2.6.20 -append "clocksource=pit quiet rw"
1
"C:\Program Files\qemu\qemu-system-arm.exe" -M vexpress-a9 -m 1024M -kernel zImage -dtb vexpress-v2p-ca9.dtb -append "root=/dev/mmcblk0 rw console=ttyAMA0" -sd rootfsubuntu18lxde.ext3 -serial stdio -smp 4
7272.PNG

在Ubuntu的qemuimg文件夹运行

1
qemu-system-arm -M vexpress-a9 -m 1024M -kernel zImage -dtb vexpress-v2p-ca9.dtb -append "root=/dev/mmcblk0 rw console=ttyAMA0 init=/sbin/init" -sd rootfs.ext3 -smp 4 -serial stdio
727.PNG

第一步 建立交叉编译环境

一开始运行老师给的代码

结果错误,

akVgGq.png

后来GUO同学给了这个修改后的代码,运行正常。

运行下面代码

1
qemu-system-arm -M vexpress-a9 -m 512M -kernel zImage -dtb vexpress-v2p-ca9.dtb -initrd ramdisk.gz -append "root=/dev/mmcblk0 clocksource=pit rw console=tty0 rdinit=/init" -sd rootfs.ext3

结果:

7273.PNG

用gcc编译helloworld

akV8VH.png

交叉编译时出错,umont不可用导致mnt卸载不了,文件不能更新

akVGad.png

重新写了一下代码,进入mnt文件夹中

1
2
3
4
5
6
7
sudo mkdir root
cd root/
sudo cp ~/src/test.arm .
cd ../..
sudo umount mnt
qemu-system-arm -M vexpress-a9 -m 512M -kernel zImage -dtb vexpress-v2p-ca9.dtb -initrd ramdisk.gz -append "root=/dev/mmcblk0 clocksource=pit rw console=tty0 rdinit=/init" -sd rootfs.ext3

akeHv6.png

在弹出的界面进入root运行test.arm

ake7gx.png

成功

交叉编译后的运行环境搭建成功.

第二步 下载并编译QT4

准备

下载

官方下载地址:https://download.qt.io/archive/qt/4.8/4.8.7/

也可以从这里下载:

链接:https://pan.baidu.com/s/1SOsVu6--3ujsS9u9l9UIHA
提取码:83dw

解压,编译

1
2
3
tar xvf qt-everywhere-opensource-src-4.8.7.tar.gz
cd qt-everywhere-opensource-src-4.8.7
./configure -prefix /usr/local/qt-4.8.7-install -opensource -confirm-license -embedded arm -host-little-endian -no-cups -no-3dnow -nomake examples -nomake demos -nomake docs -xplatform /qws/linux-arm-gnueabi-g++ -little-endian -no-webkit

解压后

akmfQP.png

编译成功后

akmhsf.png

记住目录 (交叉编译器)

1
/qws/linux-arm-gnueabi-g++

编译和安装开发环境

分别编译(make)和安装(make install)qt-4.8.7开发环境

分别执行

1
2
make
sudo make install

检查是否安装完成,查看版本

1
qmake --version

如果找不到qmake可能是环境变量没有配置:

老师又给错了

1
export QMAKESPEC=/usr/local/qt-4.8.6-install/mkspecs/linux-arm-gnueabi-g++

正确的是

1
2
export QMAKESPEC=/usr/local/qt-4.8.7-install/mkspecs/linux-arm-gnueabi-g++
export QMAKESPEC=/usr/local/qt-4.8.7-install/mkspecs/qws/linux-arm-gnueabi-g++

如果你有多个qt版本,可以使用如下命令来切换你刚才安装的qt-4.8.7为默认版本

1
qtchooser -install -f default /usr/local/qt-4.8.7-install/bin/qmake

结果

akuy8A.png

.

.

.

qemu搭建arm开发环境

接上个文档

.

一开始就出现巨大问题,浪费了四五个小时,问题是路径找不到,可能是环境变量的设置问题

折腾了很长时间,问了两位同学,最后瞎整弄成功了,可以qmake 和 make了


第三步 编写qt程序

编写hello

建立文件夹及文件

1
2
3
4
5
6
mkdir src
cd src
mkdir hello
cd hello
touch hello1.cpp
sudo gedit hello1.cpp

再将代码复制到cpp中

1
2
3
4
5
6
7
#include <QApplication>
#include <QDebug>
int main(int argc,char *argv[])
{
qDebug("Hello, welcome to Qt world!");
return 0;
}

创建hello1.cpp.PNG

完成

编译文件

输入qmake .make等等

1
2
3
qmake -project hello1.cpp
qmake hello.pro
make

hello.PNG

建立ui文件并编译

建立main.cpp

内容为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include<iostream>
#include<QApplication>
#include<QWidget>
#include<QPushButton>
#include<QPoint>
#include<QDebug>

int main(int argc,char** argv)
{
QApplication app(argc,argv);//这个对象只能有一个 单实例
QWidget widget;
QPushButton button;
widget.move(200,100);//位置
widget.resize(300,400);//宽高

button.setParent(&widget);//给它设置父窗口 就是嵌套到大窗口上
button.move(100,100);
button.setText("hello");
button.resize(50,20);
widget.show();//顶级窗口出现 可以最大最小化
qDebug()<<"button pos:"<<button.pos()<<" "<<button.size()<<endl;

return app.exec();
}
编译qtui文件
1
2
3
qmake -project main.cpp
qmake qtui.pro
make
实现如下图

qtui.PNG

第四步 在BusyBox文件系统下增加QT运行环境

创建文件系统

转载mnt并把环境cp进来

1
2
3
4
5
sudo mount rootfsqt4.7.ext3 mnt
cd mnt
cd usr/local
cp -rf /usr/local/qt-4.8.7-install .
cd ../..

将编译的文件cp到文件系统

如果没有文件夹则重新建

1
2
3
4
5
6
mkdir home
cd home
mkdir root
cd root
cp ~/src/hello/hello .
cp ~/src/qtui/qtui .

解除挂载,准备运行QEMU

在mnt上层文件夹中运行

sudo umount mnt

第五步

运行

1
qemu-system-arm -M vexpress-a9 -m 512M -kernel zImage -dtb vexpress-v2p-ca9.dtb -initrd ramdisk.gz -append "root=/dev/mmcblk0 clocksource=pit rw console=tty0 rdinit=/init" -sd rootfs.ext3

捕获.PNG

进入文件夹./hello运行qt程序hello

结果

qtworld.PNG

执行./qtui -qws出现窗口

可能需要建立tmp文件夹

qtui2.PNG

完成


HIT

曹新宇 19点13分

2020/7/28 安徽宿州