【IMX6ULL学习笔记之Linux系统移植03】——Linux系统移植

第二部分,Linux移植

Linux 获取

  • https://www.kernel.org

Linux编译

  1. 新建名为mx6ull_lux_emmc.sh的shell脚本

    #!/bin/sh
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- disclean
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- imx_v7_mfg_defconfig
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- all -j16
    
  2. 给予权限

    chmod 777 mx6ull_lux_emmc.sh
    
  3. 运行脚本

编译出错解决
  • 错误提示“ recipe for target ‘arch/arm/boot/compressed/piggy.lzo’failed”

    解决方案:安装lozp库

    sudo apt-get insatll lzop
    

Linux编译文件组成

  • arch文件夹 与架构相关的文件

    • arch/arm/configs中是不同平台的默认配置文件:xxx_defconfig,也就是编译脚本中的imx_v7_defconfig

    • arch/arm/boot/dts中是对应平台的设备树文件

    • arch/arm/boot文件夹中会保存编译生成的镜像文件zImage

  • block文件夹中是块设备目录

  • .config文件中保存着Linux最终的配置信息,根据此配置信息来编译对应的模块

分析Linux设置(屏蔽代码)

{
    "search.exclude": {
        "**/node_modules": true,
        "**/bower_components": true,

        "**/*.o":true,
        "**/*.su":true,
        "**/*.cmd" :true,
        "Documentation":true,

        /*屏蔽不用的架构相关的文件*/
        "arch/ alpha":true,
        "arch/arc":true,
        "arch/arm64":true,
        "arch/avr32":true,
        "arch/[b-z]*":true,
        "arch/arm/plat*":true,
        "arch/arm/mach-[a-h]*":true,
        "arch/arm/mach-[n-z]*":true,
        "arch/arm/mach-i[n-z]*":true,
        "arch/arm/mach-m[e-v]*":true,
        "arch/arm/mach-k*":true,
        "arch/arm/mach-1*":true,

        /*屏蔽排除不用的配置文件*/
        "arch/arm/configs/[a-h]*":true,
        "arch/arm/configs/[j-z]*":true,
        "arch/arm/configs/imo*":true,
        "arch/arm/configs/in*":true,
        "arch/arm/configs/io*":true,
        "arch/arm/configs/ix*":true,

        /*屏蔽掉不用的DTB文件*/
        "arch/arm/boot/dts/[a-h]*":true,
        "arch/arm/boot/dts/[k-z]*":true,
        "arch/arm/boot/dts/in*":true,
        "arch/arm/boot/dts/imx1大": true,
        "arch/arm/boot/dts/imx7*":true,
        "arch/arm/boot/dts/imx2*":true,
        "arch/arm/boot/dts/imx3*":true,
        "arch/arm/boot/dts/imx5*":true,
        "arch/arm/boot/dts/imx6d*":true,
        "arch/arm/boot/dts/imx6q*":true,
        "arch/arm/boot/dts/imx6s*":true,
        "arch/arm/boot/dts/imx6ul-*":true,
        "arch/arm/boot/dts/imx6u11-9x9*":true,
        "arch/arm/boot/dts/imx6ull-14x14-ddr*":true,
    },
    "files.exclude": {
        "**/.git": true,
        "**/.svn": true,
        "**/.hg": true,
        "**/CVS": true,
        "**/.DS_Store": true,

        "**/*.o":true,
        "**/*.su":true,
        "**/*.cmd" :true,
        "Documentation":true,

        /*屏蔽不用的架构相关的文件*/
        "arch/ alpha":true,
        "arch/arc":true,
        "arch/arm64":true,
        "arch/avr32":true,
        "arch/[b-z]*":true,
        "arch/arm/plat*":true,
        "arch/arm/mach-[a-h]*":true,
        "arch/arm/mach-[n-z]*":true,
        "arch/arm/mach-i[n-z]*":true,
        "arch/arm/mach-m[e-v]*":true,
        "arch/arm/mach-k*":true,
        "arch/arm/mach-1*":true,

        /*屏蔽排除不用的配置文件*/
        "arch/arm/configs/[a-h]*":true,
        "arch/arm/configs/[j-z]*":true,
        "arch/arm/configs/imo*":true,
        "arch/arm/configs/in*":true,
        "arch/arm/configs/io*":true,
        "arch/arm/configs/ix*":true,

        /*屏蔽掉不用的DTB文件*/
        "arch/arm/boot/dts/[a-h]*":true,
        "arch/arm/boot/dts/[k-z]*":true,
        "arch/arm/boot/dts/in*":true,
        "arch/arm/boot/dts/imx1大": true,
        "arch/arm/boot/dts/imx7*":true,
        "arch/arm/boot/dts/imx2*":true,
        "arch/arm/boot/dts/imx3*":true,
        "arch/arm/boot/dts/imx5*":true,
        "arch/arm/boot/dts/imx6d*":true,
        "arch/arm/boot/dts/imx6q*":true,
        "arch/arm/boot/dts/imx6s*":true,
        "arch/arm/boot/dts/imx6ul-*":true,
        "arch/arm/boot/dts/imx6u11-9x9*":true,
        "arch/arm/boot/dts/imx6ull-14x14-ddr*":true,
    }
}

