备注:本文以正点原子imx6ull芯片Alpha开发板为例。参考《正点原子嵌入式linux驱动开发指南V1.4.pdf》整理的笔记。



一、下载源码、编译源码

该步骤的作用是:测试源码是否可以正常编译,如果可以确定自己的源码能够正常编译通过无误,则可以跳过此步骤

  1. ARM芯片官网下载对应的U-BOOT,并解压

    tar -vxjf uboot-imx-2016.03-2.1.0-g8b546e4.tar.bz2
    

    下表格为常用目录,以及后续修改配置需要打交道的文件夹及含义

    目录含义
    configs各种芯片型号的配置文件均在此文件夹下,根据自己使用的芯片有对应的配置文件
    比如:
      imx6ull对应的配置文件名称为:mx6ull_xxxx_defconfig
    其中:
      当板卡为emmc启动方式时使用配置文件mx6ull_14x14_evk_emmc_defconfig
      当板卡为nand启动方式时使用配置文件mx6ull_14x14_evk_nand_defconfig
    include/configs头文件
    board/freescale板级文件
  2. 安装依赖库

    sudo apt-get install libncurses5-dev
    
  3. u-boot根目录下编写shell编译脚本

    vim mx6ull_14x14_emmc.sh
    

    文件中写入如下内容:

    因为我是用的开发板是emmc启动板卡,所以第二条命令使用配置文件mx6ull_14x14_evk_emmc_defconfig

    #!/bin/bash
    
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_evk_emmc_defconfig
    make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16
    
  4. 赋予脚本可执行权限

    chomd 777 mx6ull_14x14_emmc.sh
    
  5. 执行脚本,编译u-boot

    ./mx6ull_14x14_emmc.sh
    
  6. 编译完成后终端显示如下镜像信息

    ......
    fg.cfgtmp board/freescale/mx6ullevk/imximage.cfg
      ./tools/mkimage -n board/freescale/mx6ullevk/imximage.cfg.cfgtmp -T imximage -e 0x87800000 -d u-boot.bin u-boot.imx 
    Image Type:   Freescale IMX Boot Image
    Image Ver:    2 (i.MX53/6/7 compatible)
    Mode:         DCD
    Data Size:    425984 Bytes = 416.00 kB = 0.41 MB
    Load Address: 877ff420
    Entry Point:  87800000
    



二、修改源码(适配自己的开发板)

  修改源码,作用其实是将源码中跟自己板卡最接近的平台的【配置文件】和【头文件】和【板级文件】拷贝一份重命名为自己板卡的对应文件,然后修改里面的源码,在进行编译生成zImage/rootfs等文件。

  这里阿尔法开发板芯片为imx6ull,emmc启动方式,所以在后续拷贝文件时,NXP官方evk开发板与阿尔法开发板最为类似,故,拷贝文件名形如【mx6ull_14x14_evk_emmc_xxx】,命名为自己板卡【mx6ull_alientek_emmc_xxx】

2.1 拷贝配置文件

  1. 拷贝类似平台配置文件,重名民为自己的平台配置文件

    cd configs
    cp mx6ull_14x14_evk_emmc_defconfig mx6ull_alientek_emmc_defconfig
    
  2. 修改配置文件

    将第1行和第4行的mx6ullevk修改为mx6ull_alientek_emmc

    vim mx6ull_alientek_emmc_defconfig
    修改为如下内容:
    
    CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6ull_alientek_emmc/imximage.cfg,MX6ULL_EVK_EMMC_REWORK"
    CONFIG_ARM=y
    CONFIG_ARCH_MX6=y
    CONFIG_TARGET_MX6ULL_ALIENTEK_EMMC=y
    CONFIG_CMD_GPIO=y
    

