linux系统中详解u-boot之网络移植与调试

简介: linux系统中详解u-boot之网络移植与调试

今天给大家讲一讲如何完善u-boot网络部分的移植和调试。

一、前章回顾

上一章,已经讲过如何讲uboot.2022.10版本移植到我们自己的imx6ull开发板上,但是最后编译下载后网络部分未能正确识别,今天我们就来讲一讲网络部分的调试。

上一篇uboot编译后,上电启动,串口打印如下:

U-Boot 2022.10-gaef9f25a-dirty (Apr 05 2023 - 17:49:18 +0800)
CPU:   Freescale i.MX6ULL rev1.1 792 MHz (running at 396 MHz)
CPU:   Industrial temperature grade (-40C to 105C) at 26C
Reset cause: POR
Model: Freescale i.MX6 UltraLiteLite 14x14 EVK Board
Board: MX6ULL TOTO
DRAM:  512 MiB
Core:  65 devices, 17 uclasses, devicetree: separate
MMC:   FSL_SDHC: 0, FSL_SDHC: 1
Loading Environment from MMC... OK
In:    serial
Out:   serial
Err:   serial
Net:   Could not get PHY for FEC1: addr 1
Could not get PHY for FEC1: addr 1
Get shared mii bus on ethernet@2188000
Could not get PHY for FEC1: addr 2
Get shared mii bus on ethernet@2188000
Could not get PHY for FEC1: addr 2
No ethernet found.
Hit any key to stop autoboot: 
=>

通过打印信息,我们可以发现连phy都没有正确识别到。首先来回顾一下,上一篇我们采用的是NXP官方默认imx6ull开发板的配置参数,任何参数都未做修改,现在使用默认配置网络未能正确识别,说明我们的硬件设计与官方的设计有偏差。因此,首先需要查看原理图,确认默认NXP imx6ull的网络管脚与我们自己硬件原理图上是否一致。

二、硬件原理图检查

1.确认硬件原理图的fec对应的phy地址

从imx6ull开发板硬件原理图上可以得到,ENET1对应的phy addr为:0x0,ENET2对应的phy addr为:0x1。

2.修改网卡fec1的phy地址

imx6ull对应的设备树文件imx6ull-14x14-evk.dtsi,从设备树文件中可以得到,imx6ull FEC1对应为ethphy0,而ethphy0对应的phy地址默认为2,这与我们开发板硬件给的phy地址不符合,因此修改设备树中FEC1对应的phy地址为0

&fec1 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_enet1>;
    phy-mode = "rmii";
    phy-handle = <&ethphy0>;
    phy-supply = <&reg_peri_3v3>;
    status = "okay";
};
&fec2 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_enet2>;
    phy-mode = "rmii";
    phy-handle = <&ethphy1>;
    phy-supply = <&reg_peri_3v3>;
    status = "okay";    
    mdio {
        #address-cells = <1>;
        #size-cells = <0>;
        ethphy0: ethernet-phy@2 {
            compatible = "ethernet-phy-id0022.1560";
            reg = <2>;
            ...
        };
        ethphy1: ethernet-phy@1 {
            compatible = "ethernet-phy-id0022.1560";
            reg = <1>;
            ...
        };
    };
};

修改FEC1节点对应的phy地址为0x0,如下;

mdio {
        #address-cells = <1>;
        #size-cells = <0>;
        ethphy0: ethernet-phy@0 {
            compatible = "ethernet-phy-id0022.1560";
            reg = <0>;
            micrel,led-mode = <1>;
            clocks = <&clks IMX6UL_CLK_ENET_REF>;
            clock-names = "rmii-ref";
        };
        ...
    }

重新编译,烧写验证,还是报错。

3.网络初始化检查

接下来就只有从网络初始化入口initr_net函数开始,查看网络初始化哪里有问题。

在board_r文件中的init_sequence_r调用

可以看到initr_net函数其实就两个作用,一是调用eth_initialize进行网络初始化,二是调用reset_phy对phy进行复位,具体实现,如下;

