u-boot2013.01 smdk2410 启动第二阶段分析之引导内核

时间:2022-05-14 16:32:40

. 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")  |   

|            字符串                   |   setup_commandline_tag
|                                          |
|-------------------------- -----|
      tag   (0x54410009)    |
|---------------------------------|
|      size                               |
|-----------------------------------|-----------------
|       root_dev       (0)          |     
|----------------------------------|        
|        page_size     (0)          |        
|------------------------------------|        setup_start_tag
|        flag                 (0)         |         
|-----------------------------------|
|            tag (0x54410001)   | 
|-----------------------------------|                  
|         size      (5)                   |                    
|------------------------------------|0x30000100---------