image.c
来自「uboot详细解读可用启动引导LINUX2.6内核」· C语言 代码 · 共 2,365 行 · 第 1/5 页
C
2,365 行
static void genimg_print_size (uint32_t size){#ifndef USE_HOSTCC printf ("%d Bytes = ", size); print_size (size, "\n");#else printf ("%d Bytes = %.2f kB = %.2f MB\n", size, (double)size / 1.024e3, (double)size / 1.048576e6);#endif}#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)static void genimg_print_time (time_t timestamp){#ifndef USE_HOSTCC struct rtc_time tm; to_tm (timestamp, &tm); printf ("%4d-%02d-%02d %2d:%02d:%02d UTC\n", tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);#else printf ("%s", ctime(×tamp));#endif}#endif /* CONFIG_TIMESTAMP || CONFIG_CMD_DATE || USE_HOSTCC *//** * get_table_entry_name - translate entry id to long name * @table: pointer to a translation table for entries of a specific type * @msg: message to be returned when translation fails * @id: entry id to be translated * * get_table_entry_name() will go over translation table trying to find * entry that matches given id. If matching entry is found, its long * name is returned to the caller. * * returns: * long entry name if translation succeeds * msg otherwise */static char *get_table_entry_name (table_entry_t *table, char *msg, int id){ for (; table->id >= 0; ++table) { if (table->id == id) return (table->lname); } return (msg);}const char *genimg_get_os_name (uint8_t os){ return (get_table_entry_name (uimage_os, "Unknown OS", os));}const char *genimg_get_arch_name (uint8_t arch){ return (get_table_entry_name (uimage_arch, "Unknown Architecture", arch));}const char *genimg_get_type_name (uint8_t type){ return (get_table_entry_name (uimage_type, "Unknown Image", type));}const char *genimg_get_comp_name (uint8_t comp){ return (get_table_entry_name (uimage_comp, "Unknown Compression", comp));}/** * get_table_entry_id - translate short entry name to id * @table: pointer to a translation table for entries of a specific type * @table_name: to be used in case of error * @name: entry short name to be translated * * get_table_entry_id() will go over translation table trying to find * entry that matches given short name. If matching entry is found, * its id returned to the caller. * * returns: * entry id if translation succeeds * -1 otherwise */static int get_table_entry_id (table_entry_t *table, const char *table_name, const char *name){ table_entry_t *t;#ifdef USE_HOSTCC int first = 1; for (t = table; t->id >= 0; ++t) { if (t->sname && strcasecmp(t->sname, name) == 0) return (t->id); } fprintf (stderr, "\nInvalid %s Type - valid names are", table_name); for (t = table; t->id >= 0; ++t) { if (t->sname == NULL) continue; fprintf (stderr, "%c %s", (first) ? ':' : ',', t->sname); first = 0; } fprintf (stderr, "\n");#else for (t = table; t->id >= 0; ++t) { if (t->sname && strcmp(t->sname, name) == 0) return (t->id); } debug ("Invalid %s Type: %s\n", table_name, name);#endif /* USE_HOSTCC */ return (-1);}int genimg_get_os_id (const char *name){ return (get_table_entry_id (uimage_os, "OS", name));}int genimg_get_arch_id (const char *name){ return (get_table_entry_id (uimage_arch, "CPU", name));}int genimg_get_type_id (const char *name){ return (get_table_entry_id (uimage_type, "Image", name));}int genimg_get_comp_id (const char *name){ return (get_table_entry_id (uimage_comp, "Compression", name));}#ifndef USE_HOSTCC/** * genimg_get_format - get image format type * @img_addr: image start address * * genimg_get_format() checks whether provided address points to a valid * legacy or FIT image. * * New uImage format and FDT blob are based on a libfdt. FDT blob * may be passed directly or embedded in a FIT image. In both situations * genimg_get_format() must be able to dectect libfdt header. * * returns: * image format type or IMAGE_FORMAT_INVALID if no image is present */int genimg_get_format (void *img_addr){ ulong format = IMAGE_FORMAT_INVALID; image_header_t *hdr;#if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT) char *fit_hdr;#endif hdr = (image_header_t *)img_addr; if (image_check_magic(hdr)) format = IMAGE_FORMAT_LEGACY;#if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT) else { fit_hdr = (char *)img_addr; if (fdt_check_header (fit_hdr) == 0) format = IMAGE_FORMAT_FIT; }#endif return format;}/** * genimg_get_image - get image from special storage (if necessary) * @img_addr: image start address * * genimg_get_image() checks if provided image start adddress is located * in a dataflash storage. If so, image is moved to a system RAM memory. * * returns: * image start address after possible relocation from special storage */ulong genimg_get_image (ulong img_addr){ ulong ram_addr = img_addr;#ifdef CONFIG_HAS_DATAFLASH ulong h_size, d_size; if (addr_dataflash (img_addr)){ /* ger RAM address */ ram_addr = CFG_LOAD_ADDR; /* get header size */ h_size = image_get_header_size ();#if defined(CONFIG_FIT) if (sizeof(struct fdt_header) > h_size) h_size = sizeof(struct fdt_header);#endif /* read in header */ debug (" Reading image header from dataflash address " "%08lx to RAM address %08lx\n", img_addr, ram_addr); read_dataflash (img_addr, h_size, (char *)ram_addr); /* get data size */ switch (genimg_get_format ((void *)ram_addr)) { case IMAGE_FORMAT_LEGACY: d_size = image_get_data_size ((image_header_t *)ram_addr); debug (" Legacy format image found at 0x%08lx, size 0x%08lx\n", ram_addr, d_size); break;#if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: d_size = fit_get_size ((const void *)ram_addr) - h_size; debug (" FIT/FDT format image found at 0x%08lx, size 0x%08lx\n", ram_addr, d_size); break;#endif default: printf (" No valid image found at 0x%08lx\n", img_addr); return ram_addr; } /* read in image data */ debug (" Reading image remaining data from dataflash address " "%08lx to RAM address %08lx\n", img_addr + h_size, ram_addr + h_size); read_dataflash (img_addr + h_size, d_size, (char *)(ram_addr + h_size)); }#endif /* CONFIG_HAS_DATAFLASH */ return ram_addr;}/** * fit_has_config - check if there is a valid FIT configuration * @images: pointer to the bootm command headers structure * * fit_has_config() checks if there is a FIT configuration in use * (if FTI support is present). * * returns: * 0, no FIT support or no configuration found * 1, configuration found */int genimg_has_config (bootm_headers_t *images){#if defined(CONFIG_FIT) if (images->fit_uname_cfg) return 1;#endif return 0;}/** * boot_get_ramdisk - main ramdisk handling routine * @argc: command argument count * @argv: command argument list * @images: pointer to the bootm images structure * @arch: expected ramdisk architecture * @rd_start: pointer to a ulong variable, will hold ramdisk start address * @rd_end: pointer to a ulong variable, will hold ramdisk end * * boot_get_ramdisk() is responsible for finding a valid ramdisk image. * Curently supported are the following ramdisk sources: * - multicomponent kernel/ramdisk image, * - commandline provided address of decicated ramdisk image. * * returns: * 0, if ramdisk image was found and valid, or skiped * rd_start and rd_end are set to ramdisk start/end addresses if * ramdisk image is found and valid * * 1, if ramdisk image is found but corrupted * rd_start and rd_end are set to 0 if no ramdisk exists */int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images, uint8_t arch, ulong *rd_start, ulong *rd_end){ ulong rd_addr, rd_load; ulong rd_data, rd_len; image_header_t *rd_hdr;#if defined(CONFIG_FIT) void *fit_hdr; const char *fit_uname_config = NULL; const char *fit_uname_ramdisk = NULL; ulong default_addr; int rd_noffset; int cfg_noffset; const void *data; size_t size;#endif *rd_start = 0; *rd_end = 0; /* * Look for a '-' which indicates to ignore the * ramdisk argument */ if ((argc >= 3) && (strcmp(argv[2], "-") == 0)) { debug ("## Skipping init Ramdisk\n"); rd_len = rd_data = 0; } else if (argc >= 3 || genimg_has_config (images)) {#if defined(CONFIG_FIT) if (argc >= 3) { /* * If the init ramdisk comes from the FIT image and * the FIT image address is omitted in the command * line argument, try to use os FIT image address or * default load address. */ if (images->fit_uname_os) default_addr = (ulong)images->fit_hdr_os; else default_addr = load_addr; if (fit_parse_conf (argv[2], default_addr, &rd_addr, &fit_uname_config)) { debug ("* ramdisk: config '%s' from image at 0x%08lx\n", fit_uname_config, rd_addr); } else if (fit_parse_subimage (argv[2], default_addr, &rd_addr, &fit_uname_ramdisk)) { debug ("* ramdisk: subimage '%s' from image at 0x%08lx\n", fit_uname_ramdisk, rd_addr); } else#endif { rd_addr = simple_strtoul(argv[2], NULL, 16); debug ("* ramdisk: cmdline image address = 0x%08lx\n", rd_addr); }#if defined(CONFIG_FIT) } else { /* use FIT configuration provided in first bootm * command argument */ rd_addr = (ulong)images->fit_hdr_os; fit_uname_config = images->fit_uname_cfg; debug ("* ramdisk: using config '%s' from image at 0x%08lx\n", fit_uname_config, rd_addr); /* * Check whether configuration has ramdisk defined, * if not, don't try to use it, quit silently. */ fit_hdr = (void *)rd_addr; cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config); if (cfg_noffset < 0) { debug ("* ramdisk: no such config\n"); return 1; } rd_noffset = fit_conf_get_ramdisk_node (fit_hdr, cfg_noffset); if (rd_noffset < 0) { debug ("* ramdisk: no ramdisk in config\n"); return 0; } }#endif /* copy from dataflash if needed */ rd_addr = genimg_get_image (rd_addr); /* * Check if there is an initrd image at the * address provided in the second bootm argument * check image type, for FIT images get FIT node. */ switch (genimg_get_format ((void *)rd_addr)) { case IMAGE_FORMAT_LEGACY: printf ("## Loading init Ramdisk from Legacy " "Image at %08lx ...\n", rd_addr); show_boot_progress (9); rd_hdr = image_get_ramdisk (rd_addr, arch, images->verify); if (rd_hdr == NULL) return 1; rd_data = image_get_data (rd_hdr); rd_len = image_get_data_size (rd_hdr); rd_load = image_get_load (rd_hdr); break;#if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: fit_hdr = (void *)rd_addr; printf ("## Loading init Ramdisk from FIT " "Image at %08lx ...\n", rd_addr); show_boot_progress (120); if (!fit_check_format (fit_hdr)) { puts ("Bad FIT ramdisk image format!\n"); show_boot_progress (-120); return 1; } show_boot_progress (121); if (!fit_uname_ramdisk) { /* * no ramdisk image node unit name, try to get config * node first. If config unit node name is NULL * fit_conf_get_node() will try to find default config node */ show_boot_progress (122); cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config); if (cfg_noffset < 0) { puts ("Could not find configuration node\n"); show_boot_progress (-122); return 1; } fit_uname_config = fdt_get_name (fit_hdr, cfg_noffset, NULL); printf (" Using '%s' configuration\n", fit_uname_config); rd_noffset = fit_conf_get_ramdisk_node (fit_hdr, cfg_noffset); fit_uname_ramdisk = fit_get_name (fit_hdr, rd_noffset, NULL); } else { /* get ramdisk component image node offset */ show_boot_progress (123); rd_noffset = fit_image_get_node (fit_hdr, fit_uname_ramdisk); } if (rd_noffset < 0) { puts ("Could not find subimage node\n"); show_boot_progress (-124); return 1; } printf (" Trying '%s' ramdisk subimage\n", fit_uname_ramdisk); show_boot_progress (125); if (!fit_check_ramdisk (fit_hdr, rd_noffset, arch, images->verify)) return 1; /* get ramdisk image data address and length */ if (fit_image_get_data (fit_hdr, rd_noffset, &data, &size)) { puts ("Could not find ramdisk subimage data!\n"); show_boot_progress (-127); return 1; } show_boot_progress (128); rd_data = (ulong)data; rd_len = size; if (fit_image_get_load (fit_hdr, rd_noffset, &rd_load)) { puts ("Can't get ramdisk subimage load address!\n"); show_boot_progress (-129); return 1; } show_boot_progress (129); images->fit_hdr_rd = fit_hdr; images->fit_uname_rd = fit_uname_ramdisk; images->fit_noffset_rd = rd_noffset; break;#endif default: puts ("Wrong Ramdisk Image Format\n"); rd_data = rd_len = rd_load = 0; }#if defined(CONFIG_B2) || defined(CONFIG_EVB4510) || defined(CONFIG_ARMADILLO) /* * We need to copy the ramdisk to SRAM to let Linux boot */ if (rd_data) { memmove ((void *)rd_load, (uchar *)rd_data, rd_len);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?