static int initr_net(void)
{
    puts("Net:   ");
    eth_initialize();
#if defined(CONFIG_RESET_PHY_R)
    debug("Reset Ethernet PHY\n");
    reset_phy();
#endif
    return 0;
}

继续往下,我们可以看到,phy_init初始化函数中只调用了phy_micrel_ksz8xxx_init对Micrel公司生产的ksz8系列的phy进行了初始化,如下;

int phy_init(void)
{
...
#ifdef CONFIG_PHY_MICREL_KSZ8XXX
    phy_micrel_ksz8xxx_init();
#endif 
#ifdef CONFIG_PHY_MICREL_KSZ90X1
    phy_micrel_ksz90x1_init();
#endif
...
#ifdef CONFIG_PHY_SMSC
    phy_smsc_init();
#endif
...
    genphy_init();
    return 0;
}

而我们的硬件fec1和fec2都是使用SMSC公司生产的LAN8720A,因此修改为调用phy_smsc_init初始化phy芯片LAN8720A。

具体修改为在mx6ull_toto_defconfig文件添加宏定义CONFIG_PHY_SMSC=y;然后屏蔽CONFIG_PHY_MICREL=y和CONFIG_PHY_MICREL_KSZ8XXX=y,如下;

4.fec部分管脚确认

继续往下,在fecmxc_probe函数中发现调用了fec_gpio_reset()函数复位fec网卡,但是设备树文件中没有配置复位管脚

fecmxc_of_to_plat函数会对设备中的phy的这三个定义进行解析。因此在设备中添加如下三个定义:

在硬件原理图中找到eth1、eth2phy复位管脚对应imx6ull芯片的管脚

设备树文件imx6ul-14x14-evk.dtsi中,具体配置如下:

5.检查是否存在多设备管脚复用

下面要做的就是查看在设备树文件中查看一下,刚刚添加的两个GPIO管脚在其他设备中是否存在该管脚复用情况

查找结果如上,spi4接口中使用了GPIO5的7和8两个管脚,并且该设备status状态为“okay”激活,解决方法如下,disable掉spi4接口。

还有一种方法就是删除使用gpio5两个管脚的两行定义,这里就不演示了。

编译验证如下

uboot下只会使用一个网口,因此屏蔽一个

6.使用默认ENET2

使用uboot中imx6ull默认的网卡ENET2默认网卡,宏定义CONFIG_FEC_ENENT_DEV,路径:/include/configs/mx6ull_toto.h

#ifdef CONFIG_CMD_NET
#define CONFIG_FEC_ENET_DEV     1
#endif

在设备树文件中将FEC1节点的status设置为disabled

&fec1 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_enet1>;
    phy-mode = "rmii";
    phy-handle = <&ethphy0>;
    phy-supply = <&reg_peri_3v3>;
    phy-reset-gpios = <&gpio5 7 GPIO_ACTIVE_LOW>; // 复位引脚
    phy-reset-duration = <100>;
    phy-reset-post-delay = <100>;
    status = "disabled";    //禁用
};

三、编译烧写,下载验证

SecureCRT 输出结果如下:

U-Boot 2022.10-g8d3c4ea8-dirty (May 20 2023 - 11:49:18 +0800)
CPU:   Freescale i.MX6ULL rev1.1 792 MHz (running at 396 MHz)
CPU:   Industrial temperature grade (-40C to 105C) at 34C
Reset cause: POR
Model: Freescale i.MX6 UltraLiteLite 14x14 EVK Board
Board: MX6ULL TOTO
DRAM:  512 MiB
Core:  61 devices, 17 uclasses, devicetree: separate
MMC:   FSL_SDHC: 0, FSL_SDHC: 1
Loading Environment from MMC... OK
In:    serial
Out:   serial
Err:   serial
Net:   
Error: ethernet@20b4000 address not set.
Error: ethernet@20b4000 address not set.
No ethernet found.
Hit any key to stop autoboot:  0 
=> 
=>

提示:

