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

Uboot移植

uboot编译

  • 首先解压Uboot压缩包

    tar -vxjf packname
    
  • 编译

    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_ddr512_emmc_defconfig
    make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j12
    

    注:mx6ull_14x14_ddr512_emmc_defconfig是正点原子的U-Boot里面的配置文件,具体文件可以去./configs中查看,官方的文件是mx6ull_14x14_evk_emmc_defconfig

  • 编写脚本mx6ull_lux_emmc.sh编译

    #!/bin/bash
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_ddr512_emmc_defconfig
    make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j12
    

    使用chmod 777 mx6ull_lux_emmc.sh,给予权限

    执行

    ./mx6ull_lux_emmc.sh
    

uboot烧写与启动

  • 通过烧写进SD卡进行启动

    chmod 777 imxdownload
    ./imxdownload u-boot.bin /dev/sdc
    
  • 查看SD卡目录指令

    ls /dev/sd*
    
  • BOOT设置为从SD卡启动

uboot命令

  • 系统相关

    • help
    • bootz
    • bdinfo
    • printenv
    • version
    • saveenv
    • setenv
  • 内存相关

    • md
    • nm
    • mm
    • mw
    • cp
    • cmp
  • 网络相关

    • ipaddr
    • ethaddr
    • gatewayip
    • netmask
    • serverip
    • ping
    • dhcp
    • nfs
    • nfs [loadAddr] [hostIPAddr:][fileaddr]
    • tftp
  • EMMC、SD相关

    mmc info 输出 MMC 设备信息
    mmc read 读取 MMC 中的数据。
    mmc wirte 向 MMC 设备写入数据。
    mmc rescan 扫描 MMC 设备。
    mmc part 列出 MMC 设备的分区。
    mmc dev 切换 MMC 设备。
    mmc list 列出当前有效的所有 MMC 设备。
    mmc hwpartition 设置 MMC 设备的分区。
    mmc bootbus…… 设置指定 MMC 设备的 BOOT_BUS_WIDTH 域的值。
    mmc bootpart…… 设置指定 MMC 设备的 boot 和 RPMB 分区的大小。
    mmc partconf…… 设置指定 MMC 设备的 PARTITION_CONFG 域的值。
    mmc rst 复位 MMC 设备
    mmc setdsr 设置 DSR 寄存器的值
    • mmc part查看MMC分区

      如果 EMMC 里面烧写了 Linux 系统的话, EMMC 是有3 个分区的,第 0 个分区存放 uboot,第 1 个分区存放 Linux 镜像文件和设备树,第 2 个分区存
      放根文件系统。如果查询只有两个分区,那是因为第 0 个分区没有格式化,所以识别不出来,实际上第 0 个分区是存在的。一个新的 SD 卡默认只有一个分区,那就是分区 0,所以前面讲解的 uboot 烧写到 SD 卡,其实就是将 u-boot.bin 烧写到了 SD 卡的分区 0 里面。后面学习 Linux 内核移植的时候再讲解怎么在 SD 卡中创建并格式化第二个分区,并将 Linux 镜像文件和设备树文件存放到第二个分区中

  • FAT格式文件相关

    • fatinfo

    • fatls

      • 可以通过指令查询EMMC分区1和2中的镜像文件、设备树文件和根文件系统

        fatls mmc 1:1
        ls mmc 1:1
        ls mmc 1:2
        
    • fstype

    • fatload

      • fatload 命令用于将指定的文件读取到 DRAM 中

      • 将 EMMC 分区 1 中的 zImage 文件读取到 DRAM 中的0X80800000 地址处

        fatload mmc 1:1 80800000 zImage
        
    • fatwrite

  • BOOT操作相关

    • bootz
    • bootm
    • boot
  • 其他命令

    • reset
    • go
    • run
    • mtest

uboot编译文件组成

  • arch 存放与架构有关的文件

  • board 和具体板子有关

  • configs 此文件夹为uboot配置文件,同一命名为xxx_defconfig

    • 使用命令配置uboot(一定要在编译uboot之前配置)

      make mx6ull_14x14_ddr512_emmc_defconfig
      
  • Makefile文件是定顶层Makefile文件

  • u-boot.xxx文件包含一系列文件,包括

    • u-boot:编译出来的 ELF 格式的 uboot 镜像文件。
    • u-boot.bin:编译出来的二进制格式的 uboot 可执行镜像文件。
    • u-boot.cfg: uboot 的另外一种配置文件。
    • u-boot.imx: u-boot.bin 添加头部信息以后的文件, NXP 的 CPU 专用文件。
    • u-boot.lds:链接脚本。
    • u-boot.map: uboot 映射文件,通过查看此文件可以知道某个函数被链接到了哪个地址上。
    • u-boot.srec: S-Record 格式的镜像文件。
    • u-boot.sym: uboot 符号文件。
    • u-boot-nodtb.bin:和 u-boot.bin 一样, u-boot.bin 就是 u-boot-nodtb.bin 的复制文件。
  • .config文件,uboot配置文件,使用配置命令后自动生成的文件

