首页 > 系统相关 >【IMX6ULL学习笔记】九、Linux内核移植

【IMX6ULL学习笔记】九、Linux内核移植

时间:2023-02-17 15:33:50浏览次数:43  
标签:kodo ENET2 dtb phy 内核 Linux imx6ull IMX6ULL

一、在 Linux 中添加自己的开发板
1、添加开发板默认配置文件
将 arch/arm/configs 目 录 下 的 imx_v7_mfg_defconfig 重新复制一份,命名为 imx_kodo_emmc_defconfig,命令如下:
cd arch/arm/configs
cp imx_v7_mfg_defconfig imx_kodo_emmc_defconfig

以后就可以使用如下命令来配置正点原子 EMMC 版开发板对应的 Linux 内核了:
make imx_kodo_emmc_defconfig

2、添加开发板对应的设备树文件
添加适合 EMMC 版开发板的设备树文件,进入目录 arch/arm/boot/dts 中,复制一份 imx6ull-14x14-evk.dts,将其重命名为 imx6ull-kodo-emmc.dts,命令如下:
cd arch/arm/boot/dts
cp imx6ull-14x14-evk.dts imx6ull-kodo-emmc.dts

.dts 是设备树源码文件,编译 Linux 的时候会将其编译为.dtb 文件。imx6ull-kodo-emmc.dts 创建好以后还需要修改文件 arch/arm/boot/dts/Makefile , 找到 “ dtb- \((CONFIG_SOC_IMX6ULL)”配置项,在此配置项中加入“imx6ull-kodo-emmc.dtb”,如下所示: dtb-\)(CONFIG_SOC_IMX6ULL) +=
imx6ull-14x14-ddr3-arm2.dtb
imx6ull-14x14-ddr3-arm2-adc.dtb
imx6ull-14x14-ddr3-arm2-cs42888.dtb
imx6ull-14x14-ddr3-arm2-ecspi.dtb
imx6ull-14x14-ddr3-arm2-emmc.dtb
imx6ull-14x14-ddr3-arm2-epdc.dtb
imx6ull-14x14-ddr3-arm2-flexcan2.dtb
imx6ull-14x14-ddr3-arm2-gpmi-weim.dtb
imx6ull-14x14-ddr3-arm2-lcdif.dtb
imx6ull-14x14-ddr3-arm2-ldo.dtb
imx6ull-14x14-ddr3-arm2-qspi.dtb
imx6ull-14x14-ddr3-arm2-qspi-all.dtb
imx6ull-14x14-ddr3-arm2-tsc.dtb
imx6ull-14x14-ddr3-arm2-uart2.dtb
imx6ull-14x14-ddr3-arm2-usb.dtb
imx6ull-14x14-ddr3-arm2-wm8958.dtb
imx6ull-14x14-evk.dtb
imx6ull-14x14-evk-btwifi.dtb
imx6ull-14x14-evk-emmc.dtb
imx6ull-14x14-evk-gpmi-weim.dtb
imx6ull-14x14-evk-usb-certi.dtb
imx6ull-kodo-emmc.dtb
imx6ull-9x9-evk.dtb
imx6ull-9x9-evk-btwifi.dtb
imx6ull-9x9-evk-ldo.dtb

第 23 行为“imx6ull-alientek-emmc.dtb”,编译 Linux 的时候就可以从 imx6ull-kodo-emmc.dts 编译出 imx6ull-kodo-emmc.dtb 文件了。

3、编译测试
创建一个编译脚本 kodo.sh,脚本内容如下:

!/bin/sh

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf imx_kodo_emmc_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- all -j16

第 2 行:清理工程。
第 3 行:使用默认配置文件 imx_kodo_emmc_defconfig 来配置 Linux 内核。
第 4 行:打开 Linux 的图形配置界面,不需要每次都打开图形配置界面可以删除。
第 5 行:编译 Linux。

执行 shell 脚本 kodo.sh 编译 Linux 内核,命令如下:
chmod 777 kodo.sh //给予可执行权限
./kodo.sh //执行 shell 脚本编译内核