Error: ethernet@20b4000 address not set.
Error: ethernet@20b4000 address not set.
No ethernet found.

这是因为没有设置网络环境变量

  • 手动设置
  • 系统配置,默认生成
1.设置网络环境变量
setenv ethaddr 32:34:46:78:9A:DC    //设置开发板网卡1 MAC地址 
setenv eth1addr 32:34:46:78:9A:DD   //设置开发板网卡2 MAC地址 
setenv serverip 192.168.0.106       //设置服务器地址,一般是windows或Ubuntu地址
setenv ipaddr 192.168.0.123         //设置开发板IP地址 
setenv gatewayip 192.168.0.1        //设置开发板默认网关 
setenv netmask 255.255.255.0        //设置开发板子网掩码
setenv bootdelay 5                  //设置启动延时实际
saveenv                             //将改变覆盖到MMC

注意:u-boot的环境变量是设置在MMC中的,不会随着UBoot重新编译而清除,如果修改乱了可以使用如下命令恢复默认:

env default -a // 恢复默认设置

saveenv        // 将改变覆盖到MMC

2.使用软件配置,默认生成

configs/mx6ull_toto_defconfig 文件,使能随机生成MAC地址

CONFIG_NET_RANDOM_ETHADDR=y

重启开发板,打印信息如下;

U-Boot 2022.10-g8d3c4ea8-dirty (May 20 2023 - 11:49:18 +0800)


CPU:   Freescale i.MX6ULL rev1.1 792 MHz (running at 396 MHz)

CPU:   Industrial temperature grade (-40C to 105C) at 45C

Reset cause: WDOG

Model: Freescale i.MX6 UltraLiteLite 14x14 EVK Board

Board: MX6ULL TOTO

DRAM:  512 MiB

Core:  61 devices, 17 uclasses, devicetree: separate

MMC:   FSL_SDHC: 0, FSL_SDHC: 1

Loading Environment from MMC... OK

In:    serial

Out:   serial

Err:   serial

Net:   eth1: ethernet@20b4000 [PRIME]

Hit any key to stop autoboot:  0

=>

=>

3.验证网络是否连通

使用ping命令,验证网络是否可以正常工作

=> ping 192.168.0.106
Using ethernet@20b4000 device
ARP Retry count exceeded; starting again
ping failed; host 192.168.0.106 is not alive
=>

ping测试失败

  • 原因1:可能是windows的防火墙没有关,
  • 原因2:LAN8720初始化需要复位,修改SMSC驱动。
    我这边的原因就是ubootLAN8720初始化没有进行复位,在 drivers/net/phy/phy.c 文件中修改:

int genphy_config_aneg(struct phy_device *phydev)

{

   int result;


   /* SOFT RESET */

   phy_reset(phydev);


   if (phydev->autoneg != AUTONEG_ENABLE)

       return genphy_setup_forced(phydev);


   result = genphy_config_advert(phydev);

   ...

   ...

}

再次编译重启开发板,Ping成功。

=> ping 192.168.0.106
Using ethernet@20b4000 device
host 192.168.0.106 is alive
=>

四、FEC1网卡1调试

使用 ENET1 网卡的话就稍微复杂一点了,不是简单的将 fec2 节点下的 status 改为“disabled”,需要对在设备树arch/arm/dts/imx6ul-14x14-evk.dtsi文件进行修改和添加。

1.屏蔽或删除掉 fec2 节点内容

/*

&fec2 {

   pinctrl-names = "default";

   pinctrl-0 = <&pinctrl_enet2>;

   phy-mode = "rmii";

   phy-handle = <&ethphy1>;

   phy-supply = <&reg_peri_3v3>;

   phy-reset-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>;

   phy-reset-duration = <200>;

   phy-reset-post-delay = <100>;

   status = "okay";    


   mdio {

       #address-cells = <1>;

       #size-cells = <0>;


       ethphy0: ethernet-phy@0 {

           compatible = "ethernet-phy-id0022.1560";

           reg = <0>;

           micrel,led-mode = <1>;

           clocks = <&clks IMX6UL_CLK_ENET_REF>;

           clock-names = "rmii-ref";


       };


       ethphy1: ethernet-phy@1 {

           compatible = "ethernet-phy-id0022.1560";

           reg = <1>;

           micrel,led-mode = <1>;

           clocks = <&clks IMX6UL_CLK_ENET2_REF>;

           clock-names = "rmii-ref";

       };

   };

};

*/

