ARTICLE DETAIL

资讯详情

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

RK3568 u-boot定制实战:menuconfig配置裁剪与设备树修改指南

RK3568 u-boot定制实战:menuconfig配置裁剪与设备树修改指南 1. 拿到RK3568的u-boot源码后先搞清楚你要改什么RK3568这颗芯片在工业控制和边缘计算设备里出货量很大四核A55跑1.8GHz左右带NPU和丰富的外设接口很多做HMI、网关、运动控制器的团队都在用。但原厂SDK里的u-boot往往是个大而全的通用版本默认配置面向的是官方EVB开发板放到你自己的板子上DDR容量、存储介质、引脚分配、外设使能状态几乎全对不上。这时候就得动手改u-boot而改u-boot绕不开两个核心操作menuconfig配置裁剪和设备树修改。我前后在四五个RK3568项目上做过u-boot定制从最简单的改个串口波特率到加自定义启动画面、适配不同PHY芯片、调整SPL加载流程踩过的坑不算少。这篇内容就是把这些经验整理出来面向的是有一定嵌入式Linux基础、手上有RK3568板子、需要自己维护u-boot的工程师。不管你是刚拿到SDK不知道从哪下手还是已经改过几轮但总觉得不够系统下面这些内容应该都能对上你的需求。整个流程我会按配置体系理解→menuconfig实操→设备树修改→编译验证→问题排查这条线来走中间穿插参数计算、代码片段和实测记录。所有操作基于Rockchip官方u-boot通常随SDK发布版本多为2017.09或2024.01分支不同SDK版本细节可能有差异但核心逻辑一致。2. RK3568 u-boot的配置体系到底怎么运转2.1 三层配置结构defconfig、menuconfig、设备树很多人第一次接触RK3568的u-boot会被配置文件的层级搞晕。简单说它分三层第一层是defconfig文件放在configs/目录下比如rk3568_defconfig。这个文件定义的是编译时的默认配置项格式是CONFIG_XXXy或CONFIG_XXXn。它决定了哪些功能被编译进u-boot哪些被裁掉。第二层是menuconfig本质是一个图形化的配置界面读取defconfig作为初始值让你交互式地修改配置项保存后写回.config文件。menuconfig改的是编译哪些功能不直接改硬件描述。第三层是设备树Device Tree放在arch/arm/dts/目录下比如rk3568-evb.dts。设备树描述的是硬件长什么样——内存地址、外设寄存器基址、引脚复用、时钟频率、PHY地址等等。u-boot启动时解析设备树来初始化硬件。这三层的关系可以这样理解defconfig和menuconfig决定软件能力设备树决定硬件事实。两者必须匹配否则会出现驱动编译进去了但找不到设备或者设备树写了但驱动没使能的尴尬情况。注意很多新手只改设备树不改defconfig结果驱动没编译进去串口打印一片空白然后怀疑是设备树写错了。实际上先确认CONFIG_DM_SERIAL、CONFIG_ROCKCHIP_SERIAL这些有没有使能。2.2 为什么Rockchip的u-boot配置和标准u-boot不太一样标准u-boot的配置流程是make xxx_defconfig然后make menuconfig但Rockchip的SDK通常包了一层make.sh脚本。这个脚本做了几件事设置交叉编译工具链路径、指定defconfig、调用make并传入必要的参数、最后打包成uboot.img和loader。为什么要有这层脚本因为RK3568的启动链路比较特殊BootROM → TPL/SPL → u-boot proper。SPLSecondary Program Loader负责初始化DDR和加载完整的u-boot而DDR初始化参数跟具体板子的DDR颗粒型号、容量、频率强相关。make.sh里会处理这些打包细节手动敲make命令很容易漏掉SPL的打包步骤。我一般的工作流是先用make.sh跑通一次完整编译确认工具链和打包流程没问题然后再进入u-boot目录做细粒度的menuconfig和设备树修改改完再用make.sh重新打包。这样既利用了脚本的便利又能精确控制配置。2.3 编译产物里哪些文件跟你的修改直接相关编译完成后u-boot目录下会生成几个关键文件u-boot.binu-boot proper的二进制不含SPLspl/u-boot-spl.binSPL二进制u-boot.dtb编译后的设备树二进制uboot.imgRockchip打包格式的u-boot镜像包含u-boot proper和dtbloader.bin或MiniLoaderAll.bin包含SPL和DDR初始化固件的loader你改menuconfig影响的是u-boot.bin和spl/u-boot-spl.bin的内容改设备树影响的是u-boot.dtb。最终烧录到板子上的是uboot.img和loader。理解这个对应关系排查问题时就能快速定位是配置问题还是设备树问题。3. menuconfig实操从进入界面到关键配置项取舍3.1 进入menuconfig的正确姿势在SDK根目录下通常这样进入cd u-boot make ARCHarm CROSS_COMPILEaarch64-linux-gnu- rk3568_defconfig make ARCHarm CROSS_COMPILEaarch64-linux-gnu- menuconfig注意CROSS_COMPILE要指向你实际的工具链前缀。Rockchip SDK一般自带prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-.../bin/aarch64-none-linux-gnu-具体路径看你的SDK版本。如果make.sh已经配置好了环境变量也可以直接./make.sh menuconfig但有些版本的make.sh不支持menuconfig子命令那就老老实实用make命令。进入界面后你会看到一个大菜单。RK3568相关的配置项分散在几个位置下面挑最常改的几类说。3.2 启动介质与存储配置eMMC、SD、SPI Flash怎么选RK3568支持从eMMC、SD卡、SPI Flash、甚至网络启动。menuconfig里跟启动介质相关的配置主要在Boot options和Rockchip platform下面。关键配置项配置项作用典型值CONFIG_ROCKCHIP_BOOT_MODE_REG启动模式寄存器地址0xfdc60000CONFIG_SYS_MMC_ENV_DEV环境变量存储设备号0eMMC或1SDCONFIG_ENV_IS_IN_MMC环境变量存MMCyCONFIG_ENV_IS_IN_SPI_FLASH环境变量存SPI Flash按需CONFIG_SPL_MMC_SUPPORTSPL阶段支持MMCy如果你用的是eMMC启动CONFIG_SYS_MMC_ENV_DEV设0如果调试阶段用SD卡启动设1。这个值搞错了会出现环境变量保存失败或者启动时读不到bootargs的问题。我遇到过一块板子硬件上eMMC是mmc0SD是mmc1但SDK默认配置把环境变量设备设成了1结果每次保存环境变量都写到SD卡上拔了SD卡就恢复默认。后来改成0才正常。所以这个设备号一定要跟你的硬件设计对上。3.3 串口与调试输出波特率和调试口选择调试串口是u-boot阶段最重要的输出通道。RK3568默认用UART2作为调试口波特率1500000。但很多板子用的是UART0或UART1波特率115200。相关配置CONFIG_BAUDRATE1500000 CONFIG_DEBUG_UART_BASE0xfe660000 CONFIG_DEBUG_UART_CLOCK24000000 CONFIG_ROCKCHIP_UART_PORT2CONFIG_DEBUG_UART_BASE是UART控制器的寄存器基址。RK3568的UART2基址是0xfe660000UART0是0xfe650000UART1是0xfe658000。这个地址写错了串口就完全没输出。波特率方面1500000在Rockchip的SDK里很常见因为他们的调试工具默认用这个速率。但如果你用普通的USB转串口模块很多不支持1.5M那就得改成115200。改的时候注意CONFIG_BAUDRATE和CONFIG_DEBUG_UART_CLOCK要匹配否则会出现乱码。实操心得改波特率后如果输出乱码先检查CONFIG_DEBUG_UART_CLOCK是不是24MHz。RK3568的UART时钟源默认是24MHz晶振如果硬件上用了其他时钟源这个值要跟着改。3.4 网络与PHY配置yt8521等常见PHY怎么使能工业板子上常见的PHY芯片有yt8521、rtl8211、dp83867等。menuconfig里跟网络相关的配置CONFIG_CMD_NETy CONFIG_DM_ETHy CONFIG_ROCKCHIP_GMACy CONFIG_PHY_YT8521y CONFIG_PHY_REALTEKy CONFIG_NET_RANDOM_ETHADDRyCONFIG_PHY_YT8521这个选项不是所有u-boot版本都有如果找不到可能需要在drivers/net/phy/目录下自己添加PHY驱动然后在Kconfig里注册。yt8521这颗PHY在RK3568板子上用得很多它支持RGMII和SGMII两种接口模式。u-boot阶段一般用RGMII设备树里要配phy-mode rgmii同时注意TX/RX delay的配置。delay值不对会出现ping不通或者丢包严重。我实测下来yt8521在RGMII模式下如果PCB走线长度在5cm以内TX delay设0x0f、RX delay设0x00通常能通走线更长的话可能需要用PHY内部的delay或者调整MAC侧的delay。这个没有万能值得根据实际板子调。3.5 启动画面与开机动画u-boot阶段怎么显示LogoRK3568的u-boot支持在启动阶段显示Logo这对消费类产品很重要。相关配置CONFIG_VIDEO_ROCKCHIPy CONFIG_VIDEO_BMP_RLE8y CONFIG_CMD_BMPy CONFIG_SPLASH_SCREENy CONFIG_SPLASH_SOURCEy CONFIG_VIDEO_LOGOyLogo图片一般放在tools/logos/目录下或者通过环境变量splashimage指定地址。显示流程是u-boot初始化VOP显示控制器→ 从存储介质读取BMP图片到内存 → 调用bmp_display()显示。如果要显示开机动画多帧u-boot原生支持有限通常的做法是在u-boot里循环显示几张BMP或者直接跳到kernel后用kernel的logo机制。我试过在u-boot里做多帧动画帧率很低因为u-boot的显示驱动没做优化。如果对动画流畅度有要求建议在kernel阶段做。注意显示Logo会延长启动时间因为要初始化VOP、读取图片、等待显示稳定。如果产品对启动速度敏感这个功能要权衡。4. 设备树修改从引脚复用到外设节点的完整流程4.1 设备树文件结构rk3568.dtsi、rk3568-evb.dts和你的板级dtsRK3568的设备树分三层rk3568.dtsiSoC级定义包含所有外设控制器的寄存器基址、中断号、时钟等。这个文件一般不动。rk3568-evb.dts或类似官方EVB板级定义包含具体板子的外设使能、引脚配置。你的板级dts基于EVB修改或者从零写。实际项目中我建议复制一份rk3568-evb.dts改名成你自己的板子名比如rk3568-myboard.dts然后在arch/arm/dts/Makefile里添加对应的dtb编译目标。这样不会污染官方文件也方便版本管理。设备树里跟u-boot相关的节点主要有几类chosen启动参数、memory内存布局、aliases设备别名、以及各个外设节点uart、mmc、ethernet、i2c、spi等。4.2 引脚复用pinctrl配置触摸竖屏改横屏的典型场景RK3568的引脚复用通过pinctrl子系统管理。每个外设节点里通过pinctrl-0引用一组引脚配置。比如UART2的引脚配置uart2 { status okay; pinctrl-names default; pinctrl-0 uart2m0_xfer; };uart2m0_xfer是在rk3568-pinctrl.dtsi里定义的一组引脚。如果你硬件上UART2用的是另一组引脚比如m1就要改成uart2m1_xfer。触摸竖屏改横屏这个需求表面上是显示方向问题实际上涉及两个层面一是VOP的输出时序配置二是触摸屏的坐标映射。在u-boot阶段如果只是显示Logo改VOP的display-timings里的hactive和vactive对调同时调整hsync-len、vsync-len等参数。但触摸坐标映射u-boot阶段一般不管那是kernel里触摸驱动和input子系统的事。不过有些板子在u-boot阶段就要用触摸做交互比如恢复模式选择菜单那就需要在u-boot里处理触摸数据。RK3568的触摸通常走I2C接口设备树里配好I2C控制器和触摸芯片节点u-boot里使能对应的触摸驱动。4.3 存储设备节点eMMC和SD卡的配置差异eMMC和SD卡在设备树里都是MMC节点但配置有差异sdhci { status okay; bus-width 8; max-frequency 200000000; non-removable; cap-mmc-highspeed; mmc-hs200-1_8v; vmmc-supply vcc_3v3; vqmmc-supply vcc_1v8; }; sdmmc0 { status okay; bus-width 4; max-frequency 150000000; cap-sd-highspeed; cd-gpios gpio0 RK_PA4 GPIO_ACTIVE_LOW; vmmc-supply vcc_3v3; vqmmc-supply vcc_1v8; };eMMC节点通常加non-removable因为没有插拔检测。SD卡节点要配cd-gpios做卡检测。bus-width根据硬件设计填eMMC一般是8位SD卡4位。max-frequency不要盲目填高。eMMC 5.1理论能到200MHz但实际能不能跑稳取决于PCB走线和电源质量。我遇到过一块板子max-frequency设200MHz时u-boot阶段读eMMC偶尔出错降到150MHz就稳了。所以调试阶段可以先设低一点跑通后再往上调。4.4 网络PHY设备树配置yt8521的完整节点写法yt8521的PHY节点在设备树里通常这样写gmac1 { status okay; phy-mode rgmii; clock_in_out output; snps,reset-gpio gpio3 RK_PB7 GPIO_ACTIVE_LOW; snps,reset-active-low; snps,reset-delays-us 0 20000 100000; assigned-clocks cru SCLK_GMAC1_RX_TX; assigned-clock-parents cru SCLK_GMAC1_RGMII_SPEED; mdio { compatible snps,dwmac-mdio; #address-cells 1; #size-cells 0; phy1: ethernet-phy1 { compatible ethernet-phy-ieee802.3-c22; reg 0x1; max-speed 1000; }; }; };关键点reg 0x1是PHY的MDIO地址这个地址由硬件上PHY的strap引脚决定写错了就找不到PHY。snps,reset-gpio是PHY的复位引脚复位时序snps,reset-delays-us三个值分别是复位前延时、复位保持时间、复位后延时单位微秒。yt8521的复位保持时间一般要20ms以上复位后要等100ms左右让PHY内部PLL锁定。这些值不是随便填的datasheet里有明确要求。我见过有人填0 1000 1000结果PHY初始化不稳定偶尔能通偶尔不通。4.5 内存节点与启动参数bootargs怎么配chosen节点里的bootargs是u-boot传给kernel的启动参数chosen { bootargs consolettyS2,1500000n8 earlyconuart8250,mmio32,0xfe660000 root/dev/mmcblk0p5 rootwait rw; };console指定调试串口root指定根文件系统位置rootwait让kernel等待存储设备就绪。这些参数在u-boot阶段可以通过环境变量bootargs覆盖设备树里的只是默认值。内存节点memory0 { device_type memory; reg 0x0 0x0 0x0 0x80000000; };reg的四个值分别是起始地址高32位、起始地址低32位、大小高32位、大小低32位。RK3568的DDR起始地址是0x0大小0x80000000表示2GB。如果你的板子是4GB改成0x100000000。这个值写错了kernel启动时会报内存不足或者直接panic。5. 编译、烧录与验证make.sh的完整使用流程5.1 make.sh参数解析与常用命令Rockchip SDK的make.sh通常支持这些参数./make.sh rk3568 # 编译u-boot ./make.sh rk3568 --spl # 只编译SPL ./make.sh rk3568 --uboot # 只编译u-boot proper ./make.sh rk3568 --clean # 清理 ./make.sh rk3568 --menuconfig # 进入menuconfig有些版本的make.sh还支持--dtb指定设备树文件。如果脚本不支持可以手动改make.sh里的DEFCONFIG和DTS变量。编译完成后产物在u-boot/目录下uboot.img和loader.bin或MiniLoaderAll.bin是要烧录的文件。5.2 烧录工具与分区布局RK3568用Rockchip的烧录工具Windows下是RKDevToolLinux下是upgrade_tool。烧录时注意分区表分区内容偏移loaderSPLDDR固件0x0ubootu-boot properdtb0x4000bootkerneldtb0x8000rootfs根文件系统0x10000具体偏移看你的分区表文件parameter.txt。烧录u-boot时loader和uboot两个分区都要更新只更新uboot不更新loader可能出现SPL和u-boot版本不匹配的问题。5.3 验证修改是否生效的几种方法烧录后通过串口终端观察u-boot启动日志。几个关键验证点串口有没有输出波特率对不对DDR容量识别是否正确打印DRAM: 2 GiB之类存储设备是否识别MMC: mmcfe2b0000: 0网络PHY是否识别eth0: ethernetfe010000设备树是否加载Model: My RK3568 Board如果某项没出现就回到对应的配置或设备树节点排查。还可以在u-boot命令行里用bdinfo查看板级信息mmc list查看MMC设备mdio list查看PHYprintenv查看环境变量。这些命令能快速定位问题。6. 常见问题与排查技巧实录6.1 串口无输出从波特率到引脚复用的排查顺序串口没输出是最常见的问题。排查顺序确认波特率u-boot配置的波特率和终端软件设置是否一致确认UART基址CONFIG_DEBUG_UART_BASE是否对应实际使用的UART控制器确认引脚复用设备树里UART的pinctrl是否正确硬件上TX/RX有没有接反确认时钟CONFIG_DEBUG_UART_CLOCK是否匹配硬件晶振确认SPL阶段如果SPL阶段就没输出可能是DDR初始化失败u-boot根本没跑起来我遇到过一次串口完全没输出查了半天发现是硬件上UART2的TX引脚被复用成了GPIOpinctrl配置里没把它设回UART功能。这种问题只能对着原理图和pinctrl文件逐行核对。6.2 网络不通PHY地址、delay和复位时序的联合排查网络不通的排查现象可能原因排查方法mdio list无PHYPHY地址错、复位失败检查reg值、复位GPIO和时序PHY识别但ping不通delay配置不对调整TX/RX delay丢包严重时钟或电源问题检查RGMII时钟、电源纹波百兆能通千兆不通千兆相关配置缺失检查max-speed、时钟parentyt8521的delay配置我一般先用PHY内部delay设备树里加phy-mode rgmii-id让PHY自己处理TX/RX delay。如果不行再改成rgmii在MAC侧调delay。6.3 存储识别失败eMMC和SD卡的分辨方法eMMC识别失败常见原因bus-width配错、max-frequency太高、电源域配置不对。SD卡识别失败常见原因cd-gpios配错、卡检测极性反了。分辨方法看u-boot启动日志里MMC控制器的初始化信息。如果控制器初始化了但没识别到设备多半是硬件或电源问题如果控制器都没初始化就是配置或设备树问题。6.4 设备树编译报错常见语法与引用错误设备树编译报错通常有几类语法错误少了分号、括号不匹配引用错误xxx引用的节点不存在属性类型错误该用数组的用了字符串重复定义同一个节点定义了两次编译时用make dtbs可以单独编译设备树报错信息会指出具体行号。建议改完设备树先单独编译一次确认没语法错误再整体编译。6.5 环境变量保存失败存储设备号和分区偏移的坑环境变量保存失败先确认CONFIG_SYS_MMC_ENV_DEV和CONFIG_ENV_OFFSET。CONFIG_ENV_OFFSET是环境变量在存储设备上的偏移这个值不能跟分区表冲突。如果偏移落在uboot分区内部保存环境变量会覆盖u-boot本身导致启动失败。我一般把环境变量放在uboot分区之后、boot分区之前的一段保留区域具体偏移看分区表。改这个值之前一定要确认分区布局搞错了板子就变砖得用MaskROM模式重新烧录。7. 一些实战中攒下来的经验u-boot定制这件事说到底就是配置和设备树两条腿走路。配置决定软件能力设备树决定硬件事实两者必须对齐。我见过太多人只改一边然后花大量时间在错误的方向上排查。另外改u-boot之前一定要确保有恢复手段。RK3568支持MaskROM模式按住恢复键上电就能进入用烧录工具重新烧loader和uboot就能救回来。但前提是你手上有完整的、能启动的loader和uboot镜像。所以每次改之前先把当前能工作的版本备份一份这是最基本的保命操作。还有一点不同批次的板子可能DDR颗粒换了、PHY换了u-boot配置和设备树要跟着更新。建议把板级差异做成不同的defconfig和dts文件用make.sh的参数来切换而不是每次手动改。这样版本管理清晰也不容易出错。最后分享一个调试小技巧u-boot的CONFIG_DEBUG_UART和CONFIG_DEBUG_UART_BOARD_INIT可以在SPL阶段就输出调试信息对排查DDR初始化问题很有用。但这两个选项会增大SPL体积量产版本记得关掉。
返回列表