新闻详情

新闻详情

首页 / 资讯中心 / 详情

实验一:Hello World 三阶段编译运行比较与 U-Boot 运行环境验证

发布时间:2026/9/27 3:00:19来源:尧图网络
实验一:Hello World 三阶段编译运行比较与 U-Boot 运行环境验证
一、实验目的与教学设计本实验以已完成的 Ubuntu 18.04、Arm GNU Toolchain 12.3、Code::Blocks 16.01、U-Boot 2026.07 和 Windows QEMU 11.1.0 环境为基线。实验围绕同一个 Hello World 程序设计三个连续阶段先让学生观察成功—失败—仍失败的现象再理解 CPU 指令集匹配和程序运行环境匹配是两个不同层次。阶段 1用 Ubuntu 本机 gcc 生成 x86-64 Linux 程序并在 HOST 上正常运行。阶段 2用 ARM GNU/Linux 交叉编译器生成 ARM Linux 程序在 x86 HOST 上运行失败。阶段 3把这个 ARM Linux ELF 下载到运行于 Cortex-A9 的 U-Boot使用 bootelf 尝试启动观察CPU 已经匹配但仍然不能运行的现象。最终理解一个程序能否运行至少要同时满足两件事目标 CPU 能执行它的机器指令目标系统还必须提供该程序所依赖的运行环境。ARM Linux 用户程序不仅需要 ARM CPU还需要 Linux 内核、动态加载器、共享库和系统调用环境。教学原则把失败设计成实验现象。阶段 2 的失败说明 CPU 架构不匹配阶段 3 的失败说明即使 CPU 架构已经匹配运行环境仍可能不匹配。这两个失败正是本实验最重要的观察结果。二、实验平台与共享目录角色平台主要任务A 窗口 / HOSTUbuntu 18.04 LTSVMwareCode::Blocks 编辑、gcc/ARM GCC 编译、U-Boot 源码构建B 窗口 / TARGETWindows QEMU vexpress-a9运行 U-Boot、TFTP 下载、使用 bootelf 验证 ARM Linux ELF 的运行条件交换区Windows E:\EmbeddedLinuxLab ↔ Ubuntu /mnt/EmbeddedLinuxLabimages、tftp、scripts、logs2.1 Ubuntu 本地开发区与 Windows 交换区~/EmbeddedLinuxLab ├── src # U-Boot 等源码 ├── build # 编译中间结果 └── lab01 # 本实验工作目录 /mnt/EmbeddedLinuxLab ├── images # Windows QEMU 使用的镜像 ├── tftp # QEMU 内置 TFTP 根目录 ├── scripts └── logs目录原则U-Boot、Linux Kernel、Buildroot 和普通工程都在~/EmbeddedLinuxLab中编译/mnt/EmbeddedLinuxLab仅作 HOST ↔ Windows/QEMU 的交换入口。不要直接在 VMware 共享目录中编译大型源码树。2.2 长期自动挂载机制已验证方案VMware 中把 Windows 的E:\EmbeddedLinuxLab设为 Shared FolderShare name 固定为EmbeddedLinuxLab。Ubuntu 中安装sudoaptinstall-yopen-vm-tools open-vm-tools-desktop fusesudomkdir-p/mnt/EmbeddedLinuxLab先确认共享名vmware-hgfsclient应看到EmbeddedLinuxLab。挂载点在未挂载时应为空。临时测试cd~sudovmhgfs-fuse .host:/EmbeddedLinuxLab /mnt/EmbeddedLinuxLab-oallow_otherls/mnt/EmbeddedLinuxLab长期使用时采用 systemd 服务实现开机自动挂载。新建服务文件sudonano/etc/systemd/system/embeddedlinuxlab-mount.service[Unit] DescriptionMount VMware EmbeddedLinuxLab Shared Folder Aftervmtoolsd.service Wantsvmtoolsd.service [Service] Typeoneshot ExecStartPre-/bin/fusermount -u /mnt/EmbeddedLinuxLab ExecStartPre/bin/mkdir -p /mnt/EmbeddedLinuxLab ExecStart/usr/bin/vmhgfs-fuse .host:/EmbeddedLinuxLab /mnt/EmbeddedLinuxLab -o allow_other ExecStop/bin/fusermount -u /mnt/EmbeddedLinuxLab RemainAfterExityes [Install] WantedBymulti-user.target启用并验证sudosystemctl daemon-reloadsudosystemctl reset-failed embeddedlinuxlab-mount.servicesudosystemctl start embeddedlinuxlab-mount.service systemctl status embeddedlinuxlab-mount.servicesudosystemctlenableembeddedlinuxlab-mount.service成功判据status 中最终应为Active: active (exited)ExecStart 为status0/SUCCESS如果 ExecStartPre 的 fusermount 显示status1/FAILURE但最终服务仍 active (exited)只是表示启动前没有旧挂载可卸载可忽略。临时停止/恢复/永久取消cd~sudosystemctl stop embeddedlinuxlab-mount.service# 临时解除sudosystemctl start embeddedlinuxlab-mount.service# 恢复sudosystemctl disable embeddedlinuxlab-mount.service# 取消开机自动挂载三、阶段 1标准 Hello World 与 x86 本机编译在 Code::Blocks 新建 C Console Application工程目录建议/home/easyboard/EmbeddedLinuxLab/lab01/HelloWorldmain.c#includestdio.hintmain(void){printf(Hello World!\n);return0;}选择 GNU GCC CompilerBuild → Rebuild。等价的最小命令是gcc hello.c-ohello_x86把 Code::Blocks 结果保存为独立文件并验证cd~/EmbeddedLinuxLab/lab01cp~/EmbeddedLinuxLab/lab01/HelloWorld/bin/Debug/HelloWorld ./hello_x86filehello_x86 ./hello_x86预期输出Hello World!观察此时编译器、CPU 架构、操作系统运行环境三者都匹配x86-64 gcc → x86-64 ELF → x86-64 Ubuntu Linux因此程序可以直接运行。四、阶段 2ARM Linux 交叉编译与第一次失败保持 main.c 完全不变。在 Code::Blocks 的 Project → Build options 中把 Selected compiler 切换为已经配置好的ARM GCC 12.3 - Cortex-A9Clean / Rebuild 后Build log 中应看到arm-none-linux-gnueabihf-gcc等价的最小命令arm-none-linux-gnueabihf-gcc hello.c-ohello_arm_linux保存并比较cp~/EmbeddedLinuxLab/lab01/HelloWorld/bin/Debug/HelloWorld\~/EmbeddedLinuxLab/lab01/hello_arm_linuxcd~/EmbeddedLinuxLab/lab01filehello_x86filehello_arm_linux典型结果hello_x86: ELF 64-bit LSB ... x86-64 ... hello_arm_linux: ELF 32-bit LSB executable, ARM, EABI5 ... interpreter /lib/ld-linux-armhf.so.3 ...术语在本实验中的含义ELFExecutable and Linkable Format可执行与可链接文件格式它是包装格式其中可装 x86、ARM 等不同架构的机器码。32-bit / 64-bitELF 类别以及目标体系结构的位宽特征。本实验 Cortex-A9 为 ARMv7-A 32 位。LSBLeast Significant Byte first即小端字节序Little Endian。EABI5ARM Embedded Application Binary Interface第 5 版 ABI规定函数调用、寄存器/栈使用等二进制接口规则。dynamically linked运行时还需要目标系统的动态加载器和共享库。interpreter /lib/ld-linux-armhf.so.3明确表明这是 ARM Linux 用户态程序启动时需要 ARM Linux 动态加载器。为了避免中文环境中 readelf 字段名被本地化统一使用LC_ALLC readelf-hhello_x86|grepMachineLC_ALLC arm-none-linux-gnueabihf-readelf-hhello_arm_linux|grepMachine预期Machine: Advanced Micro Devices X86-64 Machine: ARM现在故意在 x86 HOST 上运行 ARM 程序./hello_arm_linux预期现象常见提示为Exec format error。这不是编译失败而是 CPU 架构不匹配HOST 的 x86-64 CPU 不能直接执行 ARM 指令。另一个常见现象file hello_x86可能显示 “ELF 64-bit LSB shared object, x86-64”。Ubuntu 18.04 的 GCC 默认 PIE 机制会产生这种描述只要./hello_x86能运行就不是错误。五、阶段 3把 ARM Linux ELF 强行交给 U-Boot这一阶段是一个有意设计的负面实验CPU 已经是 ARM Cortex-A9我们再把 hello_arm_linux 下载到 U-Boot使用 U-Boot 正确的 ELF 启动命令 bootelf 尝试启动。目的不是让它成功而是验证ARM 指令匹配仍然不等于运行环境匹配。为什么不用 gogo 只是从某个地址直接跳转执行hello_arm_linux 是完整 ELF 文件文件开头是 ELF Header不是程序入口处的 ARM 指令。U-Boot 的 bootelf 会解析 ELF 的 program header/section再尝试装载和启动因此更适合这个观察实验。5.1 部署 hello_arm_linux 到 QEMU TFTP 根目录cp~/EmbeddedLinuxLab/lab01/hello_arm_linux\/mnt/EmbeddedLinuxLab/tftp/ls-lh/mnt/EmbeddedLinuxLab/tftp/hello_arm_linux5.2 Windows CMD 启动 QEMU本实验保持 QEMU 内存为 512 MB 即可。阶段 3 只需要把 ARM Linux ELF 下载到内存并由 U-Boot 的 bootelf 尝试启动。C:\Program Files\qemu\qemu-system-arm.exe ^ -machine vexpress-a9 ^ -cpu cortex-a9 ^ -m 512M ^ -nographic ^ -no-reboot ^ -kernel E:\EmbeddedLinuxLab\images\u-boot ^ -nic user,tftpE:\EmbeddedLinuxLab\tftp启动时按任意键停止 autoboot然后检查 bdinfo help bootelf printenv loadaddr说明U-Boot v2026.07 中 CMD_ELF 默认启用正常应存在 bootelf。若help bootelf找不到命令应先检查.config中CONFIG_CMD_ELFy。5.3 TFTP 下载并尝试 bootelf setenv autoload no dhcp setenv serverip 10.0.2.2 tftpboot ${loadaddr} hello_arm_linux bootelf -p ${loadaddr}预期结果TFTP 下载应成功但 bootelf 不能得到预期的 Hello World 输出。实测中hello_arm_linux 被正确下载到 0x60100000执行bootelf -p ${loadaddr}后没有输出 Hello World而是返回 U-Boot 的提示符个别情况下 Windows QEMU 还可能打印 “Slirp: Failed to send packet, ret: -1”这是 QEMU 用户网络后端的提示不应把它当作程序成功运行的证据。为什么会失败hello_arm_linux 的 file 信息已经告诉我们它需要/lib/ld-linux-armhf.so.3printf 还需要 libc最终还要通过 Linux 系统调用完成 write、exit、内存管理等。U-Boot 虽然运行在 ARM 裸机上但它不是 Linux 内核也不提供 Linux 用户进程环境。ARM Cortex-A9 指令集匹配 ≠ ARM Linux 用户态运行环境已经存在六、三个阶段到底发生了什么阶段生成物CPU 是否匹配运行环境是否匹配结果1 本机 gcchello_x86 / x86-64 ELF是x86-64是Ubuntu x86-64 Linux成功2 ARM Linux GCChello_arm_linux / ARM ELF否HOST 为 x86-64否ARM Linux 用户态不存在HOST 失败3 U-Boot bootelf同一个 hello_arm_linux是Cortex-A9否没有 Linux 动态加载器 / libc / syscall不能正常输出 Hello World核心结论已经编译成 ARM 程序不是充分条件。程序能否运行既取决于 CPU 指令集是否匹配也取决于它所依赖的运行环境是否存在。hello_arm_linux 是 ARM Linux 用户态程序U-Boot 虽然运行在 ARM Cortex-A9 上却不是 Linux因此不能为它提供动态加载器、glibc 和 Linux 系统调用。七、常见问题与实测提示7.1 readelf | grep Machine 没有输出中文 Ubuntu 中 readelf 的字段名称可能被本地化grep Machine 匹配不到。统一使用LC_ALLC readelf-hhello_x86|grepMachineLC_ALLC arm-none-linux-gnueabihf-readelf-hhello_arm_linux|grepMachine7.2 hello_x86 被 file 描述为 shared objectUbuntu 18.04 默认 PIE 机制可能使 file 显示 “ELF 64-bit LSB shared object, x86-64”。只要./hello_x86能正常运行就是有效的本机可执行程序。7.3 ./hello_arm_linux 报 Exec format error这是阶段 2 的预期现象表示 x86 HOST 不能直接执行 ARM 指令。7.4 bootelf 后没有 Hello World 输出这是阶段 3 的预期现象之一。该实验的目的就是观察普通 ARM Linux ELF 即使已经运行在 ARM Cortex-A9 上仍然缺少 Linux 用户态支持因此不能得到预期的 Hello World 输出。若 QEMU 异常或无响应可用CtrlA、X退出后重新启动。7.5 tftpboot 提示 File not found / Access violation检查 Windows 文件是否确实位于E:\EmbeddedLinuxLab\tftp根目录检查 QEMU 命令是否含-nic user,tftpE:\EmbeddedLinuxLab\tftp八、实验思考题为什么 hello_arm_linux 在 x86 HOST 上失败可以直接归因于 CPU 指令集不匹配为什么把同一个 hello_arm_linux 交给 Cortex-A9 上的 U-Boot 后CPU 架构已经匹配却仍然不能正常运行ELF 是 CPU 指令集吗ELF、ARM、EABI、LSB 分别描述了程序的哪些方面如果希望 hello_arm_linux 真正在 Cortex-A9 上运行下一步还需要为 TARGET 补齐哪些系统层次九、本实验与后续课程的衔接完成实验一后学生已经具备一个非常重要的运行环境分层概念。下一步不再引入新的 Hello World 运行模型而是直接补齐 ARM Linux 所需要的系统层次让阶段 2 生成的 hello_arm_linux 最终在 Cortex-A9 的 Linux 用户态中真正运行。Linux Kernel Device Tree ↓ RootFS / BusyBox ↓ TARGET ARM Linux 用户态 ↓ 把 hello_arm_linux 真正在 Cortex-A9 上运行 ↓ 驱动 / 串口 / 网络 / 应用开发说明真正的裸机 C、启动代码、链接脚本和 PL011 UART/MMIO 等内容可以另设专题实验。实验一不提前引入这些底层细节以免干扰学生对CPU 架构和程序运行环境两个核心概念的理解。附录本版实验的技术依据U-Boot bootelf commandhttps://docs.u-boot.org/en/stable/usage/cmd/bootelf.htmlU-Boot v2026.07 VExpress-A9 defconfighttps://raw.githubusercontent.com/u-boot/u-boot/v2026.07/configs/vexpress_ca9x4_defconfigU-Boot v2026.07 VExpress common confighttps://raw.githubusercontent.com/u-boot/u-boot/v2026.07/include/configs/vexpress_common.h
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

