Linux驱动-IMX6ULL开发板qemu环境搭建
原创 thatway 那路谈OS与SoC嵌入式软件 2022-07-18 18:10
Linux
驱动
-IMX6ULL
开发板
qemu
环境搭建
俗话说“**工欲善其事,必先利其器**
”,本篇文章不介绍Linux驱动的知识,但是想学习Linux内核和驱动就需要查看和运行内核源码,这时你就需要买一个ARM开发板
,市场上资料比较全的开发板有正点原子
、野火
、百问网
的,下面以正点原子的为例说一下,首先打开:
http://www.openedv.com/docs/boards/arm-linux/zdyz-i.mx6ull.html#
这里首先是**视频**
,大家都知道看视频学习的比较快,其次是学习的PDF书籍
:
《【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.6
》。不得不说正点原子的左盟主
在Linux驱动方面的技术的确有一手,内容很好
,非常高效的帮助你学习Linux,并且视频和书等学习资料都是免费送
给大家,不要钱就可以获取到。
但是,有点小缺陷只看书不行啊,得有板子运行下才能实践出真知,不然你看书上的东西你自己都不信,并且也记不住。软件编程是
实践
的学科。下面就买开发板,买买买
:
剧情反转:
写到这里,你或许以为我是**做广告**
卖开发板来了。大错特错,相反我是来拆台的
,小一千买个开发板没那必要,就是要断人财路
方便大家。百闻网的韦东山
也是一号人物,也卖开发板,但是这人不简单,有格局,察觉到虚拟化
不可避免,开发板的生意快到头了,利用qemu
技术搞了一个模拟IMX6ULL开发板
的环境,并且免费开放参考:
https://www.bilibili.com/video/BV1pU4y1h7pn?spm_id_from=333.999.0.0
用qemu运行linux有两个好处:
1、省钱
,不用买开发板(要深入研究还是需要一个开发板)。
2、调试速度快
,修改代码编译打断点gdb运行一气呵成,随时都可以快速使用。
1. 虚拟机环境搭建
百闻网资料网盘直接提供了Ubuntu18.04的Vmware虚拟机安装包,直接加载就可以运行。
1.1 下载资料
打开http://download.100ask.net/,
找到QEMU:
下载百度网盘的资料
找到虚拟机文件:
1.2 虚拟机配置
在win10设备管理器里面查看,是否开启了虚拟化
如果没开启,需要设置BIOS开启。
使用vitualbox打开ubuntu18.04,book的密码是123456
可以自己设置一个root账号
安装vituralbox的增强功能设置剪切板和共享文件夹。
自动开发环境配置:
执行如下命令:
wget --no-check-certificate -O Configuring_ubuntu.sh https://weidongshan.coding.net/p/DevelopmentEnvConf/d/DevelopmentEnvConf/git/raw/master/Configuring_ubuntu.sh && sudo chmod +x Configuring_ubuntu.sh && sudo ./Configuring_ubuntu.sh |
git clone https://e.coding.net/weidongshan/ubuntu-18.04_imx6ul_qemu_system.git |
$ ./install_sdl.sh // 提示输入用户密码,等待安装完成 |
-M mcimx6ul-evk 指定需要模拟的单板型号。 -m 512M 指定板子的内存大小。 -kernel zImage 指定使用的内核镜像文件。 -dtb 100ask_imx6ull_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 #有了内核zImage、设备树、文件系统(rootfs.img),这就是一个完整的Linux系统。 #注意:QEMU中没有实现bootloader,以后我们会完全模拟SD卡,在SD卡上面放置u-boot、内核、设 #备树、文件系统。 |
$ ./qemu-imx6ull-gui_test.sh // 启动后,登录名是root,无需密码 |
[root@qemu_imx6ul:~]# fb-test 或 [root@qemu_imx6ul:~]# myfb-test /dev/fb0 |
sudo apt-get install nfs-kernel-server 然后,还得修改/etc/exports,添加类似以下的内容,下面的例子里允许开发板通过NFS访问Ubuntu的/home/book、/work两个目录: /home/book *(rw,nohide,insecure,no_subtree_check,async,no_root_squash) /work *(rw,nohide,insecure,no_subtree_check,async,no_root_squash) 最后,重启NFS服务,在Ubuntu上执行以下命令: sudo /etc/init.d/nfs-kernel-server restart |
启动QEMU后,它的文件系统中并没有触摸屏的操作程序tslib,需要挂载NFS、复制tslib到根文件系统后才能测试。
假设在Ubuntu的/home/book/nfs_rootfs目录下有rootfs_test。在开发板上执行以下命令:
mount -t nfs -o nolock,vers=3 10.0.2.2:/home/book/nfs_rootfs /mnt cp /mnt/* -rfd / |
[root@qemu_imx6ul:~]# ts_calibrate // 校准 [root@qemu_imx6ul:~]# ts_test // 测试 |
[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 |
[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 |
// 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 |
类别 | 国外 | 国内 |
linux kernel | https://github.com/100askTeam/qemu_imx6ull_kernel.git | https://git.dev.tencent.com/weidongshan/qemu_imx6ull_kernel.git |
qemu 源码 | https://github.com/100askTeam/qemu.git | https://gitee.com/weidongshan/qemu.git |
buildroot | https://git.dev.tencent.com/weidongshan/imx6ul_buildroot.git |
//安装repo sudo apt-get install repo book@100ask:~$ mkdir -p 100ask_imx6ull-qemu && cd 100ask_imx6ull-qemu book@100ask:~/100ask_imx6ull-qemu$ repo init -u https://e.coding.net/weidongshan/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 |
3.2 内核及设备树编译
在~/.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 |
100ask_imx6ull-qemu是代码下载的路径,如不一致需要修改
执行source .bashrc生效
编译内核及设备树,执行如下命令:
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_imx6ull_qemu_defconfig book@100ask:~/100ask_imx6ull-qemu/linux-4.9.88$ make zImage -j4 book@100ask:~/100ask_imx6ull-qemu/linux-4.9.88$ make dtbs //编译设备树文件 |
编译成功后,可以得到如下文件:
arch/arm/boot/zImage // 内核 arch/arm/boot/dts/100ask_imx6ul_qemu.dtb // 设备树 |
可以替换下载的ubuntu-18.04_imx6ul_qemu_system/imx6ull-system-image文件夹下的文件,之后运行就可以生效了。
3.3 文件系统修改
文件系统的位置在ubuntu-18.04_imx6ul_qemu_system/imx6ull-system-image/rootfs.img
Ubuntu下直接修改rootfs.img
sudo mount -o loop rootfs.img /mnt |
然后就可以在/mnt下面修改文件系统的内容了。
注意:修改完毕后,要执行以下命令:
sudo umount /mnt
3.4 其他:
开发qemu上的设备硬件程序,修改qemu代码,让qemu支持某个硬件,参考百闻网资料。
4. linux内核使用qemu调试
4.1 gdb命令调试
- 修改运行qemu的脚本加上 -s -S,会使嵌入式ARM Linux系统运行后等待GDB远程连入。
- 然后在代码根目录,使用编译器对应的gdb进行调试命令为arm-linux-gnueabihf-gdb ./vmlinux
然后设置断点,打印值,例如:
4.2 vscode调试
- 修改运行qemu的脚本加上 -s -S,会使嵌入式ARM Linux系统运行后等待GDB远程连入。
- 用vscode打开linux根目录,就是有vmlinux文件的目录,新建launch.json文件
内容为:
{ // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "name": "kernel debug", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/vmlinux", "cwd": "${workspaceFolder}", "MIMode": "gdb", "miDebuggerPath":"arm-linux-gnueabihf-gdb", "miDebuggerServerAddress": ":1234" } ] } |
program:调试的符号文件
miDebuggerPath:gdb工具
miDebuggerServerAddress:ip和端口参数
然后在代码里面打断点:
然后按F5 启动调试就可以了
VS中的调试图标:
按钮1:运行/继续 F5,真正的一步一步运行
按钮2:单步跳过(又叫逐过程) F10
,按语句单步执行。当有函数时,不会进入函数。
按钮3:单步调试(又叫逐语句)F11
:当有函数时,点击这个按钮,会进入这个函数内。
按钮4:单步跳出⇧F11:如果有循环,点击该按钮,会执行到循环外面的语句。
按钮5:重启⇧⌘F5:
按钮5:停止⇧F5:
4.3 printk调试
printk()这种方法很原始,但是一般可以解决工程中95%以上的问题。因此具体何时打印,以及打印什么东西,需要工程师逐步建立敏锐的嗅觉。加深对内核的认知,深入理解自己正在调试的模块,这才是快速解决问题的“王道”。工具只是一个辅助手段,无法代替工程师的思维。
后记:
Linux设备驱动知识很多,封面这个**马**的图片是一个书的封面,是驱动必看书,可以自己在网上找一个pdf书学习下,作为入门。配上韦东山的**qemu环境**和**左盟主**的驱动讲解,基本差不多了。
Talk is cheap
,show me the code
,后续会继续更新,
纯干货
分析,无广告,不打赏,欢迎
分享给好友
!