2.2 拷贝头文件

  1. 拷贝类似平台头文件,重命名为自己平台头文件

    cd {uboot顶层目录}
    cd include/configs/    #注意:二级子目录是:【configs】,不是【config】!!!
    cp mx6ullevk.h mx6ull_alientek_emmc.h
    
  2. 打开头文件

    vim mx6ull_alientek_emmc.h
    
  3. 修改ifndef头文件声明中的名字

    #ifndef __MX6ULLEVK_CONFIG_H
    #define __MX6ULLEVK_CONFIG_H
    

    修改为:

    #ifndef __MX6ULL_ALIENTEK_EMMC_CONFIG_H
    #define __MX6ULL_ALIENTEK_EMMC_CONFIG_H
    
  4. 在文件前面的include引用模块增加头文件引用

    该头文件中相对于mx6ull_alientek_emmc.h 中有更多的配置功能或命令

    #include "mx6_common.h"
    
  5. 头文件其他内容解析

    备注:mx6ull_alientek_emmc.h 里面有很多宏定义,这些宏定义基本用于配置 uboot,也有一些I.MX6ULL 的配置项目。如果我们自己要想使能或者禁止 uboot 的某些功能,那就在mx6ull_alientek_emmc.h 里面做修改即可。

    以下为mx6ull_alientek_emmc.h文件内容大致功能解析。(参考:《正点原子嵌入式linux驱动开发指南V1.4.pdf》)

    29~39 行,设置 DRAM 的大小
    第 50 行,定义宏 CONFIG_DISPLAY_CPUINFO, uboot 启动的时候可以输出 CPU 信息。
    第 51 行,定义宏 CONFIG_DISPLAY_BOARDINFO, uboot 启动的时候可以输出板子信息。
    第 54 行, CONFIG_SYS_MALLOC_LEN 为 malloc 内存池大小,这里设置为 16MB。
    第 5960 行,使能 I.MX6ULL 的串口功能,宏 CONFIG_MXC_UART_BASE 表示串口寄存器基地址,
            这里使用的串口1,基地址为UART1_BASE,
            UART1_BASE定义在文件arch/arm/include/asm/arch-mx6/imx-regs.h中,
            imx-regs.h是I.MX6ULL寄存器描述文件,
            根据imx-regs.h可得到UART1_BASE的值如下:(备注:该值可以在imx6ull手册中查询到)
            UART1_BASE= (ATZ1_BASE_ADDR + 0x20000)
                      =AIPS1_ARB_BASE_ADDR + 0x20000
                      =0x02000000 + 0x20000
                      =0X020200006364 行, EMMC接在I.MX6ULL的USDHC2上,
            宏 CONFIG_SYS_FSL_ESDHC_ADDR 为EMMC所使用接口的寄存器基地址,也就是 USDHC2 的基地址。
    第 224 行,宏 CONFIG_SYS_LOAD_ADDR 表示 linux kernel 在 DRAM 中的加载地址,
            也就是 linux kernel 在 DRAM 中的存储首地址, CONFIG_LOADADDR=0X80800000。
    第 225 行,宏 CONFIG_SYS_HZ 为系统时钟频率,这里为 1000Hz。
    第 227 行,宏 CONFIG_STACKSIZE 为栈大小,这里为 128KB
    第 230 行,宏 CONFIG_NR_DRAM_BANKS 为 DRAM BANK 的数量, 
            I.MX6ULL 只有一个 DRAM BANK,我们也只用到了一个 BANK,所以为 1。
    第 256 行,宏CONFIG_SYS_MMC_ENV_DEV为默认的MMC设备, 这里默认为USDHC2,也就是 EMMC。
    第 258 行,宏CONFIG_MMCROOT设置进入linux系统的根文件系统所在的分区,
            这里设置为 "/dev/mmcblk1p2",也就是 EMMC 设备的第 2 个分区。
            第 0 个分区保存 uboot,
            第 1 个分区保存 linux 镜像和设备树,
            第 2 个分区为 Linux 系统的根文件系统。
    第 331 行的宏 CONFIG_FEC_ENET_DEV 指定 uboot 所使用的网口。
            I.MX6ULL 有两个网口,为 0 的时候使用 ENET1,为 1 的时候使用 ENET2。
            宏 IMX_FEC_BASE 为 ENET 接口的寄存器首地址,
            宏 CONFIG_FEC_MXC_PHYADDR 为网口 PHY 芯片的地址。
            宏 CONFIG_FEC_XCV_TYPE 为PHY芯片所使用的接口类型, 
            I.MX6U-ALPHA 开发板的两个PHY都使用的 RMII 接口。
    

    该文件中,其中以 CONFIG_CMD 开头的宏都是用于使能相应命令的,其他的以 CONFIG 开头的宏都是完成一些配置功能的。以后会频繁的和mx6ull_alientek_emmc.h 这个文件打交道。

