U-boot 启动内核过程

本文详细介绍了U-Boot中bootm命令的实现原理及其在引导Linux内核过程中的作用。通过对U-Boot命令宏定义的解析,展示了如何自定义U-Boot命令。此外,还深入分析了do_bootm函数的工作流程。

 

U-Boot 的命令为用户提供了交互功能,并且已经实现了几十个常用的命令。如果开发板需要很特殊的操作,可以添加新的 U-Boot 命令。 U-Boot 的每一个命令都是通过 U_Boot_CMD 宏定义的。这个宏在 <include/command.h> 头文件中定义

#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \

cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage}

其中:

  • name:命令的名字,他不是一个字符串,不能用双引号括起来
  • maxargs:最大的参数个数
  • command:对应的函数指针
  • usage:一个字符串,简短的使用说明
  • help:一个字符串,比较详细的使用说明

对于bootm命令,其定义如下:

  1. U_BOOT_CMD(//bootm命令  
  2.     bootm,  CFG_MAXARGS,    1,  do_bootm,  
  3.     "bootm   - boot application image from memory\n",  
  4.     "[addr [arg ...]]\n    - boot application image stored in memory\n"  
  5.     "\tpassing arguments 'arg ...'; when booting a Linux kernel,\n"  
  6.     "\t'arg' can be the address of an initrd image\n"  
  7. #ifdef CONFIG_OF_FLAT_TREE  
  8.     "\tWhen booting a Linux kernel which requires a flat device-tree\n"  
  9.     "\ta third argument is required which is the address of the of the\n"  
  10.     "\tdevice-tree blob. To boot that kernel without an initrd image,\n"  
  11.     "\tuse a '-' for the second argument. If you do not pass a third\n"  
  12.     "\ta bd_info struct will be passed instead\n"  
  13. #endif  
  14. );  
U_BOOT_CMD(//bootm命令
 	bootm,	CFG_MAXARGS,	1,	do_bootm,
 	"bootm   - boot application image from memory\n",
 	"[addr [arg ...]]\n    - boot application image stored in memory\n"
 	"\tpassing arguments 'arg ...'; when booting a Linux kernel,\n"
 	"\t'arg' can be the address of an initrd image\n"
#ifdef CONFIG_OF_FLAT_TREE
	"\tWhen booting a Linux kernel which requires a flat device-tree\n"
	"\ta third argument is required which is the address of the of the\n"
	"\tdevice-tree blob. To boot that kernel without an initrd image,\n"
	"\tuse a '-' for the second argument. If you do not pass a third\n"
	"\ta bd_info struct will be passed instead\n"
#endif
);

bootm命令是用来引导经过U-Boot的工具mkimage打包后的kernel image的。U-Boot源代码的tools/目录下有mkimage工具,这个工具可以用来制作不压缩或者压缩的多种可启动映象文件。 mkimage在制作映象文件的时候,是在原来的可执行映象文件的前面加上一个0x40字节的头,记录参数所指定的信息,这样uboot才能识别这个映象是针对哪个CPU体系结构的,哪个OS的,哪种类型,加载内存中的哪个位置, 入口点在内存的那个位置以及映象名是什么。

U-Boot正是通过bootm命令引导Linux内核的。bootm命令调用do_bootm函数,下面我们来分析一下:


do_bootm函数流程分析


do_bootm_linux函数


### U-Boot 启动内核的命令及相关使用方法 U-Boot 是一个功能强大的引导加载程序,用于初始化硬件并启动操作系统内核。在 U-Boot 中,启动内核过程由特定的命令控制,这些命令通过 `U_BOOT_CMD` 宏定义,并且每个命令都有其特定的功能和用法。 #### 命令定义 U-Boot 的命令是通过 `U_BOOT_CMD` 宏来定义的,格式如下: ```c U_BOOT_CMD(name, maxargs, repeatable, command, "usage", "help") ``` 其中: - `name` 是命令的名称。 - `maxargs` 是命令支持的最大参数数量。 - `repeatable` 表示该命令是否可以重复执行。 - `command` 是指向实现该命令功能的函数指针。 - `"usage"` 是命令的简要用法说明。 - `"help"` 是更详细的帮助信息[^2]。 #### 启动内核的命令 U-Boot 中用于启动内核的主要命令是 `boot` 和 `bootm`。 1. **`boot` 命令** - 该命令是一个通用的启动命令,会根据配置自动选择合适的启动方式。 - 使用方法:直接输入 `boot` 即可触发默认的启动流程。 - 默认情况下,`boot` 命令会调用 `bootm` 命令来启动内核。 2. **`bootm` 命令** - `bootm` 是 U-Boot 中专门用于启动内核的命令。 - 使用方法: ```bash bootm <kernel_addr> [<initrd_addr> <fdt_addr>] ``` - `<kernel_addr>` 是内核镜像在内存中的地址。 - `<initrd_addr>` 是初始化 RAM 磁盘(initrd)的地址(可选)。 - `<fdt_addr>` 是设备树(Device Tree Blob, DTB)的地址(可选)[^1]。 3. **`go` 命令** - 该命令用于跳转到指定地址并开始执行代码。 - 使用方法: ```bash go <address> ``` - `<address>` 是要跳转的内存地址。 #### 示例代码 以下是一个典型的 U-Boot 启动内核的流程: ```bash # 加载内核到内存地址 0x80000000 tftp 0x80000000 uImage # 如果需要加载 initrd 和 dtb tftp 0x81000000 uInitrd tftp 0x82000000 uDtb # 启动内核 bootm 0x80000000 0x81000000 0x82000000 ``` #### 配置选项 在某些情况下,可能需要通过配置文件启用特定的启动介质支持。例如,启用从 SPI 闪存启动的支持可以通过以下配置实现: ```makefile # Boot media CONFIG_SPI_BOOT=y CONFIG_BOOTDELAY=3 ``` 上述配置表示启用了从 SPI 闪存启动的支持,并设置了 3 秒的启动延迟[^3]。 #### 注意事项 - 在使用 `bootm` 命令时,确保内核、initrd 和 DTB 的地址正确无误。 - 如果系统中没有 DTB 或 initrd,则可以省略对应的参数。 - 不同平台的 U-Boot 可能有不同的命令或扩展功能,具体请参考相关文档。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值