使用QEMU搭建U-Boot+LinuxKernel+busybox+NFS嵌入式开发环境

03-06 1074阅读

目录

  • 0.课程大纲
  • 1.为什么要使用QEMU学习嵌入式
    • QEMU简介
    • 使用QEMU可以做哪些事情?
    • 当前嵌入式行业现状
    • 如何适应这种变化
    • 使用QEMU学习嵌入式有哪些好处?
    • 驱动开发技能
    • 为什么要学习Linux
    • 2.搭建嵌入式开发基本环境
      • 2.1.安装u-boot-tools
      • 2.2.安装交叉编译工具
        • 什么是ABI和EABI
        • 3.QEMU安装及仿真开发板介绍
          • 自动安装
          • 手动编译安装
          • QEMU使用
          • ARM express 开发板简介
            • Vexpress系列开发板
            • Vexpress系列支持的CPU
            • 嵌入式最小系统
            • QEMU运行系统
            • 4.编译Linux内核和dtb文件
              • 4.1.下载Linux内核
              • 4.2.修改Makefile
              • 4.3.编译内核,模块,dtb文件
              • 5.使用Busybox制作根文件系统
                • 5.1.什么是根文件系统?
                  • 5.1.1.文件系统
                  • 5.1.2.为什么要使用文件系统
                  • 5.1.3.根文件系统
                  • 5.2.使用busybox制作根文件系统
                    • 5.2.1.什么是busybox
                    • 5.2.2.编译安装
                    • 5.2.3.制作根文件系统
                    • 5.2.4.制作SD卡文件系统镜像
                    • 6.使用u-boot引导启动Linux内核
                      • 6.1.嵌入式启动概述
                        • 6.1.1.嵌入式bootloader
                        • 6.1.2.常见的启动方式
                        • 6.2.u-boot编译
                        • 6.3.QEMU网络功能设置
                          • 6.3.1.配置QEMU与主机的网络连接
                          • 6.3.2.配置
                          • 6.4.内核配置编译
                            • 6.4.1.使用u-boot引导内核镜像
                            • 6.5.主机TFTP工具安装
                            • 6.6.启动测试
                            • 6.7.自动化引导
                            • 参考资料

                              0.课程大纲

                              1. 为什么要使用QEMU学习嵌入式
                              2. 搭建嵌入式开发基本环境
                              3. QEMU安装及A9开发板配置介绍
                              4. 编译,运行Linux内核
                              5. 使用Busybox制作根文件系统
                              6. 使用u-boot引导启动Linux内核
                              7. 挂载NFS文件系统
                              8. 在虚拟开发板上开发应用程序,驱动

                              1.为什么要使用QEMU学习嵌入式

                              QEMU简介

                              • QEMU是一个模拟器,可以模拟CPU,ARM,X86,MIPS等架构
                              • 可以仿真的ARM处理器:ARM926E,ARM1136,Cortex-A8/A9
                              • 模拟真实的开发板,外设:串口,LCD,网卡,USB,SD卡…

                                使用QEMU可以做哪些事情?

                                • 研究内核虚拟化
                                • 模拟CPU,对于芯片公司,流片之前在QEMU上做验证,仿真,软硬件协同设计,开发BSP和驱动
                                • 模拟开发板,在模拟平台上进行系统软件开发,驱动开发
                                • 学生,工程师可以利用qemu-system-arm学习嵌入式开发,研究Bootloader,Linux内核,驱动开发,应用开发等.

                                  当前嵌入式行业现状

                                  • CPU厂家越来越多,各种开发板层出不穷
                                  • 物联网芯片,AI芯片…
                                  • SOC越来越集成化,软硬件分工越来越明显

                                    如何适应这种变化

                                    • 分工
                                    • 精专
                                    • 嵌入式80%的知识系统和技能,都可以脱离"开发板",在QEMU仿真平台上学习和练习

                                      使用QEMU学习嵌入式有哪些好处?

                                      • 节省学习成本
                                      • 跳过开发板,硬件的各种"坑",缩短学习曲线
                                      • 重构嵌入式知识体系和技能,跟硬件无关的放到QEMU上学习
                                      • 跟开发板相关的驱动,BSP针对具体开发板深入突破
                                      • 适应不同CPU,开发板的技术要求

                                        驱动开发技能

                                        • 基本的硬件知识
                                        • Linux内核,系统架构的理解
                                        • 芯片手册,开发板

                                          为什么要学习Linux

                                          • 开源,免费

                                          • 持续更新,强大的BSP支持

                                          • Android,YunOS,Tizen,ubuntu等操作系统的内核

                                          • 应用领域广:嵌入式,服务器,桌面PC,云…

                                          • 示例

                                            2.搭建嵌入式开发基本环境

                                            2.1.安装u-boot-tools

                                            • 用来生成适应U-boot引导的镜像文件格式
                                              sudo apt install -y u-boot-tools
                                              

                                              2.2.安装交叉编译工具

                                              什么是ABI和EABI

                                              • ABI:二进制应用程序接口(Application Binary Interface(ABI) for the ARM Architecture),在计算机中,应用二进制接口描述了应用程序(或者其他类型)和操作系统之间或其他应用程序的低级接口,涵盖了数据类型的大小,布局和对齐,调用约定.
                                              • EABI:嵌入式ABI 嵌入式应用二进制接口指定了文件格式,数据类型,寄存器使用,堆积组织优化和在一个嵌入式软件中的参数的标准约定.
                                              • Arm-none-gnueabi-linux比arm-linux-gcc要好,在可一致性,兼容性上面
                                              • 早期u-boot和Linux编译可能使用的都不是一个arm-linux-gcc版本
                                                sudo apt install -y gcc-arm-linux-gnueabi
                                                sudo apt install -y g++-arm-linux-gnueabi
                                                
                                                #区别
                                                gcc-arm-linux-gnueabi    
                                                gcc-arm-linux-gnueabihf
                                                gcc-arm-none-eabi
                                                
                                                arm-linux-gnueabi-gcc -v
                                                arm-linux-gnueabi-gcc -o hello main.c
                                                readelf -h hello
                                                

                                                3.QEMU安装及仿真开发板介绍

                                                自动安装

                                                # For full system emulation
                                                sudo apt install qemu-system
                                                #For emulating Linux binaries
                                                sudo apt install qemu-user-static
                                                

                                                手动编译安装

                                                https://www.qemu.org/
                                                https://wiki.qemu.org/Hosts/Linux
                                                git clone https://gitlab.com/qemu-project/qemu.git
                                                git checkout remotes/origin/stable-8.2 -b stable-8.2
                                                sudo apt-get install git libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev ninja-build
                                                sudo apt-get install git-email
                                                sudo apt-get install libaio-dev libbluetooth-dev libcapstone-dev libbrlapi-dev libbz2-dev
                                                sudo apt-get install libcap-ng-dev libcurl4-gnutls-dev libgtk-3-dev
                                                sudo apt-get install libibverbs-dev libjpeg8-dev libncurses5-dev libnuma-dev
                                                sudo apt-get install librbd-dev librdmacm-dev
                                                sudo apt-get install libsasl2-dev libsdl2-dev libseccomp-dev libsnappy-dev libssh-dev
                                                sudo apt-get install libvde-dev libvdeplug-dev libvte-2.91-dev libxen-dev liblzo2-dev
                                                sudo apt-get install valgrind xfslibs-dev 
                                                sudo apt-get install libnfs-dev libiscsi-dev
                                                ./configure --target-list=arm-softmmu --audio-drv-list=
                                                make 
                                                sudo make install
                                                

                                                QEMU使用

                                                qemu-system-arm --version
                                                #查看支持的开发板
                                                qemu-system-arm -M help
                                                #vexpress-a9
                                                

                                                ARM express 开发板简介

                                                Vexpress系列开发板

                                                • 全称versatile express family, ARM公司自己推出的开发板
                                                • 主要用于SOC厂商设计,验证和测试自己的SOC芯片
                                                • 采用主板+子板设计,主板提供各种外围接口,子板提供CPU运算

                                                  Vexpress系列支持的CPU

                                                  • Cortex-A9: 处理器子板 Express A9x4 (V2P-CA9x4)
                                                  • Cortex-A5: 处理器子板 Express A5x2 (V2P-CA5x2s)
                                                  • Cortex-R5:
                                                  • Cortex-A15: 处理器子板 Express A15x2 (V2P-CA15x2)

                                                    使用QEMU搭建U-Boot+LinuxKernel+busybox+NFS嵌入式开发环境

                                                    使用QEMU搭建U-Boot+LinuxKernel+busybox+NFS嵌入式开发环境

                                                    使用QEMU搭建U-Boot+LinuxKernel+busybox+NFS嵌入式开发环境

                                                    使用QEMU搭建U-Boot+LinuxKernel+busybox+NFS嵌入式开发环境

                                                    使用QEMU搭建U-Boot+LinuxKernel+busybox+NFS嵌入式开发环境

                                                    DDR
                                                    外围
                                                    DUI0448I_v2p_ca9_trm.pdf
                                                    

                                                    嵌入式最小系统

                                                    CPU+DDR/SDRAM
                                                    FLASH/SD
                                                    串口+LCD
                                                    

                                                    QEMU运行系统

                                                    #-M vexpress-a : 指定具体开发板
                                                    #-m 512M : 指定内存大小
                                                    #-kernel ./zImage : 指定内核
                                                    #-dtb ./vexpress-v2p-ca9.dtb : 指定设备树
                                                    #-nographic : 不使用图像界面
                                                    #-append "console=ttyAMA0" : 指定串口控制台
                                                    qemu-system-arm -M vexpress-a9 -m 512M -kernel ./zImage -dtb ./vexpress-v2p-ca9.dtb -nographic -append "console=ttyAMA0"
                                                    

                                                    4.编译Linux内核和dtb文件

                                                    4.1.下载Linux内核

                                                    https://www.kernel.org/
                                                    longterm
                                                    

                                                    4.2.修改Makefile

                                                    vim Makefile
                                                    ARCH        ?= arm
                                                    CROSS_COMPILE ?=arm-linux-gnueabi-
                                                    

                                                    4.3.编译内核,模块,dtb文件

                                                    make vexpress_defconfig
                                                    make zImage
                                                    make modules
                                                    make dtbs
                                                    

                                                    5.使用Busybox制作根文件系统

                                                    5.1.什么是根文件系统?

                                                    5.1.1.文件系统

                                                    对存储设备上的数据进行组织的机制

                                                    5.1.2.为什么要使用文件系统

                                                    • Linux的哲学: 一切皆文件
                                                    • 用户与操作系统进行交互的主要工具: 文件系统调用
                                                    • 用户和底层存储的接口

                                                      5.1.3.根文件系统

                                                      • Linux内核启动后第一个挂载的文件系统
                                                      • 主要由基本的shell命令,各种库,字符设备,配置脚本组成
                                                      • 提供了根目录/
                                                      • RFS可以放在: nor/nand flash, SD卡, 磁盘, 网络空间上

                                                        5.2.使用busybox制作根文件系统

                                                        5.2.1.什么是busybox

                                                        • 一个集成100多个Linux常用命令和工具的软件
                                                        • 一个适合制作嵌入式文件系统的软件工具

                                                          5.2.2.编译安装

                                                          #1.下载源代码
                                                          https://busybox.net/
                                                          #2.修改Makefile
                                                          ARCH ?= arm
                                                          CROSS_COMPILE ?=arm-linux-gnueabi-
                                                          #3.配置
                                                          make defconfig
                                                          make menuconfig
                                                           Settings  --->  [*] Build static binary (no shared libs)
                                                          #4.编译
                                                          make -j2
                                                          #5.安装
                                                          make install
                                                          #安装生成目录"_install"
                                                          

                                                          5.2.3.制作根文件系统

                                                          mkdir rootfs
                                                          cd rootfs/
                                                          mkdir lib
                                                          cp -avf busybox-1.36.1/_install/* rootfs/
                                                          cp -avf /usr/arm-linux-gnueabi/lib/* rootfs/lib/
                                                          mkdir dev
                                                          cd dev/
                                                          #mknod: 创建块或字符设备节点
                                                          #-m 666: 权限读写
                                                          #tty1: 节点名称
                                                          #c: 字符设备
                                                          #4: 主设备号
                                                          #1: 次设备号
                                                          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
                                                          

                                                          5.2.4.制作SD卡文件系统镜像

                                                          #1.生成镜像
                                                          #bs: 缓冲区块的大小
                                                          #count: 块的个数
                                                          dd if=/dev/zero of=rootfs.ext3 bs=1M count=32
                                                          #2.格式化为ext3文件系统
                                                          mkfs.ext3 rootfs.ext3
                                                          #3.将各种文件copy到文件系统镜像中
                                                          sudo mount -t ext3 rootfs.ext3 /mnt -o loop
                                                          sudo cp -avf rootfs/* /mnt
                                                          sudo umount /mnt
                                                          

                                                          6.使用u-boot引导启动Linux内核

                                                          6.1.嵌入式启动概述

                                                          6.1.1.嵌入式bootloader

                                                          • 功能类似于PC的BIOS,硬件检测是否正常
                                                          • 加载操作系统镜像到RAM
                                                          • 设置不同的启动方式

                                                            6.1.2.常见的启动方式

                                                            • NOR/NAND FLASH启动
                                                            • 从SD卡启动
                                                            • Bootloader从网络加载Linux内核启动

                                                              6.2.u-boot编译

                                                              #1.下载u-boot
                                                              git clone https://gitee.com/naonano/u-boot.git
                                                              git checkout --track origin/u-boot-2023.07.y
                                                              #2.修改 Makefile
                                                              ifeq ($(HOSTARCH),$(ARCH))
                                                              CROSS_COMPILE ?=
                                                              endif
                                                              CROSS_COMPILE ?=arm-linux-gnueabi-
                                                              #3.修改 config.mk
                                                              #ARCH := $(CONFIG_SYS_ARCH:"%"=%)
                                                              ARCH := arm
                                                              #4.配置
                                                              make vexpress_ca9x4_defconfig
                                                              #5.编译
                                                              make -j2
                                                              #6.运行u-boot
                                                              qemu-system-arm -M vexpress-a9 -m 512M -nographic -kernel ../test/u-boot/u-boot
                                                              

                                                              6.3.QEMU网络功能设置

                                                              6.3.1.配置QEMU与主机的网络连接

                                                              • 采用桥接(bridge)的网络连接与Host通信
                                                              • 需要主机内核tun/tap模块支持

                                                                6.3.2.配置

                                                                参考:ubuntu 22.04 设置网桥 - netplan

                                                                #1.主机安装工具包
                                                                sudo apt install -y uml-utilities bridge-utils
                                                                #2.创建tun设备文件
                                                                ls -al /dev/net/tun
                                                                #3.编辑文件
                                                                sudo touch /etc/netplan/br0.yaml
                                                                #使用ipv4 dhcp
                                                                

                                                                ipv4 dhcp:

                                                                network:
                                                                  version: 2
                                                                  ethernets:
                                                                    enp0s8: #替换为实际网卡
                                                                      dhcp4: false
                                                                      dhcp6: false
                                                                  bridges:
                                                                    br0:
                                                                      interfaces: [enp0s8] #替换为实际网卡
                                                                      dhcp4: true
                                                                      parameters:
                                                                        stp: false
                                                                      dhcp6: false
                                                                

                                                                ipv4 静态分配:

                                                                network:
                                                                  version: 2
                                                                  ethernets:
                                                                    enp0s8:#替换为实际网卡
                                                                      dhcp4: false
                                                                      dhcp6: false
                                                                  bridges:
                                                                    br0:
                                                                      interfaces: [enp0s8] #替换为实际网卡
                                                                      dhcp4: false
                                                                      addresses: [192.168.1.250/24]
                                                                      routes:
                                                                        - to: default
                                                                          via: 192.168.1.1
                                                                      nameservers:
                                                                        addresses: [114.114.114.114]
                                                                      parameters:
                                                                        stp: false
                                                                      dhcp6: true
                                                                
                                                                sudo netplan apply
                                                                

                                                                ifconfig

                                                                br0: flags=4099  mtu 1500
                                                                        inet 192.168.1.25  netmask 255.255.255.0  broadcast 192.168.1.255
                                                                        inet6 fe80::3027:2dff:fe41:8595  prefixlen 64  scopeid 0x20
                                                                        ether 32:27:2d:41:85:95  txqueuelen 1000  (Ethernet)
                                                                        RX packets 55  bytes 9272 (9.2 KB)
                                                                        RX errors 0  dropped 0  overruns 0  frame 0
                                                                        TX packets 89  bytes 12062 (12.0 KB)
                                                                        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
                                                                enp0s8: flags=4163  mtu 1500
                                                                        inet 192.168.1.3  netmask 255.255.255.0  broadcast 192.168.1.255
                                                                        inet6 fe80::c8ff:ec6f:253e:ad4e  prefixlen 64  scopeid 0x20
                                                                        inet6 2409:8a1e:d52:a9b0:39df:8d80:83d3:9e  prefixlen 64  scopeid 0x0
                                                                        inet6 2409:8a1e:d52:a9b0:3292:9a45:5481:28ad  prefixlen 64  scopeid 0x0
                                                                        ether 08:00:27:05:ef:4f  txqueuelen 1000  (Ethernet)
                                                                        RX packets 962  bytes 156528 (156.5 KB)
                                                                        RX errors 0  dropped 0  overruns 0  frame 0
                                                                        TX packets 836  bytes 88212 (88.2 KB)
                                                                        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
                                                                lo: flags=73  mtu 65536
                                                                        inet 127.0.0.1  netmask 255.0.0.0
                                                                        inet6 ::1  prefixlen 128  scopeid 0x10
                                                                        loop  txqueuelen 1000  (Local Loopback)
                                                                        RX packets 318  bytes 29095 (29.0 KB)
                                                                        RX errors 0  dropped 0  overruns 0  frame 0
                                                                        TX packets 318  bytes 29095 (29.0 KB)
                                                                        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
                                                                

                                                                6.4.内核配置编译

                                                                6.4.1.使用u-boot引导内核镜像

                                                                #需要将内核编译为uImage格式
                                                                #需要指定uImage的加载地址
                                                                #编译时指定: 
                                                                make LOADADDR=0x60003000 uImage -j2
                                                                

                                                                6.5.主机TFTP工具安装

                                                                #1.安装
                                                                sudo apt-get install -y tftpd-hpa tftp-hpa xinetd
                                                                #2.配置ftp服务器工作目录为"/home/tftp"
                                                                sudo vim /etc/default/tftpd-hpa
                                                                	TFTP_USERNAME="tftp"
                                                                	TFTP_DIRECTORY="/home/tftp"
                                                                	TFTP_ADDRESS=":69"
                                                                	TFTP_OPTIONS="-l -c -s"
                                                                #3.建立目录
                                                                sudo mkdir -p /home/tftp
                                                                sudo chown lei:lei /home/tftp
                                                                chmod 777 -R /home/tftp
                                                                #4.启动服务
                                                                sudo service tftpd-hpa restart
                                                                #5.测试
                                                                #5.1测试下载
                                                                cd /home/tftp/
                                                                touch readme.txt
                                                                #在readme.txt中输入一些内容
                                                                #运行开发板,进入控制台
                                                                tftp -g -r readme.txt 192.168.10.107
                                                                #可以看出在开发板当前目录下下载了readme.txt
                                                                #5.2测试上传
                                                                #在开发板上,进入控制台运行命令
                                                                tftp -p -l uvc_app 192.168.10.107
                                                                #uvc_app为开发板当前目录下的文件
                                                                #在ubuntu上可以看到开发板上传上来的文件uvc_app
                                                                

                                                                6.6.启动测试

                                                                #1.复制u-boot镜像到tftp服务器目录下
                                                                cp /home/qemu/test/u-boot/u-boot /home/tftp/
                                                                #2.复制uImage镜像到tftp服务器目录下
                                                                cp /home/qemu/test/linux-6.6.18/arch/arm/boot/uImage /home/tftp/
                                                                #3.复制设备树二进制编译结果到tftp服务器目录下
                                                                cp /home/qemu/test/linux-6.6.18/arch/arm/boot/dts/arm/vexpress-v2p-ca9.dtb /home/tftp/
                                                                #4.uboot引导kernel启动
                                                                qemu-system-arm \
                                                                    -M vexpress-a9 \
                                                                    -m 512M \
                                                                    -nographic \
                                                                    -kernel /home/tftp/u-boot \
                                                                    -net nic,vlan=0 -net tap,vlan=0,ifname=tap0 \
                                                                    -sd /home/qemu/test/rootfs.ext3
                                                                

                                                                6.7.自动化引导

                                                                u-boot/include/configs/vexpress_common.h

                                                                #define CONFIG_BOOTCOMMAND \
                                                                	"tftp 0x60003000 uImage; tftp 0x60500000 vexpress-v2p-ca9.dtb; \
                                                                	setenv bootargs 'root=/dev/mmcblk0 console=ttyAMA0'; \
                                                                	bootm 0x60003000 - 0x60500000; "
                                                                #define CONFIG_IPADDR 192.168.244.128
                                                                #define CONFIG_NETMASK 255.255.255.0
                                                                #define CONFIG_SERVERIP 192.168.244.129
                                                                

                                                                参考资料

                                                                B站

                                                                QEMU系列文章: https://blog.csdn.net/phmatthaus/category_12072874.html

VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]