2.在fec1 节点下添加 mdio 子节点

&fec1 {

   pinctrl-names = "default";

   pinctrl-0 = <&pinctrl_enet1>;

   phy-mode = "rmii";

   phy-handle = <&ethphy0>;

   phy-supply = <&reg_peri_3v3>;

   phy-reset-gpios = <&gpio5 7 GPIO_ACTIVE_LOW>;

   phy-reset-duration = <100>;

   phy-reset-post-delay = <100>;

   status = "okay";


   mdio {

       #address-cells = <1>;

       #size-cells = <0>;


       ethphy0: ethernet-phy@0 {

           compatible = "ethernet-phy-id0022.1560";

           reg = <0>;

           micrel,led-mode = <1>;

           clocks = <&clks IMX6UL_CLK_ENET_REF>;

           clock-names = "rmii-ref";

       };

   };

};

3.添加MDIO和MDC引脚配置

在 ENET1 网卡对应的 pinctrl 节点中添加 MDIO 和 MDC 引脚配置

  • 将 GPIO1_IO07 复用为 ENET1_MDC 引脚
  • 将 GPIO1_IO06 复用为 ENET1_MDIO 引脚

pinctrl_enet1: enet1grp {

   fsl,pins = <

       MX6UL_PAD_GPIO1_IO07__ENET1_MDC     0x1b0b0

       MX6UL_PAD_GPIO1_IO06__ENET1_MDIO    0x1b0b0

       ...

       MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1  0x4001b031

   >;

};

4.修改ENET设备为enet0

在include/configs/mu6ull_toto.h中修改宏CONFIG_FEC_ENET_DEV为0,使用enet0

#ifdef CONFIG_CMD_NET
#define CONFIG_FEC_ENET_DEV     0
#endif

编译下载重启开发板,打印信息如下;

U-Boot 2022.10-g8d3c4ea8-dirty (May 20 2023 - 14:19:23 +0800)
CPU:   Freescale i.MX6ULL rev1.1 792 MHz (running at 396 MHz)
CPU:   Industrial temperature grade (-40C to 105C) at 40C
Reset cause: WDOG
Model: Freescale i.MX6 UltraLiteLite 14x14 EVK Board
Board: MX6ULL TOTO
DRAM:  512 MiB
Core:  60 devices, 17 uclasses, devicetree: separate
MMC:   FSL_SDHC: 0, FSL_SDHC: 1
Loading Environment from MMC... OK
In:    serial
Out:   serial
Err:   serial
Net:   eth0: ethernet@2188000
Hit any key to stop autoboot:  0
=>
=> ping 192.168.0.106
Using ethernet@2188000 device
host 192.168.0.106 is alive
=>

至此,imx6ull在uboot下FEC1和FEC2均可单独使用,感兴趣的朋友可以试一试uboot如何让fec1和fec2两个网卡同时工作。

