1 环境
- 正点原子imx6ull开发板
- kernel4.14.13
2 移植目标
开发板能够正常启动,并且网络功能正常,能使用nfs、tftp等方式,便于调试。
3 移植过程
3.1 创建自己的板级配置文件-defconfig文件
复制一份imx_v6_v7_defconfig,这里我命名为dfos_mini_defconfig。
3.2 创建配套的dts文件
复制一份imx6ull-14x14-evk.dts,重命名为dfos.dts。同时还要修改Makefile,让内核编译出dfos.dtb。
zrc@zrc:~/01 code/04/kernel 4.14$ git diff arch/arm/boot/dts/Makefile diff--gita/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index eff87a3..8757307 100644 --a/arch/arm/boot/dts/Makefile+++ b/arch/arm/boot/dts/Makefile 00 -483,7 +483,8 c@ dtb-$(CONFIG SOC IMX6UL)+= \ imx6ul-tx6ul-0010.dtb \ imx6ul-tx6ul-00ll.dtb imx6ul-tx6ul-mainboard.dtb imx6ull-14x14-evk.dtb imx6ull-14x14-evk.dtb dfos.dtb dtb-$(CONFIG SOC IMX7D)+= \ imx7d-cl-som-1mx7.dtb imx7d-colibri-eval-v3.dtb
3.3 修改内核顶层Makefile
ARCH ?= $(SUBARCH) CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"名"=号) +ARCH ?= arm +CROSS COMPILE ?= arm-linux-gnueabihf
3.4 编译
执行make dfos_mini_defconfig
编译出.config,然后再执行make编译出镜像。uboot通过tftp的方式下载镜像并且启动内核。这里插入我开发板里uboot的环境变量,关于网络功能相关配置:
setenv gatewayip "192.168.1.1" setenv ipaddr "192.168.1.110" setenv netmask "255.255.255.0" setenv serverip "192.168.1.104" setenv bootcmd "tftp 80800000 zImage; tftp 83000000 dfos.dtb; bootz 80800000 - 83000000" setenv bootargs "console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.1.104:/home/zrc/nfs/rootfs,proto=tcp rw ip=192.168.1.100:192.168.1.104:192.168.1.1:255.255.255.0::eth0:off" setenv ethaddr "00:04:9f:04:d2:35"
3.5 启动
如下图,内核启动到挂载nfs文件系统前提示打开eth0失败,随后挂载nfs失败。因此需要对网络驱动进行适配,参考正点原子提供的教程移植到4.14.13。
2.492587] hub 1-1:1.0: 4 ports detected 2.505570 Registering SWP/SWPB emulation handler 2.633977] asoc-simple-card sound: wm8960-hifi <-> 202c000.sai mapping ok 2.792030] snvs_rtc20cc000.snvs:snvs-rtc-lp:setting system clock to 1970-01-02 11:28:05 UTC(127685) 2.815764] Croovvv,etmeimiet etv. ULEDLe connect to phy 2.826723 IP-Config:Failed to open ethe 2.830916 Ip-Confia: Device 'ethe’ not found 2.839992] 2.836945] ALSA device list: #0:mx6ul-wm8960
99.060041] VFS:Unable tO mount root fs via NFs, trying floppy. 99.07061299.078116 VES: Cannot open root device "nfs" or unknown-block(2,0):error Please append a correct "root=" boot option; here are the available partitions: -6 99.086653 日100 65536 ram0 99.086674 (driver?) 99.092947 0101 65536 ram1 99.092965 (driver?) 99.099149 日102 65536 ram2 99.099166 (driver?) 99.105427 日103 65536 ram3 99.105444 (driver?) 99.1116247 日104 65536 ram4 99.111643 (driver?) 99.117906 0105 65536 ram5 99.117923 (driver?) 99.124177 日106 65536 ram6 99.124195 (driver?) 99.130377 0107 65536 ram7 99.130394 (driver?) 99.136691 日108 65536 ram8 99.136710 (driver?) 99.142975 日109 65536 ram9 99.142992 (driver?) 99.149173 日10a 65536 ram10 99.149189 (driver?) 99.155535 010b 65536 ram11 99.155552 (driver?) 99.161815 日10c 65536 ram12 99.1618317 (driver?) 99.168168] 日10d 65536 ram13 99.168186] (driver?) 99.1745267 日10e 65536 ram14 99.1745437 (driver?) 99.180808] 010f 65536 ram15 99.180827 (driver?) 99.1871877 b300 31166976 mmcblke 99.187207 driver: mmcblk 99.194157 b301 31162880 mmcblk0p1 00000000-01 99.20104599.194176 Kernel panic- not syncing: vFs: Unable to mount root fs on ur99.209640] -[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(2.0)
3.6 网络驱动修改
3.6.1 修改imx6ul-14x14-evk.dts
注意,这个修改的是imx6ul-14x14-evk.dts
,不是dfos.dts
,也不要看成imx6ull-14x14-evk.dts
,我们创建的dfos.dts会调imx6ul-14x14-evk.dts。
dfos.dts |-- imx6ul-14x14-evk.dts |-- imx6ul.dtsi
3.6.1.1 修改fec1和fec2节点
113 &fecl { 114》 pinctrl-names =“default”: 115》 pinctrl-0 =<&pinctrl_enet1 116》 》》 》 &pinctrl_enet1_reset>: 117》 phy-mode ="rmii”: 118 》 phy-handle =<ðphy0>: 119》 phy-reset-gpios = <&gpio5 7 GPIO_ACTIVE_LOW>: 120》 phy-reset-duration =<200>: 121》 status ="okay”: 122 }:123 124 &fec2 { 125》 pinctrl-names ="default”: 126》 pinctrl-0 =<&pinctrl_enet2 127》 》 》 》 &pinctrl_enet2_reset>: 128》 phy-mode ="rmii”: 129》 phy-handle =<ðphy1>: 130》 phy-reset-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>: 131 phy-reset-duration =<200>: 132 》 status ="okay”: 133 134》 mdio { 135 》 #address-cells =<1>: 136》 #size-cells = <O>; 137 138 》 ethphy0:ethernet-phy@2{ 139》 》 compatible ="ethernet-phy-ieee802.3-c22”: 140》 》 reg = <0>; 141》 》 micrel,led-mode =<1>; 与 142 》 》 clocks = <&clks IMK6UL CLK ENET REF>; 143》 》 clock-names =“rmii-ref”: 与 144》 》 } : 145 146》 》 ethphy1:ethernet-phy@1 { 147》 compatible = "ethernet-phy-ieee802.3-c22”: 148》 reg = <1>: 149》 micrel,led-mode =<1>; 150》 》 clocks = <&clks IMK6UL CLK ENET2 REF>; 151》 clock-names =“rmii-ref”: 152» }: 153》 } : 154 }:155
3.6.1.2 修改iomuxc节点
32 pinctrl_enet1_reset: enetlresetgrp [ 322 》 fsl,pins =< 323 》 /* used for enetl reset */ 324 》 MCK6ULL_PAD_SNVS_TAMPER7__GPIO5_IOO7 x10BO 325 》 7: 326 } : 327 328 pinctrl_enet2_reset: enet2resetgrp{ 329 》 fsl,pins =< 330》 》 (* used for enet2 reset */ 331 》 NK6ULL PAD SNVS TAMPERS GPIO5 IO08 x10BO
3.6.1.3 修改MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1和2
原值是0x4001b031,修改成0x4001b009.
293 》 pinctrl_enet1: enet1grp{ 294》 fsl,pins =< 》 295》 》 》 IK6UL PAD ENET1 RK EN ENET1 RK EN> Üx1b0b0 296》 》 UK6UL PAD ENET1 RY ER ENET1 RX ER> 0x1b0b0 297》 》 MK6UL PAD ENET1 RX DATAO ENET1 RDATAOO»x1b0b0 》 298》 》 》 MK6UL PAD ENET1 RX DATA1 ENET1 RDATAO1>Ox1b0bO 299》 》 》 IK6UL PAD ENET1 TX EN ENET1 TX EN> x1b0b0 300》 》 》 NK6UL_PAD_ENET1_TX_DATAO__ENET1_TDATAOO»Ox1b0b0 301》 》 》 IK6TL PAD ENET1 TX DATA1 ENET1 TDATAO1>Ox160b0 302》 》 》 MK6UL PAD ENET1 TXCLK ENET1 REF CLK1> 0x40016009 303 》 》 >: 304》 } : 305 306》 pinctrlenet2:enet2grp{ 307》 》 fsl,pins =< 308 》 》 》 IK6UL PAD GPIO1 IO07 ENET2 MDC>> Üx1b0b0 309》 》 》 ICK6UL PAD GPIO1 I006 ENET2 HDIO> 0x1b0b0 310》 》 》 IK6UL PAD ENET2 RK EN ENET2 RK EN> 0x1b0b0 311》 》 》 ICK6UL PAD ENET2 RK ER ENET2 RK ER> 0x1b0b0 312》 》 》 NK6UL PAD ENET2 RX DATAD ENET2 RDATAOO»x1b0bU 313》 》 》 NK6UL PAD ENET2 RX DATA1 ENET2 RDATAO1»x1b0b0 314》 》 》 IK6UL PAD ENET2 TX EN ENET2 TX EN> x1b0b0 315》 》 》 MK6UL PAD ENET2 TX DATAO ENET2 TDATAOO»Üx1b0b0 316》 MX6UL_PAD_ENET2_TX_DATA1__E ET2号tpi>y n 317》 》 》 IK6UL PAD ENET2 TXCLK ENET2 REF CLK2> 0x40016009
3.6.2 在arch/arm/boot/dts/imx6ul-pinfunc.h增加2个宏定义
这两个宏就是在3.6.1.2 修改iomuxc节点里用到了。
#define MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07 0x0024 0x0068 0x0000 0x5 0x0 #define MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08 0x0028 0x006C 0x0000 0x5 0x0
3.6.3 修改drivers/net/ethernet/freescale/fec_main.c
增加set_enet_tx_clk函数,并在fec_probe函数最开始调用它,设置寄存器的 SION 位为 1。
static void set_enet_tx_clk(void) { /* * 设置 MX6UL_PAD_ENET1_TX_CLK 和 MX6UL_PAD_ENET2_TX_CLK * 这两个 IO 的复用寄存器的 SION 位为 1。 */ void __iomem *IMX6U_ENET1_TX_CLK; void __iomem *IMX6U_ENET2_TX_CLK; IMX6U_ENET1_TX_CLK = ioremap(0X020E00DC, 4); writel(0X14, IMX6U_ENET1_TX_CLK); IMX6U_ENET2_TX_CLK = ioremap(0X020E00FC, 4); writel(0X14, IMX6U_ENET2_TX_CLK); } static int fec_probe(struct platform_device *pdev) { ···省略··· set_enet_tx_clk(); }
3.6.4 修改drivers/net/phy/smsc.c
增加2个头文件,df_phy_reset函数,并在smsc_phy_reset调用df_phy_reset复位phy。
#include <linux/of_gpio.h> #include <linux/io.h> static void df_phy_reset(struct phy_device *phydev) { int err; struct device_node *np; int msec = 1; int phy_reset; if(phydev->mdio.addr == 0) { /* FEC1 */ np = of_find_node_by_path("/soc/aips-bus@02100000/ethernet@02188000"); if(np == NULL) { pr_err("%s %d: get np fail\n", __func__, __LINE__); return; } } if(phydev->mdio.addr == 1) { /* FEC2 */ np = of_find_node_by_path("/soc/aips-bus@02000000/ethernet@020b4000"); if(np == NULL) { pr_err("%s %d: get np fail\n", __func__, __LINE__); return; } } err = of_property_read_u32(np, "phy-reset-duration", &msec); /* A sane reset duration should not be longer than 1s */ if (!err && msec > 1000) msec = 1; phy_reset = of_get_named_gpio(np, "phy-reset-gpios", 0); if (!gpio_is_valid(phy_reset)) return; gpio_direction_output(phy_reset, 0); gpio_set_value(phy_reset, 0); msleep(msec); gpio_set_value(phy_reset, 1); } static int smsc_phy_reset(struct phy_device *phydev) { ···省略··· df_phy_reset(phydev); ···省略··· }
至此,网络驱动修改完成,重新编译并启动。
测试
启动可以看到相关网络信息的打印,并且已经进入到根文件系统nfsroot,至此,kernel4.14.13算是成功移植到imx6ull上了,最重要的网络功能已经能正常使用。
3.651841] SMSC LAN8710/LAN872020b4000.ethernet-1:01:attached PHY driver[SMSC LAN8710/LAN8720](mii bus:phy addr=20b4000.ethernet-1:0l,irq=PoLL 3.669951] IPV6:ADDRCONF(NETDEV UP): eth0: link is not ready 5.773572] fec 20b4000.ethernet eth0: Link is Up-100Mbps/Full . flow control rx/tx 5.800395] IPV6:ADDRCONF(NETDEV CHANGE): eth0: link becomes ready 5.829959] IP.Contig:Complete: 5.833425 device=etho,hwaddr=00:04:9f:04:d2:35,ipaddr=192.168.1.100,mask=255.255.255.0,gw=192.168.1.1 5.847167 host=192.168.1.100,domain=,nis-domain=(none) 5.853354 bootserver=192.168.1.104,rootserver=192.168.1.104,rootpath= 5.867109] ALSA device list: 5.870171] #0:mx6ul-wm8960 5.965024] VFS: Mounted root (nfs filesystem) on device 0:12. 5.978374] devtmpfs:mounted 5.986200] Freeing unused kernel memory: 1024K mount:mounting tmpfs on /tmp failed: No such file or directory please press Enter to activate this console. dev etc bin # ls lib mnt linuxrc proc sbin rootfs.tar.bz2 sys us r var
号主:一枚机械专业本科生,经历了转行,从外包逆袭到芯片原厂的Linux驱动开发工程师,深入操作系统的世界,贯彻终身学习、终身成长的理念。平时喜欢折腾,寒冬之下,抱团取暖,期待你来一起探讨技术、搞自媒体副业,程序员接单和投资理财。【对了,不定期送闲置开发板、书籍、键盘等等】。
如果你想了解我的转行经验,欢迎找我交流~gongzhong号【哆哆jarvis】
一起不断探索自我、走出迷茫、找到热爱,希望和你成为朋友,一起成长~