移植Linux4.14.13到imx6ull

简介: 移植Linux4.14.13到imx6ull

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 =<&ethphy0>: 
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 =<&ethphy1>: 
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】

一起不断探索自我、走出迷茫、找到热爱,希望和你成为朋友,一起成长~

相关文章
|
4月前
|
Ubuntu Linux 开发工具
Linux下的IMX6ULL——环境搭建与软件安装(一)
Linux下的IMX6ULL——环境搭建与软件安装(一)
136 0
Linux下的IMX6ULL——环境搭建与软件安装(一)
|
4月前
|
Ubuntu Linux 虚拟化
Linux下的IMX6ULL——构建bootloader、内核、文件系统(四)
Linux下的IMX6ULL——构建bootloader、内核、文件系统(四)
202 0
Linux下的IMX6ULL——构建bootloader、内核、文件系统(四)
|
3月前
|
存储 编解码 Ubuntu
【QT】linux下alsa库的移植和QT中音视频的处理&笔记
【QT】linux下alsa库的移植和QT中音视频的处理&笔记
|
3月前
|
存储 编解码 Linux
【IMX6ULL项目】IMX6ULL上Linux系统实现产测工具框架(二)
【IMX6ULL项目】IMX6ULL上Linux系统实现产测工具框架(二)
65 1
|
3月前
|
网络协议 Linux 编译器
【原创】EtherCAT主站IgH解析(二)-- 如何将Igh移植到Linux/Windows/RTOS等多操作系统移植指南
EtherCAT主站方案对比:商业的如Acontis、TwinCAT3和开源的igh、SOEM。SOEM易移植但功能和实时性不足,适合简单应用;igh功能强大,实时性能优秀,基于内核态,适合复杂场景。igh能移植到其他RTOS,但需克服多任务无调度的挑战。依赖操作系统服务如定时器、内存分配,适合Linux内核,但移植到裸机复杂。
106 0
|
3月前
|
存储 Linux C语言
【IMX6ULL项目】IMX6ULL上Linux系统实现产测工具框架(一)
【IMX6ULL项目】IMX6ULL上Linux系统实现产测工具框架(一)
96 0
|
4月前
|
Linux 编译器 网络安全
嵌入式Linux移植dropbear
嵌入式Linux移植dropbear
149 3
|
4月前
|
JSON Ubuntu Linux
LuaJit交叉编译移植到ARM Linux
LuaJit交叉编译移植到ARM Linux
96 1
|
4月前
|
Linux 编译器 测试技术
嵌入式 Linux 下的 LVGL 移植
嵌入式 Linux 下的 LVGL 移植
179 0
|
4月前
|
Linux 计算机视觉
Linux交叉编译opencv并移植ARM端
通过以上步骤,你可以在Linux上交叉编译OpenCV,并将生成的库文件和头文件移植到ARM平台上,从而在ARM上使用OpenCV。 买CN2云服务器,免备案服务器,高防服务器,就选蓝易云。百度搜索:蓝易云
403 0