“Qemu”的版本间的差异
Weidongshan(讨论 | 贡献) (→参数讲解) |
Weidongshan(讨论 | 贡献) |
||
第337行: | 第337行: | ||
<div style="margin-left:0cm;margin-right:0cm;"></div> | <div style="margin-left:0cm;margin-right:0cm;"></div> | ||
− | === | + | === QEMU操作示例 === |
<div style="margin-left:0cm;margin-right:0cm;">先执行以下命令启动QEMU,它模拟百问网imx6ul-qemu开发板:</div> | <div style="margin-left:0cm;margin-right:0cm;">先执行以下命令启动QEMU,它模拟百问网imx6ul-qemu开发板:</div> | ||
− | + | <syntaxhighlight lang="bash"> | |
$ ./qemu-imx6ul-gui.sh // 启动后,登录名是root,无需密码 | $ ./qemu-imx6ul-gui.sh // 启动后,登录名是root,无需密码 | ||
− | + | </syntaxhighlight> | |
<div style="margin-left:0cm;margin-right:0cm;">它会弹出一个开发板的界面,并且运行该开发板的Linux系统,你可以在终端中操作该开发板:</div> | <div style="margin-left:0cm;margin-right:0cm;">它会弹出一个开发板的界面,并且运行该开发板的Linux系统,你可以在终端中操作该开发板:</div> | ||
第349行: | 第349行: | ||
<div style="margin-left:0cm;margin-right:0cm;"><span style="color:#ff0000;">注意</span>:当你的鼠标点击QEMU的GUI界面时,鼠标将无法移出这个GUI界面。这时可以通过快捷键“Ctrl+Alt+g”把鼠标从GUI界面中退出来。</div> | <div style="margin-left:0cm;margin-right:0cm;"><span style="color:#ff0000;">注意</span>:当你的鼠标点击QEMU的GUI界面时,鼠标将无法移出这个GUI界面。这时可以通过快捷键“Ctrl+Alt+g”把鼠标从GUI界面中退出来。</div> | ||
− | ==== | + | ==== 操作设备管理器 ==== |
<div style="margin-left:0cm;margin-right:0cm;">我们的计划是模拟更多的外设,为形象地操作这些外设,每个外设都会有一个GUI界面。可能会有多达几十、上百个外设,如果一下子显示那么多GUI界面,会很乱。</div> | <div style="margin-left:0cm;margin-right:0cm;">我们的计划是模拟更多的外设,为形象地操作这些外设,每个外设都会有一个GUI界面。可能会有多达几十、上百个外设,如果一下子显示那么多GUI界面,会很乱。</div> | ||
第368行: | 第368行: | ||
<div style="margin-left:0cm;margin-right:0cm;"></div> | <div style="margin-left:0cm;margin-right:0cm;"></div> | ||
− | ==== | + | ==== 操作LCD ==== |
<div style="margin-left:0cm;margin-right:0cm;">我们模拟的IMX6ULL板子,它的Linux系统中已经带有LCD的测试命令,可以执行以下命令测试:</div> | <div style="margin-left:0cm;margin-right:0cm;">我们模拟的IMX6ULL板子,它的Linux系统中已经带有LCD的测试命令,可以执行以下命令测试:</div> | ||
− | + | <syntaxhighlight lang="bash"> | |
[root@qemu_imx6ul:~]# fb-test | [root@qemu_imx6ul:~]# fb-test | ||
− | + | </syntaxhighlight> | |
或 | 或 | ||
− | + | <syntaxhighlight lang="bash"> | |
[root@qemu_imx6ul:~]# myfb-test /dev/fb0 | [root@qemu_imx6ul:~]# myfb-test /dev/fb0 | ||
− | + | </syntaxhighlight> | |
<div style="margin-left:0cm;margin-right:0cm;">效果如下:</div> | <div style="margin-left:0cm;margin-right:0cm;">效果如下:</div> | ||
第386行: | 第386行: | ||
<div style="margin-left:0cm;margin-right:0cm;"></div> | <div style="margin-left:0cm;margin-right:0cm;"></div> | ||
− | ==== | + | ==== 操作LED ==== |
<div style="margin-left:0cm;margin-right:0cm;">我们模拟的IMX6ULL板子,它的Linux系统中已经带有LED驱动和测试命令,可以执行以下命令测试:</div> | <div style="margin-left:0cm;margin-right:0cm;">我们模拟的IMX6ULL板子,它的Linux系统中已经带有LED驱动和测试命令,可以执行以下命令测试:</div> | ||
− | + | <syntaxhighlight lang="bash"> | |
[root@qemu_imx6ul:~]# cd led_driver_qemu/ | [root@qemu_imx6ul:~]# cd led_driver_qemu/ | ||
− | |||
[root@qemu_imx6ul:~/led_driver_qemu]# insmod 100ask_led.ko | [root@qemu_imx6ul:~/led_driver_qemu]# insmod 100ask_led.ko | ||
− | |||
[root@qemu_imx6ul:~/led_driver_qemu]# ./ledtest /dev/100ask_led0 off | [root@qemu_imx6ul:~/led_driver_qemu]# ./ledtest /dev/100ask_led0 off | ||
− | |||
[root@qemu_imx6ul:~/led_driver_qemu]# ./ledtest /dev/100ask_led0 on | [root@qemu_imx6ul:~/led_driver_qemu]# ./ledtest /dev/100ask_led0 on | ||
− | + | </syntaxhighlight> | |
<div style="margin-left:0cm;margin-right:0cm;">效果如下:</div> | <div style="margin-left:0cm;margin-right:0cm;">效果如下:</div> | ||
第403行: | 第400行: | ||
<div style="text-align:center;">[[Image:图片 42.png|top]]</div> | <div style="text-align:center;">[[Image:图片 42.png|top]]</div> | ||
− | ==== | + | ==== 使用按键来控制LED ==== |
<div style="margin-left:0cm;margin-right:0cm;">我们模拟的IMX6ULL板子,它的Linux系统中已经带有LED驱动、按键驱动和测试命令。</div> | <div style="margin-left:0cm;margin-right:0cm;">我们模拟的IMX6ULL板子,它的Linux系统中已经带有LED驱动、按键驱动和测试命令。</div> | ||
<div style="margin-left:0cm;margin-right:0cm;">首先在“QEMU 设备管理器”中打开按键的界面,然后执行以下命令测试:</div> | <div style="margin-left:0cm;margin-right:0cm;">首先在“QEMU 设备管理器”中打开按键的界面,然后执行以下命令测试:</div> | ||
− | + | <syntaxhighlight lang="bash"> | |
[root@qemu_imx6ul:~]# cd led_driver_qemu/ | [root@qemu_imx6ul:~]# cd led_driver_qemu/ | ||
− | |||
[root@qemu_imx6ul:~/led_driver_qemu]# insmod 100ask_led.ko | [root@qemu_imx6ul:~/led_driver_qemu]# insmod 100ask_led.ko | ||
− | |||
[root@qemu_imx6ul:~/led_driver_qemu]# cd ../button_driver_qemu/ | [root@qemu_imx6ul:~/led_driver_qemu]# cd ../button_driver_qemu/ | ||
− | |||
[root@qemu_imx6ul:~/button_driver_qemu]# insmod button_drv.ko | [root@qemu_imx6ul:~/button_driver_qemu]# insmod button_drv.ko | ||
− | |||
[root@qemu_imx6ul:~/button_driver_qemu]# insmod board_100ask_qemu_imx6u | [root@qemu_imx6ul:~/button_driver_qemu]# insmod board_100ask_qemu_imx6u | ||
− | |||
[root@qemu_imx6ul:~/button_driver_qemu]# ./button_led_test | [root@qemu_imx6ul:~/button_driver_qemu]# ./button_led_test | ||
− | + | </syntaxhighlight> | |
<div style="margin-left:0cm;margin-right:0cm;">效果如下图(只实现了左边的2个按键,右边的2个按键留待以后实现其他目的):</div> | <div style="margin-left:0cm;margin-right:0cm;">效果如下图(只实现了左边的2个按键,右边的2个按键留待以后实现其他目的):</div> | ||
第451行: | 第443行: | ||
<div style="margin-left:0cm;margin-right:0cm;"></div> | <div style="margin-left:0cm;margin-right:0cm;"></div> | ||
− | ==== | + | ==== 读写I2C EEPROM AT24C02 ==== |
<div style="margin-left:0cm;margin-right:0cm;">我们模拟的IMX6ULL板子,它已经实现了对I2C设备AT24C02的模拟。</div> | <div style="margin-left:0cm;margin-right:0cm;">我们模拟的IMX6ULL板子,它已经实现了对I2C设备AT24C02的模拟。</div> | ||
<div style="margin-left:0cm;margin-right:0cm;">首先在“QEMU 设备管理器”中打开at24c02的界面,然后执行以下命令测试:</div> | <div style="margin-left:0cm;margin-right:0cm;">首先在“QEMU 设备管理器”中打开at24c02的界面,然后执行以下命令测试:</div> | ||
− | + | <syntaxhighlight lang="bash"> | |
// 0x50是AT24C02的I2C设备地址 | // 0x50是AT24C02的I2C设备地址 | ||
− | |||
[root@qemu_imx6ul:~]# i2c_usr_test /dev/i2c-0 0x50 r 0 // 读地址0 | [root@qemu_imx6ul:~]# i2c_usr_test /dev/i2c-0 0x50 r 0 // 读地址0 | ||
− | |||
data: , 0, 0x00 | data: , 0, 0x00 | ||
− | |||
[root@qemu_imx6ul:~]# i2c_usr_test /dev/i2c-0 0x50 w 1 0x58 // 写地址1,写入0x58 | [root@qemu_imx6ul:~]# i2c_usr_test /dev/i2c-0 0x50 w 1 0x58 // 写地址1,写入0x58 | ||
− | + | </syntaxhighlight> | |
<div style="margin-left:0cm;margin-right:0cm;">效果如下图:</div> | <div style="margin-left:0cm;margin-right:0cm;">效果如下图:</div> | ||
第505行: | 第494行: | ||
<div style="margin-left:0cm;margin-right:0cm;"></div> | <div style="margin-left:0cm;margin-right:0cm;"></div> | ||
− | <div style="margin-left:0cm;margin-right:0cm;"></div>== 使用QEMU进行嵌入式Linux开发 == | + | <div style="margin-left:0cm;margin-right:0cm;"></div> |
+ | == 使用QEMU进行嵌入式Linux开发 == | ||
<div style="margin-left:0cm;margin-right:0cm;">完整的嵌入式Linux系统包含:bootloader、Linux内核、设备树、根文件系统。</div> | <div style="margin-left:0cm;margin-right:0cm;">完整的嵌入式Linux系统包含:bootloader、Linux内核、设备树、根文件系统。</div> | ||
第519行: | 第509行: | ||
<div style="margin-left:0.635cm;margin-right:0cm;">[http://wiki.100ask.org/VMwareAndUbuntuNetworkSetupGuide http://wiki.100ask.org/VMwareAndUbuntuNetworkSetupGuide]</div> | <div style="margin-left:0.635cm;margin-right:0cm;">[http://wiki.100ask.org/VMwareAndUbuntuNetworkSetupGuide http://wiki.100ask.org/VMwareAndUbuntuNetworkSetupGuide]</div> | ||
− | ==== | + | ==== 设置git邮箱账号和用户名 ==== |
<div style="margin-left:0cm;margin-right:0cm;">在Ubuntu中执行如下命令:</div> | <div style="margin-left:0cm;margin-right:0cm;">在Ubuntu中执行如下命令:</div> | ||
− | + | <syntaxhighlight lang="bash"> | |
book@100ask:~$ git config --global user.email "you@example.com" | book@100ask:~$ git config --global user.email "you@example.com" | ||
− | |||
book@100ask:~$ git config --global user.name "Your Name" | book@100ask:~$ git config --global user.name "Your Name" | ||
− | + | </syntaxhighlight> | |
<div style="margin-left:0cm;margin-right:0cm;">初次使用GIT时,需要配置邮箱帐号和用户名,可以随意指定。</div> | <div style="margin-left:0cm;margin-right:0cm;">初次使用GIT时,需要配置邮箱帐号和用户名,可以随意指定。</div> | ||
− | ==== | + | ==== 下载源码 ==== |
<div style="margin-left:0cm;margin-right:0cm;">考虑到代码仓库过多,特使用repo工具管理代码。</div> | <div style="margin-left:0cm;margin-right:0cm;">考虑到代码仓库过多,特使用repo工具管理代码。</div> | ||
<div style="margin-left:0cm;margin-right:0cm;">先用git clone下载repo工具,再用repo工具下载源码:</div> | <div style="margin-left:0cm;margin-right:0cm;">先用git clone下载repo工具,再用repo工具下载源码:</div> | ||
− | + | <syntaxhighlight lang="bash"> | |
book@100ask:~$ git clone https://git.dev.tencent.com/codebug8/repo.git | book@100ask:~$ git clone https://git.dev.tencent.com/codebug8/repo.git | ||
− | |||
book@100ask:~$ mkdir -p 100ask_imx6ull-qemu && cd 100ask_imx6ull-qemu | book@100ask:~$ mkdir -p 100ask_imx6ull-qemu && cd 100ask_imx6ull-qemu | ||
− | |||
book@100ask:~/100ask_imx6ull-qemu$ ../repo/repo init -u https://dev.tencent.com/u/weidongshan/p/manifests/git -b linux-sdk -m imx6ull/100ask-imx6ull_qemu_release_v1.0.xml --no-repo-verify | book@100ask:~/100ask_imx6ull-qemu$ ../repo/repo init -u https://dev.tencent.com/u/weidongshan/p/manifests/git -b linux-sdk -m imx6ull/100ask-imx6ull_qemu_release_v1.0.xml --no-repo-verify | ||
− | |||
book@100ask:~/100ask_imx6ull-qemu$ ../repo/repo sync -j4 | book@100ask:~/100ask_imx6ull-qemu$ ../repo/repo sync -j4 | ||
− | + | </syntaxhighlight> | |
<div style="margin-left:0cm;margin-right:0cm;">上面使用的repo管理的是国内coding仓库,从国内仓库下载会快很多。</div> | <div style="margin-left:0cm;margin-right:0cm;">上面使用的repo管理的是国内coding仓库,从国内仓库下载会快很多。</div> | ||
第564行: | 第550行: | ||
<div style="margin-left:0cm;margin-right:0cm;">设置交叉编译工具主要是设置PATH, ARCH和CROSS_COMPILE三个环境变量,下面介绍具体设置方法。</div> | <div style="margin-left:0cm;margin-right:0cm;">设置交叉编译工具主要是设置PATH, ARCH和CROSS_COMPILE三个环境变量,下面介绍具体设置方法。</div> | ||
− | ==== | + | ==== 永久生效 ==== |
<div style="margin-left:0cm;margin-right:0cm;">如需永久修改,请修改用户配置文件。在Ubuntu系统下,修改如下:</div> | <div style="margin-left:0cm;margin-right:0cm;">如需永久修改,请修改用户配置文件。在Ubuntu系统下,修改如下:</div> | ||
− | + | <syntaxhighlight lang="bash"> | |
book@100ask:~$ vi ~/.bashrc | book@100ask:~$ vi ~/.bashrc | ||
− | + | </syntaxhighlight> | |
<div style="margin-left:0cm;margin-right:0cm;">在行尾添加或修改:</div> | <div style="margin-left:0cm;margin-right:0cm;">在行尾添加或修改:</div> | ||
− | + | <syntaxhighlight lang="bash"> | |
export ARCH=arm | export ARCH=arm | ||
− | |||
export CROSS_COMPILE=arm-linux-gnueabihf- | export CROSS_COMPILE=arm-linux-gnueabihf- | ||
− | |||
export PATH=$PATH:/home/book/100ask_imx6ull-qemu/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin | export PATH=$PATH:/home/book/100ask_imx6ull-qemu/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin | ||
+ | </syntaxhighlight> | ||
− | + | ==== 临时生效 ==== | |
− | ==== | ||
<div style="margin-left:0cm;margin-right:0cm;">如果你有很多单板,为了不冲突,你不能使用“永久生效”的办法。比如你有32位的ARM板,也有64位的ARM板,在使用前者时需要设置ARCH=arm,在使用后者时需要设置ARCH=arm64。</div> | <div style="margin-left:0cm;margin-right:0cm;">如果你有很多单板,为了不冲突,你不能使用“永久生效”的办法。比如你有32位的ARM板,也有64位的ARM板,在使用前者时需要设置ARCH=arm,在使用后者时需要设置ARCH=arm64。</div> | ||
<div style="margin-left:0cm;margin-right:0cm;">这种情况下,可以使用“export”命令设置环境变量,这种设置方法只对当前终端有效:</div> | <div style="margin-left:0cm;margin-right:0cm;">这种情况下,可以使用“export”命令设置环境变量,这种设置方法只对当前终端有效:</div> | ||
− | + | <syntaxhighlight lang="bash"> | |
book@100ask:~$ export PATH=$PATH:/home/book/100ask_imx6ull-qemu/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin | book@100ask:~$ export PATH=$PATH:/home/book/100ask_imx6ull-qemu/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin | ||
− | |||
book@100ask:~$ export ARCH=arm | book@100ask:~$ export ARCH=arm | ||
− | |||
book@100ask:~$ export CROSS_COMPILE=arm-linux-gnueabihf- | book@100ask:~$ export CROSS_COMPILE=arm-linux-gnueabihf- | ||
+ | </syntaxhighlight> | ||
− | + | ==== 手动指定 ==== | |
− | ==== | ||
<div style="margin-left:0cm;margin-right:0cm;">执行make命令时,可以手工指定ARCH架构、CROSS_COMPILE等变量:</div> | <div style="margin-left:0cm;margin-right:0cm;">执行make命令时,可以手工指定ARCH架构、CROSS_COMPILE等变量:</div> | ||
− | + | <syntaxhighlight lang="bash"> | |
book@100ask:~$ export PATH=$PATH:/home/book/100ask_imx6ull-qemu/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin | book@100ask:~$ export PATH=$PATH:/home/book/100ask_imx6ull-qemu/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin | ||
− | |||
book@100ask:~$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- | book@100ask:~$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- | ||
− | + | </syntaxhighlight> | |
<div style="margin-left:0cm;margin-right:0cm;">不过这种方法效率太低,不建议使用。</div> | <div style="margin-left:0cm;margin-right:0cm;">不过这种方法效率太低,不建议使用。</div> |
2019年11月25日 (一) 11:36的版本
目录
- 1 QEMU使用手册
-
2 QEMU开发手册
- 2.1 1. QEMU下载与编译
- 2.2 2. QEMU的设备创建过程
- 2.3 3. QEMU的设备模拟
- 2.4 4. 模拟LED
- 2.5 5. 模拟LCD
- 2.6 6. QEMU的输出:GUI系统
- 2.7 7. QEMU的输入:鼠标事件
- 2.8 8. 使用中断
- 2.9 9. 模拟按键
- 2.10 10. QEMU启动过程
- 2.11 11. 调试
QEMU使用手册
QEMU简介
还有很多模拟器,比如VMWare、Virtual Box等。但是VMWare、Virtual Box只能模拟x86、AMD64/Intel64等PC系统;
用户模式(User Mode)
$ gcc -o hello hello.c -static
$ ./hello // 这个hello程序是使用gcc给PC机编译的,可以直接运行
Hello, world!
$ arm-linux-gnueabihf-gcc -o hello hello.c -static // 它是给ARM板子编译的
$ ./hello // 所以无法在PC上运行
bash: ./hello: cannot execute binary file: Exec format error
$ ./qemu-arm ./hello // 我们可以用QEMU在PC上运行它
Hello, world!
- 你没有安装ARM交叉编译工具链
- 你没有安装QEMU
系统模式(System Mode)
我们做的改进
*
- 模拟网卡
- 模拟LCD显示功能
- 模拟led灯、按键
- 模拟at24cxx i2c存储芯片,直接可以通过用户态操作看到效果
- 增加逻辑分析仪显示功能
- 后续会逐渐增加更多的模拟硬件模块
QEMU快速使用
准备工作
- 一台可以上网的windows电脑
- 一个可以正常使用Ubuntu虚拟机VMWare系统,也要能上网
$ sudo apt-get update
$ sudo apt-get install qemu qemu-kvm libvirt-bin bridge-utils virt-manager
获取镜像
① ubuntu-18.04开发环境下qemu imx6ul系统镜像下载地址:
② ubuntu-16.04开发环境下qemu imx6ul系统镜像下载地址:
① ubuntu-16.04解压操作步骤
$ tar -xvf weidongshan-ubuntu-16.04_imx6ul_qemu_system-release.tgz
② ubuntu-18.04解压操作步骤
$ tar -xvf weidongshan-ubuntu-18.04_imx6ul_qemu_system-release.tgz
运行QEMU系统
首次运行需要安装SDL环境以及解压文件系统镜像:
$ ./install_sdl.sh // 提示输入用户密码,等待安装完成
运行带GUI的imx6ul模拟器
$ ./qemu-imx6ul-gui.sh // 启动后,登录名是root,无需密码
$ ./qemu-imx6ul-gui.sh fire // 启动后,登录名是root,无需密码
$ ./qemu-imx6ul-gui.sh atk // 启动后,登录名是root,无需密码
运行不带GUI的imx6ul模拟器
$ ./qemu-imx6ul-nogui.sh // 启动后,登录名是root,无需密码
参数讲解
-M mcimx6ul-evk
指定需要模拟的单板型号。
-m 512M
指定板子的内存大小。
-kernel zImage
指定使用的内核镜像文件。
-dtb 100ask_imx6ul_qemu.dtb
指定使用的设备树文件。
-display sdl
指定使用那种图形显示输出。
-serial mon:stdio
指定串口信息输出。
-drive file=rootfs.img,format=raw,id=mysdcard
名为mysdcard的drive,源为rootfs.img
-device sd-card,drive=mysdcard
添加一个sd-card设备,内容来自名为mysdcard的drive
-append “console=ttymxc0,115200 rootfstype=ext4 root=/dev/mmcblk1 rw rootwait init=/sbin/init loglevel=8”
指定内核的命令行参数
-nic user
指定网卡为user mode
百问网imx6ull-qemu开发板资料下载
QEMU操作示例
$ ./qemu-imx6ul-gui.sh // 启动后,登录名是root,无需密码
操作设备管理器
操作LCD
[root@qemu_imx6ul:~]# fb-test
或
[root@qemu_imx6ul:~]# myfb-test /dev/fb0
操作LED
[root@qemu_imx6ul:~]# cd led_driver_qemu/
[root@qemu_imx6ul:~/led_driver_qemu]# insmod 100ask_led.ko
[root@qemu_imx6ul:~/led_driver_qemu]# ./ledtest /dev/100ask_led0 off
[root@qemu_imx6ul:~/led_driver_qemu]# ./ledtest /dev/100ask_led0 on
使用按键来控制LED
[root@qemu_imx6ul:~]# cd led_driver_qemu/
[root@qemu_imx6ul:~/led_driver_qemu]# insmod 100ask_led.ko
[root@qemu_imx6ul:~/led_driver_qemu]# cd ../button_driver_qemu/
[root@qemu_imx6ul:~/button_driver_qemu]# insmod button_drv.ko
[root@qemu_imx6ul:~/button_driver_qemu]# insmod board_100ask_qemu_imx6u
[root@qemu_imx6ul:~/button_driver_qemu]# ./button_led_test
读写I2C EEPROM AT24C02
// 0x50是AT24C02的I2C设备地址
[root@qemu_imx6ul:~]# i2c_usr_test /dev/i2c-0 0x50 r 0 // 读地址0
data: , 0, 0x00
[root@qemu_imx6ul:~]# i2c_usr_test /dev/i2c-0 0x50 w 1 0x58 // 写地址1,写入0x58
使用QEMU进行嵌入式Linux开发
=== 获取源码 ===
设置git邮箱账号和用户名
book@100ask:~$ git config --global user.email "you@example.com"
book@100ask:~$ git config --global user.name "Your Name"
下载源码
book@100ask:~$ git clone https://git.dev.tencent.com/codebug8/repo.git
book@100ask:~$ mkdir -p 100ask_imx6ull-qemu && cd 100ask_imx6ull-qemu
book@100ask:~/100ask_imx6ull-qemu$ ../repo/repo init -u https://dev.tencent.com/u/weidongshan/p/manifests/git -b linux-sdk -m imx6ull/100ask-imx6ull_qemu_release_v1.0.xml --no-repo-verify
book@100ask:~/100ask_imx6ull-qemu$ ../repo/repo sync -j4
=== 设置工具链 ===
永久生效
book@100ask:~$ vi ~/.bashrc
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-
export PATH=$PATH:/home/book/100ask_imx6ull-qemu/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin
临时生效
book@100ask:~$ export PATH=$PATH:/home/book/100ask_imx6ull-qemu/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin
book@100ask:~$ export ARCH=arm
book@100ask:~$ export CROSS_COMPILE=arm-linux-gnueabihf-
手动指定
book@100ask:~$ export PATH=$PATH:/home/book/100ask_imx6ull-qemu/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin
book@100ask:~$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
3.3 编译内核及设备树
book@100ask:~/100ask_imx6ull-qemu$ cd linux-4.9.88
book@100ask:~/100ask_imx6ull-qemu/linux-4.9.88$ make mrproper
book@100ask:~/100ask_imx6ull-qemu/linux-4.9.88$ make 100ask_imx6ul_qemu_defconfig
book@100ask:~/100ask_imx6ull-qemu/linux-4.9.88$ make zImage -jN //编译zImage 内核镜像,其中N参数可以根据CPU个数,来加速编译系统。
book@100ask:~/100ask_imx6ull-qemu/linux-4.9.88$ make dtbs //编译设备树文件
arch/arm/boot/zImage // 内核
arch/arm/boot/dts/100ask_imx6ul_qemu.dtb // 设备树
3.4 修改文件系统
sudo mount -o loop rootfs.img /mnt
sudo umount /mnt
3.5 启动模拟器后使用NFS
$ ./qemu-imx6ul-gui.sh // 启动后,登录名是root,无需密码
3.5.1 在Ubuntu上安装、配置NFS服务
sudo apt-get install nfs-kernel-server
/home/book *(rw,nohide,insecure,no_subtree_check,async,no_root_squash)
/work *(rw,nohide,insecure,no_subtree_check,async,no_root_squash)
sudo /etc/init.d/nfs-kernel-server restart
sudo mount -t nfs -o nolock,vers=3 127.0.0.1:/home/book /mnt
ls /mnt
3.5.2 开发板获取IP地址
[root@qemu_imx6ul:~]# ifconfig eth0 10.0.2.15
3.5.3 挂载主机nfs目录
[root@qemu_imx6ul:~]# mount -t nfs -o nolock,vers=3 10.0.2.2:/home/book/nfs_rootfs /mnt
更新QEMU
4.1 下载最新的release包
① ubuntu-18.04开发环境下qemu imx6ul系统镜像下载地址:
② ubuntu-16.04开发环境下qemu imx6ul系统镜像下载地址:
4.2 下载最新的qemu-system-arm可执行程序及配置文件
https://dev.tencent.com/u/weidongshan/p/ubuntu-16.04_imx6ul_qemu_system/git
https://dev.tencent.com/u/weidongshan/p/ubuntu-18.04_imx6ul_qemu_system/git
4.3 下载最新的qemu源码并编译
QEMU开发手册
# 添加外设
- 添加外设的GUI
- 在虚拟开发板上开发测试程序
1. QEMU下载与编译
1.1 源码下载
$ git clone https://gitee.com/weidongshan/qemu.git
或
$ git clone https://github.com/100askTeam/qemu.git
$ git pull origin
1.2 配置、编译、安装
./configure --prefix=$PWD/ --target-list="arm-softmmu arm-linux-user" --enable-debug --enable-sdl --enable-kvm --enable-tools --disable-curl
$ make
$ make install
ERROR: pixman >= 0.21.8 not present.
Please install the pixman devel package.
① 确定库的名称:
$ apt-cache search pixman
libpixman-1-0 - pixel-manipulation library for X and cairo
libpixman-1-dev - pixel-manipulation library for X and cairo (development files)
② 安装开发包:
$ sudo apt-get install libpixman-1-dev
$ sudo apt-get install pkg-config
$ sudo apt-get install libsdl2-dev
$ sudo apt-get install libpixman-1-dev
qemu-system-arm
1.3 使用新的qemu-system-arm
ubuntu-18.04_imx6ul_qemu_system/qemu-system-arm/bin
或
ubuntu-16.04_imx6ul_qemu_system/qemu-system-arm/bin
ubuntu-18.04_imx6ul_qemu_system/qemu-system-arm/etc
或
ubuntu-16.04_imx6ul_qemu_system/qemu-system-arm/etc
1.4 QEMU源码目录
2. QEMU的设备创建过程
2.1 重要结构体TypeInfo
static void __attribute__((constructor)) do_qemu_init_imx_gpio_register_types (void) \
{ \
register_module_init(imx_gpio_register_types, MODULE_INIT_QOM); \
}
2.2 生成TypeImpl
a15mp_register_types
ask100fb_register_types
main
① 分配一个TypeImpl结构体,使用TypeInfo来设置它:
② 把TypeImpl放入链表:type_table
2.3 使用TypeImpl:实例化
① 分配:
② 设置:
① qdev_create/qdev_init_nofail
② sysbus_init_child_obj/object_property_set_bool
2.4 实例化方法1:qdev_create/qdev_init_nofail
2.4.1 qdev_create分析
① 第2个参数是name,会被用来找到对应的TypeInfo结构体
② 分配instance_size大小的内存,即分配ASK100FbState结构体,这用来表示LCD
③ 调用TypeInfo结构体中的class_init函数
④ 调用TypeInfo结构体中的instance_init函数
2.4.2 qdev_init_nofail分析
2.4.3 总结:怎么创建设备
① 先定义一个TypeInfo结构体
② 注册这个TypeInfo结构体:
③ 使用type_init,把ask100fb_register_types函数放入链表中
④ 调用qdev_create创建设备,这会传入type name
⑤ 调用qdev_init_nofail设置设备的状态为realized,这会导致类别的realize函数被调用。
① TypeInfo中的class_init:它会设置dc->realize = 某个函数
② TypeInfo中instance_size大小的对象被malloc
③ TypeInfo中的instance_init函数被调用,它被用来初始化步骤②中malloc出来的结构体
④ dc->realize被调用
2.5 实例化方法2:object_initialize_child/object_property_set_bool
2.5.1 object_initialize_child分析
2.5.2 object_property_set_bool分析
2.5.3 总结:怎么创建设备
① 先定义一个TypeInfo结构体
② 注册这个TypeInfo结构体:
③ 使用type_init,把a15mp_register_types函数放入链表中
④ 调用object_initialize_child创建设备,这会传入type name
⑤ 调用object_property_set_bool设置设备的状态为realized,这会导致类别的realize函数被调用。
2.6 怎么创建设备
2.6.1 设置TypeInfo结构体
2.6.3 使用TypeInfo创建设备/设置设备的realized属性为true
qdev_create/qdev_init_nofail
object_initialize_child/object_property_set_bool
3. QEMU的设备模拟
3.1 QEMU模拟外设的原理
① CPU读某个地址时,QEMU模拟外设的行为,把数据返回给CPU
② CPU写某个地址时,QEMU获得数据,用来模拟外设的行为。
① 写LCD控制器,根据外接的LCD设置参数,比如分辨率、BPP、各种时序
② 从FrameBuffer中不断获得数据发给LCD,在LCD上显示出来。
① 写LCD控制器的相关寄存器
② 分配FrameBuffer,写FrameBuffer
① 记录驱动程序写寄存器的值,解析出分辨率等信息
② 记录FrameBuffer的地址,并持续不断地从中得到图像数据并显示出来
① 设置LCD控制器时:
qemu_a1a2_read
qemu_a1a2_write
② 写FrameBuffer时:
3.2 给某段地址提供读写函数
3.2.1 memory_region_init_io/memory_region_add_subregion
4. 模拟LED
4.1 主要函数
4.2 添加一段内存
IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3
5. 模拟LCD
common-obj-$(CONFIG_FSL_IMX6UL) += 100ask_qemu_fb.o
5.1 在Linux上编写LCD驱动程序
① 对于LCD控制器,只需要操作4个寄存器:
② 对于FrameBuffer:
5.3 重要函数分析
6. QEMU的输出:GUI系统
6.1 创建GUI Console
7. QEMU的输入:鼠标事件
common-obj-$(CONFIG_FSL_IMX6UL) += button_ui.o
7.3 输入事件处理流程
sdl2_2d_refresh
7.4 QEMU捕获的输入事件,可以作为ABS也可以作为REL事件上传
8. 使用中断
8.1 外设发出哪一个中断?
8.8.1 调用sysbus_init_irq初始化qemu_irq
① 它会给设备dev添加一个属性prop,prop的名字是“sysbus-irq[0]”或“sysbus-irq[1]”
② 会给这个prop添加一个link,link到&s->irq[0]或&s->irq[1]
8.8.2 调用sysbus_connect_irq连接中断
qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX6UL_I2Cn_IRQ[i])
8.2 中断触发
发出中断:
清除中断:
① 用户按下按键后,使用“qemu_set_irq(irq, 1)”发出中断
② 客户机的程序处理完中断后,它会写ISR寄存器来清除中断:
notify_imx_gpio_change
qemu_set_irq(s->irq[0], 1);
imx_gpio_write
9. 模拟按键
9.3 更新按键图片的同时
10. QEMU启动过程
10.1 各个模块的注册
#define type_init(function) module_init(function, MODULE_INIT_QOM)
#define module_init(function, type) \
static void __attribute__((constructor)) do_qemu_init_ ## function(void) \
{ \
register_dso_module_init(function, type); \
}
10.2 各个模块的初始化
main
① 分配一个TypeImpl结构体,使用TypeInfo来设置它:
② 把TypeImpl放入链表:type_table
10.5 CPU的初始化
10.6 在system memory中添加内存
11. 调试
11.1 要调试,运行gdb程序之前,必须先进入源码目录
11.2 调试QEMU本身
gdb --args /home/book/mywork/qemu/qemu_git/qemu/bin/qemu-system-arm -M \
mcimx6ul-evk -m 512M -kernel /home/book/nfs_rootfs/zImage \
-dtb /home/book/nfs_rootfs/mynet.dtb -serial stdio \
-drive file=/home/book/mywork/imx6ull_test_image/buildroot_rootfs.img,format=raw,id=mysdcard -device sd-card,drive=mysdcard \
-append "console=ttymxc0,115200 console=tty1 rootfstype=ext4 root=/dev/mmcblk1 rw rootwait init=/sbin/init loglevel=8" \
-nic user
11.3 调试之前就运行的QEMU
① 首先确定qemu-system-arm进程的PID
ps -A | grep qemu
② 在QEMU源码目录下执行如下命令:
sudo gdb -p 9527
11.4 调试客户机上的Linux内核
11.4.1 首先运行qemu-system-arm
gdb --args /home/book/mywork/qemu/qemu_git/qemu/bin/qemu-system-arm -M \
mcimx6ul-evk -m 512M -kernel /home/book/nfs_rootfs/zImage \
-dtb /home/book/nfs_rootfs/mynet.dtb -serial stdio \
-drive file=/home/book/mywork/imx6ull_test_image/buildroot_rootfs.img,format=raw,id=mysdcard -device sd-card,drive=mysdcard \
-append "console=ttymxc0,115200 console=tty1 rootfstype=ext4 root=/dev/mmcblk1 rw rootwait init=/sbin/init loglevel=8" \
-nic user -s -S