[架构之路-27]:目标系统 - 系统软件 - bootloader uboot的方案选择移植与定制化(硬件电路板的适配)

Posted 文火冰糖的硅基工坊

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[架构之路-27]:目标系统 - 系统软件 - bootloader uboot的方案选择移植与定制化(硬件电路板的适配)相关的知识,希望对你有一定的参考价值。

目录

第1章 uboot移植概述

1.1 uboot概述

1.2 uboot定制的级别与层次

1.3 设备厂家对uboot的选择

1.4 什么是uboot的移植

第2章 uboot移植与适配的步骤 -- 编译NXP官方uboot

2.1 步骤1:下载/准备uboot参考源码

2.2 步骤2:配置uboot

2.3 步骤3:编译uboot

2.4 步骤4:烧录uboot

2.5 验证驱动与外设硬件

第3章 uboot移植与适配的步骤 -- 移植和定制自己的uboot

3.1 步骤1:建立自己目标板程序目录

3.2 步骤2:添加目标开发板默认配置文件

3.3 步骤3:新的单板编译测试

3.4 步骤4:修改外设驱动程序

第4章 总结


第1章 uboot移植概述

1.1 uboot概述

uboot 的全称是 Universal Boot Loader, 是一个主要用于嵌入式系统的引导加载程序,可以支持多种不同的计算机系统结构,包括PPC、ARM、AVR32、MIPSx8668k、NiosMicroBlaze。这也是一套在GNU通用公共许可证之下发布的自由软件。uboot 是一个遵循 GPL 协议的开源软件, uboot 是一个裸机(无操作系统)代码,可以看作是一个裸机综合例程。

1.2 uboot定制的级别与层次

(1)Uboot的官方版本

U-Boot | DENX

uboot 是一个主要用于嵌入式系统的引导加载程序,可以支持多种不同的计算机系统结构,包括PPC、ARM、AVR32、MIPSx8668k、Nios与MicroBlaze

uboot 官方的 uboot 源码主要是为半导体厂商准备的。

(2)CPU架构的定制

一个新的硬件电路板,只能选用其中一款CPU架构,因此,需要定制化uboot的CPU架构。

(3)SOC半导体芯片厂家的定制

不同的soc芯片厂家,虽然CPU架构可能相同,如都是ARM CPU核。但SOC芯片内部的架构和内部外设控制器的组成可能是不相同的。不同厂家的SOC芯片,其内部的外设控制器的个数、外设控制器的寄存器的定义、SOC内部的架构、内部的总线、连接关系有可能都不相同。

因此,SOC芯片厂家需要修正uboot官网提供的源代码。

半导体厂商会下载 uboot 官方的 uboot 源码,然后将自家相应的芯片移植进去。

也就是说半导体厂商会自己维护一个版本的 uboot,这个版本的 uboot 相当于是他们定制的。

如NLP:uboot-imx - i.MX U-Boot

(4)开发版本厂家公开版本

开发版本厂家会采用SOC芯片厂家的芯片,再叠加一定的外设,生产出自己的特定领域应用的通用开发板。开发板厂家,提供SOC芯片厂家没有的外设,且不同外设厂家,会设计不同的外设电路和整个硬件电路板的电路。因此,开发板厂家根据自身开发板的需要,进行了部分修改,生成自己的版本。

野火提供的 uboot 下载链接:
ebf_linux_uboot: 野火所有Linux系列产品使用的uboot源码仓库

git clone https://gitee.com/Embedfire/ebf_linux_uboot.git

//切换 ebf_v2020_10_imx 分支

git checkout ebf_v2020_10_imx

(5)设备厂家私有版本

设备厂家一般不会直接用 uboot 官方的 U-Boot 源码, 不同的设备厂家,其底层硬件是不相同的,设备厂家可能会基于前面提到的版本,再进一步对uboot进行修改,生成自己的私有版本 。

设备生产厂家生产的硬件,才是正在满足特定业务需要的硬件产品。

1.3 设备厂家对uboot的选择

不同层面的uboot定制,采用的方法是不相同的。

文本重点探讨设备厂家如何基于开发板厂家提供的uboot,定制化自己产品的uboot。

设备厂家的硬件和Uboot有几种选择:

(1)基于芯片厂家的SOC芯片,全新设计电路板 =》可以选择基于SOC芯片厂家的uboot版本,进行裁剪和适配。

