uboot分析之bootm_start
bootm命令执行过程中调用了bootm_start函数,这个函数比较重要,所以先分析它。
1.common/cmd_bootm.c
- static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
- {
- void *os_hdr;
- int ret;
- memset ((void *)&images, 0, sizeof (images));
- images.verify = getenv_yesno ("verify");
- bootm_start_lmb();
- 寻找可用的内核镜像,见下面的分析。主要根据传入的参数检查镜像的合法性并获取信息。
- os_hdr = boot_get_kernel (cmdtp, flag, argc, argv,
- &images, &images.os.image_start, &images.os.image_len);
- if (images.os.image_len == 0) {
- puts ("ERROR: can't get kernel image!/n");
- return 1;
- }
-
- switch (genimg_get_format (os_hdr)) {
- case IMAGE_FORMAT_LEGACY:
- images.os.type = image_get_type (os_hdr);
- images.os.comp = image_get_comp (os_hdr);
- images.os.os = image_get_os (os_hdr);
- images.os.end = image_get_image_end (os_hdr);
- images.os.load = image_get_load (os_hdr);
- break;
- default:
- puts ("ERROR: unknown image format type!/n");
- return 1;
- }
-
- if (images.legacy_hdr_valid) {
- images.ep = image_get_ep (&images.legacy_hdr_os_copy);
- } else {
- puts ("Could not find kernel entry point!/n");
- return 1;
- }
- if (((images.os.type == IH_TYPE_KERNEL) ||
- (images.os.type == IH_TYPE_MULTI)) &&
- (images.os.os == IH_OS_LINUX)) {
- 3250的配置中这个函数不做任何工作
- ret = boot_get_ramdisk (argc, argv, &images, IH_INITRD_ARCH,
- &images.rd_start, &images.rd_end);
- if (ret) {
- puts ("Ramdisk image is corrupt or invalid/n");
- return 1;
- }
- }
- images.os.start = (ulong)os_hdr;
- images.state = BOOTM_STATE_START;
- return 0;
- }
|
总结一下这个函数的主要工作:第一步校验镜像的正确性,获取镜像的信息(根据镜像头),第二部将第一步获取的信息存入images(主要是填充image_info_t类型的os成员)
2. bootm_headers_t
- typedef struct bootm_headers {
-
-
-
-
-
- image_header_t *legacy_hdr_os;
- image_header_t legacy_hdr_os_copy;
- ulong legacy_hdr_valid;
- #ifndef USE_HOSTCC
- 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;
- #endif
- int verify;
- #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;
- } bootm_headers_t;
-
-
-
- 内核镜像头 include/image.h
- typedef struct image_header {
- uint32_t ih_magic; 镜像头部幻数,为#define IH_MAGIC 0x27051956
- uint32_t ih_hcrc; 镜像头部crc校验码
- uint32_t ih_time; 镜像创建时间戳
- uint32_t ih_size; 镜像数据大小(不算头部)1828536
- uint32_t ih_load; 数据将要载入的内存地址 80008000
- uint32_t ih_ep; 镜像入口地址 80008000
- uint32_t ih_dcrc; 镜像数据校验码
- uint8_t ih_os; 操作系统类型 #define IH_OS_LINUX 5
- uint8_t ih_arch; CPU架构类型 #define IH_ARCH_ARM 2
- uint8_t ih_type; 镜像类型 IH_TYPE_KERNEL
- uint8_t ih_comp; 压缩类型 IH_COMP_NONE
- uint8_t ih_name[IH_NMLEN]; 镜像名字Linux-2.6.27.8,#define IH_NMLEN 32
- } image_header_t;
- 镜像信息 include/image.h
- typedef struct image_info {
- ulong start, end; 镜像的起始地址和尾地址
- ulong image_start, image_len; 镜像数据的开始地址和长度
- ulong load; 镜像数据的装载地址
- uint8_t comp, type, os; 压缩类型,镜像类型和操作系统类型
- } image_info_t;
|
3。boot_get_kernel
-
-
-
-
-
-
-
-
-
-
-
-
- 寻找可用的内核镜像
- static void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
- bootm_headers_t *images, ulong *os_data, ulong *os_len)
- {
- image_header_t *hdr;
- ulong img_addr;
-
- if (argc < 2) {
- img_addr = load_addr;
- debug ("* kernel: default image load address = 0x%08lx/n",
- load_addr);
- } else {
- img_addr = simple_strtoul(argv[1], NULL, 16);
- debug ("* kernel: cmdline image address = 0x%08lx/n", img_addr);
- }
- show_boot_progress (1);
-
- img_addr = genimg_get_image (img_addr);
-
- *os_data = *os_len = 0;
- switch (genimg_get_format ((void *)img_addr)) {
- case IMAGE_FORMAT_LEGACY:
- printf ("## Booting kernel from Legacy Image at %08lx .../n",
- img_addr);
- hdr = image_get_kernel (img_addr, images->verify);
- if (!hdr)
- return NULL;
- show_boot_progress (5);
-
- switch (image_get_type (hdr)) {
- case IH_TYPE_KERNEL:
- *os_data = image_get_data (hdr);
- *os_len = image_get_data_size (hdr);
- break;
- case IH_TYPE_MULTI:
- image_multi_getimg (hdr, 0, os_data, os_len);
- break;
- case IH_TYPE_STANDALONE:
- *os_data = image_get_data (hdr);
- *os_len = image_get_data_size (hdr);
- break;
- default:
- printf ("Wrong Image Type for %s command/n", cmdtp->name);
- show_boot_progress (-5);
- return NULL;
- }
-
-
-
- 拷贝一份镜像的头部到images中。
- memmove (&images->legacy_hdr_os_copy, hdr, sizeof(image_header_t));
-
- images->legacy_hdr_os = hdr;
- images->legacy_hdr_valid = 1;
- show_boot_progress (6);
- break;
- default:
- printf ("Wrong Image Format for %s command/n", cmdtp->name);
- show_boot_progress (-108);
- return NULL;
- }
- debug (" kernel data at 0x%08lx, len = 0x%08lx (%ld)/n",
- *os_data, *os_len, *os_len);
- return (void *)img_addr;
- }
|
4。image_get_kernel
- common/cmd_bootm.c
- static image_header_t *image_get_kernel (ulong img_addr, int verify)
- {
- image_header_t *hdr = (image_header_t *)img_addr;
- if (!image_check_magic(hdr)) {
- puts ("Bad Magic Number/n");
- show_boot_progress (-1);
- return NULL;
- }
- show_boot_progress (2);
- if (!image_check_hcrc (hdr)) {
- puts ("Bad Header Checksum/n");
- show_boot_progress (-2);
- return NULL;
- }
- show_boot_progress (3);
- image_print_contents (hdr);
-
-
-
-
-
-
-
- if (verify) {
- puts (" Verifying Checksum ... ");
- if (!image_check_dcrc (hdr)) {
- printf ("Bad Data CRC/n");
- show_boot_progress (-3);
- return NULL;
- }
- puts ("OK/n");
- }
- show_boot_progress (4);
- if (!image_check_target_arch (hdr)) {
- printf ("Unsupported Architecture 0x%x/n", image_get_arch (hdr));
- show_boot_progress (-4);
- return NULL;
- }
- return hdr;
- }
|
评论暂时关闭