分析uboot设置(屏蔽代码)

  • .vscode文件下新建settings.json

  • 首先保存工作区,不然它不起作用

  • 以下为settings.json的内容(路径之间不能有空格,不然木得效果)

    • 既然要复制过去,就先解决下Ubuntu和Windows互相复制粘贴的问题

      sudo apt-get autoremove open-vm-tools
      sudo apt-get install open-vm-tools-desktop
      
{
    "search.exclude": {
        "**/node_modules": true,
        "**/bower_components": true,
        "**/*.o":true,
        "**/*.su":true,
        "**/*.cmd":true,
        "arch/arc" : true,
        "arch/avr32" : true,
        "arch/blackfin" :true,
        "arch/m68k" :true,
        "arch/microblaze" :true ,
        "arch/mips" :true,
        "arch/nds32" :true,
        "arch/nios2" :true,
        "arch/openrisc":true,
        "arch/powerpc" :true,
        "arch/sandbox" :true,
        "arch/sh" : true,
        "arch/sparc" : true,
        "arch/x86" :true,
        "arch/arm/mach*":true,
        "arch/arm/cpu/arml1*":true,
        "arch/arm/cpu/arm720t" :true, 
        "arch/arm/cpu/arm9*" :true,
        "arch/arm/cpu/armv7m" :true,
        "arch/arm/cpu/armv8": true,
        "arch/arm/cpu/pxa" :true,
        "arch/arm/cpu/sa1100": true,
        "board/[a-e]*":true,
        "board/[g-z]*" :true,
        "board/[0-9]*" :true,
        "board/[A-Z]*":true,
        "board/fir*":true,
        "board/freescale/b*":true,
        "board/freescale/1*" :true,
        "board/freescale/m5*" :true,
        "board/freescale/mp*" :true,
        "board/freescale/c29*" :true,
        "board/freescale/cor*":true,
        "board/freescale/mx7*" :true,
        "board/freescale/mx2*" :true,
        "board/freescale/mx3*" :true,
        "board/freescale/mx5*": true,
        "board/freescale/p*" :true,
        "board/freescale/q*" : true,
        "board/freescale/t*":true,
        "board/freescale/v*" :true,
        "configs/[a-1]*" :true,
        "configs/[n-z]*":true,
        "configs/[A-Z]*" :true,
        "configs/M[a-z]*" :true,
        "configs/M[A-Z]*":true,
        "configs/M[0-9] *":true,
        "configs/m[a-w] *":true,
        "configs/m[0-9] *":true,
        "configs/[0-9]*":true,
        "include/configs/[a-1]*":true,
        "include/configs/[n-z]*":true,
        "include/configs/[A-Z]*":true,
        "include/configs/m[a-w]*" :true,

    },
    "files.exclude": {
        "**/.git": true,
        "**/.svn": true,
        "**/.hg": true,
        "**/CVS": true,
        "**/.DS_Store": true,
        "**/*.o":true,
        "**/*.su":true,
        "**/*.cmd":true,
        "arch/arc" : true,
        "arch/avr32" : true,
        "arch/blackfin" :true,
        "arch/m68k" :true,
        "arch/microblaze" :true ,
        "arch/mips" :true,
        "arch/nds32" :true,
        "arch/nios2" :true,
        "arch/openrisc":true,
        "arch/powerpc" :true,
        "arch/sandbox" :true,
        "arch/sh" : true,
        "arch/sparc" : true,
        "arch/x86":true,
        "arch/arm/mach*":true,
        "arch/arm/cpu/arml1*":true,
        "arch/arm/cpu/arm720t" :true, 
        "arch/arm/cpu/arm9*" :true,
        "arch/arm/cpu/armv7m" :true,
        "arch/arm/cpu/armv8": true,
        "arch/arm/cpu/pxa" :true,
        "arch/arm/cpu/sa1100": true,
        "board/[a-e]*":true,
        "board/[g-z]*" :true,
        "board/[0-9]*" :true,
        "board/[A-Z]*":true,
        "board/fir*":true,
        "board/freescale/b*":true,
        "board/freescale/1*" :true,
        "board/freescale/m5*" :true,
        "board/freescale/mp*" :true,
        "board/freescale/c29*" :true,
        "board/freescale/cor*":true,
        "board/freescale/mx7*" :true,
        "board/freescale/mx2*" :true,
        "board/freescale/mx3*" :true,
        "board/freescale/mx5*": true,
        "board/freescale/p*" :true,
        "board/freescale/q*" : true,
        "board/freescale/t*":true,
        "board/freescale/v*" :true,
        "configs/[a-1]*" :true,
        "configs/[n-z]*":true,
        "configs/[A-Z]*" :true,
        "configs/M[a-z]*" :true,
        "configs/M[A-Z]*":true,
        "configs/M[0-9]*":true,
        "configs/m[a-w]*":true,
        "configs/m[0-9]*":true,
        "configs/[0-9]*":true,
        "include/configs/[a-1]*":true,
        "include/configs/[n-z]*":true,
        "include/configs/[A-Z]*":true,
        "include/configs/m[a-w]*" :true,
    }
}