编译完成以后就会在目录 arch/arm/boot 下生成 zImage 镜像文件。在 arch/arm/boot/dts 目录下生成 imx6ull-kodo-emmc.dtb 文件。将这两个文件拷贝到 tftp 目录下,然后重启开发板,在 uboot 命令模式中使用 tftp 命令下载这两个文件并启动,命令如下:
tftp 80800000 zImage
tftp 83000000 imx6ull-kodo-emmc.dtb
bootz 80800000 - 83000000

只要出现如图所示内容就表示 Linux 内核启动成功:

二、CPU 主频和驱动修改
1、CPU 主频修改

2、使能 8 线 EMMC 驱动
Linux 内核驱动里面 EMMC 默认是 4 线模式的, 8 线模式的速度快,所以将 EMMC 的驱动修改为 8 线模式,直接修改设备树即可,打开文件 imx6ull-kodo-emmc.dts,找到如下所示内容:
&usdhc2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usdhc2>;
non-removable;

status = "okay";

};

将其改为如下代码即可:
&usdhc2 {
pinctrl-names = "default", "state_100mhz", "state_200mhz";
pinctrl-0 = <&pinctrl_usdhc2_8bit>;
pinctrl-1 = <&pinctrl_usdhc2_8bit_100mhz>;
pinctrl-2 = <&pinctrl_usdhc2_8bit_200mhz>;
bus-width = <8>;
non-removable;
no-1-8-v;
status = "okay";
};

修改完成以后保存一下 imx6ull-kodo-emmc.dts,然后使用命令“make dtbs”重新编译一下设备树,编译完成以后使用新的设备树重启 Linux 系统即可。

3、修改网络驱动
学习 Linux 驱动开发的时候要用到网络调试驱动,所以要把网络驱动调试好。开发板的网络和 NXP 官方的网络硬件上不同,网络 PHY 芯片由 KSZ8081 换为了 LAN8720A,两个网络 PHY 芯片的复位 IO 也不同,需要做修改。

①、修改 LAN8720 的复位以及网络时钟引脚驱动
ENET1 复位引脚 ENET1_RST 连接在 I.M6ULL 的 SNVS_TAMPER7 这个引脚上。ENET2 的复位引脚 ENET2_RST 连接在 I.MX6ULL 的 SNVS_TAMPER8 上。
打开设备树文件 imx6ull-kodo-emmc.dts,找到如下代码:
pinctrl_spi4: spi4grp {
fsl,pins = <
MX6ULL_PAD_BOOT_MODE0__GPIO5_IO10 0x70a1
MX6ULL_PAD_BOOT_MODE1__GPIO5_IO11 0x70a1
MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07 0x70a1
MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08 0x80000000
>;
};