移植Linux

  1. 编译完成之后,首先修改顶层Makefile中的ARCH 和 CROSS_COMPILE

  2. 将编译生成的镜像文件zImage和生成的设备树文件imx6ull-14x14-evk.dtb文件放入TFTP文件夹中,在uboot中将其下载到开发板中

    cp arch/arm/boot/zImage /home/zuozhongkai/linux/tftpboot/ -f
    cp arch/arm/boot/dts/imx6ull-14x14-evk.dtb /home/zuozhongkai/linux/tftpboot/ -f
    
    tftp 80800000 zImage
    tftp 83000000 imx6ull-14x14-evk.dtb
    bootz 80800000 – 83000000
    
  3. 会提示根文件系统未指定导致内核崩溃

添加自己的开发板

  1. 拷贝arch/arm/configs中的imx_v7_mfg_defconfig为imx_lux_emmc_defconfig

    • 不要拷贝imx_v7_mfg_defconfig,拷贝这个后续更改主频时钟频率会发现主频为792000KHz
    • 拷贝imx_v7_defconfig这个
  2. 拷贝arch/arm/boot/dts/中的imx6ull-14x14-evk.dts为imx6ull-lux-emmc.dts

  3. 在arch/arm/boot/dts中找到Makefile文件,在其中找到dtb-$(CONFIG_SOC_IMX6ULL),在其中添加imx6ull-lux-emmc.dtb,这样在进行编译的时候就会将imx6ull-lux-emmc.dts文件编译成imx6ull-lux-emmc.dtb 文件

  4. 重写编译脚本,因为要用自己复制为编译文档编译

    #!/bin/sh
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- disclean
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- imx_lux_emmc_defconfig
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- all -j16
    
  5. 重新启动内核,用新编译的镜像文件和设备树文件

Linux移植适配

LCD驱动修改

在设备树中找到lcdif结点

&lcdif {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_lcdif_dat
             &pinctrl_lcdif_ctrl>;
    display = <&display0>;
    status = "okay";

    display0: display {
        bits-per-pixel = <24>;
        bus-width = <24>;

        display-timings {
            native-mode = <&timing0>;
            timing0: timing0 {
            clock-frequency = <31000000>;
            hactive = <800>;
            vactive = <480>;

            hfront-porch = <40>;
            hback-porch = <88>;
            hsync-len = <48>;

            vback-porch = <32>;
            vfront-porch = <13>;
            vsync-len = <3>;

            hsync-active = <0>;
            vsync-active = <0>;
            de-active = <1>;
            pixelclk-active = <0>;
            };
        };
    };
};
主频修改
  1. 主频不修改,则主频为198000

  2. 使能8线EMMC

    • 修改设备树代码

      &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;
          status = "okay";
      };
      
    • 重新编译设备树,重启