2.3 拷贝开发板对应板级文件夹

  1. 拷贝板级文件夹,重命名为自己的开发板对应文件夹

    cd {u-boot顶层目录}
    cd board/freescale/
    cp mx6ullevk mx6ull_alientek_emmc -rf
    cd mx6ull_alientek_emmc
    
  2. 修改文件名

    mv mx6ullevk.c mx6ull_alientek_emmc.c
    
  3. 修改同目录下Makefile文件内容

    vim Makefile
    

    修改第六行文件名为自己板卡文件名

    obj-y  := mx6ull_alientek_emmc.o  
    
  4. 修改同目录下imximage.cfg 文件

    vim imximage.cfg
    

    将imximage.cfg 文件中的

    PLUGIN board/freescale/mx6ullevk/plugin.bin 0x00907000
    

    修改为

    PLUGIN board/freescale/mx6ull_alientek_emmc/plugin.bin 0x00907000
    
  5. 修改同目录下Kconfig 文件

    删除Kcofig原有内容,复制如下内容:

    if TARGET_MX6ULL_ALIENTEK_EMMC
    
    config SYS_BOARD
            default "mx6ull_alientek_emmc"
    
    config SYS_VENDOR
            default "freescale"
    
    config SYS_SOC
            default "mx6"
    
    config SYS_CONFIG_NAME
            default "mx6ull_alientek_emmc"
    
    endif
    
  6. 修改同目录下MAINTAINERS 文件

    删除MAINTAINERS原有内容,复制如下内容(其实就是修改了板卡名字)

    MX6ULLEVK BOARD
    M:      Peng Fan <peng.fan@nxp.com>
    S:      Maintained
    F:      board/freescale/mx6ull_alientek_emmc/
    F:      include/configs/mx6ull_alientek_emmc.h
    F:      configs/mx6ull_14x14_evk_defconfig
    F:      configs/mx6ull_9x9_evk_defconfig
    
  7. 修改u-boot图形界面配置文件

    cd [U-BOOT根目录]
    cd arch/arm/cpu/armv7/mx6/
    vim 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"
    
  8. Uboot启动时开发板名称可以在这里修改,也可以在这里加入一些自己需要的LOG(可选)

    vim board/freescale/mx6ull_alientek_emmc/mx6ull_alientek_emmc.c
    

    第798行,int checkboard(void)函数中有开发板的名字。

    puts("Board: MX6ULL 14x14 EVK\n"); 
    

2.4 网络驱动修改

  U-Boot移植一般必须要解决的驱动有串口、网口、EMMC/NAND、SD卡等,网络驱动修改后续再进行补充,可查阅正点原子《嵌入式驱动开发指南》—>《U-Boot》章节 —>《在U-Boot中添加自己的开发板》小节 —> 《网络驱动修改》小节查阅具体步骤。




三、编译新的U-Boot(自己开发板的U-Boot)

  1. 新建编译脚本文件

    cd [U-BOOT根目录]
    vim mx6ull_alientek_emmc.sh
    

    加入如下内容:

    #!/bin/bash
    
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_alientek_emmc_defconfig
    make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16
    
  2. 执行脚本,进行U-BOOT编译

    chmod 777 mx6ull_alientek_emmc.sh
    ./mx6ull_alientek_emmc.sh
    
  3. 成功编译完成后,终端显示如下

    注意:编译完成后会在U-Boot根目录下生成u-boot.bin文件,该bin文件就是我们需要烧写到SD卡中的引导文件

    ...
      ./tools/mkimage -n board/freescale/mx6ull_alientek_emmc/imximage.cfg.cfgtmp -T imximage -e 0x87800000 -d u-boot.bin u-boot.imx 
    Image Type:   Freescale IMX Boot Image
    Image Ver:    2 (i.MX53/6/7 compatible)
    Mode:         DCD
    Data Size:    425984 Bytes = 416.00 kB = 0.41 MB
    Load Address: 877ff420
    Entry Point:  87800000
    
  4. 检查添加的mx6ull_alientek_emmc.h头文件是否被引用

    编译完成之后,在终端输入:

    grep -nR "mx6ull_alientek_emmc.h"
    

    若出现很多文件都引用了mx6ull_alientek_emmc.h 这个头文件,则表示新板卡添加成功。