示例代码中第 5 和 6 行就是初始化 SNVS_TAMPER7 和 SNVS_TAMPER8 这两个
引脚的,不过是作为了 SPI4 的 IO,所以将 5 和 6 这两行注释掉。
继续在 imx6ull-alientek-emmc.dts 中找到如下所示代码:
spi4 {
compatible = "spi-gpio";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_spi4>;
pinctrl-assert-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>;
......
cs-gpios = <&gpio5 7 0>;

第 5 行:设置 GPIO5_IO08 为 SPI4 的一个功能引脚(不清楚具体作为什么功能用),而 GPIO5_IO08 就是 SNVS_TAMPER8 的 GPIO 功能引脚。
第 7 行:设置 GPIO5_IO07 作为 SPI4 的片选引脚,而 GPIO5_IO07 就是 SNVS_TAMPER7 的 GPIO 功能引脚。需要 GPIO5_IO07 和 GPIO5_IO08 分别作为 ENET1 和 ENET2 的复位引脚,因此将示例代码中的第 5 行和第 7 行处的代码注释掉!

在 imx6ull-kodo-emmc.dts 里面找到名为“iomuxc_snvs”的节点(就是直接搜索),然后在此节点下添加网络复位引脚信息,添加完成以后的“iomuxc_snvs”的节点内容如下:
&iomuxc_snvs {
pinctrl-names = "default_snvs";
pinctrl-0 = <&pinctrl_hog_2>;
imx6ul-evk {
......
/省略掉其他/

    /*enet1 reset zuozhongkai*/
    pinctrl_enet1_reset: enet1resetgrp {
        fsl,pins = <
            /* used for enet1 reset */
            MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07 0x10B0
        >;
    };
    
    /*enet2 reset zuozhongkai*/
    pinctrl_enet2_reset: enet2resetgrp {
        fsl,pins = <
            /* used for enet2 reset */
            MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08 0x10B0
        >;
    };
};

};

第 1 行:imx6ull-kodo-emmc.dts 文件中 iomuxc_snvs 节点。
第 9~14 行:ENET1 网络复位引脚配置信息。
第 17~22 行:ENET2 网络复位引脚配置信息。

最后还需要修改一下 ENET1 和 ENET2 的网络时钟引脚配置,继续在 imx6ull-kodo-emmc.dts 中找到如下所示代码:
pinctrl_enet1: enet1grp {
fsl,pins = <
MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN 0x1b0b0
MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER 0x1b0b0
MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00 0x1b0b0
MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01 0x1b0b0
MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN 0x1b0b0
MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x1b0b0
MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x1b0b0
MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 0x4001b009
>;
};

pinctrl_enet2: enet2grp {
fsl,pins = <
MX6UL_PAD_GPIO1_IO07__ENET2_MDC 0x1b0b0
MX6UL_PAD_GPIO1_IO06__ENET2_MDIO 0x1b0b0
MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN 0x1b0b0
MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER 0x1b0b0
MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00 0x1b0b0
MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01 0x1b0b0
MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN 0x1b0b0
MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b0b0
MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b0b0
MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 0x4001b009
>;
};

第 10 和 25 行:分别为 ENET1 和 ENET2 的网络时钟引脚配置信息,将这两个引脚的电气属性值改为 0x4001b009,原来默认值为 0x4001b031。

修改完成以后保存一下 imx6ull-kodo-emmc.dts,网络复位以及时钟引脚驱动就修改好了。

②、修改 fec1 和 fec2 节点的 pinctrl-0 属性
在 imx6ull-kodo-emmc.dts 文件中找到名为“fec1”和“fec2”的这两个节点,修改其中的“pinctrl-0”属性值,修改以后如下所示:
&fec1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet1
&pinctrl_enet1_reset>;
phy-mode = "rmii";
......
status = "okay";
};

&fec2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet2
&pinctrl_enet2_reset>;
phy-mode = "rmii";
......
};

第 3~4 行:修改后的 fec1 节点“pinctrl-0”属性值。
第 12~13 行:修改后的 fec2 节点“pinctrl-0”属性值。

③、修改 LAN8720A 的 PHY 地址
在 uboot 移植时, ENET1 的 LAN8720A 地址为 0x0,ENET2 的 LAN8720A
地址为 0x1。在 imx6ull-kodo-emmc.dts 中找到如下代码:
&fec1 {
pinctrl-names = "default";
......
phy-handle = <&ethphy0>;
status = "okay";
};

&fec2 {
pinctrl-names = "default";
......
phy-handle = <&ethphy1>;
status = "okay";

mdio {
    #address-cells = <1>;
    #size-cells = <0>;

    ethphy0: ethernet-phy@0 {
        compatible = "ethernet-phy-ieee802.3-c22";
        reg = <2>;
    };

    ethphy1: ethernet-phy@1 {
        compatible = "ethernet-phy-ieee802.3-c22";
        reg = <1>;
    };
};

};