修改网络驱动
  1. 修改复位引脚驱动

    • 复位引脚用的是SNVS_TAMPER7 和SNVS_TAMPER8,所以要将用到这两个引脚的地方删除掉
    • 在设备树文件下找到用到这两个引脚的地方,屏蔽掉(删掉)
    • spi4grp
    • spi4
    • 配置SNVS_TAMPER7和SNVS_TAMPER8作为网络复位引脚
      • enet1grp
      • MX6UL_PAD_SNVS_TAMPER7__GPIO5_IO07 0x10B0
      • enet2grp
      • MX6UL_PAD_SNVS_TAMPER8__GPIO5_IO08 0x10B0
  2. 修改PHY地址

    • 操作复位引脚,低电平有效,持续26ms

    • smsc,disable-energy-detect”表明 PHY 芯片是 SMSC 公司的,这样 Linux 内核就会找到 SMSC 公司的 PHY 芯片驱动来驱动 LAN8720A

    • ENET1 的 PHY 地址为 0,所以“@”后面是 0(默认为 2)

    • reg 的值也表示 PHY 地址, ENET1 的 PHY 地址为 0,所以 reg=0

      &fec1 {
          pinctrl-names = "default";
          pinctrl-0 = <&pinctrl_enet1>;
          phy-mode = "rmii";
          phy-handle = <&ethphy0>;
          phy-reset-gpios = <&gpio5 7 GPIO_ACTIVE_LOW>;
          phy-reset-duration = <26>;
          status = "okay";
      };
      
      &fec2 {
          pinctrl-names = "default";
          pinctrl-0 = <&pinctrl_enet2>;
          phy-mode = "rmii";
          phy-handle = <&ethphy1>;
          phy-reset-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>;
          phy-reset-duration = <26>;
          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>;
              };
          };
      };
      
  3. 修改fec_main.c

    • 如果要在 I.MX6ULL 上使用 LAN8720A 就需要设置ENET1 和 ENET2 的 TX_CLK 引脚复位寄存器的 SION 位为 1

    • 找到文件 drivers/net/ethernet/freescale/fec_main.c

          int num_tx_qs;
          int num_rx_qs;
      
          /*
              设置 MX6UL_PAD_ENET1_TX_CLK 和 MX6UL_PAD_ENET2_TX_CLK
              3453 * 这两个 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);
      
          fec_enet_get_queue_num(pdev, &num_tx_qs, &num_rx_qs);
      
  4. 配置Linux内核,使能驱动

    • 使用make menuconfig 使能LAN8720A驱动

    • -> Device Drivers
          -> Network device support
              -> PHY Device support and infrastructure
                  -> Drivers for SMSC PHYs
      
  5. 修改smsc.c文件

    • 找到文件drivers/net/phy/smsc.c

    • static int smsc_phy_reset(struct phy_device *phydev)
      {
          int timeout = 50000;
          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;
      }
      
  6. 网络驱动测试

    • 修改完网络驱动注意保存配置信息,通过图形化配置的信息会保存在.config文件中,当执行make distclean 时,.config 文件会被清除,配置信息也就没了

    • 保存配置信息

      • 配置完成之后,退出,将.config 文件复制成为编译时的配置文件xxx_defconfig
      • 在图形化配置界面在配置完成之后直接保存配置
    • 不执行make distclean 命令,重新编译时只会编译需要编译的文件,已经编译过的文件不会再次编译,节省编译时间

    • 编译测试

    • 打开两个网卡

      ifconfig eth0 up
      ifconfig eth1 up
      
    • 看到"SMSC LAN8710/LAN8720”字样,说明当前的网络驱动使用的就是我们前面使能的 SMSC 驱动

    • 给网卡配置IP地址

      ifconfig eth0 192.168.31.251
      ifconfig eth1 192.168.31.252
      
    • pingUbuntu主机

      ping 192.168.31.224
      

你可能感兴趣的:(NXP-IMX6ULL,Linux学习过程笔记,linux,学习)