前言:
各位看官老爷们,最近我可是经历了一场惊心动魄的内核编译之旅!那真叫一个“人在家中坐,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内核编译路上苦苦挣扎的你! 如果觉得有用,记得点赞收藏哦! 😉 祝大家编译顺利,早日成功!
评论区