学嵌入式不得不知的Bootloader(U-boot)

    技术2022-07-10  153

    Bootloader 基本概念

    Bootloader是硬件启动的引导程序,是运行操作系统的前提; 在操作系统内核或用户应用程序运行之前运行的一小段代码。对软硬件进行相应的初始化和设定,为最终运行操作系统准备好环境; 在嵌入式系统中,整个系统的启动加载任务通常由Bootloader来完成。

    Bootloader的特点

    Bootloader不属于操作系统,一般采用汇编语言和C语言开发。需要针对特定的硬件平台编写。 在移植系统时,首先为开发板移植Bootloader。 Bootloader不但依赖于CPU的体系结构,而且依赖于嵌入式系统板级设备的配置。

    Bootloader的操作模式

    自启动模式:在这种模式下,Bootloader从目标机上的某个固态存储设备上将操作系统加载到RAM中运行,整个过程并没有用户的介入。 交互模式:在这种模式下,目标机上的Bootloader将通过串口或网络等通信手段从开发主机(Host)上下载内核映像和根文件系统映像等到RAM中。可以被 Bootloader写到目标机上的固态存储媒质中,或者直接进行系统的引导。也可以通过串口接收用户的命令。

    常用的bootloader之U-boot介绍

    u-boot(Universal Boot Loader)是德国DENX小组开发的用于多种嵌入式CPU的bootloader程序。遵循GPL条款。 从FADSROM、8xxROM 、PPCBOOT、Armboot逐步发展演化而来; U-boot的特点:

    代码结构清晰、易于移植(见目录结构)支持多种处理器体系结构(见arch目录)支持众多开发板(目前官方包中有200多种,见board目录)命令丰富、有监控功能支持网络协议、USB、SD等多种协议和设备支持文件系统更新较活跃,使用者多,有助于解决问题

    U-BOOT 命令

    命令分类

    环境设置、数据传输、存储器访问、加载运行 printenv 显示所有环境变量

    U-boot # printenv baudrate=115200 ipaddr=192.168.1.100 ethaddr=12:34:56:78:9A:BC serverip=192.168.1.10 ……

    setenv 设置新的环境变量

    U-boot # setenv myboard FS4412 U-boot # printenv baudrate=115200 ipaddr=192.168.1.100 ethaddr=11:22:33:44:55:66 serverip=192.168.1.10 myboard=FS4412 Environment size: 320/16380 bytes

    saveenv 将当前定义的所有的环境变量值存入flash中

    tftp 通过网络下载程序

    U-boot # setenv ethaddr 11:22:33:44:55:66 U-boot # setenv ipaddr 192.168.1.100 U-boot # setenv serverip 192.168.1.10 U-boot # tftp 41000000 application.bin U-boot # tftp 41000000 zImage

    protect 对Nor Flash写保护

    protect on 0 10000 对区间[0x0, 0x10000]进行写保护 protect off 0 10000 对上述区间取消写保护

    erase 擦除Nor FLASH

    erase all 擦除FLASH所有的扇区 erase 0 10000 把FLASH区间 [0x0, 0x10000]擦除

    Nand相关命令

    nand read addr off size nand write addr off size nand erase [clean] [off size]

    movi 命令

    movi init ---初始化eMMC并显示相关信息 movi read u-boot/kernel addr movi write u-boot/kernel addr movi read rootfs addr size movi write rootfs addr size

    bootcmd 自启动命令

    如果定义了该变量,在自启动模式下将会执行该环境变量中的命令。 U-boot # setenv bootcmd tftp 41000000 uImage\; bootm 41000000 U-boot # saveenv

    go addr 执行内存中的二进制代码,简单的跳转到指定地址 bootm kernel-addr ramdisk-addr dtb-addr 引导内核为内核传参,其中内核和ramdisk通常为mkimage处理过的二进制文件。

    U-BOOT 配置编译

    U-Boot目录结构

    平台相关 arch, board, include… 平台无关 common, net, fs, drivers… 工具和文档 tools, doc

    U-boot的编译

    整个工程通过Makefile来组织编译。顶层目录下的Makefile中包含了开发板的配置信息。从顶层目录开始递归地调用各级子目录下的Makefile,最后链接成u-boot映像。

    顶层目录下的 Makefile

    它负责u-boot整体配置和编译 在Makefile中指定使用的交叉工具链 配置u-boot: make origen_config 编译: make

    U-BOOT编译生成的映像文件

    U-boot镜像下载烧录

    烧录编译产生的镜像 u-boot.bin

    初次或开发板代码损坏不能正常启动时,可采用JTAG工具烧录 专用的烧录工具如h-jtag或DNW等 在u-boot已经能工作,升级或修正U-boot时,可用U-boot中的命令来烧录 其它方式 如SD卡 , Fastboot命令

    镜像固化位置

    ROM、NOR FLASH、NAND FLASH EMMC等

    U-BOOT 启动流程

    第一条指令如何执行 初始化那些硬件,先后顺序如何 如何加载内核 性能提升

    U-Boot 启动源码分析

    第一条指令位置(参考u-boot.map) arch/arm/cpu/armv7/start.S 里的 _start: b reset 设置为SVC模式 msr cpsr,r0 关闭MMU Cache cpu_init_cp15 基本硬件设备初始化 board/samsung/fs4412/lowlevel_init.S 的 lowlevel_init 关中断 看门狗 ,初始化时钟 串口,flash,内存 自搬移到内存 relocate_code 设置栈, IRQ stack frame


    准备进入C部分 bl _main ( 参u-boot.map ) 大部分硬件初始化 arch\arm\lib\board.c\board_init_f 里的init_sequence 搬移内核到内存运行 common/main.c main_loop -> getenv (“bootcmd”) bootdelay >= 0 && s && !abortboot (bootdelay)) 下的 run_command (bootcmd)

    U-BOOT 移植方法

    善用对比软件Beyond 选择官方源码版本下载, 配置编译 a. 指定交叉编译工具链 b. 指定cpu 和board(参考最类似配置如origen) c. 编译 实现串口信息输出 a. 跟踪运行路径(led点灯法) b. 串口输出(检查uart初始化相关部分代码 见lowlevel_init.s) 网卡移植(实现能用tftp nfs 方便开发调试) a. 寄存器地址 b. 参数设置 FLASH移植(实现能下载软件到FLASH,产品能离线运行)

    Processed: 0.013, SQL: 9