Skip to main content.
Navigation:
DENX
>
U-Boot
>
TaskRefactorBootmImage
Translations:
Edit
|
Attach
|
Raw
|
Ref-By
|
Printable
|
More
U-Boot
Sections of this site:
DENX Home
|
DULG
|
ELDK-5
|
Know
|
Training
|
U-Boot
|
U-Bootdoc
Topics
U-Boot Home
Documentation
Source Code
The Custodians
Custodian Repositories
Development Process
Release Cycle
Coding Style
Patches
Tasks
Contacts
Changes
Index
List of pages in U-Boot
Search
---+!! Refactor =bootm= and Image Commands %TOC% Problems: * =bootm= has gathered more and more variants of sequences for booting the target OS. * Kumar has created a =bootm <subcmd>= changeset to break the currently unbreakable sequence into steps that can be run sequentially and allows modifications (run commands) in between the =bootm= steps. * =image.c= has grown large and unwieldy. This was aggravated by adding the =FIT= image handling to it. * Can we split the =FIT= image processing out into a =fit_image.c= file? ---++ Sequence 1 ==fdt boardsetup== * Do board-specific FDT setup 1 ==fdt chosen== * Create the FDT =/chosen= node 1 interrupts off * Disable interrupts (need =CONFIG_CMD_IRQ=) 1 ==usb stop== * USB stop (only if USB is supported) 1 ==dcache off ; icache off== * Disable cache (only needed for the Amiga One 3SE 1 ==bootm start <os> <initrd> <fdtaddr>== * =bootm start $loadaddr $ramdiskaddr $fdtaddr= * Sets the addresses... 1 ==bootm ramdisk== * Copies the ramdisk to high memory, honoring the env variable =initrd_high= and leaving room for the =logbuffer= 1 ==bootm fdt== * Copies the fdt to a "good" location 1 ==bootm bdt== * Sets up the bd_t struct values (legacy) 1 ==bootm cmdline== * Sets up the (linux) command line 1 ==bootm prepos== * OS-specific preparations before relocation or go 1 ==bootm loados== * Copies (with decompressing, if necessary) the OS to its execution address 1 ==bootm go== ---++ Original Sequence 1 Initialize / fill out the =images= structure 1 =lmb= * env specified region: =getenv_bootm_low(); / getenv_bootm_size(); * board reserved region (optional): =board_lmb_reserve(&lmb);= 1 =os_hdr = boot_get_kernel (cmdtp, flag, argc, argv, &images, &os_data, &os_len);= 1 =/* get image parameters */= (different methods of filling out these variables based on =IMAGE_FORMAT_LEGACY= or =IMAGE_FORMAT_FIT=) * =type= * =comp= * =os= * =image_end= * =load_start= * =image_start= * =load_end= (set to zero, filled in after decompressing) * =type_name= 1 Disable interrupts 1 USB stop (if CONFIG_CMD_USB) 1 Disable caches (if CONFIG_AMIGAONEG3SE) 1 Decompress the image (based on compression type) * Sets =load_end= to the proper value 1 Some sanity checking (load vs. image start and end, header validity) 1 Add image load region to =lmb= 1 OS-specific start function - should not return * We need to support the ability to load the images but not actually transfer control to the OS * We need to support the ability to modify the device tree before its handled to the OS. These modification need to be controlled at runtime and not compile time. * Traditional: =bootm <osaddr> [(-|<ramdisk>) [<fdtaddr>]]= <blockquote><tt><pre> => bootm $loadaddr $ramdiskaddr $fdtaddr ## Booting kernel from Legacy Image at 00408000 ... Image Name: Linux-2.6.26-06077-gc010b2f Image Type: PowerPC Linux Kernel Image (gzip compressed) Data Size: 1391935 Bytes = 1.3 MB Load Address: 00000000 Entry Point: 00000000 Verifying Checksum ... OK ## Loading init Ramdisk from Legacy Image at 01000000 ... Image Name: Simple Embedded Linux Framework Image Type: PowerPC Linux RAMDisk Image (gzip compressed) Data Size: 1731902 Bytes = 1.7 MB Load Address: 00000000 Entry Point: 00000000 Verifying Checksum ... OK ## Flattened Device Tree blob at 00400000 Booting using the fdt blob at 0x400000 Uncompressing Kernel Image ... OK Loading Ramdisk to 0fdf7000, end 0ff9dd3e ... OK </pre></tt></blockquote> ---+++ Refactoring =cmd_bootm.c= * External functions * =extern int gunzip (void *dst, int dstlen, unsigned char *src, unsigned long *lenp);= * =extern void bz_internal_error(int);= * =extern flash_info_t flash_info[]; /* info for FLASH chips */= (used by "imls" command) * =extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);= * Helper functions * =static void fixup_silent_linux (void);= * =static image_header_t *image_get_kernel (ulong img_addr, int verify);= * =static int fit_check_kernel (const void *fit, int os_noffset, int verify);= * =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);= * Board-specific helper functions * =void board_lmb_reserve(struct lmb *lmb) __attribute__((weak, alias("__board_lmb_reserve")));= * Command functions * =int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])= * =static int image_info (unsigned long addr);= - =iminfo= command * =static int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);= - =imls= command * Function pointer * =typedef void boot_os_fn (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], bootm_headers_t *images); /* pointers to os/initrd/fdt */= * =extern boot_os_fn do_bootm_linux;= - __Q:__ Why is this one =extern=? (Probably cause its implemented in the <ARCH>/bootm.c) * =static boot_os_fn do_bootm_netbsd;= * =static boot_os_fn do_bootm_lynxkdi;= * =static boot_os_fn do_bootm_rtems;= * =static boot_os_fn do_bootm_vxworks;= * =static boot_os_fn do_bootm_qnxelf;= * =static boot_os_fn do_bootm_artos;= * ...and support functions used with the function pointers * =extern void lynxkdi_boot (image_header_t *);= * =int do_bootvx (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);= * =int do_bootelf (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);= ---+++ Refactoring =image.c= * External functions * Legacy image handling * =int image_check_hcrc (image_header_t *hdr)= (legacy support) * =int image_check_dcrc (image_header_t *hdr)= (legacy support) * =ulong image_multi_count (image_header_t *hdr)= (legacy support) * =void image_multi_getimg (image_header_t *hdr, ulong idx, ulong *data, ulong *len)= (legacy support) * =void image_print_contents (image_header_t *hdr)= (legacy support) * =int boot_get_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base)= * Externally available utility functions * =int getenv_yesno (char *var)= (utility) * =ulong getenv_bootm_low(void)= - returns the env variable =bootm_low= or, if not defined, the lowest address of RAM (utility) * =phys_size_t getenv_bootm_size(void) - returns the env variable =bootm_size= or, if not defined, the size of RAM (utility) * =void memmove_wd (void *to, void *from, size_t len, ulong chunksz)= - move memory, kicking the WDT * New image handling * =int genimg_get_format (void *img_addr)= - new image format detection and identification * =ulong genimg_get_image (ulong img_addr)= * =int genimg_has_config (bootm_headers_t *images)= * =int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images, uint8_t arch, ulong *rd_start, ulong *rd_end)= * =int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len, ulong *initrd_start, ulong *initrd_end)= - used by =lib_*/bootm.c= - seems misplaced. * =int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, char **of_flat_tree, ulong *of_size)= * =int boot_get_fdt (int flag, int argc, char *argv[], bootm_headers_t *images, char **of_flat_tree, ulong *of_size)= * =int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end, ulong bootmap_base)= * Translate IDs to strings * =const char *genimg_get_os_name (uint8_t os)= * =const char *genimg_get_arch_name (uint8_t arch)= * =const char *genimg_get_type_name (uint8_t type)= * =const char *genimg_get_comp_name (uint8_t comp)= * Translate strings to IDs * =int genimg_get_os_id (const char *name)= * =int genimg_get_arch_id (const char *name)= * =int genimg_get_type_id (const char *name)= * =int genimg_get_comp_id (const char *name)= * Helper functions * =static void image_print_type (image_header_t *hdr)= * =static image_header_t* image_get_ramdisk (ulong rd_addr, uint8_t arch, int verify)= * =static void genimg_print_size (uint32_t size)= * =static void genimg_print_time (time_t timestamp)= * =static char *get_table_entry_name (table_entry_t *table, char *msg, int id)= - translate an ID to a printable name * =static int get_table_entry_id (table_entry_t *table, const char *table_name, const char *name)= * =static void fdt_error (const char *msg)= * =static image_header_t *image_get_fdt (ulong fdt_addr)= * =static int fit_check_fdt (const void *fit, int fdt_noffset, int verify)= * =static int fit_parse_spec (const char *spec, char sepc, ulong addr_curr, ulong *addr, const char **name)= * =inline int fit_parse_conf (const char *spec, ulong addr_curr, ulong *addr, const char **conf_name)= * =inline int fit_parse_subimage (const char *spec, ulong addr_curr, ulong *addr, const char **image_name)= * =static void fit_get_debug (const void *fit, int noffset, char *prop_name, int err)= * =void fit_print_contents (const void *fit)= * =void fit_image_print (const void *fit, int image_noffset, const char *p)= * =void fit_image_print_hash (const void *fit, int noffset, const char *p)= * =int fit_get_desc (const void *fit, int noffset, char **desc)= * =int fit_get_timestamp (const void *fit, int noffset, time_t *timestamp)= * =int fit_image_get_node (const void *fit, const char *image_uname)= * =int fit_image_get_os (const void *fit, int noffset, uint8_t *os)= * =int fit_image_get_arch (const void *fit, int noffset, uint8_t *arch)= * =int fit_image_get_type (const void *fit, int noffset, uint8_t *type)= * =int fit_image_get_comp (const void *fit, int noffset, uint8_t *comp)= * =int fit_image_get_load (const void *fit, int noffset, ulong *load)= * =int fit_image_get_entry (const void *fit, int noffset, ulong *entry)= * =int fit_image_get_data (const void *fit, int noffset, const void **data, size_t *size)= * =int fit_image_hash_get_algo (const void *fit, int noffset, char **algo)= * =int fit_image_hash_get_value (const void *fit, int noffset, uint8_t **value, int *value_len)= * =int fit_set_timestamp (void *fit, int noffset, time_t timestamp)= * =static int calculate_hash (const void *data, int data_len, const char *algo, uint8_t *value, int *value_len)= * =int fit_set_hashes (void *fit)= * =int fit_image_set_hashes (void *fit, int image_noffset)= * =int fit_image_hash_set_value (void *fit, int noffset, uint8_t *value, int value_len)= * =int fit_image_check_hashes (const void *fit, int image_noffset)= * =int fit_all_image_check_hashes (const void *fit)= * =int fit_image_check_os (const void *fit, int noffset, uint8_t os)= * =int fit_image_check_arch (const void *fit, int noffset, uint8_t arch)= * =int fit_image_check_type (const void *fit, int noffset, uint8_t type)= * =int fit_image_check_comp (const void *fit, int noffset, uint8_t comp)= * =int fit_check_format (const void *fit)= * =int fit_conf_get_node (const void *fit, const char *conf_uname)= * =static int __fit_conf_get_prop_node (const void *fit, int noffset, const char *prop_name)= * =int fit_conf_get_kernel_node (const void *fit, int noffset)= * =int fit_conf_get_ramdisk_node (const void *fit, int noffset)= * =int fit_conf_get_fdt_node (const void *fit, int noffset)= * =void fit_conf_print (const void *fit, int noffset, const char *p)= * =static int fit_check_ramdisk (const void *fit, int rd_noffset, uint8_t arch, int verify)= * Board-specific helper functions * Command functions * Function pointer ---+++ New Commands Thoughts... This section is some thoughts about if we made an =imload= command with subcommands rather than shoehorning the image manipulation into the =bootm= command. * I'm wondering whether the OS/ramdisk/fdtblob needs to be loaded into RAM separately. The fdtblob needs to be modified before booting, that needs to be separate. The ramdisk may not exist. Conclusion: yes, might as well do all of them separately. * We already have a copy command for memory chunks and =fdt move= for fdtblobs. We should be able to script things using existing+new commands. Missing: * An "uncompress" command. * A way of getting addresses and length information from the images. Unfortunately, our =hush= shell doesn't implement back-ticks "`". We could hack our way around this by setting env variables as side effects. fUgly... :-( 1 Copy fdt into destination address 1 Copy initrd into destination address 1 Decompress/copy OFP into destination address (requires interrupts disabled) * ==imload fit <fitaddr>== * Load a FIT image into appropriate locations * ==imload os <osaddr>== * Load an OS image into the appropriate location * Return (set env variables?) for start and end addresses * ==imload ramdisk <ramdisk>== * Load a RAMDISK image into the appropriate location * Return (set env variables?) for start and end addresses * What is needed is the ramdisk start address, destination address, and length. Then a =cp= command can do the move?! * ==imload fdt <fdtaddr>== * Load a FDT blob into the appropriate location * Return (set env variables?) for start and end addresses * What is needed is the blob start address, destination address, and length. Then a =fdt move= (or =cp=?) command can do the move?! * ==bootm bdt== * Sets up the bd_t struct values (legacy) * ==bootm cmdline== * Sets up the (linux) command line * ==bootm prepos== * OS-specific preparations before relocation or go * ==bootm go==