(2)基于开发板厂家提供的参考版,设计自己的电路 =》 可以选择基于开发板厂家的uboot版本,进行裁剪和适配。

备注:

很少有设备厂家,直接基于uboot官网提供的版本,进行裁剪和适配的。

这是因为,基于uboot官网提供的版本需要修改的内容较多。

最高效和快速的方式,就是基于开发板厂家提供的uboot进行裁剪和适配。

1.4 什么是uboot的移植

所谓uboot移植,就是把第三方的uboot的移植到自己的目标板上执行的过程。

移植工作大小,取决于自身目标板的硬件与第三方的硬件的差别。

第三方的uboot的来源,更加相似的大小,由近到远分为:

(1)组织内部,其他产品或项目使用的uboot

适用于自身产品的硬件是从组织内的其他硬件产品改进升级过来的。这适用于组织内大部分产品的研发。

(2)开发板厂家提供的uboot

适用于自身产品的硬件是基于第三方提供的开发板改进而来,或者是硬件直接使用了第三方提供的开发板。

开发板常见通常会提供uboot,然后基于该uboot进一步做定制化的开发,增加开发板厂家没有的功能,如硬件检测功能,多MAC地址,产品序列号、双uboot切换等功能。

这种方案,是很多小公司采用的方法。

如《正点原子》是开发板厂家,它们就会提供自己的开发板的uboot。

(3)SOC芯片厂家提供的uboot

适用于自身产品的硬件是基于第三方提供的开发板改进而来。

SOC芯片厂家通常也会提供自己的开发板,但为了更大的兼容性和适应性,SOC芯片厂家的开发板通常都比较复杂,是大而全的开发板。设备厂家通常根据自己业务的需求进行裁剪。

这种方案,是很多大厂采用的方法 。

(4)uboot官方提供的uboot

很少有公司自己基于uboot官方提供的uboot,uboot官方支持的硬件型号大而全,它主要的任务就是适应性强和泛化能力强,因此,官方的uboot,功能都比较抽象,尽可能不做具体的特定硬件相关的功能。而实际的硬件产品,又需要特定硬件的驱动与功能。

因此,大部分设备厂家都采用前三种方案。

本文,采用最常见的方案:基于(3)SOC芯片厂家提供的uboot,如恩智浦SOC芯片为例。

使用的uboot的不是最新的,但最新的uboot移植的步骤是相似的。

第2章 uboot移植与适配的步骤 -- 编译NXP官方uboot

2.1 步骤1:下载/准备uboot参考源码

(1)uboot官网

(1)网上下载现成的uboot开源代码:Index of /pub/u-boot/

在该网站中选择与板子兼容的uboot源文件(公司中一般咨询硬件工程师)

(2)在Linux系统下解压
tar xf 压缩包名

(2)NXP官方uboot

NXP官方uboot仓库地址为:https://source.codeaurora.org/external/imx/uboot-imx官方使用的Uboot为2016.03的版本。
这里直接使用正点原子下载好的NXP官方Uboot:uboot-imx-rel_imx_4.1.15_2.1.0_ga.tar.bz2。

将Uboot压缩包发送到Ubuntu虚拟机,并解压:
tar -vxjf uboot-imx-rel_imx_4.1.15_2.1.0_ga.tar.bz2。

2.2 步骤2:配置uboot

(0)cd到uboot目录中

(1)设置临时环境变量

export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-

(2)清理构建

make distclean

(3)图像化配置uboot

uboot或Linux内核可以通过输入“make menuconfig”来打开图形化配置界面。

menuconfig是一套图形化的配置工具,需要ncurses库支持。ncurses库提供零一系列的API函数供调用者生成基于文本的图形界面,因此需要先在Ubuntu中安装ncurses库

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

menuconfig重点会用到两个文件:“.config”和“Kconfig”,.config文件保存着uboot的配置项,使用menuconfig配置完uboot后该文件会被更新;Kconfig文件是图形界面的描述文件,即描述界面应该有什么内容,很多目录下都会有Kconfig文件。

在打开图形化配置界面前,需要先对uboot进行一次默认配置。

之后使用“make menuconfig”命令打开图形化界面:

make menuconfig

打开后的界面如下示:

(4)或手工配置uboot

uboot可以通过 mx6ull_xxx_defconfig和 mx6ull_xxx_emmc.h文件来手工文本方式配置;其中xxx换成自己的需要的版本。

