云计算百科
云计算领域专业知识百科平台

Linux驱动与系统移植---U-Boot启动Linux内核流程详解以及U-Boot与zImage文件的制作流程

一. UBoot 详解

1.1 概念

        Linux 系统要启动就必须需要一个 bootloader 程序,也就说芯片上电以后先运行一段 bootl oader 程序。这段 bootloader 程序会先初始化 DDR 等外设,然后将 Linux 内核从 flash(NAND, NOR FLASH,SD,MMC 等) 拷贝到 DDR 中,最后启动 Linux 内核。

        bootloader 最主要的工作就是启动 Linux 内核,bootloader 和 Linux 内核的关系就跟 PC 上的 BIOS 和 Windows 的关系一样,bootloader 就相当于 BIOS。

        uboot是bootloader的一种,主要作用是在内核加载前对硬件设备初始化,并为内核的
运行提供引导功能
 

1.2 IMX6ULL 核心板资源

1.2.1 核心板

        IMX6ULL 的核心板资源

                主控芯片,采用BGA封装
                24MHz晶振
                32.768KHz,RTC使用,日历等等,这个时钟不变
                8 GB EMMC,flash (ROM),永久保存数据
                512M DDR3L,(RAM),运存,断电数据丢失

1.2.2 主控芯片内部

        在主控芯片内部,还有:

                ROM:96 KB,存放第一阶段启动代码(固化代码,不可改),运行完此代码之后再根据拨码开关的选择到指定位置去运行(SD卡等)

                OCRAM:128 KB,也叫 IRAM

1.3 IMX6ULL 启动流程

        iMX6ULL 必须用 SPL + U‑Boot 组合,因为片内 RAM 只有 128KB,装不下完整
U‑Boot,必须分两阶段

        SPL(Secondary Program Loader):第二阶段程序加载

二. U-Boot 与内核文件的制作

2.1 U-Boot 的制作

        基本流程:

                1、解压uboot压缩包,并进入uboot源码目录

tar -zxvf uboot.tar.gz
cd uboot

                2、uboot图形界面是基于ncurses库编写的,所以需要先安装该库

sudo apt-get install libncurses5-dev

                3、编译uboot源码

                        distclean 的作用:目的是清除工程,将源码恢复到原始状态,类似复位

                        CROSS_COMPILE:设置交叉编译工具链

                        V=0:控制编译输出的详细程度, 0表示启动静默/精简输出模式, 1表示完整的编译命令,便于调试

                        第二句的作用:生成 .config 配置文件,文件中指定了哪些需要编译,原来的.c很多,只需要编译ARM架构下面的imx6u的.c即可
                        最后一句的作用:使用16核来编译uboot

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_alientek_emmc_defconfig
make V=0 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16

                4、生成的文件

                        生成的文件主要位于 uboot 顶层目录:u-boot.imx,u-boot.lds,u-boot.map等

                        注意:其中 u-boot.bin 就是编译出来的 uboot 二进制文件。uboot 是个裸机程序,因此需要在其前面加上头部(IVT、DCD 等数据)才能在 IMX6ULL 上执行,u-boot.imx 文件就是添加头部以后的 u-boot.bin,u-boot.imx 就是最终要烧写到开发板中的 uboot 镜像文件

  

2.2 内核文件的制作

        基本流程:

                1、先安装必要的工具

sudo apt-get install lzop

                2、把linux内核复制到虚拟机,解压操作

tar -zxvf linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek.tar.gz
ls

                3、编译的命令

                        具体思路和 U-Boot 文件的制作一样:先清理工程,再生成配置文件,最后编译即可

cd linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek/
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- imx_alientek_emmc_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig #内核地图,驱动,模块和c文件的关系
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- all -j16

                4、生成结果

                        结果文件主要有2个:
                                内核镜像文件: arch/arm/boot/zImage
                                设备树文件: arch/arm/boot/dts/imx6ull-alientek-emmc.dtb文件
                                还有相关的驱动文件 *.ko

                5、将编译好的两个文件拷贝到tftp管理目录下

cp arch/arm/boot/zImage ~/tftpboot/ -rf
cp arch/arm/boot/dts/imx6ull-alientek-emmc.dtb ~/tftpboot/ -rf

                6、重新启动开发板,每次从Ubuntu管理目录下载最新版本的内核和设备树文件
 

三. U-Boot 启动详解

        总共三个阶段

3.1 阶段一 (Boot ROM 阶段)

        这一步不属于 U‑Boot,但必须先做,才能启动 U‑Boot。
        这一步的作用:
                1、检测启动模式(SD 卡、 EMMC、 NAND、 QSPI)。 sd/emmc设备没有完全初始化,内部程序写死,只会读取前面一部分内容根据拨码开关有关,决定了启动方式,为了第二阶段到指定的启动设备上去加载U-Boot
                2、初始化最基础的时钟 arm_pll 396M, system_PLL 528M
                3、读取启动设备的第一个镜像(SPL),从片上的 Rom 中
                4、把 SPL 加载到片内 RAM(运存)(OCRAM 0x00900000)
                5、跳转到 SPL 执行

3.2 阶段二 U‑Boot SPL(第一阶段 U‑Boot)

        SPL = Secondary Program Loader,第二阶段程序加载器

        SPL:加载UBoot的前4K

        运行位置:片内 RAM(OCRAM)

        核心使命:初始化 DDR,然后加载完整 U‑Boot

        SPL 完成的详细工作:u-boot.imx = IVT+BOOTData+DCD

                1、关闭看门狗,防止芯片自动复位。

                2、设置 CPU 主频 / 系统时钟:iMX6ULL 通常设为 792MHz,初始化 PLL 锁相环。

                3、初始化 IOMUXC 引脚复用:配置 DDR 引脚、启动设备引脚。

                4、初始化 DDR 控制器 + DDR 校准:没有 DDR,后面的 U‑Boot 和 Linux 都无法运行。

                5、初始化 NAND/SD/EMMC/QSPI,完全初始化 sd/emmc控制器:为了读取完整 U‑Boot 镜像。

                6、从 Flash/SD卡中读取完整 U‑Boot 到 DDR,加载地址:DDR=0x87800000

                7、跳转到 DDR 中的 U‑Boot 执行,SPL 使命结束

