生活随笔
收集整理的這篇文章主要介紹了
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;??} ? |
總結
以上是生活随笔為你收集整理的uboot分析之bootm_start的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。