. 1.读取内核 nand read.jffs
do_nand
...
nand_read
. 启动内核boot
2. bootm 整体流程
do_bootm==========================================================================================
bootm_start(cmdtp, flag, argc, argv)
os_hdr = boot_get_kernel(cmdtp, flag, argc, argv, &images, &images.os.image_start, &images.os.image_len);//kernel
ret = boot_get_ramdisk(argc, argv, &images, IH_INITRD_ARCH,&images.rd_start, &images.rd_end); //ramdisk
ret = boot_get_fdt(flag, argc, argv, &images, &images.ft_addr, &images.ft_len); //设备树
bootm_load_os
boot_fn = boot_os[images.os.os];
do_bootm_linux
boot_prep_linux(images);
setup_start_tag(gd->bd);//传递参数
setup_commandline_tag(gd->bd, commandline);
setup_memory_tags(gd->bd);
setup_board_tags(¶ms);
setup_end_tag(gd->bd);
boot_jump_linux(images);
unsigned long machid = gd->bd->bi_arch_number;
void (*kernel_entry)(int zero, int arch, uint params);
kernel_entry = (void (*)(int, int, uint))images->ep;
r2 = gd->bd->bi_boot_params;
kernel_entry(0, machid, r2);
具体分析:
1.int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) bootm 30007fc0
if (argc > 1)
simple_strtoul(argv[1], &endp, 16);
//==>argv[1] = 0x30007fc0
bootm_start(cmdtp, flag, argc, argv)
memset((void *)&images, 0, sizeof(images));
//image 是一个全局变量
bootm_headers_t images; /* pointers to os/initrd/fdt images */
typedef struct bootm_headers {
image_header_t *legacy_hdr_os; /* image header pointer */
image_header_t legacy_hdr_os_copy; /* header copy */
ulong legacy_hdr_valid;
image_info_t os; /* os image info */
ulong ep; /* entry point of OS */
ulong rd_start, rd_end;/* ramdisk start/end */
ulong ft_len; /* length of flat device tree */
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)
image_header_t:
typedef struct image_header {
__be32 ih_magic; /* Image Header Magic Number */
__be32 ih_hcrc; /* Image Header CRC Checksum */
__be32 ih_time; /* Image Creation Timestamp */
__be32 ih_size; /* Image Data Size */
__be32 ih_load; /* Data Load Address */ //加载地址
__be32 ih_ep; /* Entry Point Address */ //入口地址
__be32 ih_dcrc; /* Image Data CRC Checksum */
uint8_t ih_os; /* Operating System */
uint8_t ih_arch; /* CPU architecture */
uint8_t ih_type; /* Image Type */
uint8_t ih_comp; /* Compression Type */
uint8_t ih_name[IH_NMLEN]; /* Image Name */
} image_header_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;
/* get kernel image header, start address and length */
os_hdr = boot_get_kernel(cmdtp, flag, argc, argv,&images, &images.os.image_start, &images.os.image_len);
boot_get_kernel // pointer to image header if valid image was found, plus kernel start address and length, otherwise NULL
image_header_t *hdr;
ulong img_addr;
img_addr = simple_strtoul(argv[1], NULL, 16);
//img_addr = 0x30007fc0
/* find kernel entry point */
if (images.legacy_hdr_valid) {
images.ep = image_get_ep(&images.legacy_hdr_os_copy);
//得到内核的入口地址。即真正的内核的地址
/* find ramdisk */
ret = boot_get_ramdisk(argc, argv, &images, IH_INITRD_ARCH,
&images.rd_start, &images.rd_end);
//如果bootm 的第二个参数为 - 表示滤过 ramdisk
#if defined(CONFIG_OF_LIBFDT)
/* find flattened device tree */
ret = boot_get_fdt(flag, argc, argv, &images,
&images.ft_addr, &images.ft_len);
//如果需要linux 使用设备树。则 CONFIG_OF_LIBFDT 需要在相应的配置文件进行配置 如smdk2440.h
if (argc > 1)
simple_strtoul(argv[1], &endp, 16);
//==>argv[1] = 0x30007fc0
bootm_start(cmdtp, flag, argc, argv)
memset((void *)&images, 0, sizeof(images));
//image 是一个全局变量
bootm_headers_t images; /* pointers to os/initrd/fdt images */
typedef struct bootm_headers {
image_header_t *legacy_hdr_os; /* image header pointer */
image_header_t legacy_hdr_os_copy; /* header copy */
ulong legacy_hdr_valid;
image_info_t os; /* os image info */
ulong ep; /* entry point of OS */
ulong rd_start, rd_end;/* ramdisk start/end */
ulong ft_len; /* length of flat device tree */
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)
image_header_t:
typedef struct image_header {
__be32 ih_magic; /* Image Header Magic Number */
__be32 ih_hcrc; /* Image Header CRC Checksum */
__be32 ih_time; /* Image Creation Timestamp */
__be32 ih_size; /* Image Data Size */
__be32 ih_load; /* Data Load Address */ //加载地址
__be32 ih_ep; /* Entry Point Address */ //入口地址
__be32 ih_dcrc; /* Image Data CRC Checksum */
uint8_t ih_os; /* Operating System */
uint8_t ih_arch; /* CPU architecture */
uint8_t ih_type; /* Image Type */
uint8_t ih_comp; /* Compression Type */
uint8_t ih_name[IH_NMLEN]; /* Image Name */
} image_header_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;
/* get kernel image header, start address and length */
os_hdr = boot_get_kernel(cmdtp, flag, argc, argv,&images, &images.os.image_start, &images.os.image_len);
boot_get_kernel // pointer to image header if valid image was found, plus kernel start address and length, otherwise NULL
image_header_t *hdr;
ulong img_addr;
img_addr = simple_strtoul(argv[1], NULL, 16);
//img_addr = 0x30007fc0
/* find kernel entry point */
if (images.legacy_hdr_valid) {
images.ep = image_get_ep(&images.legacy_hdr_os_copy);
//得到内核的入口地址。即真正的内核的地址
/* find ramdisk */
ret = boot_get_ramdisk(argc, argv, &images, IH_INITRD_ARCH,
&images.rd_start, &images.rd_end);
//如果bootm 的第二个参数为 - 表示滤过 ramdisk
#if defined(CONFIG_OF_LIBFDT)
/* find flattened device tree */
ret = boot_get_fdt(flag, argc, argv, &images,
&images.ft_addr, &images.ft_len);
标签tag
struct tag_header {
u32 size;
u32 tag;
};
struct tag {
struct tag_header hdr;
union {
struct tag_core core;
struct tag_mem32 mem;
struct tag_videotext videotext;
struct tag_ramdisk ramdisk;
struct tag_initrd initrd;
struct tag_serialnr serialnr;
struct tag_revision revision;
struct tag_videolfb videolfb;
struct tag_cmdline cmdline;
/*
* Acorn specific
*/
struct tag_acorn acorn;
/*
* DC21285 specific
*/
struct tag_memclk memclk;
} u;
};
tag图:
|--------------------------------| -----------------
| tag (0) |
| size (0) | setup_end_tag
|--------------------------------| -----------------
| start (0x30000000) |
|--------------------------------|
| size (0x4000000) |
|--------------------------------| setup_memory_tags
| tag (0x54410002) |
|-------------------------------- |
| size (4) |
|---------------------------------|-----------------
| |
| getenv("bootatgs") |
| |
|-------------------------- -----|
tag (0x54410009) |
|---------------------------------|
| size |
|-----------------------------------|-----------------
| root_dev (0) |
|----------------------------------|
| page_size (0) |
|------------------------------------| setup_start_tag
| flag (0) |
|-----------------------------------|
| tag (0x54410001) |
|-----------------------------------|
| size (5) |
|------------------------------------|0x30000100---------