bootm 用于将内核镜像加载到内存的指定地址处,如果有需要还要解压镜像,然后根据操作系统和体系结构的不同给内核传递不同的启动参数,最后启动内核。
一、arm 架构处理器对 linux 内核启动之前环境的五点需求
1、cpu 寄存器设置
* R0 = 0
* R1 = 板级 id
* R2 = 启动参数在内存中的起始地址
2、cpu 模式
* 禁止所有中断
* 必须为SVC(超级用户)模式
3、缓存、MMU
* 关闭 MMU
* 指令缓存可以开启或者关闭
* 数据缓存必须关闭并且不能包含任何脏数据
4、设备
* DMA 设备应当停止工作
5、boot loader 需要跳转到内核镜像的第一条指令处
这些需求都由 boot loader 实现,在常用的 uboot 中完成一系列的初始化后最后通过 bootm 命令加载 linux 内核。该命令用法介绍如下:
# help bootm
bootm - boot application image from memory
Usage:
bootm [addr [arg ...]]
- boot application image stored in memory
passing arguments 'arg ...'; when booting a Linux kernel,
'arg' can be the address of an initrd image
Sub-commands to do part of the bootm sequence. The sub-commands must be
issued in the order below (it's ok to not issue all sub-commands):
start [addr [arg ...]]
loados - load OS image
cmdline - OS specific command line processing/setup
bdt - OS specific bd_t processing
prep - OS specific prep before relocation or go
go - start OS
二、基础数据结构
在 bootm 中常用的数据结构有 image_info_t 和 bootm_headers_t,定义如下:
/* 镜像信息 */
typedef struct image_info {
ulong start, end; /* start/end of blob */
ulong image_start, image_len; /* start of image within blob, len of image */
ulong load; /* load addr for the image */
uint8_t comp, type, os; /* compression, type of image, os type */
} image_info_t;
/* bootm 头 */
typedef struct bootm_headers {
image_header_t *legacy_hdr_os; /* 指向镜像头的指针 */
image_header_t legacy_hdr_os_copy; /* 镜像头的备份 */
ulong legacy_hdr_valid; /* 镜像头存在标记 */
image_info_t os; /* 系统镜像信息 */
ulong ep; /* 系统入口地址 */
ulong rd_start, rd_end; /* 虚拟磁盘起始地址 */
ulong ft_len; /* 平坦设备树的长度 */
ulong initrd_start;
ulong initrd_end;
ulong cmdline_start;
ulong cmdline_end;
bd_t *kbd;
int verify; /* getenv("verify")[0] != 'n' */
#define BOOTM_STATE_START (0x00000001)
#define BOOTM_STATE_LOADOS (0x00000002)
#define BOOTM_STATE_RAMDISK (0x00000004)
#define BOOTM_STATE_FDT (0x00000008)
#define BOOTM_STATE_OS_CMDLINE (0x00000010)
#define BOOTM_STATE_OS_BD_T (0x00000020)
#define BOOTM_STATE_OS_PREP (0x00000040)
#define BOOTM_STATE_OS_GO (0x00000080)
int state; /* 状态标记 */
struct lmb lmb; /* 逻辑内存块 */
} bootm_headers_t;