十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

RK3588/RK3568 Android12内核单独编译与环境变量避坑指南

RK3588/RK3568 Android12内核单独编译与环境变量避坑指南 1. 全编译的痛为什么内核必须学会单独编我先说一个真实的开发场景。你手里有一块RK3588的开发板跑Android12玩到第三天需求来了屏幕模组换了一家触摸IC改了一个型号或者要在板子上外接一颗新的音频Codec。这些改动落到代码层面全是设备树、内核config、内核驱动的事情。你要是老老实实每次全编译一遍Android12第一次全量构建哪怕是i9级别的机器加上NVMe固态也得两个小时起步。后面每次增量编译运气好半小时运气差碰到公共头文件变了又是四十分钟起步。一天下来有效工作时间全耗在等编译上。更麻烦的是全编译还会被无关问题打断。你改的是内核dts但系统镜像里某个JAVA模块因为网络拉包失败挂了整个make流程终止你连验证内核的机会都没有。单独编译内核就没有这个问题它只关心arch/arm64下的东西所有和系统应用层、framework层无关的构建都不会触发。再算一笔烧录账。全编译产物是一个完整的update.img动辄两三GB用RKDevTool烧录复制加写入要等好几分钟。而单独编译内核最终产物就是几十MB的boot.img和几MB的resource.img烧录时间按秒算。调试阶段一天可能要烧几十次这个时间差累积下来非常可观的。所以我说单独编内核和单独烧内核是玩RK3568/RK3588 Android12的必修课没有人会每次全量编译整个系统来验证一个dts修改。下面这套流程我跑了很多遍RK3568和RK3588通用环境变量那些坑基本都踩过了照着做就行。2. 动手前先看清家底SDK内核目录、工具链与三分钟检查清单2.1 SDK里四个你真正需要关心的位置Rockchip的Android12 SDK解压之后目录庞大得能劝退新人但编译内核真正需要关心的位置只有四个第一个是内核源码目录。用ls -d kernel-*查一下常见的是kernel-4.19或kernel-5.10。RK3568在Android12上多数SDK给的是kernel-4.19RK3588则两种都可能出现这取决于你什么时候从Rockchip或方案商拿到的SDK。千万不要凭芯片型号去猜内核目录直接看SDK里实际存在什么。有些定制板卡方案商还会直接改内核大版本所以这一步不要省。第二个是交叉工具链目录。Android12 SDK里通常自带prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/这是Rockchip用来编译内核的GCC工具链。注意它和编译Android系统应用层用的Clang不是一回事别混了。后面会有专门章节讲工具链混用的问题。第三个是板级配置目录device/rockchip/。你烧录时查partition分区表要用的parameter文件、产品mk文件都在这。不同产品、不同芯片的parameter内容不一样后续烧录offset要从这里查。第四个是固件二进制目录rkbin/。里面放的是Rockchip的loader等二进制比如RK3588的SPL loader烧录时如果板子状态异常需要用rkdeveloptool db加载它。另外还有一个rockdev/目录SDK构建完成后可烧录镜像会软链接到这里。很多时候./mkimage.sh打包完boot.img和resource.img就出现在这里不用去out目录里翻。2.2 编译器选型先走通GCC再考虑ClangAndroid12是个分水岭。Google在AOSP层面已经移除了GCC编译内核的支持全面切换Clang/LLVM。但Rockchip的SDK保留了两条路GCC和Clang都能编。GCC 4.9路径Rockchip默认流程。SDK自带的脚本、文档、示例全都默认指向它兼容性最好。我认为90%的场景都应该先用GCC跑通尤其是新手不要在工具链选型上给自己加难度。Clang路径只有在验证编译器相关问题、追查某些只有Clang才能复现的bug、或者要编Google主线内核时才需要考虑切Clang。我一直强调这个顺序的原因很简单单独编译内核这件事本身已经有足够多的变量了环境变量、defconfig、打包、烧录工具链再引入一个变量出问题时你根本不知道是代码问题还是编译器问题。先把GCC跑通后续进化成Clang也是顺手的事。2.3 三分钟检查清单正式编译之前花三分钟确认环境能帮你省下后面一小时的排错时间# 1. 确认内核目录看当前SDK是kernel-4.19还是kernel-5.10 ls -d kernel-* # 预期输出: kernel-5.10 # 2. 确认工具链目录存在 ls prebuilts/gcc/linux-x86/aarch64/ # 预期输出: aarch64-linux-android-4.9 # 3. 确认主机有make/gcc等基础工具 which make gcc # 预期输出: /usr/bin/make /usr/bin/gcc # 4. 磁盘余量检查建议留20GB以上 df -h关于磁盘多说一句。很多人的机器全编完Android12之后剩余空间其实已经很紧张。内核编译虽然没有整包构建那么夸张但也会在当前内核目录下生成大量.o文件如果磁盘满了报错信息五花八门编译器写到一半说No space left on device你很容易误判成代码问题。我的底线是至少留20GB余量有条件留50GB最稳妥。3. 内核单独编译完整流程从defconfig到boot.img与resource.img3.1 环境变量初始化三行export是全部前提假设SDK根目录变量为SDK_ROOT当前内核目录是kernel-5.10。kernel-4.19的操作一模一样只是目录名不同。直接照抄cd $SDK_ROOT/kernel-5.10 export ARCHarm64 export CROSS_COMPILE$SDK_ROOT/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android- export PATH$SDK_ROOT/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin:$PATH这三行的作用分别是ARCHarm64告诉Makefile当前编译目标的CPU架构是arm64而不是你主机默认的x86。CROSS_COMPILE指定交叉编译器的完整路径前缀。Makefile会把$(CROSS_COMPILE)gcc拼成要执行的编译器名称。PATH把工具链bin目录加到最前面保证make在找工具链时优先命中SDK自带的版本而不是宿主机的其他交叉编译器。如果你一定要用Clang把CROSS_COMPILE换成下面这样同时保留前面两行export CCclang export CLANG_TRIPLEaarch64-linux-gnu-但我在前面已经说了新手先别碰Clang这里只做展示。3.2 生成内核配置rockchip_defconfig的选择与验证配置生成就一条命令make rockchip_defconfig它会把arch/arm64/configs/rockchip_defconfig展开成当前目录下的.config。Rockchip的这套汇总defconfig本身会通过Kconfig机制根据芯片型号打开对应的配置项所以RK3568和RK3588在Android12平台下都用这个名字。这里有一个重要的验证步骤做完后不要急着往下编。直接搜config文件确认芯片对应的配置项真的打开了grep -E CONFIG_ROCKCHIP_RK3588|CONFIG_ROCKCHIP_RK3568 .config你编译RK3588预期看到CONFIG_ROCKCHIP_RK3588y编译RK3568预期看到CONFIG_ROCKCHIP_RK3568y。如果两个都不是说明defconfig没选对你的芯片继续往下编译只会得到一个起不来的内核。这个坑我在早期换SDK版本时踩过一次浪费了整整半天。如果只是为了编译做到这一步就够了。但如果你还想去掉默认没打开的某些驱动或者临时打开某个调试选项可以顺手做一次图形化配置make menuconfigmenuconfig需要系统装了ncurses库没有的话先sudo apt install libncurses5-dev libncursesw5-dev。改完配置后如果你希望下次编译还保留这些改动需要把改动保存回defconfig否则下次make rockchip_defconfig会把你的修改覆盖掉。保存的方法是make savedefconfig生成的精简defconfig再手动覆盖到arch/arm64/configs/rockchip_defconfig。这一步很多新手会漏掉建议养成习惯。3.3 执行编译Image和dtbs.img两个目标缺一不可配置就绪后执行make -j$(nproc) Image dtbs.img这里有两个目标各有各的用处Image编译生成的arm64内核镜像最终产物在arch/arm64/boot/Image。dtbs.img把当前平台相关的dts编译成dtb再打包成Rockchip的resource.img格式。最终产物在当前内核目录下名字就是resource.img。为什么要两个一起编因为Android12平台上内核Image和dtb/resource是分开打包、分开烧录的。你光编Image不编dtbs.img改了dts也白改。反过来如果只编dtbs.img不编Image内核代码的改动又进不去。两个一起编最省事。关于并发数-j$(nproc)nproc会返回CPU逻辑核心数常规情况下直接用没问题。但如果你的机器内存小于16GB建议手动降级用-j8甚至-j4。内核编译是纯CPU密集型任务每个并发编译任务会吃掉几百MB内存内存不够时会被OOM Killer直接杀掉报错信息看起来像是代码问题实际是内存不够。我在8GB老机器上踩过一次教训深刻。编译结束后确认两个关键产物都生成了ls -lh arch/arm64/boot/Image resource.img正常情况下Image大小在30-50MB之间resource.img根据dtb数量和logo文件大小在几百KB到几MB之间。如果只有Image没有resource.img说明dtbs.img目标没执行成功回去看编译日志。3.4 打包boot.img两种方式看你的环境支持哪个到这里你已经有了Image和resource.img但还不能直接烧录。RKDevTool和rkdeveloptool烧录认的是分区镜像boot分区需要把Image和ramdisk打包成boot.img。打包有两条路。方式一用SDK根目录的mkimage.sh。这是最省事的方式。先回到SDK根目录再执行cd $SDK_ROOT ./mkimage.shmkimage.sh会扫描你刚编译的内核产物找到Image和resource.img后将它们和ramdisk一起打包成boot.img和resource.img输出到out/target/product目录以及rockdev目录。它的优点是处理了所有依赖关系resource.img也会重新生成好。缺点是这个脚本依赖之前lunch过的产品环境。如果你是在一个干净终端里直接跑它可能会默认用某个产品配置最后打包出来的镜像和你板子实际用的分区表对不上。所以如果你发现mkimage.sh生成的boot.img路径不对多半是shell环境缺了产品信息。方式二手动用mkbootimg。更可控但需要找到mkbootimg工具而且需要手动指定ramdisk.img。先找到工具find $SDK_ROOT -name mkbootimg -type f 2/dev/null通常它存在于out/host/linux-x86/bin/mkbootimg前提是你完整编译过系统或者在rkbin/tools/mkbootimg。找到后$SDK_ROOT/out/host/linux-x86/bin/mkbootimg \ --kernel $SDK_ROOT/kernel-5.10/arch/arm64/boot/Image \ --ramdisk $SDK_ROOT/out/target/product/rk3588/ramdisk.img \ -o boot.img注意--ramdisk路径里的产品名要换成你自己板的实际目录名。如果你不确定ramdisk路径可以用ls out/target/product/看看当前产品目录是什么。其实在实际开发中我更推荐方式一因为mkimage.sh会自动把resource.img也放出来。手动方式容易只打包boot.img忘了重新生成resource.img导致dts改动没进到烧录包里。如果你手动打包记得两个都准备好。4. 环境变量避坑案例每一个坑背后都是浪费掉的一下午标题里专门提到环境变量避坑说明这不是小事。Rockchip这套平台的编译流程本身很成熟绝大多数编译失败其实不是代码问题而是环境变量问题。下面这几个坑我全踩过或者亲眼看着别人踩过。4.1 CROSS_COMPILE只写前缀没写完整路径这是新手最高发的错误。有人会写成export CROSS_COMPILEaarch64-linux-android-看起来和教程差不多但如果PATH里没有工具链路径make在拼出aarch64-linux-android-gcc后会直接报command not found。更隐蔽的是如果系统里之前用apt装过gcc-aarch64-linux-gnu或者你source过别的芯片厂商的环境脚本PATH里可能真的有一个同名前缀的编译器它不报找不到而是编译到一半报根本看不懂的语法错误。这种情况下排错非常痛苦。我的经验是CROSS_COMPILE必须写完整绝对路径前缀同时把bin目录加进PATH。两条都做互相兜底export CROSS_COMPILE$SDK_ROOT/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android- export PATH$SDK_ROOT/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin:$PATH然后务必验证一下当前终端实际生效的编译器which aarch64-linux-android-gcc如果输出不是SDK里的路径说明PATH顺序有问题继续往下编就是给自己挖坑。4.2 忘设ARCHarm64编出一个x86内核的迷惑行为这个坑非常有意思。只设了CROSS_COMPILE没设ARCH的话make会默认当前主机的架构。在x86主机上它就会尝试编译x86内核。这时候你看到的报错往往集中在arch/x86/路径下或者汇编器报某些指令不识别。判断技巧只要编译输出里出现了arch/x86/字样立刻CtrlC重新export ARCHarm64再编。不要想着碰运气继续跑x86的内核就算编出来烧到ARM板子上也起不来。顺便说一句export这个坑最烦人的地方在于它不是报一个立竿见影的错误而是一堆看似无关的报错堆在一起。我建议在make之前先用一串echo自检一下echo $ARCH echo $CROSS_COMPILEARCH输出应该是arm64CROSS_COMPILE输出应该是完整路径前缀。习惯成自然每次编译前这两条命令就是护身符。4.3 多平台开发的环境变量残留污染嵌入式开发的人手里通常不止一块板子今天调RK3588明天调海思后天调全志这是常态。问题在于如果沿用同一个终端窗口上次编译海思平台设置的环境变量会残留下来。比如CROSS_COMPILE还指向上一个平台的工具链路径或者KERNEL_DIR指向别的内核目录。这时候的你不过是换了个目录而已但编译器已经换人了。症状非常典型一进内核目录make立刻报工具链找不到或者版本不匹配。我的操作习惯是每次切换平台时绝不复用上一个终端。开一个新终端先清空再设置unset ARCH unset CROSS_COMPILE unset CC unset CLANG_TRIPLE再用env | grep -iE arch|cross|cc|kernel确认环境干净了然后再设置当前平台的环境变量。一次清空省得后面被莫名其妙的问题折磨。4.4 source build/envsetup.sh之后的环境污染Android开发者通常习惯先执行source build/envsetup.sh lunch rk3588_s-userdebug这个环境对编译整个Android系统非常有用但如果你在这个环境里接着去编内核可能会被一堆Android构建变量干扰。比如TARGET_PRODUCT、ANDROID_PRODUCT_OUT这些变量可能会让mkimage.sh把boot.img输出到错误的产品目录或者让make阶段的行为和预期不一致。我的建议是独立开个终端专门编内核不要source envsetup.sh。除非你有多年经验知道自己在干什么。这不是说envsetup.sh有什么问题而是保持环境变量最小化能大幅降低出问题的概率。4.5 GCC和Clang混用导致链接阶段崩溃有些同学会照着网上教程设置CCclang又没有关掉之前残留的GCC相关变量最后出现GCC编译、Clang链接或者反过来Clang编译、GCC的as去汇编的混乱局面。报错往往在链接阶段什么ld.lld: error: unrecognized argument之类。这种混用状态最难排因为编译日志里一半是clang一半是gcc。记清楚逻辑Clang只是编译器它生成的汇编要交给GNU assembler处理所以用Clang时CROSS_COMPILE还是必须设置的。要么全部走GCC默认路径要么全部走Clang路径。我综合评价下来对Rockchip SDK来说GCC路径是最省心的99%的调试场景不需要Clang。另外还有个小坑工具链和主机架构也要匹配。如果你的主机是32位系统SDK自带的这个x86_64预编译工具链是用不了的。现在应该没什么人用32位系统了但如果是老旧的虚拟机镜像还是确认一下uname -m是x86_64比较好。4.6 编译报缺依赖那是系统包的问题不是内核代码问题虽然不是环境变量但很容易被误判。比如报fatal error: openssl/bio.h: No such file or directory这是缺libssl-dev报flex: command not found是缺flex报bison: command not found是缺bison。这些都不是内核代码问题用apt装一下sudo apt install libssl-dev flex bison bc装上之后重新编译通常问题就消失了。这条经验分享一下免得你在网上搜半天编译错误发现自己只是没装系统包。5. 烧录内核的四种方式分区选择、命令参数与适用场景5.1 烧录前必须懂的分区概念boot和resource哪个都不能漏Rockchip Android12平台和内核相关的分区主要有两个boot分区存放boot.img里面是内核Image和ramdisk。resource分区存放resource.img里面是设备树dtb和开机logo资源。关键原则如果改动涉及dtsboot.img和resource.img要一起烧。只烧boot.img而不烧resource.img可能出现屏幕不亮、触摸无响应、外设不工作等情况因为内核和设备树不匹配。反过来如果只是改了内核代码逻辑或config开关不涉及硬件描述那烧boot.img就够resource.img可以不烧。要确认自己的改动是不是涉及dts最简单的判断标准你有没有动过arch/arm64/boot/dts/rockchip/下的文件。动过就要一起烧。5.2 方式一Windows下RKDevTool新手最友好的图形化烧录如果你身边有Windows机器用RKDevTool是门槛最低的方式。流程如下让板子进Loader模式。两种方法板子开着机并且能连adb执行adb shell reboot loader。板子断电按住板上的升级键RECOVERY/固件升级键插上USB或者上电等待PC识别到Loader设备。打开RKDevTool设备列表中会出现一个Loader设备。在烧录列表中找到boot分区点击右侧选择文件选中你编译的boot.img。如果dts有改动同时找到resource分区选中resource.img。只勾选这两行点击执行。这里要特别提醒千万忍住不要点一键烧录或者勾选所有分区。RKDevTool的勾选逻辑是勾哪个烧哪个如果你把整包固件都勾上等于又回到了全量烧录浪费时间不说还容易因为你手里的固件版本不配套而把板子刷起不来。5.3 方式二Linux下rkdeveloptool命令行最常用Linux环境下rkdeveloptool是官方开源的USB烧录工具可以直接从Rockchip仓库拉源码编译也可以在部分Ubuntu源上直接apt安装。先让板子进Loader模式和上面一样然后按这个顺序操作# 列出所有连接的设备确认板子被识别 rkdeveloptool ld # 如果设备识别不到或状态异常先用db命令加载loader rkdeveloptool db $SDK_ROOT/rockdev/rk3588_spl_loader_v1.08.bin # 写入boot分区 rkdeveloptool wl 0x4000 boot.img # 写入resource分区 rkdeveloptool wl 0x6000 resource.img # 重启设备 rkdeveloptool rdrkdeveloptool的wl命令参数是以512字节扇区为单位的偏移。这里的0x4000是boot分区偏移0x6000是resource分区偏移这只是我RB3588平台的一个示例值不同SDK、不同产品完全可能不一样。正确做法是打开SDK里对应产品的parameter文件搜索(boot)和(resource)关键字找到实际的扇区偏移。以RK3588一份典型parameter文件为例相关片段长这样CMDLINE: mtdpartsrkxxxx:...:0x000020000x00004000(boot),...:0x000020000x00006000(resource),...这里的0x00004000(boot)就表示boot分区起始扇区是0x40000x00006000(resource)表示resource分区起始扇区是0x6000。直接用这个数字传给wl命令就对。强烈建议每次烧录前把你手上固件的parameter文件解出来看一眼不要凭记忆敲offset。我吃过一次亏换了SDK版本之后boot分区offset从0x4000变成了别的值我还按老经验烧结果烧完板子起不来。5.4 方式三adb加dd调试阶段效率最高的烧录方法这是我最爱的烧录方式没有之一。前提是板子是userdebug或eng版本有root权限。过程不超过十秒# 连接板子并获取root adb root # 确认boot分区节点存在并查看分区情况 adb shell ls -l /dev/block/by-name/boot # 传输boot.img到板子 adb push boot.img /data/local/tmp/ # 用dd写入boot分区 adb shell dd if/data/local/tmp/boot.img of/dev/block/by-name/boot bs1M # resource.img同样处理 adb push resource.img /data/local/tmp/ adb shell dd if/data/local/tmp/resource.img of/dev/block/by-name/resource bs1M # 重启 adb reboot为什么这个方法效率高因为不需要进Loader模式不需要额外烧录工具不需要断电按键一条adb命令就把镜像写进分区了。对于一天改十几次内核的调试场景这是最顺手的路径。风险提示dd命令写错分区的后果是灾难性的。执行前务必确认of指向的是/dev/block/by-name/boot或/dev/block/by-name/resource不要手滑写到其他分区。如果板子上没有/dev/block/by-name这个软链接目录可以先执行adb shell ls /dev/block/by-name/看看实际分区名有些定制系统分区命名可能不一样。5.5 方式四fastboot能不能用看设备部分RK板子在Android12上开启了fastboot支持可以这样试adb reboot bootloader fastboot devices fastboot flash boot boot.img fastboot flash resource resource.img fastboot reboot但坦白说Rockchip平台上fastboot不是默认必现的不同SDK差异很大。如果fastboot devices识别不到就别纠结用前面三种方式。fastboot在RK平台更像是一个可用可不用的彩蛋不要依赖它。6. 烧录后的验证与启动失败排查6.1 确认内核真的更新了烧录完重启第一件事是验证内核版本和编译时间adb shell uname -a adb shell cat /proc/version/proc/version里会显示内核编译时间。如果你打印出的时间正好是你刚才编译的时间说明boot分区烧对了。如果时间还是旧版本说明你烧的分区不对或者板子实际从另一个分区启动了。比如部分板子使用A/B分区架构实际启动的是boot_a或boot_b而不是名为boot的符号链接默认指向的那个。这种情况需要烧到对应的a/b分区。设备树的验证也做一下adb shell cat /proc/device-tree/model adb shell cat /proc/device-tree/compatible如果model输出和你的板型或你改动的dts一致说明resource分区也烧对了。如果model是老的那resource.img没生效回去查烧录offset。6.2 卡在开机logo不动两个img不匹配的问题烧录后板子卡在开机logo最常见的两个原因一是boot.img和resource.img不是同一套SDK编出来的内核和dts版本不匹配二是内核config缺了某个启动关键配置。排查思路建议这样走先确保两个img来自同一次make调用。如果你用旧SDK编了resource.img新SDK编了boot.imglogo卡死不奇怪。回退到之前能用的完整固件确认板子本身没坏。手边常备一份全量固件和烧录工具是干这行的基本素养。如果完整固件能启动再只烧新的boot.img不烧resource.img看能不能过logo。能过的话基本断定问题出在resource.img身上不能过就是boot.img的问题。这样二分定位最快。6.3 能进系统但外设异常优先怀疑dts不匹配内核能起来但Wifi打不开、触摸没响应、蓝牙扫描不到、音频不出声这类问题在单独编译烧录场景下最大概率是resource.img里的dtb没更新和你当前内核版本不匹配或者dts的硬件描述与真实硬件布局不一致。解决方向把resource.img完整重新烧一次。如果你不方便重烧还有一个排查小技巧把新旧resource.img里的dtb分别反编译出来做对比# dtc是设备树编译器在SDK或者系统dtc工具都可以 dtc -I dtb -O dts -o old.dts old.dtb dtc -I dtb -O dts -o new.dts new.dtb diff old.dts new.dts这样你能很直观地看到设备树差异判断是不是某些硬件节点因为dts没更新而缺失。另外还有一层容易被忽略——dtsi的include层级。Rockchip的dts通常由多个dtsi分散include组成你改的是某个子dtsi但最终编译进resource.img的可能是另一个dts文件。如果你改了某个通用dtsi记得确认最终生效的dts确实包含了你的改动用生成的dtb反编译确认最靠谱。6.4 内核panic或反复重启串口日志才是关键如果内核在启动早期就panicadb还没起来你看不到dmesg。这时候必须接串口。Rockchip平台的调试串口默认波特率是1500000不是常见的115200这个特别容易坑到人。用minicom或者picocom连sudo picocom -b 1500000 /dev/ttyUSB0打开串口后上电你能看到完整的U-Boot日志和内核启动日志。panic栈在哪一行、哪个驱动初始化失败串口上打印得明明白白。调内核启动问题没有串口等于瞎猜。最常见的几种panic原因dts里某个节点引用的时钟不存在clk_get失败导致驱动直接BUG。内核config里关闭了某个平台必需的驱动比如GIC中断控制器没编进去。内存布局和dts里的reg地址不匹配导致访问非法地址。这些在串口日志里其实都有提示关键是先学会看日志。另外建议每次编译完把Image保存在一个有版本标识的目录里比如boot_20250610_1600.img不然烧多了之后你根本不知道自己烧的是哪一个。6.5 容易忽略的坑ramdisk和vendor分区里的内核模块Android12里不少内核驱动是编译成.ko模块放在ramdisk或vendor分区里的。单独编译内核烧录后如果这些分区里的模块没跟着更新会出现内核能起来、但某些功能异常的情况。比如模块加载时报version magic不匹配或者unknown symbol都是模块和内核版本对不上的典型症状。出现这种情况别怀疑内核编译有问题要意识到是模块盘跟不上了。处理方式把对应模块重新编译后手动push到板子对应目录。先看模块都在哪adb shell ls /vendor/lib/modules/ adb shell ls /vendor/lib/modules/*.ko然后从你内核编译产物中找到对应的.kofind $SDK_ROOT/kernel-5.10 -name *.ko | grep your_modulepush进去adb push your_module.ko /vendor/lib/modules/ adb shell sync adb reboot不过要注意模块和内核版本强相关每次改内核后最好都用同一套编译产物把相关模块一起更新不要混着用。6.6 环境变量坑的最后一口气重编前先清理不管上面哪种问题让你重新编译建议重新编译前把内核目录里的旧产物清理一下尤其是改了defconfig里的大选项之后。有时候旧编译产物会缓存一些config相关的中间文件导致你改了配置却不生效make clean # 或者如果你想彻底一点 make mrproper然后重新走一遍defconfig、make流程。这一条不是环境变量问题但和编译异常的关系极其密切。尤其是你在menuconfig里改了某个选项却发现编译产物没有任何变化先make clean再试。调到最后你会发现RK3568/RK3588内核单独编译这件事本身并不难难的是每一次出错都让人觉得毫无头绪。而所有毫无头绪的背后几乎都是环境变量、分区偏移、模块匹配这几个老问题在轮流转。把这篇教程里提到的问题都提前避开了你就能把一天里省下来的时间真正花在调试业务代码上而不是和编译环境较劲。这是我个人实际做下来最大的体会也希望对你有用。
返回列表