移植uboot

  • 解压NXP官方的I.MX6ULL EVK的uboot

  • 配置uboot

    • 在configs中找相关的xxx_defconfig文件
    • 14x14
    • emmc
  • 编译

    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_evk_emmc_defconfig
    make V=1 ARCH=arm CROSS_COMPILE=arm-linux-guneabihf- -j12
    
  • 为省略后面的架构以及编译指令,可在顶层Makefile中配置

    ARCH = arm
    CROSS_COMPILE = arm-linux-gnueabihf-
    

    可是使用一下指令编译

    make mx6ull_14x14_evk_emmc_defconfig
    make V=1 -j12
    
  • 使用脚本mx6ull_lux_emmc.sh编译

    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- disclean
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_evk_emmc_defconfig
    make V=1 ARCH=arm CROSS_COMPILE=arm-linux-guneabihf- -j12
    
  • 使用SD卡烧写u-boot.bin

更新uboot

  • 具体方法:我们可以使用命令“mmc write”来升级 uboot,也就是在 uboot 中更新 uboot。

  • 这里要用到 nfs 或者 tftp 命令,通过 nfs 或者 tftp 命令将新的 u-boot.bin 下载到开发板的 DRAM 中,然后再使用命令“mmc write”将其写入到 MMC设备中。

  1. 将编译出来的 u-boot.imx(u-boot.bin 前面加了一些头文件)拷贝到 Ubuntu 中的tftpboot 目录下。最后使用 tftp 命令将其下载到 0x80800000 地址处

    tftp 80800000 u-boot.imx
    
  2. 如果u-boot.imx 大小为 416768 字节, 416768/512=814,所以我们要向 SD 卡中写入814 个块,如果有小数的话就要加 1 个块。使用命令“mmc write”从 SD 卡分区 0 第 2 个块(扇区)开始烧写,一共烧写 814(0x32E)个块

    mmc dev 0 0
    mmc write 80800000 2 32E
    
  3. 烧写成功,重启开发板(从SD卡启动),查看版本号

  4. 更新 EMMC 中的 uboot 也是一样的。

此处更新Uboot还是用到了网络,有没有不用网络的方法,能直接将uboot下载到SD卡中…

./imxdownload 不就是嘛

那么如何将Linux内核、设备树和跟文件系统直接烧写到SD卡中呢

更新zImage镜像

  • 具体方法:我们可以通过 fatwrite 命令在 uboot 中更新 linux 镜像文件和设备树。首先将提供的 zImage 镜像文件拷贝到 Ubuntu 中的tftpboot 目录下 ,使用命令 tftp 将 zImage 下载到 DRAM 的 0X80800000 地址处 ,通过命令fatwrite将其写入到EMMC的分区1中
  1. 使用命令 tftp 将 zImage 下载到 DRAM 的 0X80800000 地址处

    tftp 80800000 zImage
    
  2. zImage 大小为 6039328(0X5C2720)个字节,接下来使用命令 fatwrite 将其写入到 EMMC 的分区 1 中,文件名字为 zImage

    fatwrite mmc 1:1 80800000 zImage 0x5c2720
    

修改Uboot

复制mx6ull_14x14_evk_emmc_defconfig为mx6ull_lux_emmc_defconfig

  • 修改其中的内容

