任务描述

后期有基于RK3588开发智能处理设备的需求,需要使用RK3588的CAN总线、2路以太网、1路PCIe3.0x4转4路电口千兆以太网。

需要使用公板SDK编译自己的u-boot、kernel、dts、rootfs等固件,刷到Firefly-ITX-3588J开发板中,进行bringup工作的前期验证,为后续bringup自己的板子奠定基础。

本篇记录一些刷写使用公板SDK编译固件的过程中遇到的问题。

u-boot

在u-boot启动阶段,u-boot会对dts进行解析。【坑1-需要搞清楚u-boot解析设备树都做了什么】

RK3588在u-boot阶段不同的地方在于,u-boot在解析电源模块的时候,会分析当前使用的电源模块方案。RK3588有单PMIC方案和双PMIC方案,这两种不同方案的固件不可以互烧,否则可能会烧坏芯片。u-boot在代码中对PMIC进行了分析,如果硬件PMIC方案与软件不符,会在u-boot阶段进行拦截,同时启动log里面也会喷下图dev_err函数中相应的log。

在公板SDK中,EVB1版本使用的是双电方案,EVB7版本使用的是单电方案。由于ITX-3588J使用的也是单电方案(见上图),因此在SDK中的DTS设置,要选择EVB7的。选择EVB7设备树再编译一下kernel(RK3588 SDK中dts和kernel是编译在一起的),再次启动,u-boot阶段就可以正常启动了。

rootfs

使用公版EVB7直接编译的u-boot、kernel,通过电源模块的检查后,内核就可以启动了,但到开始挂载rootfs的时候,VFS挂载出错。

通过对比启动log,发现Kernel Command Line缺少了一段关于rootfs的参数。

rootfs挂载出错的Kernel Command Line:

Kernel command line: storagemedia=emmc androidboot.storagemedia=emmc androidboot.mode=normal  storagenode=/mmc@fe2e0000 androidboot.verifiedbootstate=orange earlycon=uart8250,mmio32,0xfeb50000 console=ttyFIQ0 irqchip.gicv3_pseudo_nmi=0

rootfs正常挂载时的Kernel Command Line:

Kernel command line: storagemedia=emmc androidboot.storagemedia=emmc androidboot.mode=normal  storagenode=/mmc@fe2e0000 androidboot.verifiedbootstate=orange ro rootwait earlycon=uart8250,mmio32,0xfeb50000 console=ttyFIQ0 irqchip.gicv3_pseudo_nmi=0 root=PARTLABEL=rootfs rootfstype=ext4 overlayroot=device:dev=PARTLABEL=userdata,fstye=ext4,mkfs=1 coherent_pool=1m systemd.gpt_auto=0 cgroup_enable=memory swapaccount=1

根据log可以确定,是在启动时没有把rootfs的分区等信息传递给kernel,导致kernel不知挂载rootfs。

Kernel command line的内容是通过bootargs变量传递给内核的,在dts中查询到设置bootargs变量的位置,在rk3588-android.dtsi(EVB7引用的是这个dtsi)的chosen节点中,补充bootargs变量内容。

更改后重新编译kernel,再启动系统,发现可以正常挂载rootfs(会有一堆报错,是由于设备树跟板子不匹配等报错,但不影响进入系统)。

kernel & dts

kernel和dts部分,主要是针对ITX-3588J开发板,基于公板SDK,对设备树和内核驱动进行修改,以实现后续要使用的接口全部正常工作。主要调试了PCIe接口、CAN总线和一路以太网口。

PCIe转以太网

PCIe转以太网部分主要工作有两项,一个是PCIe接口在设备树中的配置,二是编译PCIe转以太网网卡驱动。

PCIe接口在设备树中的配置没有遇到什么问题,参考ITX-3588J设备树中关于PCIe3.0x4的设置,对应修改EVB7中的PCIe3.0x4的管脚设置(涉及到的是一个复位管脚),PCIe接口就可以正常使用了。使用lspci命令也可以枚举到插入的网卡设备。

PCIe转以太网网卡是采购的,卖家提供了驱动的源码,需要使用当前开发使用的内核源码,重新编译一个模块。具体编译过程参考【坑2-写编译模块的blog】。编译完成后,insmod到内核中,经ping测试和回环测试,网卡可以正常使用。

CAN总线

CAN总线的配置有两项工作,一个是在设备树中配置CAN节点,二是在内核中使能CAN总线的驱动。

设备树中CAN节点的配置可以参考ITX-3588J的设置,直接复用代码就可以。

CAN总线驱动的使能,需要修改kernel编译时使用的deconfig文件,将CONFIG_CAN和CONFIG_CANFD_ROCKCHIP两个选项设置为y,保存后重新编译kernel。

上述操作后,CAN总线也可以正常使用。【坑3-blog正点原子CAN总线调试】

以太网

直接在ITX-3588J使用EVB7的设备树,只有一个网口是正常的,另一个网口处于不能工作的状态。

通过查阅设备树源码,EVB7的设备树的确只配置了gmac1、mdio1一个网口节点,需要手动添加gmac0、mdio0作为另一个节点。其中,gmac对应的是mac,mdio对应的phy。【坑4-关于mac和phy的学习】

具体的配置可以直接参考ITX-3588J的设备树代码。

配置完成后,重新编译内核。启动系统后使用ifconfig -a命令发现仍然只有一个网卡,在/proc/device-tree下,发现mac节点已经有两个了,即ethernet@fc1b0000和ethernet@fc1e0000。

使用dmesg | grep gmac命令查看内核log,发现有如下报错:

[    2.866398] rockchip-pinctrl pinctrl: could not request pin 149 (gpio4-21) from group gmac0-miim  on device rockchip-pinctrl
[    2.866404] rk_gmac-dwmac fe1b0000.ethernet: Error applying setting, reverse things back
[    2.866421] rk_gmac-dwmac: probe of fe1b0000.ethernet failed with error -22

gmac0-miim的管脚申请失败,怀疑是设备树中管脚存在复用现象,再次使用dmesg | grep gpio4-21命令,发现该管脚果然被uart9复用。回到设备树,将所有复用该管脚的其它节点注释掉,重新编译内核和设备树。

经上述操作,两个自带的以太网口全部正常工作了。

调试回顾

整个调试过程中,涉及的一些操作

  • 设备驱动在内核树内和内核树外的构建
  • 设备树的修改、配置和内核模块的配置
  • 网卡的测试和CAN接口的测试
  • 系统启动过程以及u-boot、kernel和rootfs功能作用等的补充理解
说点什么
请文明发言!
支持Markdown语法
好耶,沙发还空着ヾ(≧▽≦*)o
Loading...