宁波环保营销型网站建设保姆级教程 2026/9/27 3:50:10

宁波环保营销型网站建设保姆级教程

宁波环保营销型网站建设保姆级教程 域名服务器搞不懂?别慌。这行干了十年,见过太多环保企业老板因为选错服务器,网站打开要3秒,客户全跑了。今天这篇 宁波环保营销型网站建设 的 保姆级建站教程…

阅读更多 →
汽车头尾检测数据集:VOC+YOLO双格式5319张三类别实战指南 2026/9/27 3:50:10

汽车头尾检测数据集:VOC+YOLO双格式5319张三类别实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
《HarmonyOS 7 精准碰一碰跨设备协作开发实战》02:触点坐标怎么变成应用里的精准落点【鸿蒙心迹】 2026/9/27 3:50:10

《HarmonyOS 7 精准碰一碰跨设备协作开发实战》02:触点坐标怎么变成应用里的精准落点【鸿蒙心迹】

上一篇我们解决了"能传",这一篇要解决"传哪"。同样一张图片,碰左边进素材库,碰中间进画布,碰右边进属性区——坐标到底是怎么变成业务落点的?先讲个我调试时遇到的事。 我把CrossDrop工作台分成了…

阅读更多 →
北京网页设计避坑指南:看懂这3点,拿到透明建站报价 2026/9/27 3:50:04

北京网页设计避坑指南:看懂这3点,拿到透明建站报价

北京网页设计避坑指南:看懂这3点,拿到透明建站报价 在北京找网页设计,最怕什么?不是技术不行,而是 报价不透明 。昨天刚谈好“全包”8000块,今天加个后台功能收2000,下周换个SSL证书又收1500。很多老板跟我吐槽,明明看着是同样的企…

阅读更多 →
万网可以做网站吗新手入门避坑:防黑挂马实操指南 2026/9/27 3:50:04

万网可以做网站吗新手入门避坑:防黑挂马实操指南

万网可以做网站吗新手入门避坑:防黑挂马实操指南 网站被黑挂马,后台却查不到日志?别慌,这种“幽灵入侵”专挑新手管理者的网站下手。很多刚接触【万网可以做网站吗】的朋友,以为买了域名和服务器就万事大吉,结果上线三天,首页变赌博广告,SEO权重清…

阅读更多 →
SFF-8472与DDM深度解析:光模块数字诊断协议与运维实战指南 2026/9/27 3:50:03

SFF-8472与DDM深度解析:光模块数字诊断协议与运维实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