添加开发板对应头文件

  • 在include/configs下添加对应头文件
  • 复制include/configs/mx6ullevk.h为mx6ull_lux_emmc.h
  • 修改其中的内容

添加对应的板级文件夹

  • 在board/freescale中复制文件夹mx6ullevk为mx6ull_lux_emmc

    cd board/freescale
    cp mx6ullevk -r mx6ull_lux_emmc
    
  • 重命名mx6ullevk.c

    cd mx6ull_lux_emmc
    mv mx6ullevk.c mx6ull_lux_emmc.c
    
  • 修改mx6ull_lux_emmc文件夹下的Makefile文件

  • 修改 mx6ull_alientek_emmc 目录下的 imximage.cfg 文件

  • 修改 mx6ull_alientek_emmc 目录下的 Kconfig 文件

  • 修改 mx6ull_alientek_emmc 目录下的 MAINTAINERS 文件

  • 修改 U-Boot 图形界面配置文件

    • 修改文件arch/arm/cpu/armv7/mx6/Kconfig

    • 在 207 行加入如下内容:

      config TARGET_MX6ULL_ALIENTEK_EMMC
      bool "Support mx6ull_alientek_emmc"
      select MX6ULL
      select DM
      select DM_THERMAL
      
    • 在最后一行的 endif 的前一行添加如下内容:

      source "board/freescale/mx6ull_alientek_emmc/Kconfig"
      
  • 修改编译脚本编译uboot

  • 验证是否编译成功

    • 执行

      grep -nR "mx6ull_alientek_emmc.h"
      

      如果有很多文件都引用了mx6ull_alientek_emmc.h这个头文件,那就说明新板子添加成功

  • 烧写测试

Uboot移植适配

LCD驱动修改
  • 一般uboot中驱动修改都在mx6ull_lux_emmc.c及其头文件中修改

  • 修改参数包括

    • LCD使用的GPIO
    • LCD的背光GPIO
    • LCD参数配置
  • 在.c文件中修改LCD参数配置

    struct display_info_t const displays[] = {{
        .bus = MX6UL_LCDIF1_BASE_ADDR,
        .addr = 0,
        .pixfmt = 24,
        .detect = NULL,
        .enable    = do_enable_parallel_lcd,
        .mode    = {
            .name            = "TFT4384",
            .xres           = 800,
            .yres           = 480,
            .pixclock       = 32258,
            .left_margin    = 88,
            .right_margin   = 40,
            .upper_margin   = 32,
            .lower_margin   = 13,
            .hsync_len      = 48,
            .vsync_len      = 3,
            .sync           = 0,
            .vmode          = FB_VMODE_NONINTERLACED
    } } };
    
  • 修改uboot中的panel参数

    setenv panel TFT4384
    saveenv
    
  • 重启Uboot

网络驱动修改
  • 网络驱动修改主要包括

    • LAN8720器件ID

      1. 正点原子的板子NET1的地址为0x00,NET2的地址为0x01
      2. 在头文件中找到CONFIG_FEC_ENET_DEV,这里默认为1,即使用NET2,刚好对应地址0x01
      3. 修改当CONFIG_FEC_ENET_DEV为0时的地址,对应NET1,其地址是0x00,修改
      4. 修改CONFIG_PHY_MICREL为CONFIG_PHY_SMSC
    • 复位引脚初始化

      1. 首先删除uboot中74LV595的驱动代码

      2. 删除

        #define IOX_SDI IMX_GPIO_NR(5, 10)
        #define IOX_STCP IMX_GPIO_NR(5, 7)
        #define IOX_SHCP IMX_GPIO_NR(5, 11)
        #define IOX_OE IMX_GPIO_NR(5, 8)
        

        替换代码:

        #define ENET1_RESET IMX_GPIO_NR(5, 7)
        #define ENET2_RESET IMX_GPIO_NR(5, 8)
        

        这是驱动的复位引脚

      3. 删除有关74LV595相关代码

        • static iomux_v3_cfg_t const iox_pads[] =
        • static void iox74lv_init(void)
        • void iox74lv_set(int index)
      4. 删除board_init中与74LV595相关代码

        imx_iomux_v3_setup_multiple_pads(iox_pads, ARRAY_SIZE(iox_pads));
        iox74lv_init();
        
      5. 添加复位引脚驱动

        • 在static iomux_v3_cfg_t const fec1_pads[] 和static iomux_v3_cfg_t const fec2_pads[]中加入 复位引脚IO配置

          MX6_PAD_SNVS_TAMPER7__GPIO5_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL)
          
          MX6_PAD_SNVS_TAMPER8__GPIO5_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL)
          
        • 在setup_iomux_fec 中添加复位功能

          gpio_direction_output(ENET1_RESET, 1);
          gpio_set_value(ENET1_RESET, 0);
          mdelay(20);
          gpio_set_value(ENET1_RESET, 1);
          
    • LAN8720驱动

      1. 修改 drivers/net/phy/phy.c 文件中的函数 genphy_update_link uboot启动Linux内核

      2. 加入以下代码

        #ifdef CONFIG_PHY_SMSC
        static int lan8720_flag=0;
            int bmcr_reg=0;
            if(lan8720_flag==0)
            {
                bmcr_reg = phy_read(phydev,MDIO_DEVAD_NONE,MII_BMCR);
                phy_write(phydev,MDIO_DEVAD_NONE,MII_BMCR,BMCR_RESET);
                while(phy_read(phydev,MDIO_DEVAD_NONE,MII_BMCR)&0x8000)
                {
                    udelay(100);
                }
                phy_write(phydev,MDIO_DEVAD_NONE,MII_BMCR,bmcr_reg);
                lan8720_flag=1;
            }
        #endif
        
    • Uboot中设置网络环境变量

      setenv ipaddr 192.168.1.55 //开发板 IP 地址
      setenv ethaddr 00:04:9f:04:d2:35 //开发板网卡 MAC 地址
      setenv gatewayip 192.168.1.1 //开发板默认网关
      setenv netmask 255.255.255.0 //开发板子网掩码
      setenv serverip 192.168.1.250 //服务器地址,也就是 Ubuntu 地址
      saveenv //保存环境变量
      

