02.bootload启动

1.bootload概念

bootload-->内核-->文件系统

建议大家在学习之前,先去看一下百度百科的bootload启动流程解释部分

bootload的作用

软件是依赖于硬件运行的,比如内存、 MCU 等,刚上电的那一刻,即使是最简单的程序也无法运行,更不用说启动操作系统内核,因为这个时候软件代码所需要的执行环境还没有准备好,所以必须对硬件进行初始化操作。这里要明白最终的目标是进入操作系统内核,在进入操作系统内核之前所运行的一小段程序代码就被称为是 BootLoader。这段代码的主要作用就是初始化硬件设备、建立内存空间映射,从而将系统的软硬件配置为合适的状态,为最终的操作系统内核提供良好的运行环境。

Bootloader 是一种很常见的软件技术,日常使用的手机、路由器、游戏机、电视机及其他嵌入式产品大多都采用这个技术。

单片机--主要应用低端市场,相对来说不是需要特别复杂的设置(软件层次),不代表硬件很简单,底层数据采集,电机控制,环境监测

RK3399--主要应用消费类电子产品,可视化电子产品,摄像头,手机,电视机,偏向于应用方向。

Bootloader 的功能(加载阶段)

Stage 1:

这个阶段一般是用汇编来实现的, 高级语言运行所需的环境还没准备好,比如函数参数传递使用的寄存器、内存、外设总线、栈空间等, 它主要是完成一些 CPU体系结构的初始化,并调用第二阶段的入口函数,执行对应的代码。

Stage 2:

这个阶段一般使用 C 语言来编写,主要的作用就是加载或者安装设备驱动,让一部分必须的外设运行起来, 比如串口、显示屏、 I/O 口的按键、指示灯、网口等,主要是为了后续的内核加载提供基础, 这个阶段被称为是平台初始化(PlatForm Initialize)。

Stage 3:

这个阶段的主要作用就是加载操作系统的内核,并向内核传递一些启动参数, 并将执行流程跳转入操作系统的内核。 这个传参过程不是必须的!但目前基于 Linux 操作系统的都有这个功能 。

这样的分层设计、 分阶段启动, 从软件架构上看, 使得代码结构清晰、流程简洁, 能更利于对多个硬件平台的兼容和扩展;从软件功能上看,特定平台的硬件资源在逐步加载,最终完成启动流程。

为什么使用bootload

常见的Bootloader

Bootloader 并不是某个特定的软件,而是在完成对硬件初始化、操作系统加载、引导功能的软件的统称。在不同的发展阶段,针对不同的 MCU 平台,出现了多个完成Bootloader 功能的软件。 其中, U-Boot 因为开源、良好的软件架构和硬件兼容性,得到广泛应用。 下表简单列出了目前集中主流 Bootloader 的对比。

uboot介绍

U-Boot(Universal Boot Loader),是一个遵循 GPL 协议的开源软件, 也是一个广泛使用的 Bootloader。

U-Boot 配置及编译过程

交叉编译基本概念

交叉编译, 就是在一个平台编译出可以在另外一个平台运行的可执行文件。 比如说,我们可以在 x86 平台上编译出能够在 arm 平台上运行的可执行文件。本质上,就是在 x86平台上,按照 arm 平台规则翻译了可执行文件。 完成这个编译过程的, 通常叫交叉编译工具, 因为这个工具往往是很多个程序组成, 也叫交叉编译工具链。 执行编译的平台,叫宿主机; 编译出来的程序运行的平台, 叫目标平台或目标板。

通用的 U-Boot 源码,都配套提供了针对常见平台的交叉编译工具链。同时,部分厂家针对自己的 MCU 和板卡产品,也会提供自己的工具链。实际使用过程中,优先选择厂家提供的工具链。

获取源码:

我们当前源码包中的boot是经过裁剪(瑞芯微--》九鼎)之后,适合于RK3399使用的boot

官方路径:

The U-Boot Documentation — Das U-Boot unknown version documentation

一般我们在做开发的时候,不会直接选择uboot官方提供的引导程序,而是根据瑞芯微或者其他的开发商提供的代码进行修改,这样可以缩短项目的开发周期。

uboot结构:

重要目录介绍:

arch: 存放和硬件平台及 CPU 体系架构相关的文件,下面 根据不同的硬件 CPU 架构分子目录。