四、烧写U-Boot到SD卡,启动U-Boot

  1. 终端执行命令

    ls /dev/sd*
    
  2. 插上SD卡后,再执行上述命令看多出来的SD卡序号是多少,我这里是/dev/sdb 和 /dev/sdb1,1表示分区一,后面使用/dev/sdb即可。

  3. 使用工具imxdownload 将 u-boot.bin 烧写到SD卡

    cd [u-boot根目录]
    cp [工具imxdownload路径]/imxdownload [u-boot根目录]
    imxdownload u-boot.bin /dev/sdb
    
  4. 将SD卡插入开发板,开发上电直接敲击任意按键进入U-Boot

  5. U-boot启动后,命令行左侧会出现一个“=>”标志。

  6. U-boot启动过程中,屏幕上(串口)会打印一些U-boot信息,包含时间、版本、网络等。




五、U-Boot命令

  1. 常用命令

    printenv
    setenv        setenv ipaddr xxx
                  setenv serveraddr xxx
                  setenv bootdelay 5
                  ...
    saveenv
    ping
    tftp
    nfs
    
  2. 其他命令

    help
    echo
    run
    
  3. mmc相关命令

    mmc list    #sd卡和emmc驱动检查
    
    mmc dev 0    #选择mmc设备0
    mmc info       #打印mmc0设备的设备信息
    
    mmc dev 1    #选择mmc设备1
    mmc info       #打印mmc1设备的设备信息
    



六、问题答疑

6.1 编译脚本的命令解析

  1. 怎么确定u-boot编译命令该用什么命令?命令所带参数都从哪来?

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

    解答:

    参数含义
    mx6ull_14x14_ddr512_emmc_defconfig来自u-boot源码中configs目录中的配置文件名。
    半导体厂商出场的时候为了简化开发人员的开发难度,会配置很多开发板的一套默认配置,在configs目录下,对应的芯片使用对应的配置文件即可。
    -j12表示12个线程都进行编译,一般系统支持几核几线程线程可以根据需要设置,满线程时,编译速度最快。
    V=1在终端中输出短命令虽然看起来很清爽,但是不利于分析uboot的编译过程。可以通过设置变量“V=1“来实现完整的命令输出



七、补充:配置环境变量【bootcmd】和【bootargs】

当U-Boot移植完成以后,下一步就要进行内核移植了。内核移植过程中,如果采用tftp服务器和nfs服务器挂载文件系统的话,则需要在U-Boot中配置环境变量【bootcmd】和【bootargs】的值,这样U-Boot才能识别去哪里下载zImage文件、dtb文件、以及在哪里查找文件系统等。具体两个参数的值设置方法分别在前面的博客【搭建TFTP服务器】和【搭建NFS服务器】文章末尾有介绍。此处仍旧做个记录。

配置环境变量【bootcmd】和【bootargs】步骤如下:

  • 板卡上电,倒计时结束前按任意键进入U-Boot
  • 执行如下命令配置【bootcmd】
    setenv bootcmd 'tftp 80800000 zImage; tftp 83000000 imx6ull-alientek-emmc.dtb; bootz 80800000 - 83000000'
    
  • 执行如下命令配置【bootargs】
    setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs rw nfsroot=192.168.0.250:/home/lsy/tools/nfs/rootfs ip=192.168.0.100:192.168.0.250:192.168.0.1:255.255.255.0::eth0:off'
    
  • 保存环境变量
    save
    

然后重启板卡,U-Boot就会根据配置好的参数,到指定服务器IP地址中寻找zImage文件、dtb文件以及文件系统了。




Logo

更多推荐