第 1~6 行:ENET1 对应的设备树节点。
第 8~28 行:ENET2 对应的设备树节点。但是第 14~26 行的 mdio 节点描述了 ENET1 和 ENET2 的 PHY 地址信息。将代码改为如下内容:
&fec1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet1
&pinctrl_enet1_reset>;
phy-mode = "rmii";
phy-handle = <&ethphy0>;
phy-reset-gpios = <&gpio5 7 GPIO_ACTIVE_LOW>;
phy-reset-duration = <200>;
status = "okay";
};

&fec2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet2
&pinctrl_enet2_reset>;
phy-mode = "rmii";
phy-handle = <&ethphy1>;
phy-reset-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>;
phy-reset-duration = <200>;
status = "okay";

mdio {
    #address-cells = <1>;
    #size-cells = <0>;

    ethphy0: ethernet-phy@0 {
        compatible = "ethernet-phy-ieee802.3-c22";
        smsc,disable-energy-detect;
        reg = <0>;
    };

    ethphy1: ethernet-phy@1 {
        compatible = "ethernet-phy-ieee802.3-c22";
        smsc,disable-energy-detect;
        reg = <1>;
    };
};

};

第 18 和 19 行:添加了 ENET1 网络复位引脚所使用的 IO 为 GPIO5_IO07,低电平有效,复位低电平信号持续时间为 200ms。
第 18 和 19 行:ENET2 网络复位引脚所使用的 IO 为 GPIO5_IO08,同样低电平有效,持续时间同样为 200ms。
第 28 和 34 行:“smsc,disable-energy-detect”表明 PHY 芯片是 SMSC 公司的,这样 Linux 内核就会找到 SMSC 公司的 PHY 芯片驱动来驱动 LAN8720A。
第 26 行:注意“ethernet-phy@”后面的数字是 PHY 的地址,ENET1 的 PHY 地址为 0,所以“@”后面是 0(默认为 2)。
第 29 行:reg 的值也表示 PHY 地址,ENET1 的 PHY 地址为 0,所以 reg=0。
第 32 行:ENET2 的 PHY 地址为 1,因此“@”后面为 1。
第 35 行:因为 ENET2 的 PHY 地址为 1,所以 reg=1。
至此,LAN8720A 的 PHY 地址就改好了,保存一下 imx6ull-kodo-emmc.dts 文件。然后使用“make dtbs”命令重新编译一下设备树。

④、修改 fec_main.c 文件
要在 I.MX6ULL 上使用 LAN8720A,需要修改一下 Linux 内核源码,打开
drivers/net/ethernet/freescale/fec_main.c,找到 fec_probe 函数,加入如下代码:
static int
fec_probe(struct platform_device *pdev)
{
struct fec_enet_private *fep;
struct fec_platform_data *pdata;
struct net_device *ndev;
int i, irq, ret = 0;
struct resource *r;
const struct of_device_id *of_id;
static int dev_id;
struct device_node *np = pdev->dev.of_node, *phy_node;
int num_tx_qs;
int num_rx_qs;

/* 设置 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);

......
return ret;
}

第 18~25 就是新加入的代码,如果要在 I.MX6ULL 上使用 LAN8720A 就需要设置
ENET1 和 ENET2 的 TX_CLK 引脚复位寄存器的 SION 位为 1。

⑤、配置 Linux 内核,使能 LAN8720 驱动
输入命令“make menuconfig”,打开图形化配置界面,选择使能 LAN8720A 的驱动,路径如下:
-> Device Drivers
-> Network device support
-> PHY Device support and infrastructure
-> Drivers for SMSC PHYs

⑥、修改 smsc.c 文件
在测试 NFS 挂载文件系统的时候发现文件系统挂载成功率很低!提示 NFS 服务器找不到。NFS 挂载就是通过网络来挂载文件系统,这样做的好处就是方便我们后续调试 Linux 驱动。既然是挂载失败那么可以肯定的是网络驱动有问题,网络驱动分两部分:内部 MAC+外部 PHY,内部 MAC 驱动是由 NXP 提供的,一般不会出问题,所以只有可能是外部 PHY,也就是 LAN8720A 的驱动可能出问题了。在 uboot 中需要对LAN8720A 进行一次软复位,要设置 LAN8720A 的 BMCR(寄存器地址为 0)寄存器 bit15 为 1。所以猜测,在 Linux 中也需要对 LAN8720A 进行一次软复位。
LAN8720A 的驱动文件是 drivers/net/phy/smsc.c,在此文件中有个叫做 smsc_phy_reset 的函数,看名字这是 SMSC PHY 的复位函数,因此 LAN8720A 肯定也会使用到这个复位函数,修改此函数的内容,修改以后的 smsc_phy_reset
函数内容如下所示:
static int smsc_phy_reset(struct phy_device *phydev)
{
int err, phy_reset;
int msec = 1;
struct device_node np;
int timeout = 50000;
if(phydev->addr == 0) /
FEC1 */ {
np = of_find_node_by_path("/soc/aips-bus@02100000/ethernet@02188000");
if(np == NULL) {
return -EINVAL;
}
}

if(phydev->addr == 1) /* FEC2 */ {
    np = of_find_node_by_path("/soc/aips-bus@02000000/ethernet@020b4000");
    if(np == NULL) {
        return -EINVAL;
    }
}

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);