vi mx6ull_14x14_evk_emmc_defconfig

(5)生出配置文件对应的C代码

加载板级配置文件,具体的板级配置文件在 uboot 根目录下的 configs 目录下,选择emmc版本

make mx6ull_14x14_evk_emmc_defconfig

2.3 步骤3:编译uboot

配置好之后编译:

make

编译出的文件:

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-nodtb.bin的复制文件

2.4 步骤4:烧录uboot

uboot的承载体可以是:

  • SD卡
  • Flash
  • ROM

这里选择的SD卡。

(1)插上读卡器

使用 lsblk 命令查看磁盘设备,如下所示

(2) 执行以下烧录命令

将 u-boot-dtb.imx 烧写到/dev/sdb 中。

sudo dd iflag=dsync oflag=dsync if=u-boot.imx of=/dev/sdb seek=2

烧录成功提示:

2.5 验证驱动与外设硬件

(1)连接目标板

  • 通过串口连接目标板
  • 把SD卡插入到目标板
  • 配置目标板从SD启动

(2)启动目标板

检查uboot的编译时间

检查DRAM的大小:512M

(3)测试 EMMC 驱动

SD 卡和 EMMC 驱动检查,SD卡大小8GB,正常,EMMC大小为8GB,正常。

 (4)LCD显示设备检查

uboot打印日志中提示LCD显示设备是Display: TFT43AB (480x272)

(5)网络设备检查

目标板使用的 PHY 芯片与NXP 官方的I.MX6ULL EVK 开发板使用的 KSZ8081 芯片一样,所以网卡驱动部分不需要修改。

(6)检查自己关心的其他设备

............. 

至此,uboot编译成功,并且在开发板上运行正常。

接下来,需要修改uboot,适配自己的硬件,并且要确保在自己的目标上运行正常。

第3章 uboot移植与适配的步骤 -- 移植和定制自己的uboot

3.1 步骤1:建立自己目标板程序目录

(1)新建单板目录和文件

cd  board/freescale
cp -rf mx6ullevk/ mx6ullfire

备注:新的目标板“mx6ullfire”是基于现有的目标板“mx6ullevk”修改得到。

最终会得到目标板的工程文件如下:

  • mx6ullfire.c :里写了一些 uboot 启动代码和我们对板子引脚读取的代码。
  • plugin.S :用汇编写的设置 ddr 和时钟,一般不需要更改。
  • Makefile :里面修改 C 文件编译后的 o 文件,有多少个就写多少个 o 文件,注意与 c 文件名字相同。
  • Kconfig : (目录: board/路径/目标文件夹/Kconfig)。
  • imximage.cfg : (目录: board/路径/目标文件夹)(NXP 特有的文件, 只需要修改一处即可, 这是添加头部信息的)
     

(2)修改主文件

进入新建的目录,进行修改文件,重命名c文件:

mv mx6ullevk.c mx6ullfire.c

(3)修改makefile

obj-y  := mx6ullfire.o

(4)修改Kconfig 文件

if TARGET_MX6ULL_FIRE

config SYS_BOARD
        default "mx6ullfire"

config SYS_VENDOR
        default "freescale"

config SYS_CONFIG_NAME
        default "mx6ullfire"

endif

(5)修改imximage.cfg 文件

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

(6)修改MAINTAINERS .cfg 文件

MX6ULLEVK BOARD
M:      Peng Fan <peng.fan@nxp.com>
S:      Maintained
F:      board/freescale/mx6ullfire/
F:      include/configs/mx6ullfire.h
F:      configs/mx6ull_fire_emmc_defconfig

3.2 步骤2:添加目标开发板默认配置文件

(1)派生配置文件

cp mx6ull_14x14_evk_emmc_defconfig   mx6ull_fire_emmc_defconfig

(2)修改配置文件

修改该文件中的下面两行内容:

CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6ullfire/imximage.cfg,MX6ULL_EVK_EMMC_REWORK"
CONFIG_TARGET_MX6ULL_FIRE=y

(3)创建开发板头文件

cp include/configs/mx6ullevk.h mx6ullfire.h

(4)修改头文件

拷贝完成以后将:
#ifndef __MX6ULLEVK_CONFIG_H
#define __MX6ULLEVK_CONFIG_H
改为:
#ifndef __MX6ULLFIRE_CONFIG_H
#define __MX6ULLFIRE_CONFIG_H

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

