告别物理开发板用QEMU搭建嵌入式Linux开发环境Ubuntu 20.04 QEMU 5.1.0嵌入式开发领域长期依赖物理开发板进行调试和验证但硬件成本高、环境配置复杂等问题一直困扰着开发者和学习者。本文将带你用QEMU在Ubuntu 20.04上构建完整的ARM嵌入式Linux开发环境从零开始实现内核启动到根文件系统加载的全流程。1. 环境准备与QEMU安装在开始之前我们需要准备一个干净的Ubuntu 20.04系统。推荐使用物理机安装或VMware/VirtualBox虚拟机分配至少4GB内存和50GB磁盘空间。不同于传统虚拟机QEMU的特殊之处在于它能模拟多种CPU架构这正是我们需要的核心功能。安装基础编译工具链sudo apt update sudo apt install -y build-essential git flex bison libncurses-dev \ libssl-dev libelf-dev bc python3-dev libglib2.0-dev libpixman-1-devQEMU提供两种安装方式软件源安装和源码编译。虽然apt install qemu-system-arm更简单但为了获得最新特性和更好的兼容性我们选择从源码编译5.1.0版本wget https://download.qemu.org/qemu-5.1.0.tar.xz tar xvJf qemu-5.1.0.tar.xz cd qemu-5.1.0 ./configure --target-listarm-softmmu,aarch64-softmmu make -j$(nproc) sudo make install提示编译过程可能持续30分钟以上-j$(nproc)参数会使用所有CPU核心加速编译验证安装成功qemu-system-arm --version qemu-system-arm -machine help # 查看支持的开发板型号2. 交叉编译工具链配置嵌入式开发离不开交叉编译工具。我们选择Linaro提供的gcc-arm工具链它针对ARM架构进行了深度优化wget https://releases.linaro.org/components/toolchain/binaries/7.5-2019.12/arm-linux-gnueabihf/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz sudo tar -xJf gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz -C /opt将工具链加入PATH环境变量echo export PATH/opt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin:$PATH ~/.bashrc source ~/.bashrc测试交叉编译器arm-linux-gnueabihf-gcc --version3. 构建嵌入式Linux系统三大组件3.1 编译U-Boot引导程序U-Boot是嵌入式领域的标准引导加载程序我们先获取最新源码并编译git clone https://source.denx.de/u-boot/u-boot.git cd u-boot make ARCHarm CROSS_COMPILEarm-linux-gnueabihf- vexpress_ca9x4_defconfig make ARCHarm CROSS_COMPILEarm-linux-gnueabihf- -j$(nproc)编译产物u-boot就是我们需要的引导程序。如果遇到依赖错误常见解决方案缺少libssl-devsudo apt install libssl-devdtc版本过低sudo apt install device-tree-compiler3.2 使用Buildroot构建根文件系统传统手动构建根文件系统过程繁琐Buildroot可以自动化这一过程git clone git://git.buildroot.net/buildroot cd buildroot make qemu_arm_vexpress_defconfig make menuconfig关键配置项Target options → ARM (little endian)Toolchain → External toolchain (选择之前安装的Linaro工具链)System configuration → 设置root密码和自动登录Filesystem images → 勾选cpiogz格式开始构建make -j$(nproc)构建完成后输出文件位于output/images/目录其中rootfs.cpio.gz就是我们需要的最小根文件系统。3.3 编译Linux内核获取Linux稳定版内核源码并配置git clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git cd linux-stable make ARCHarm CROSS_COMPILEarm-linux-gnueabihf- vexpress_defconfig make ARCHarm CROSS_COMPILEarm-linux-gnueabihf- menuconfig确保以下选项已启用Device Drivers → Character devices → Serial drivers → ARM AMBA PL011 serial portKernel Features → Use the ARM EABI to compile the kernel编译内核和设备树make ARCHarm CROSS_COMPILEarm-linux-gnueabihf- zImage dtbs -j$(nproc)4. 整合与启动完整系统4.1 创建虚拟SD卡镜像dd if/dev/zero ofsd.img bs1M count64 mkfs.vfat sd.img挂载镜像并复制必要文件sudo mkdir -p /mnt/sd sudo mount -o loop sd.img /mnt/sd sudo cp linux-stable/arch/arm/boot/zImage /mnt/sd sudo cp linux-stable/arch/arm/boot/dts/vexpress-v2p-ca9.dtb /mnt/sd sudo umount /mnt/sd4.2 启动QEMU虚拟机使用以下命令启动完整系统qemu-system-arm -M vexpress-a9 -m 512M -kernel u-boot/u-boot \ -nographic -sd sd.img -append consolettyAMA0 root/dev/ram rdinit/sbin/init \ -initrd buildroot/output/images/rootfs.cpio.gz启动成功后在U-Boot命令行中手动加载内核fatload mmc 0:0 0x62008000 zImage fatload mmc 0:0 0x64008000 vexpress-v2p-ca9.dtb bootz 0x62008000 - 0x640080004.3 自动化启动脚本为避免每次手动输入命令可以创建启动脚本start_qemu.sh#!/bin/bash qemu-system-arm -M vexpress-a9 -m 512M -kernel u-boot/u-boot \ -nographic -sd sd.img -append consolettyAMA0 root/dev/ram rdinit/sbin/init \ -initrd buildroot/output/images/rootfs.cpio.gz \ -serial mon:stdio -net nic -net user,hostfwdtcp::2222-:22添加执行权限chmod x start_qemu.sh5. 高级功能扩展5.1 网络配置与SSH访问在Buildroot配置中启用网络工具和SSH服务make menuconfigTarget packages → Networking applications → opensshSystem configuration → Run a getty after boot → 勾选ttyAMA0重新编译后可通过端口2222访问QEMU虚拟机ssh -p 2222 rootlocalhost5.2 共享文件夹配置在主机上创建共享目录QEMU启动时添加参数-fsdev local,security_modelpassthrough,idfsdev0,path/path/to/share \ -device virtio-9p-pci,idfs0,fsdevfsdev0,mount_taghostshare在虚拟机中挂载共享目录mkdir /mnt/host mount -t 9p -o transvirtio hostshare /mnt/host5.3 调试内核与应用程序使用GDB进行内核调试qemu-system-arm -M vexpress-a9 -m 512M -kernel zImage \ -dtb vexpress-v2p-ca9.dtb -nographic -append consolettyAMA0 \ -S -s在另一个终端中arm-linux-gnueabihf-gdb vmlinux (gdb) target remote :1234 (gdb) b start_kernel (gdb) c
告别物理开发板:用QEMU搭建嵌入式Linux开发环境(Ubuntu 20.04 + QEMU 5.1.0)
告别物理开发板用QEMU搭建嵌入式Linux开发环境Ubuntu 20.04 QEMU 5.1.0嵌入式开发领域长期依赖物理开发板进行调试和验证但硬件成本高、环境配置复杂等问题一直困扰着开发者和学习者。本文将带你用QEMU在Ubuntu 20.04上构建完整的ARM嵌入式Linux开发环境从零开始实现内核启动到根文件系统加载的全流程。1. 环境准备与QEMU安装在开始之前我们需要准备一个干净的Ubuntu 20.04系统。推荐使用物理机安装或VMware/VirtualBox虚拟机分配至少4GB内存和50GB磁盘空间。不同于传统虚拟机QEMU的特殊之处在于它能模拟多种CPU架构这正是我们需要的核心功能。安装基础编译工具链sudo apt update sudo apt install -y build-essential git flex bison libncurses-dev \ libssl-dev libelf-dev bc python3-dev libglib2.0-dev libpixman-1-devQEMU提供两种安装方式软件源安装和源码编译。虽然apt install qemu-system-arm更简单但为了获得最新特性和更好的兼容性我们选择从源码编译5.1.0版本wget https://download.qemu.org/qemu-5.1.0.tar.xz tar xvJf qemu-5.1.0.tar.xz cd qemu-5.1.0 ./configure --target-listarm-softmmu,aarch64-softmmu make -j$(nproc) sudo make install提示编译过程可能持续30分钟以上-j$(nproc)参数会使用所有CPU核心加速编译验证安装成功qemu-system-arm --version qemu-system-arm -machine help # 查看支持的开发板型号2. 交叉编译工具链配置嵌入式开发离不开交叉编译工具。我们选择Linaro提供的gcc-arm工具链它针对ARM架构进行了深度优化wget https://releases.linaro.org/components/toolchain/binaries/7.5-2019.12/arm-linux-gnueabihf/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz sudo tar -xJf gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz -C /opt将工具链加入PATH环境变量echo export PATH/opt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin:$PATH ~/.bashrc source ~/.bashrc测试交叉编译器arm-linux-gnueabihf-gcc --version3. 构建嵌入式Linux系统三大组件3.1 编译U-Boot引导程序U-Boot是嵌入式领域的标准引导加载程序我们先获取最新源码并编译git clone https://source.denx.de/u-boot/u-boot.git cd u-boot make ARCHarm CROSS_COMPILEarm-linux-gnueabihf- vexpress_ca9x4_defconfig make ARCHarm CROSS_COMPILEarm-linux-gnueabihf- -j$(nproc)编译产物u-boot就是我们需要的引导程序。如果遇到依赖错误常见解决方案缺少libssl-devsudo apt install libssl-devdtc版本过低sudo apt install device-tree-compiler3.2 使用Buildroot构建根文件系统传统手动构建根文件系统过程繁琐Buildroot可以自动化这一过程git clone git://git.buildroot.net/buildroot cd buildroot make qemu_arm_vexpress_defconfig make menuconfig关键配置项Target options → ARM (little endian)Toolchain → External toolchain (选择之前安装的Linaro工具链)System configuration → 设置root密码和自动登录Filesystem images → 勾选cpiogz格式开始构建make -j$(nproc)构建完成后输出文件位于output/images/目录其中rootfs.cpio.gz就是我们需要的最小根文件系统。3.3 编译Linux内核获取Linux稳定版内核源码并配置git clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git cd linux-stable make ARCHarm CROSS_COMPILEarm-linux-gnueabihf- vexpress_defconfig make ARCHarm CROSS_COMPILEarm-linux-gnueabihf- menuconfig确保以下选项已启用Device Drivers → Character devices → Serial drivers → ARM AMBA PL011 serial portKernel Features → Use the ARM EABI to compile the kernel编译内核和设备树make ARCHarm CROSS_COMPILEarm-linux-gnueabihf- zImage dtbs -j$(nproc)4. 整合与启动完整系统4.1 创建虚拟SD卡镜像dd if/dev/zero ofsd.img bs1M count64 mkfs.vfat sd.img挂载镜像并复制必要文件sudo mkdir -p /mnt/sd sudo mount -o loop sd.img /mnt/sd sudo cp linux-stable/arch/arm/boot/zImage /mnt/sd sudo cp linux-stable/arch/arm/boot/dts/vexpress-v2p-ca9.dtb /mnt/sd sudo umount /mnt/sd4.2 启动QEMU虚拟机使用以下命令启动完整系统qemu-system-arm -M vexpress-a9 -m 512M -kernel u-boot/u-boot \ -nographic -sd sd.img -append consolettyAMA0 root/dev/ram rdinit/sbin/init \ -initrd buildroot/output/images/rootfs.cpio.gz启动成功后在U-Boot命令行中手动加载内核fatload mmc 0:0 0x62008000 zImage fatload mmc 0:0 0x64008000 vexpress-v2p-ca9.dtb bootz 0x62008000 - 0x640080004.3 自动化启动脚本为避免每次手动输入命令可以创建启动脚本start_qemu.sh#!/bin/bash qemu-system-arm -M vexpress-a9 -m 512M -kernel u-boot/u-boot \ -nographic -sd sd.img -append consolettyAMA0 root/dev/ram rdinit/sbin/init \ -initrd buildroot/output/images/rootfs.cpio.gz \ -serial mon:stdio -net nic -net user,hostfwdtcp::2222-:22添加执行权限chmod x start_qemu.sh5. 高级功能扩展5.1 网络配置与SSH访问在Buildroot配置中启用网络工具和SSH服务make menuconfigTarget packages → Networking applications → opensshSystem configuration → Run a getty after boot → 勾选ttyAMA0重新编译后可通过端口2222访问QEMU虚拟机ssh -p 2222 rootlocalhost5.2 共享文件夹配置在主机上创建共享目录QEMU启动时添加参数-fsdev local,security_modelpassthrough,idfsdev0,path/path/to/share \ -device virtio-9p-pci,idfs0,fsdevfsdev0,mount_taghostshare在虚拟机中挂载共享目录mkdir /mnt/host mount -t 9p -o transvirtio hostshare /mnt/host5.3 调试内核与应用程序使用GDB进行内核调试qemu-system-arm -M vexpress-a9 -m 512M -kernel zImage \ -dtb vexpress-v2p-ca9.dtb -nographic -append consolettyAMA0 \ -S -s在另一个终端中arm-linux-gnueabihf-gdb vmlinux (gdb) target remote :1234 (gdb) b start_kernel (gdb) c