int rc = phy_read(phydev, MII_LAN83C185_SPECIAL_MODES);
if (rc < 0)
    return rc;

/* If the SMSC PHY is in power down mode, then set it
  * in all capable mode before using it.
  */
if ((rc & MII_LAN83C185_MODE_MASK) ==
    MII_LAN83C185_MODE_POWERDOWN) {
    /* set "all capable" mode and reset the phy */
    rc |= MII_LAN83C185_MODE_ALL;
    phy_write(phydev, MII_LAN83C185_SPECIAL_MODES, rc);
}

phy_write(phydev, MII_BMCR, BMCR_RESET);
/* wait end of reset (max 500 ms) */

do {
    udelay(10);
    if (timeout-- == 0)
        return -1;
    rc = phy_read(phydev, MII_BMCR);
} while (rc & BMCR_RESET);
return 0;

}

第 7~12 行:获取 FEC1 网卡对应的设备节点。
第 14~19 行:获取 FEC2 网卡对应的设备节点。
第 21 行:从设备树中获取“phy-reset-duration”属性信息,也就是复位时间。
第 25 行:从设备树中获取“phy-reset-gpios”属性信息,也就是复位 IO。
第 29~32 行:设置 PHY 的复位 IO,复位 LAN8720A。
第 41~48 行:以前的 smsc_phy_reset 函数会判断 LAN8720 是否处于 Powerdown 模式,只有处于 Powerdown 模式的时候才会软复位 LAN8720。这里我们将软复位代码移出来,这样每次调用 smsc_phy_reset 函数 LAN8720A 都会被软复位。
最后我们还需要在 drivers/net/phy/smsc.c 文件中添加两个头文件,因为修改后的 smsc_phy_reset 函数用到了 gpio_direction_output 和 gpio_set_value 这两个函数,需要添加的头文件如下所示:

include <linux/of_gpio.h>

include <linux/io.h>

⑦、网络驱动测试
修改好设备树和 Linux 内核以后重新编译一下,得到新的 zImage 镜像文件和 imx6ull-kodo-emmc.dtb 设备树文件,使用网线将 I.MX6U-ALPHA 开发板的两个网口与路由器或者电脑连接起来,最后使用新的文件启动 Linux 内核。启动以后使用“ifconfig”命令查看一下当前活动的网卡有哪些。

⑧、网络挂载根文件系统
网络驱动移植好以后,将根文件系统 rootfs 使用 NFS 挂载到 Linux 系统上,
uboot 里面的 bootargs 环境变量会设置“root”的值,所以我们将 root 的值改为 NFS 挂载即可。
在 Linux 内核源码里面有相应的文档 Documentation/filesystems/nfs/
nfsroot.txt,格式如下:
root=/dev/nfs nfsroot=[:][,] ip=::::::::