uboot启动Linux内核

  • 有两种方式,EMMC和网络
  • 下面是从网络启动,并同时在串口和LCD屏上显示启动过程
setenv bootargs 'console=tty1 console=ttymxc0,115200 root=/dev/nfs rw nfsroot=192.168.31.224:/home/lux/Linux/nfs/rootfs ip=192.168.31.55:192.168.31.224:192.168.31.1:255.255.255.0::eth0:off'
setenv bootcmd 'tftp 80800000 zImage;tftp 83000000 imx6ull-lux-emmc.dtb;bootz 80800000 - 83000000'
从EMMC启动
  • ls emmc 1:1
    

    查询EMMC中是否有zImage文件和设备树文件

  • 设置bootargs和bootcmd启动Linux内核

    setenv bootcmd 'mmc dev 1;fatload mmc 1:1 80800000 zImage;fatload mmc 1:1 83000000 imx6ull-lux-emmc.dtb;bootz 80800000 - 83000000'
    setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw'
    
  • 执行命令启动Linux内核

    boot
    或者
    run bootcmd
    
从网络启动
  • 设置bootargs和bootcmd启动Linux内核

    setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw'
    setenv bootcmd 'mmc dev 1;fatload mmc 1:1 80800000 zImage;fatload mmc 1:1 83000000 imx6ull-lux-emmc.dtb;bootz 80800000-83000000'
    
  • 执行命令启动Linux内核

    boot 
    或者
    run bootcmd
    
    如果启动失败可能是TFTP服务器未安装或者配置
    1. 安装TFTP服务器

      sudo apt-get install tftp-hpa tftpd-hpa
      
    2. 创建一个文件夹用来存放TFTP文件

      mkdir tftpboot
      chmod 777 tftpboot
      
    3. 配置tftp,新建文件夹/etc/xinetd.d/tftp 输入一下内容

      server tftp
      {
          socket_type        = dgram
          protocol        = udp
          wait            = yes
          user            = root
          server            = /usr/sbin/in.tftpd
          server_args         = -s /home/lux/Linux/tftpboot/
          disable            = no
          per_source        = 11
          cps                = 100 2
          flags            = IPv4
      }
      
    4. 启动tftp

      sudo service tftpd-hpa start
      
    5. 打开/etc/default/tftpd-hpa文件,修改为一下内容

      # /etc/default/tftpd-hpa
      
      FTFP_USERNAME="tftp"
      TFTP_DIRECTORY="/home/lux/Linux/tftpboot"
      TFTP_ADDRESS=":69"
      TFTP_OPTIONS="-l -c -s"
      
    6. 重启TFTP服务器

      sudo service tftpd-hpa restart
      
    7. 验证

      tftp 80800000 zImage
      

图形化配置

  • 安装对应工具

    sudo apt-get install build-essential
    sudo apt-get install libncurses5
    sudo apt-get install libncurses5-dev
    

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