目录
相关文章
|
23天前
|
Linux
在 Linux 系统中,“cd”命令用于切换当前工作目录
在 Linux 系统中,“cd”命令用于切换当前工作目录。本文详细介绍了“cd”命令的基本用法和常见技巧,包括使用“.”、“..”、“~”、绝对路径和相对路径,以及快速切换到上一次工作目录等。此外,还探讨了高级技巧,如使用通配符、结合其他命令、在脚本中使用,以及实际应用案例,帮助读者提高工作效率。
64 3
|
23天前
|
监控 安全 Linux
在 Linux 系统中,网络管理是重要任务。本文介绍了常用的网络命令及其适用场景
在 Linux 系统中,网络管理是重要任务。本文介绍了常用的网络命令及其适用场景,包括 ping(测试连通性)、traceroute(跟踪路由路径)、netstat(显示网络连接信息)、nmap(网络扫描)、ifconfig 和 ip(网络接口配置)。掌握这些命令有助于高效诊断和解决网络问题,保障网络稳定运行。
59 2
|
18天前
|
Ubuntu Linux 网络安全
linux系统ubuntu中在命令行中打开图形界面的文件夹
在Ubuntu系统中,通过命令行打开图形界面的文件夹是一个高效且实用的操作。无论是使用Nautilus、Dolphin还是Thunar,都可以根据具体桌面环境选择合适的文件管理器。通过上述命令和方法,可以简化日常工作,提高效率。同时,解决权限问题和图形界面问题也能确保操作的顺利进行。掌握这些技巧,可以使Linux操作更加便捷和灵活。
15 3
|
23天前
|
安全 网络协议 Linux
本文详细介绍了 Linux 系统中 ping 命令的使用方法和技巧,涵盖基本用法、高级用法、实际应用案例及注意事项。
本文详细介绍了 Linux 系统中 ping 命令的使用方法和技巧,涵盖基本用法、高级用法、实际应用案例及注意事项。通过掌握 ping 命令,读者可以轻松测试网络连通性、诊断网络问题并提升网络管理能力。
64 3
|
26天前
|
安全 Linux 数据安全/隐私保护
在 Linux 系统中,查找文件所有者是系统管理和安全审计的重要技能。
在 Linux 系统中,查找文件所有者是系统管理和安全审计的重要技能。本文介绍了使用 `ls -l` 和 `stat` 命令查找文件所有者的基本方法,以及通过文件路径、通配符和结合其他命令的高级技巧。还提供了实际案例分析和注意事项,帮助读者更好地掌握这一操作。
43 6
|
16天前
|
安全 网络安全 数据安全/隐私保护
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
在数字化时代,网络安全和信息安全已成为我们生活中不可或缺的一部分。本文将介绍网络安全漏洞、加密技术和安全意识等方面的知识,并提供一些实用的技巧和建议,帮助读者更好地保护自己的网络安全和信息安全。
|
5天前
|
存储 SQL 安全
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
随着互联网的普及,网络安全问题日益突出。本文将介绍网络安全的重要性,分析常见的网络安全漏洞及其危害,探讨加密技术在保障网络安全中的作用,并强调提高安全意识的必要性。通过本文的学习,读者将了解网络安全的基本概念和应对策略,提升个人和组织的网络安全防护能力。
|
6天前
|
SQL 安全 网络安全
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
随着互联网的普及,网络安全问题日益突出。本文将从网络安全漏洞、加密技术和安全意识三个方面进行探讨,旨在提高读者对网络安全的认识和防范能力。通过分析常见的网络安全漏洞,介绍加密技术的基本原理和应用,以及强调安全意识的重要性,帮助读者更好地保护自己的网络信息安全。
24 10
|
8天前
|
SQL 安全 网络安全
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
在数字化时代,网络安全和信息安全已成为我们生活中不可或缺的一部分。本文将介绍网络安全漏洞、加密技术和安全意识等方面的内容,并提供一些实用的代码示例。通过阅读本文,您将了解到如何保护自己的网络安全,以及如何提高自己的信息安全意识。
33 10
|
6天前
|
安全 网络安全 数据安全/隐私保护
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
在数字化时代,网络安全和信息安全已成为我们日常生活中不可或缺的一部分。本文将深入探讨网络安全漏洞、加密技术和安全意识等方面的问题,并提供一些实用的建议和解决方案。我们将通过分析网络攻击的常见形式,揭示网络安全的脆弱性,并介绍如何利用加密技术来保护数据。此外,我们还将强调提高个人和企业的安全意识的重要性,以应对日益复杂的网络威胁。无论你是普通用户还是IT专业人士,这篇文章都将为你提供有价值的见解和指导。