:服务器 IP 地址,也就是存放根文件系统主机的 IP 地址,那就是 Ubuntu 的 IP 地址,比如 Ubuntu 主机 IP 地址为 192.168.148.103。
:根文件系统的存放路径,比如/home/kodo/NFS/rootfs。
:NFS 的其他可选选项,一般不设置。
:客户端 IP 地址,也就是开发板的 IP 地址,Linux 内核启动以后就会使用此 IP 地址来配置开发板。此地址一定要和 Ubuntu 主机在同一个网段内,并且没有被其他的设备使用,比如设置为 192.168.148.240。
:服务器 IP 地址。
:网关地址,如 192.168.1.1。
:子网掩码 255.255.255.0。
:客户机的名字,一般不设置,此值可以空着。
:设备名,也就是网卡名,一般是 eth0,eth1….,正点原子的 I.MX6U-ALPHA 开发板的 ENET2 为 eth0,ENET1 为 eth1。如果你的电脑只有一个网卡,那么基本只能是 eth0。这里我们使用 ENET2,所以网卡名就是 eth0。
:自动配置,一般不使用,所以设置为 off。
:DNS0 服务器 IP 地址,不使用。
:DNS1 服务器 IP 地址,不使用。
根据上面的格式 bootargs 环境变量的 root 值如下:
root=/dev/nfs nfsroot=192.168.148.103:/home/kodo/NFS/rootfs,proto=tcp rw ip=192.168.148.240:192.168.148.103:192.168.1.1:255.255.255.0::eth0:off

“proto=tcp”表示使用 TCP 协议,“rw”表示 nfs 挂载的根文件系统为可读可写。

启动开发板,进入 uboot 命令行模式,然后重新设置 bootargs 环境变量,命令如下:
setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.148.103:/home/kodo/NFS/rootfs,proto=tcp rw ip=192.168.148.240:192.168.148.103:192.168.1.1:255.255.255.0::eth0:off'
setenv bootcmd 'tftp 80800000 zImage;tftp 83000000 imx6ull-kodo-emmc.dtb;bootz 80800000 - 83000000'
saveenv

⑨、LCD 控制台设置
想要设置 LCD 作为终端控制台,需要设置 uboot 中的 bootargs,重启开发板,进入 Linux 命令行,重新设置 bootargs 参数的 console 内容,命令如下:
setenv bootargs 'console=tty1 console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.148.103:/home/kodo/NFS/rootfs,proto=tcp rw ip=192.168.148.240:192.168.148.103:192.168.1.1:255.255.255.0::eth0:off'

设置了两遍 console,第一次设置 console=tty1,也就是设置 LCD 屏幕为控制台,第二遍又设置 console=ttymxc0,115200,也就是设置串口也作为控制台。相当于打开了两个 console,一个是 LCD,一个是串口,重启开发板 LCD 和串口都会显示 Linux 启动 log 信息。但是此时还不能使用 LCD 作为终端进行交互,设置还未完成。
打开开发板根文件系统中的 /etc/inittab 文件,在里面加入下面这一行:
tty1::askfirst:-/bin/sh

添加完成以后的/etc/inittab 文件内容如图所示:

修改完成以后保存 /etc/inittab 并退出,然后重启开发板,重启以后开发板 LCD 屏幕最后一行会显示下面一行语句:
Please press Enter to activate this console.

上述提示语句说的是:按下回车键使能当前终端,可以接上一个 USB 键盘,Linux 内核默认已经使能了 USB 键盘驱动了,因此可以直接使用 USB 键盘。