board: 存放不同厂家的板卡产品相关的文件,下面以厂 家为名称分子目录。

drivers: 存放所有外围芯片的驱动, 如网卡、 USB、串口、 LCD、 Nand Flash 等。 这些驱动是保证 U-Boot 作为一个早 期调试平台,提供基本的硬件功能。

fs: 存放文件系统相关的代码。 net: 存 放 网 络 协 议 相 关 的 代 码 , 主 要 是 支 持 在 Bootloader 阶段使用 TCP/IP 协议栈及一些网络命令。

common: 存放与处理器体系结构无关的通用代码, 如命令 解析代码/common/command.c、所有命令的上层代码 cmd_*.c、环境变量处理代码 env_*.c、 CRC 校验等都位于 本目录下。 configs: 存放 U-Boot 的配置文件,不同厂家会根据自己 产品情况提供基本的配置文件。 Include, lib: 头文件和库文件路径。当需要在 U-Boot 上进行开发时使用。 比如,增加自己的驱动或调试命令。

查看boot中包含的内容:

uboot的命令:

作为 Bootloader 的基本功能,为用户提供调试手段,便于用户解决启动和操作系统加载过程中的问题,是非常重要的。 U-Boot 通过简单的命令行界面,为用户提供丰富的调试命令;同时,我们也可以在其中增加自己的命令,极大方便了内核的开发和调试过程。

进入调试模式

安装一个软件

调试接口连接方式:
将USB转串口连接到电脑上:

通过设备管理器查看使用的端口:

选择端口进行设置:

开启电源,启动bootload加载内核,在bootload运行的过程中,看到如下命令行,点击键盘上的ctrl+c即可进入bootload中,查看bootload内容:

在进入bootload之前,设备加载打印的信息如下:

u-boot中全部命令:

?       - alias for 'help'
android_print_hdr- print android image header
base    - print or set address offset
bdinfo  - print Board Info structure
boot    - boot default, i.e., run 'bootcmd'
boot_android- Execute the Android Bootloader flow.
bootavb - Execute the Android avb a/b boot flow.
bootd   - boot default, i.e., run 'bootcmd'
booti   - boot arm64 Linux Image image from memory
bootm   - boot application image from memory
bootp   - boot image via network using BOOTP/TFTP protocol
bootrkp - Boot Linux Image from rockchip image type
bootz   - boot Linux zImage image from memory
charge  - Charge display
cmp     - memory compare
coninfo - print console devices and information
cp      - memory copy
crc32   - checksum calculation
dhcp    - boot image via network using DHCP/TFTP protocol
dm      - Driver model low level access
download- enter rockusb/bootrom download mode
dtimg   - manipulate dtb/dtbo Android image
dump_atags- Dump the content of the atags
dump_bidram- Dump bidram layout
dump_irqs- Dump IRQs
dump_sysmem- Dump sysmem layout
echo    - echo args to console
editenv - edit environment variable
env     - environment handling commands
exit    - exit script
ext2load- load binary file from a Ext2 filesystem
ext2ls  - list files in a directory (default /)
ext4load- load binary file from a Ext4 filesystem
ext4ls  - list files in a directory (default /)
ext4size- determine a file's size
false   - do nothing, unsuccessfully
fastboot- use USB or UDP Fastboot protocol
fatinfo - print information about filesystem
fatload - load binary file from a dos filesystem
fatls   - list files in a directory (default /)
fatsize - determine a file's size
fatwrite- write file into a dos filesystem
fdt     - flattened device tree utility commands
fstype  - Look up a filesystem type
go      - start application at address 'addr'
gpt     - GUID Partition Table
help    - print command description/usage
iomem   - Show iomem data by device compatible(high priority) or node name
lcdputs - print string on video framebuffer
load    - load binary file from a filesystem
loop    - infinite loop on address range
ls      - list files in a directory (default /)
md      - memory display
mdio    - MDIO utility commands
mii     - MII utility commands
mm      - memory modify (auto-incrementing address)
mmc     - MMC sub system
mmcinfo - display MMC info
mw      - memory write (fill)
nfs     - boot image via network using NFS protocol
nm      - memory modify (constant address)
part    - disk partition related commands
ping    - send ICMP ECHO_REQUEST to network host
printenv- print environment variables
pxe     - commands to get and boot from pxe files
rbrom   - Perform RESET of the CPU
reset   - Perform RESET of the CPU
rkimgtest- Test if storage media have rockchip image
rktest  - Rockchip board modules test
rockchip_show_bmp- load and display bmp from resource partition
rockchip_show_logo- load and display log from resource partition
rockusb - Use the rockusb Protocol
run     - run commands in an environment variable
save    - save file to a filesystem
setcurs - set cursor position within screen
setenv  - set environment variables
showvar - print local hushshell variables
size    - determine a file's size
source  - run script from memory
sysboot - command to get and boot from syslinux files
test    - minimal test like /bin/sh
tftpboot- boot image via network using TFTP protocol
true    - do nothing, successfully
usb     - USB sub-system
usbboot - boot from USB device
version - print monitor, compiler and linker version