3.3 阶段三 U‑Boot 主程序(第二阶段,真正的 U‑Boot)

运行位置: DDR 0x87800000

        所做的工作:

                1.加载 Linux 内核和设备树到内存

                        加载 zImage 到:0x80800000;加载 dtb 到 0x83000000

                2.读取环境变量,解析启动命令

                3.传递启动参数给内核

                4.启动 Linux 内核

3.4 整体所完成的工作

                1.初始化DDR(最关键)        bootrom

                2.初始化时钟(CPU主频、总线时钟)        bootrom

                3.初始化启动设备(SD/EMMC/NAND)        bootrom+

                4.加载 Linux 内核和设备树到内存

                        加载 zImage 到:0x80800000;加载 dtb 到 0x83000000

                5.传递启动参数给内核

                6.启动 Linux 内核

四. 解释IVT、BOOTData与DCD

4.1 IVT (Image Vector Table,镜像向量表)

4.1.1 什么是 IVT

        可以把它理解为一个“地址簿”或“导航地图”。位于启动设备的特定偏移位置(例如SD卡/EMMC是从1KB偏移处开始)。BootROM启动后,会首先在固定位置找到这个地址簿。

4.1.2 作用

        为BootROM提供引导所需的所有关键信息的地址。

4.1.3 关键字段

        IVT内部包含了多个32位的地址指针,主要包括:

        
        简单来说,BootROM通过读取IVT,才知道去哪里找真正的用户程序(entry),如何去配置硬件(dcd)以及程序有多大(boot_data)

4.2 DCD (Device Configuration Data,设备配置数据)

4.3 IVT、 DCD与Boot Data的协作关系

五. U-Boot 阶段常用命令

5.1 环境变量操作命令

        eg:

env default -a #uboot 变量回复默认
saveenv# 保存变量
reset#重启uboot
setenv ipaddr 192.168.1.50 # 设置开发板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.100#设置pc段的ip地址
setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.1.100:/home/linux/nfs/rootfs,v3,proto=tcp rw ip=192.168.1.50:192.168.1.100:192.168.1.1:255.255.255.0::eth0:off' #设置根文件系统的位置
setenv bootcmd 'tftp 80800000 zImage;tftp 83000000 imx6ull-alientek-emmc.dtb;bootz 80800000 – 83000000' #设置 下载zImage ,dtb
saveenv #保存变量
reset#重启uboot

详解:

        1、setenv bootargs 'console=ttymxc0,115200 root=/dev/nfsnfsroot=192.168.1.100:/home/linux/nfs/rootfs,proto=tcp rw ip=192.168.1.50:192.168.1.100:192.168.1.1:255.255.255.0::eth0:off'

        注意:bootargs保存着uboot传递给Linux内核的参数

        作用:设置根文件系统位置,从nfs网络中启动Linux系统
                启动参数
                console:表示控制台
                ttymxc0:表示发到串口0,波特率:115200
                网络文件来自192.168.1.100
                可读可写

        2、setenv bootcmd 'tftp 80800000 zImage;tftp 83000000 imx6ullalientekemmc.dtb;bootz 80800000 – 83000000'

        注意:bootcmd保存着uboot默认命令, uboot倒计时结束以后就会执行bootcmd中的命

        作用:设置下载zImage,dtb;从网络中下载内核、设备树、启动
                启动命令
                倒计时结束,走这条命令
                去PC机下载文件
                内核放在80800000这个地址
                设备树放在83000000这个地址
                bootz:启动;  -:表示不使用文件系统,上面一条指令已经配置过了

    

5.2 网络命令

5.3 boot命令

六. Linux 启动总流程

        1、bootROM阶段:
                a. IMX6U平台在芯片0x0地址处接了96k bootROM,里面是厂商固化的启动代码,上

                电启动后触发复位异常。

                b. 根据用户设置的启动方式,将EMMC或SD卡存储器的前4k代码拷贝到SRAM中执行,

                其中包括(IVT镜像入口地址: 0X877FF400 (0x8780 0000 -3k) 、 DCD:

                DDR基础初始化代码、 BootData:镜像加载地址及大小)。

                c. 根据BootData将SPL加载到OCRAM中。 (on-chip ram)

        2、SPL阶段:
                a. 在OCRAM中运行SPL代码。

                b. 对DDR做深度初始化。

                c. 将完整的uboot拷贝到87800000地址

                d. 重新定位链接地址 (board_init_f -> relocate_code,relocate_vectors)

        3、uboot阶段:

                a. 重新设置异常向量表,执行reset复位异常

                b. 运行uboot完成对硬件设备初始化(网卡,串口,屏幕等外设)

                c. 与用户交互,执行bootcmd加载内核

        4、内核阶段:

                a. 运行内核代码

        5、文件系统阶段:

                a. 执行init进程

                b. 启动配置文件/etc/inittab

                c. 运行/etc/init.d/rcS脚本

                d. 挂载/etc/fatab文件

                e. 启动终端

赞(0)
未经允许不得转载:网硕互联帮助中心 » Linux驱动与系统移植---U-Boot启动Linux内核流程详解以及U-Boot与zImage文件的制作流程
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!