侧边栏壁纸
博主头像
Synced & Youthful 博主等级

行动起来,活在当下

  • 累计撰写 6 篇文章
  • 累计创建 20 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

ARM内核编译血泪史:从“文件找不到”到“绝处逢生”,我与Bug抗争的惊天72小时!😱

Administrator
2025-02-09 / 0 评论 / 0 点赞 / 10 阅读 / 0 字

前言:

各位看官老爷们,最近我可是经历了一场惊心动魄的内核编译之旅!那真叫一个“人在家中坐,Bug天上来”! 编译ARM内核,听起来高大上吧? 但背后的辛酸,谁编谁知道! 不说了,先上错误,让大家感受一下这绝望的气息:

fatal error: linux/compiler-gcc14.h: No such file or directory

第一回合: “文件找不到” 的迷雾

刚开始,我以为只是小问题,缺个头文件? 补上不就完事了! 网上冲浪一波,有人说改个文件名就行? 我天真地信了,把 compiler-gcc4.h 改成了 compiler-gcc14.h... 结果呢? 呵呵,编译错误是没了,但新的妖蛾子又出来了!

/usr/bin/ld: scripts/dtc/dtc-parser.tab.o:(.bss+0x50): multiple definition of `yylloc'

我当时内心是崩溃的:文件是找到了,怎么又冒出来个“重复定义”? 这内核编译的水,也太深了吧! 😭

拨开迷雾: GCC版本不兼容?

冷静下来,仔细分析错误信息,再结合之前“文件找不到”的线索,我隐约感觉是不是 交叉编译工具链 的版本出了问题? 难道内核大哥指定要GCC 4,我用的版本太高攀不上了?

于是,我开始老老实实检查我的交叉编译工具链:

  • 确认GCC版本: arm-linux-gnueabihf-gcc -v 一查,果然,版本是14!

  • “病急乱投医”式改文件名 : 现在回想起来,把 compiler-gcc4.h 改名简直是“掩耳盗铃”,自欺欺人! 内核要的是 内容匹配 的头文件,个名字有个P用! 赶紧 撤销 这个愚蠢的操作!

柳暗花明: 寻找正确的交叉编译工具链

既然怀疑是GCC版本问题,那就得 更换 工具链! 问题来了,换哪个版本? GCC 4? 上哪去找GCC 4的交叉编译工具链? 又是一番痛苦的搜索... (此处省略一万字心酸历程)

这个Linaro Releases 依旧可以下载到 较老或者较新的ARM gcc 交叉编译工具链

同时Ubuntu系统中的gcc也不能太高, 不然即使更换了低版本的gcc交叉编译工具依然会报错 multiple definition of `yylloc'

需要gcc设置为gcc-9的版本,之前是gcc-13版本无法正常编译。

安装gcc指令

sudo apt install gcc-9

更新 update-alternatives 配置

sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 30

峰回路转: 配置内核才是正道!

正当我为了工具链焦头烂额的时候,新的错误又给了我当头一棒:

安装了个gcc-4.6.4,结果无法识别, 又是一番折腾发现需要安装依赖

sudo apt-get install ia32-libs
sudo apt-get install lib32z1

嘿, 可以了!

再编译试试

mkimage" command not found - U-Boot images will not be built

这次错误倒是直接明了: mkimage 命令找不到! 这又是啥? U-Boot 镜像? 新的知识点扑面而来,感觉脑子不够用了...

冷静!冷静! 分析错误信息,原来 mkimage 是用来 创建 U-Boot 镜像 的工具,编译内核需要用到! 找不到命令,那还不简单,安装 呗!

sudo apt-get install u-boot-tools

搞定! mkimage 安装成功! 再跑一遍编译命令,嗯? 这次错误是没了,但是... 怎么停下来了?

Cross-compiler tool prefix (CROSS_COMPILE) [] (NEW)
...
Compile also drivers which will not load (COMPILE_TEST) [N/y/?] (NEW) 

竟然进入了内核配置界面! 这是什么操作? 原来,我一直 忽略了一个重要的步骤 —— 内核配置!

顿悟时刻: make menuconfig 才是精髓!

我一直以为 make uImage 就能直接编译内核,太天真了! 内核编译,首先要 配置make menuconfig 命令才是打开内核配置大门的钥匙!

make menuconfig 到底干啥的? 简单来说,它就是让你 定制内核 的! 你可以选择:

  • 编译哪些功能? (网络协议、文件系统、各种驱动...)

  • 针对哪个硬件平台? (不同的ARM架构、开发板...)

  • 使用哪些编译选项? (优化级别、调试选项...)

没有配置,内核编译系统就不知道该怎么干活,只能傻眼了!而我直接运行编译命令,就相当于 “裸奔”,内核当然要一步步问我,让我手动配置了!

正确的姿势: make menuconfig 走起!

明白了问题的关键,我赶紧执行了:

make menuconfig ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-

熟悉的蓝色界面出现了! 各种配置选项看得我眼花缭乱,但这次我没有慌,而是耐心地:

  • 浏览菜单: 了解内核的各个组成部分。

  • 查看帮助: 不明白的选项就按 ? 查看帮助文档。

  • 根据需求配置: 选择需要的模块,剔除不必要的功能 (虽然一开始我也不知道该裁剪啥,就先保持默认了...)

  • 保存配置: 最重要的一步! 配置完成后,一定要 保存!保存!保存! 重要的事情说三遍! 否则之前的配置都白费了!

守得云开见月明: 编译成功!🎉🎉🎉

完成 make menuconfig 配置并保存后,我再次运行了编译命令:

make uImage ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- -j4

这次,奇迹发生了! 编译过程自动进行了! 刷刷刷的编译信息飞速滚动,不再有任何交互式选择,也不再报错!

等待漫长的编译过程结束后,终于看到了 编译成功的提示! 激动的心情难以言表! 感觉这几天踩过的坑,流过的泪,都值了!

终极总结: ARM内核编译避坑指南 🚀

经历了这次“惊天动地”的内核编译之旅,我总结出以下几点血泪教训,希望能帮助大家少走弯路:

1. 仔细阅读错误信息! 错误信息是最好的老师,它会告诉你问题出在哪里,不要盲目猜测和乱试。

2. 交叉编译工具链要选对! 确保工具链版本与内核版本兼容,并且 主机平台架构要匹配! (血的教训,32位工具链在64位系统上要装 lib32z1!)

3. make menuconfig 是内核配置的灵魂!先配置,后编译! 不要跳过配置步骤直接编译!

4. 不熟悉的配置选项,一定要查看帮助文档 (? 键! 理解每个选项的含义,才能做出正确的选择

5. 遇到 mkimage 找不的错误,安装 u-boot-tools!

6. make clean / make mrproper 是解决各种编译疑难杂症的万能! 遇到奇怪的问题,先清理一下编译环境试试

7. 多Google,多查资料,多看社区论坛! 很多问题前人都到过,善用搜索可以节省大量时间

8. 保持耐心和信心! 内核编译是一个复杂的过程,遇到错误是正常的,不要轻易放弃坚持下去,你一定能成功! 💪

最后的最后,希望这篇文章能帮助到正在ARM内核编译路上苦苦挣扎的你! 如果觉得有用,记得点赞收藏哦! 😉 祝大家编译顺利,早日成功!

0

评论区