当前使用的u-boot中环境变量内容:

=> printenv
arch=arm
baudrate=115200
board=evb_rk3399
board_name=evb_rk3399
boot_a_script=load ${devtype} ${devnum}:${distro_bootpart} ${scriptaddr} ${prefix}${script}; source ${scriptaddr}
boot_extlinux=sysboot ${devtype} ${devnum}:${distro_bootpart} any ${scriptaddr} ${prefix}extlinux/extlinux.conf
boot_net_usb_start=usb start
boot_prefixes=/ /boot/
boot_script_dhcp=boot.scr.uimg
boot_scripts=boot.scr.uimg boot.scr
boot_targets=mmc1 mmc0 usb0 pxe dhcp
bootargs=storagemedia=emmc androidboot.storagemedia=emmc androidboot.mode=normal
bootcmd=boot_android ${devtype} ${devnum};bootrkp;run distro_bootcmd;
bootcmd_dhcp=run boot_net_usb_start; if dhcp ${scriptaddr} ${boot_script_dhcp}; then source ${scriptaddr}; fi;
bootcmd_mmc0=setenv devnum 0; run mmc_boot
bootcmd_mmc1=setenv devnum 1; run mmc_boot
bootcmd_pxe=run boot_net_usb_start; dhcp; if pxe get; then pxe boot; fi
bootcmd_usb0=setenv devnum 0; run usb_boot
bootdelay=1
cpu=armv8
cpuid#=5447395639342e30300000000016030a
devnum=0
devtype=mmc
distro_bootcmd=for target in ${boot_targets}; do run bootcmd_${target}; done
ethaddr=1a:31:9c:ed:46:4c
fdt_addr_r=0x08300000
kernel_addr_r=0x00280000
mmc_boot=if mmc dev ${devnum}; then setenv devtype mmc; run scan_dev_for_boot_part; fi
partitions=uuid_disk=${uuid_gpt_disk};name=loader1,start=32K,size=4000K,uuid=${uuid_gpt_loader1};name=loader2,start=8MB,size=4MB,uuid=${uuid_gpt_loader2};name=trust,size=4M,uuid=${uuid_gpt_atf};name=boot,size=112M,bootable,uuid=${uuid_gpt_boot};name=rootfs,size=-,uuid=B921B045-1DF0-41C3-AF44-4C6F280D3FAE;
pxefile_addr_r=0x00600000
ramdisk_addr_r=0x0a200000
rkimg_bootdev=if mmc dev 1 && rkimgtest mmc 1; then setenv devtype mmc; setenv devnum 1; echo Boot from SDcard;elif mmc dev 0; then setenv devtype mmc; setenv devnum 0;elif mtd_blk dev 0; then setenv devtype mtd; setenv devnum 0;elif mtd_blk dev 1; then setenv devtype mtd; setenv devnum 1;elif mtd_blk dev 2; then setenv devtype mtd; setenv devnum 2;elif rknand dev 0; then setenv devtype rknand; setenv devnum 0;elif rksfc dev 0; then setenv devtype spinand; setenv devnum 0;elif rksfc dev 1; then setenv devtype spinor; setenv devnum 1;fi;
scan_dev_for_boot=echo Scanning ${devtype} ${devnum}:${distro_bootpart}...; for prefix in ${boot_prefixes}; do run scan_dev_for_extlinux; run scan_dev_for_scripts; done;
scan_dev_for_boot_part=part list ${devtype} ${devnum} -bootable devplist; env exists devplist || setenv devplist 1; for distro_bootpart in ${devplist}; do if fstype ${devtype} ${devnum}:${distro_bootpart} bootfstype; then run scan_dev_for_boot; fi; done
scan_dev_for_extlinux=if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}extlinux/extlinux.conf; then echo Found ${prefix}extlinux/extlinux.conf; run boot_extlinux; echo SCRIPT FAILED: continuing...; fi
scan_dev_for_scripts=for script in ${boot_scripts}; do if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${script}; then echo Found U-Boot script ${prefix}${script}; run boot_a_script; echo SCRIPT FAILED: continuing...; fi; done
scriptaddr=0x00500000
serial#=ad481058a1dab68d
soc=rockchip
stderr=serial,vidconsole
stdout=serial,vidconsole
usb_boot=usb start; if usb dev ${devnum}; then setenv devtype usb; run scan_dev_for_boot_part; fi
vendor=rockchip