(5)把新增开发板添加到U-Boot 图形界面配置文件中

修改arch/arm/cpu/armv7/mx6/Kconfig文件,仿照其它单板文件,添加:

config TARGET_MX6ULL_FIRE
	bool "Support mx6ullfire"
	select MX6ULL
	select DM
	select DM_THERMAL

在末尾处添加:

source "board/freescale/mx6ullfire/Kconfig"

至此,可以通过uboot的通用的配置、编译环境来对新增加的目标板进行配置和编译了。

3.3  步骤3:新的单板编译测试

(1)配置

make menuconfig

(2)编译

make distclean
make mx6ull_fire_emmc_defconfig
make

(3)烧录

sudo dd iflag=dsync oflag=dsync if=u-boot.imx of=/dev/sdb seek=2

(4)串口验证

 和原厂uboot运行效果一样,新建单板成功。

至此,可以针对针对自己的目标板修改驱动程序了。

3.4 步骤4:修改外设驱动程序

一般 uboot 中修改驱动,基本都是在 xxx.h 和 xxx.c 这两个文件中进行的, xxx 为板子名称,比如 mx6ullfire.h 和 mx6ullfire.c 这两个文件。

(1)修改LCD驱动

一般修改 LCD 驱动重点注意以下几点:

①、 LCD 所使用的 GPIO,查看 uboot 中 LCD 的 IO 配置是否正确。

②、 LCD 背光引脚 GPIO 的配置。

③、 LCD 配置参数是否正确。

如果开发板使用的是野火的5.0 寸 800x480RGB 电容触摸屏,LCD引脚配置与NXP官方一致,只需要配置参数即可:
 

        .mode   = 
                .name                   = "TFT800x480",
                .xres           = 800,
                .yres           = 480,
                .pixclock       = 37037,
                .left_margin    = 46,
                .right_margin   = 20,
                .upper_margin   = 22,
                .lower_margin   = 22,
                .hsync_len      = 1,
                .vsync_len      = 1,
                .sync           = 0,
                .vmode          = FB_VMODE_NONINTERLACED

然后在include/configs/mx6ullfire.h文件中,修改uboot默认环境变量设置:

"panel=TFT800x480\\0" \\

重新编译uboot,烧写到SD卡中运行,测试屏幕。

 (2)修改其他驱动程序

第4章 总结

uboot 移植到此结束,简单总结一下 uboot 移植的过程:

(1)不管是购买的开发板还是自己做的开发板,基本都是参考半导体厂商的 dmeo 板,而半导体厂商会在他们自己的开发板上移植好 uboot、 linux kernel 和 rootfs 等,最终制作好 BSP包提供给用户。我们可以在官方提供的 BSP 包的基础上添加我们的板子,也就是俗称的移植。

(2)我们购买的开发板或者自己做的板子一般都不会原封不动的照抄半导体厂商的 demo板,都会根据实际的情况来做修改,既然有修改就必然涉及到 uboot 下驱动程序的移植。

(3)一般 uboot 中需要解决串口、 NAND、 EMMC 或 SD 卡、网络和 LCD 驱动,因为 uboot的主要目的就是启动 Linux 内核,所以不需要考虑太多的外设驱动。

(4)在 uboot 中添加自己的板子信息,根据自己板子的实际情况来修改 uboot 中的驱动程序。

(5)在开发板或SOC芯片厂家提供的参考uboot下,移植uboot的工作其实并不难度,大部分的工作是配合硬件调试第一版的硬件电路。

(6)设备厂家可能会增加对硬件电路的自检测功能。

以上是关于[架构之路-27]:目标系统 - 系统软件 - bootloader uboot的方案选择移植与定制化(硬件电路板的适配)的主要内容,如果未能解决你的问题,请参考以下文章

[架构之路-56]:目标系统 - 平台软件 - 总体架构概述

[架构之路-28]:目标系统 - 系统软件 - Linux OS内核功能架构图解内核构建内核启动流程

[架构之路-25]:目标系统 - 系统软件 - bootloader uboot内存映射与启动流程

[架构之路-21]:目标系统 - 系统软件 - 计算机系统架构计算机指令系统结构化程序与分层编程。

[架构之路-29]:目标系统 - 系统软件 - Linux OS内核以及内核驱动的调试技术

[架构之路-26]:目标系统 - 系统软件 - bootloader uboot使用方法常用命令