关于 Linux 内核的移植就讲解到这里,简单总结一下移植步骤:
①、在 Linux 内核中查找可以参考的板子,一般都是半导体厂商自己做的开发板。
②、编译出参考板子对应的 zImage 和.dtb 文件。
③、使用参考板子的 zImage 文件和.dtb 文件在我们所使用的板子上启动 Linux 内核,看
能否启动。
④、如果能启动的话就万事大吉,如果不能启动那就悲剧了,需要调试 Linux 内核。不
过一般都会参考半导体官方的开发板设计自己的硬件,所以大部分情况下都会启动起
来。启动Linux 内核用到的外设不多,一般就 DRAM(Uboot 都初始化好的)和串口。
作为终端使用的串口一般都会参考半导体厂商的 Demo 板。
⑤、修改相应的驱动,像 NAND Flash、EMMC、SD 卡等驱动官方的 Linux 内核都是已
经提供好了,基本不会出问题。重点是网络驱动,因为 Linux 驱动开发一般都要通过
网络调试代码,所以一定要确保网络驱动工作正常。如果是处理器内部 MAC+外部
PHY 这种网络方案的话,一般网络驱动都很好处理,因为在 Linux 内核中是有外部
PHY 通用驱动的。只要设置好复位引脚、PHY 地址信息基本上都可以驱动起来。
⑥、Linux 内核启动以后需要根文件系统,如果没有根文件系统的话肯定会崩溃,所以确
定 Linux内核移植成功以后就要开始根文件系统的构建。

标签:kodo,ENET2,dtb,phy,内核,Linux,imx6ull,IMX6ULL
From: https://www.cnblogs.com/KuDianWanJia/p/17130342.html

相关文章

  • Linux基础实训(利用线程和互斥锁)
                         实验要求(linux)1定义一个长度为8的数组2输入不同的8个(大写)字母(ASDFGHJK)3对字符串进行排序4用线程和互斥锁输出按顺......
  • Linux如何查看系统和进程的运行状态?
    对于运维人员来讲,监控服务器的运行状态是他们的必要工作,而Linux系统提供了很多关于服务器运行状态的命令,那么Linux如何查看系统和进程的运行状态?可以使用top命令,接下来......
  • 【IMX6ULL学习笔记】四、 U-BOOT启动流程
    一、链接脚本u-boot.lds详解要分析uboot的启动流程,首先要找到“入口”,找到第一行程序在哪里。程序的链接是由链接脚本来决定的,所以通过链接脚本可以找到程序的入口。......
  • 【IMX6ULL学习笔记】五、U-BOOT移植与解析
    一、移植自定义开发板流程1、添加mx6ull_kodo_emmc_defconfig配置文件(.config)在/configs目录下,复制mx6ull_14x14_evk_emmc_defconfig文件,重命名为mx6ull_kodo_emm......
  • linux下安装nginx
    1.首先去官网下载安装包  链接:http://nginx.org/en/download.html    或者直接在linux下使用wget进行下载。  首先命令行查看有没有wget,没有则下载:yumins......
  • curl post请求发送json数据两种方式(Window/Linux)
    curlpost请求发送json数据两种方式(Window/Linux) 设置请求头Content-Typecurl发送post请求,默认的content-type是:application/x-www-form-urlencoded。要发送json格式,......
  • 【Linux系统】Centos7系统下配置samba共享
    (【Linux系统】Centos7系统下配置samba共享)一、Samba服务介绍Samba是一套使用SMB(ServerMessageBlock)协议的应用程序,通过支持这个协议,Samba允许Linux服务器与Win......
  • linux源码解析12–page数据结构
    几个问题:1.当开启了MMU之后,CPU访问内存的最小单位是多少呢?page2.linux怎样描述这个页呢?3.linux内核里,怎么理解和使用这个页?linux内核用stuctpage来描述一个物理页面:1......
  • linux ip route 配置ECMP
    配置如下:iprouteadd100.0.0.0/16nexthopvia1.1.1.1devvnet0weight1nexthopvia2.2.2.1devvnet1weight1说明:nexhop 指定下一跳dev 指定接口wei......
  • Linux中完全卸载nginx
    前言在开局配置Nginx时有可能会配置错误,报各种错误代码。看不懂或者懒得去看这个报错时,其实最简单的方式是卸载并重装咯。今天就带大家一起学习下,如何彻底卸载nginx程序。......