Environment size: 3320/32764 bytes

文件传输软件FZ

依赖于SSH服务

sudo apt-get install openssh-server

如果连接不上,安装FTP服务:

sudo apt-get install vsftpd
sudo vi /etc/vsftpd.conf
sudo /etc/init.d/vsftpd restart

savenv无法使用的问题解决

注意路径:

u-boot的配置界面:

箭头键在菜单中导航<输入>选择子菜单--->(或空子菜单----)。突出显示的字母│

│ 是热键。按<Y>包括、<N>排除、<M>模块化特征。按<Esc><Esc>退出,<?>│

│ 有关帮助,</>有关搜索。图例:[*]内置[]排除<M>模块<>模块功能

选择环境参数配置选项:

Select the location of the environment (Environment in a block device)  --->
以上选项的help内容如下:

Kconfig--主要就是我们当前看到的菜单中的显示的内容

.config--是用户配置完boot之后,执行./mk.sh -u之后,根据大家的配置,生成的一个配置文件

配置完成之后,按键盘的esc键退出

重新编译我们的u-boot,将镜像文件下载到驱动板中:

./mk.sh -u

./mk.sh -U

将镜像文件重新下载到开发板中即可

每一天都需要去看内核中的源码,一定记住不同文件的路径

U-BOOT中的命令框架:

U_BOOT_CMD 宏

U-Boot 的每一个命令都是通过 U_BOOT_CMD 宏定义来实现的,这个宏在include/command.h 头文件中定义。每一个命令定义了一个 cmd_tbl_t 结构体,结构体包含的成员变量有:命令名称、最大参数个数、是否重复、命令执行函数、用法、帮助。

路径位置:

u-boot\include\command.h

ll_entry_decalre()链表

为了便于管理命令数据结构,命令结构体被统一链接到一个数据段中:

find_cmd()函数

路径位置:

u-boot\common\command.c

从控制台输入的命令都被送到 common/command.c 中的 find_cmd()函数解释执行,根据匹配输入的命令,从列表中找出对应的命令结构体,并调用其回调处理函数完成命令处理。 命令响应的过程,就是命令的查找与回调函数处理的过程, 如下图:

U-Boot 控制命令实现

cmd/Kconfig 菜单配置

在 cmd/Kconfig 文件中,增加 CMD_BUZ_TEST 菜单配置; 该菜单配置使得相应命令能在 make menuconfig 中被选中。

u-boot/cmd/Kconfig

当前路径下的Makefile文件修改:

编译的过程大家参考“boot的移植”

进入菜单查看配置:

按Y选中即可:

如果有相同的菜单操作同一个外设,一定要记得取消一个

Enable 'buztest' command 记得取消

单独编译u-boot同时也可以使用以下指令编译我们的u-boot

需要首先设置交叉编译器
make -j4 CROSS_COMPILE=aarch64-linux-gnu-
make--makefile执行命令
-j4--可以使用多线程编译
CROSS_COMPILE=aarch64-linux-gnu- 设置交叉编译器

-j4 -j后面跟的数值大小和虚拟机配置有关系:

设置环境变量:

设置好以上环境变量之后,再次执行:

make -j4 CROSS_COMPILE=aarch64-linux-gnu-

编译完成之后,返回u-boot的上一级目录,执行

./mk.sh -u

  • 12
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值