uboot下载和移植
U-Boot、Linux kernel(内核) 和 rootfs (根文件系统,包含了一些常用命令和文件)这三者一起构成了一个完整的 Linux 系 统。
一、uboot简介(笔者所述针对学习时购买的正点原子阿尔法开发板,详情还请参考其开发手册)
1、简介:Linux 启动需要一个 bootloader 程序,上电后先运行bootloader,因为 linux 是运行在DDR里面的,bootloader 程序会先初始化DDR等外设,一般 linux 镜像zimage(uimage)+设备树(.tdb文件)存放到外置存储区(SPI_flash、SD、EMMC、NAND等),然后将Linux内核(镜像)从flash,拷贝到 DDR 中,再去启动。
2、特点:● uboot是一个通用的 bootloader,支持多种架构,也不仅能启动linux系统,如 vxworks。
● linux也不仅仅通过uboot启动。
3、开发板要运行uboot条件:板子能正常工作;有DDR或DRAM,串口、外置存储。
4、烧录,我们打开提供的烧录工具,选择对应的文件,点击Start,等待烧录完成(如果不能烧录可以只接OTG那跟USB线),如下,然后点击Stop,然后Exit即可烧录完成。
5、初看uboot启动过程,如图,当我们将程序烧录到开发板中,打印如下:
6、设备树:内核通过设备树知道系统的硬件配置,从而使内核能正确地完成对硬件的初始化和驱动。
二、下载uboot
1、buoot官网: http://www.denx.de/wiki/U-Boot/
2、源码下载地址:Index of /pub/u-boot/ (denx.de) https://ftp.denx.de/pub/u-boot/ 一般官方 uboot 源码是给半导体厂商准备的,厂商会选择一个版本源码下载,将自家相应的芯片移植进去。这个版本的 uboot 相当于是他们定制的。对他们的芯片支持会很全,虽然 uboot 官网源码一般也支持他们的芯片,但没有厂商自己维护的全面。如:NXP官方的 MX6ULL EVK板子。
3、从芯片厂商网站获取:http://git.freescale.com/git/cgit.cgi/imx/uboot-imx.git/tag/?h=imx_v2016.03_4.1.15_2.0.0_ga&id= rel_imx_4.1.15_2.1.0_ga (或者搜索其官网https://www.nxp.com)
三、编译uboot
1、在Ubuntu下新建一个自己的工作目录linux/uboot ,将从NXP官网下载的uboot源码放到此目录下解压(tar -vxjf +压缩文件)。
2、编译时如下设置:第一条:包含使用的架构,编译链、清除工程,第二条相当于“make mx6ull_14x14_ddr512_emmc_defconfig”,用于配置 uboot(configs/这是使用正点原子自己修改的配置文件,如果编译的是NXP的uboot则找到官方的配置文件:mx6ull_14x14_evk_emmc_defconfig),最后一条相当于 “make“ ,”-j12”表示使用 12 核来编译 uboot(这个也可以不使用),V=1表示打印详细日志。中间的使用什么架构和配置可以直接写到 makefile 文件里。
注意上图第二行和第三行是同一条指令
3、首先在 Ubuntu 中安装 ncurses 库,否则编译会报错,安装命令如下: sudo apt-get install libncurses5-dev 如果没有安装交叉编译链: sudo apt-get install gcc-arm-linux-gnueabihf 命令。执行安装软件包命令前最好先执行: sudo apt-get update 命令来更新Ubuntu软件包库。
4、如果执行第二条命令时报错则安装: sudo apt-get install bison flex 此命令是用来安装Bison和Flex软件的,如果是报找不到配置文件错误则有可能复制的uboot不是正点原子的。或者重新复制解压。
● Bison:它是一个用于生成 LALR(1)类型分析器的工具,通常用于编译器和解释器的开发中。
● Flex:它是一个快速的词法分析器生成工具,用于扫描源文件并将其划分为词法单元,以便后续的语法分析工作
5、如果执行第三条编译命令时:error: unrecognized -march target: armv5 是因为此编译器不支持ARMv5 指令集,重新安装 arm-linux-gnueabi-gcc 编译器即可。
6、编译完生成u-boot.bin,必须向这个文件添加头部信息,编译后会通过/tools/mkimage软甲自动添加头部信息,生成u-boot.imx,如下,最后就是将这个文件改两次名(该烧录工具只支持固定名字)后烧录到开发板。
7、如何裁剪:如上在编译时configs文件里笔者只留下开发板对应的配置文件是可以编译通过的,比如像net文件夹等删除后就编译报错,是因为makefile里包含了该依赖,如果熟悉makefile则可自行修改。
四、移植NXP官方uboot到开发板(如下涉及到改文件名字的可以不改)
· 1、通过上面方法我们编译官方的uboot并烧录到开发板里,上电运行情况:
● 4.3寸LCD可以显示NXP的logo,但如果是其它型号和尺寸的LCD屏就会显示不出来,需要改buoot中的LCD驱动才行。
● 网络驱动异常:由于正点原子开发板网络芯片引脚和NXP官方的有差异,需要改驱动。
● uboot 启动正常,DRAM 识别正确, EMMC 驱动正常。
2、添加并修改开发板默认配置文件:NXP官方uboot默认配置文件为:mx6ull_14x14_evk_emmc_defconfig 如需更改则改为自己想要的名字即可,更改完如下地方需要对应上。
注意:我们在前面说编译出来的u-boot.bin会在头部加入一些数据后重新生成.imx文件,这个头部信息就是放在上图路径中的imximage.cfg文件中的(此文件比如使能时钟,初始化DDR等)。
3、添加并修改开发板对应头文件:复 制 include/configs/mx6ullevk.h,如需更改则改为自己想要的名字即可,更改完头文件的条件编译要对应上。使能或者裁剪 uboot 的某些功能就是在这个文件下修改的,包括配置 flash 分区。
● 第 29~39 行,设置 DRAM 的大小
● 第 50 行,定义了宏 CONFIG_DISPLAY_CPUINFO,表示uboot 启动的时候可以显示 CPU 信息
● 第 51 行,定义了宏 CONFIG_DISPLAY_BOARDINFO,表示uboot 启动的时候可以输出板子信息
● 第 59、60 行,使能 I.MX6ULL 的串口功能
● 第 231 行,宏 PHYS_SDRAM 为 I.MX6ULL 的 DRAM 控制器 MMDC0 所管辖的 DRAM 范 围起始地址,也就是 0X80000000
● 第 258 行,宏 CONFIG_MMCROOT 设置进入 linux 系统的根文件系统所在的分区,这里设 置为"/dev/mmcblk1p2",也就是 EMMC 设备的第 2 个分区。第 0 个分区保存 uboot,第 1 个分 区保存 linux 镜像和设备树,第 2 个分区为 Linux 系统的根文件系统
● 第 325~342 行,与网络相关的宏定义,比如使能 dhcp、ping 等命令
● 第 344~END,一些其余的宏定义,如 CONFIG_VIDEO 开启 LCD,CONFIG_VIDEO_LOGO 显示 logo,CONFIG_CMD_BMP 使能 BMP图片,这样可以在uboot阶段显示logo
...............................................................................................详情请参考正点原子 <<MX6U嵌入式linux驱动开发指南V1.6.pdf>>
4、添加开发板对应的板级文件夹:每个板子都有一个对应的文件夹来存放板级文件,可将其中 mx6ullevk.c 文件重命名为我们想要的名字(如果改了名字则mx6ullevk下的makefile第6行也要改成对应名字)。
(1)、如果 mx6ullevk (第2点文件夹) 被重命名,则 imximage.cfg 也需要修改:PLUGIN board/freescale/mx6ullevk/plugin.bin 0x00907000
(2)、修改 mx6ullevk 目录下的 Kconfig 文件,假设此文件夹被重命名为:mx6ull_alientek_emmc 则修改如下:
(3)、修改 mx6ullevk 目录下的 MAINTAINERS 文件,假设此文件夹被重命名为:mx6ull_alientek_emmc 并且头文件被重命名为 mx6ull_alientek_emmc.h 则修改如下:
(4)、修改U-Boot图形界面配置文件:修改文件arch/arm/cpu/armv7/mx6/Kconfig(如果用的I.MX6UL的话,应该修改arch/arm/Kconfig这个文件),在207行加入如下内容:
接下来就可以编译了,此时编译里的配置文件就要根据我们刚才修改的文件名了,不过效果跟第1步一模一样,这几部只是改了一下文件名。
五、驱动修改
简介:一般来说,针对不同开发板,板级目录下会有一个相应的.C文件,include下也会有一个头文件,修改驱动基本也都是在这两个文件中进行。
1、LCD驱动修改注意事项(从代码里可以查到相应设置):
2、网络驱动修改:
(1)、MX6U-ALPHA网络简介:其内部有个以太网MAC外设,需外接PHY芯片实现网络通信,即内部MAC+外部PHY。
(2)、没有内部MAC的CPU,可采用DM9000来实现联网。其提供了一个类似SRAM的访问接口,主控通过这个接口与其进行,即外部MAC+外部PHY(没有集成的通信快)。
(3)、NXP使用KSZ8081(PHY)芯片,正点原子使用LAN8720A(PHY)芯片。所以需要调整网络驱动。MX6ULL会读取LAN8720内部寄存器来判断当前物理链接状态、连接速度、双工状态等,通过MDIO接口读取PHY内部寄存器,MDIO接口有两个脚:ENET_MDC:时钟 、ENET_MDIO:数据,同一接口多个PHY使用不同的器件地址来区分。
(4)、修改注意事项: ①、ENET1复位引脚初始化。②、LAN8720A的器件ID。③、LAN8720驱动
3、bootcmd 和 bootargs 环境变量修改:用 shell 脚本语言开发的
(1)、bootcmd 存着 uboot 默认命令,uboot 倒计时结束执行 bootcmd 中的命令。这些命令一般用来启动Linux内核,如读取 EMMC 或 NAND Flash 中的 Linux 内核镜像文件和设备树文件到 DRAM 中,然后启动Linux内核。文件include/env_default.h。
(2)、bootargs 保存着 uboot 传递给 Linux 内核的参数:
①、console用来设置linux终端(控制台),也就是通过什么设备来和Linux进行交互,是串口还是LCD屏幕
②、root 用来设置根文件系统的位置,root=/dev/mmcblk1p2用于指明根文件系统存放在 mmcblk1 设备的分区2中
③、rootfstype用于指定根文件系统类型
4、从EMMC启动Linux系统:将编译出来的 Linux 镜像文件 zImage 和设备树文件保存在 EMMC 中,uboot 从 EMMC 中读取这两个文件并启动。如何移植linux和设备树文件及如何保存到 EMMC ?
5、从网络启动Linux系统:唯一目的就是为了调试。
六、uboot常用命令
命令行模式下输入“help”或者“?"可查看当前 uboot 所支持的命令,输入“help(或?) 命令名”既可以查看命令的详细用法
1、信息查询命令3 个:bdinfo:查看板子信息; printenv:输出环境变量; version:uboot 版本号
2、环境变量操作命令:setenv 和 saveenv(设置和保存):一般环境变量存放在外部 flash 中,启动时再读取到 DRAM 中,所以 setenv 修改的是 DRAM中的环境变量值,注意保存。
将环境变量 bootdelay 改为 5,倒计时时间
环境变量值有空格时要用单引号括起来,如下:如果新建则:setenv author gty 删除则赋空值。
1、md 命令 :用于显示内存值,格式如下
七、Kernel
1、下载内核:官网: https://www.kernel.org,跟uboot一样,我们下载NXP针对这个开发板维护的。
2、编译内核:编译前要安装 lzop 库 sudo apt-get install lzop 这里设置的配置参数有点多,写一个shell脚本:mx6ull_alientek_emmc.sh
运行:./mx6ull_alientek_emmc.sh (chmod给执行权限),运行后开始编译弹出如下界面:配置界面和 uboot 一样,这里不用配置,按两下 ESC退出,退出后开始编译。
如上错误是gcc版本问题,可以回退旧版本,或者更改源码目录解决,打开下载到ubuntu的内核源码目录,在如下路径找到 dec-lexer.lex.c_shippen文件。
找到该行,在标记处前面增加 extern
内核源码目录下Documentation/Changes文件可以查看最低版本的编译器支持。如下第一行看到最低支持:3.2
可能是gcc版本或编译器问题,回退gcc到9.5,并更新最新的编译器还是不行,替换编译器:sudo apt-get install gcc-arm-linux-gnueabi (很多警告,无输出)
3、安装内核: