




已阅读5页,还剩8页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Bootm的流程分析Bootm的流程分析一、在开始之前先说明一下bootm相关的东西。1、首先说明一下,S3C2410架构下的bootm只对sdram中的内核镜像文件进行操作(好像AT91架构提供了一段从flash复制内核镜像的代码,不过针对s3c2410架构就没有这段代码,虽然可以在u-boot下添加这段代码,不过好像这个用处不大),所以请确保你的内核镜像下载到sdram中,或者在bootcmd下把flash中的内核镜像复制到sdram中。 2、-a参数后是内核的运行地址,-e参数后是入口地址。3、1)如果我们没用mkimage对内核进行处理的话,那直接把内核下载到0x30008000再运行就行,内核会自解压运行(不过内核运行需要一个tag来传递参数,而这个tag建议是由bootloader提供的,在u-boot下默认是由bootm命令建立的)。 2)如果使用mkimage生成内核镜像文件的话,会在内核的前头加上了64byte的信息,供建立tag之用。bootm命令会首先判断bootm xxxx 这个指定的地址xxxx是否与-a指定的加载地址相同。(1)如果不同的话会从这个地址开始提取出这个64byte的头部,对其进行分析,然后把去掉头部的内核复制到-a指定的load地址中去运行之(2)如果相同的话那就让其原封不同的放在那,但-e指定的入口地址会推后64byte,以跳过这64byte的头部。bootm 用于加载并启动 U-Boot 能辨识的操作系统映像,即 bootm 加载的映像必须是用mkimage工具打过包的映像,bootm 不能启动直接的内核映像,因为bootm必须从映像的头获取映像的一些信息,比如操作系统的类型,映像是否压缩,映像的加载地址和压缩地址等。更详细的映像头信息可以查看mkimage工具的说明。而bootm的详细用法可通过help bootm获得。 = help bootm bootm addr arg . - boot application image stored in memory passing arguments arg .; when booting a Linux kernel, arg can be the address of an initrd image Bootm 用于将内核映像加载到指定的地址,如果需要还要进行解压映像。然后根据操作系统和体系结构的不同给内核传递不同的内核参数,最后启动内核。 bootm 可以有两个参数,第一个参数为内核映像的地址,它可以是 RAM 地址或者 Flash 地址。第二个参数是可选参数,即initrd映像的地址,当采用Ramdisk 作为根文件系统时需要使用 bootm 的第二个参数。当需要加载 initrd 映像时,首先 U-Boot 把内核映像加载到指定地址,然后再把 Ramdisk 映像加载到指定地址,同时把 Ramdisk 映像的大小和地址告知内核。Bootm命令后U-Boot会将控制权交给Kmon/cmd_bootm.c是bootm的命令实现代码,下面结合U-Boob引导内核启动信息来分析bootm代码,下面是我的开发板的启动信息:U-Boot 2009.11 (Jun 25 2010 - 08:28:06)DRAM: 64 MBFlash: 2 MBNAND: 64 MiBIn: serialOut: serialErr: serialNet: dm9000Hit any key to stop autoboot: 0 NAND read: device 0 offset 0x80000, size 0x500000 5242880 bytes read: OK# Booting kernel from Legacy Image at 30008000 . Image Name: mark Created: 2010-07-02 15:37:07 UTC Image Type: ARM Linux Kernel Image (uncompressed) Data Size: 1800624 Bytes = 1.7 MB Load Address: 30008000 Entry Point: 30008040 Verifying Checksum . OK XIP Kernel Image . OKOKStarting kernel .Uncompressing Linux. done, booting the kernel.Linux version (rootubuntu) (gcc version 4.3.2 (Sourcery G+ Lite 2008q3-72) ) #64 Fri Jul 2 08:30:03 PDT 2010CPU: ARM920T 41129200 revision 0 (ARMv4T), cr=c0007177CPU: VIVT data cache, VIVT instruction cacheMachine: Study-S3C2440Memory policy: ECC disabled, Data cache writebackcmd_bootm.c先分析bootm命令在U-Boot中是如何添加的:U_BOOT_CMD(bootm,CONFIG_SYS_MAXARGS,1,do_bootm,boot application image from memory,addr arg .n - boot application image stored in memoryntpassing arguments arg .; when booting a Linux kernel,ntarg can be the address of an initrd imagen#if defined(CONFIG_OF_LIBFDT)tWhen booting a Linux kernel which requires a flat device-treenta third argument is required which is the address of thentdevice-tree blob. To boot that kernel without an initrd image,ntuse a - for the second argument. If you do not pass a thirdnta bd_info struct will be passed insteadn#endif#if defined(CONFIG_FIT)tnFor the new multi component uImage format (FIT) addressesntmust be extened to include component or configuration unit name:ntaddr: - direct component image specificationntaddr# - configuration specificationntUse iminfo command to get the list of existing componentntimages and configurations.n#endifnSub-commands to do part of the bootm sequence. The sub-commands must benissued in the order below (its ok to not issue all sub-commands):ntstart addr arg .ntloados - load OS imagen#if defined(CONFIG_PPC) | defined(CONFIG_M68K) | defined(CONFIG_SPARC)tramdisk - relocate initrd, set env initrd_start/initrd_endn#endif#if defined(CONFIG_OF_LIBFDT)tfdt - relocate flat device treen#endiftcmdline - OS specific command line processing/setupntbdt - OS specific bd_t processingntprep - OS specific prep before relocation or gontgo - start OS);宏U_BOOT_CMD用于定义U-Boot命令,它的定义如下:#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) cmd_btl_t _u_boot_cmd #name Struct_Section=#name,maxargs,rep,cmd,usage,help|#define Struct Section _attribute_ (unused,section (.u_boot_cmd)宏U_BOOT_CMD展开后如下所示:cmd_tlb_t _u_boot_cmd_bootm _a见嵌入式liinux应用开发完全手册do_bootm函数分析static boot_os_fn *boot_os = #ifdef CONFIG_BOOTM_LINUXIH_OS_LINUX = do_bootm_linux, /由于我使用的是linux内核,编译时将会选择该函数#endifint do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv) /这里的argc和argv就是bootm命令行参数 boot_os_fn*boot_fn; /定义跳转到操作系统执行的指针if (bootm_start(cmdtp, flag, argc, argv) /调用bootm_start函数return 1;iflag = disable_interrupts(); /禁止中断ret = bootm_load_os(images.os, &load_end, 1); /调用bootm_load_os函数boot_fn = boot_osimages.os.os; /根据OS类型去选择启动操作系统的函数boot_fn(0, argc, argv, &images); /执行do_bootm_linux函数do_bootm函数中调用的几个重要的函数是bootm_start、bootm_load_os、do_bootm_linux,下面一一分析。bootm_startstatic bootm_headers_t images;/* pointers to os/initrd/fdt images */static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char *argv) void*os_hdr; /* 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); . /* get image parameters */switch (genimg_get_format (os_hdr) /获取image头格式类型case IMAGE_FORMAT_LEGACY: /老的image头格式images.os.type = image_get_type (os_hdr); /获取image的类型p = image_get_comp (os_hdr); /获取image的压缩类型images.os.os = image_get_os (os_hdr); /获取image的OS类型images.os.end = image_get_image_end (os_hdr); /获取image开始地址images.os.load = image_get_load (os_hdr); /获取image结束地址break;/* find kernel entry point */if (images.legacy_hdr_valid) images.ep = image_get_ep (&images.legacy_hdr_os_copy); /获取image入口指针ulong load_addr = CONFIG_SYS_LOAD_ADDR;/* Default Load Address */寻找内核映像、校验它的完整性和定位内核数据位置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;/* find out kernel image address */if (argc verify); /获取image头/校验早期格式内核映像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) /校验MAGIC numberputs (Bad Magic Numbern);show_boot_progress (-1);return NULL;show_boot_progress (2);if (!image_check_hcrc (hdr) /image头校验puts (Bad Header Checksumn);show_boot_progress (-2);return NULL;show_boot_progress (3);image_print_contents (hdr); /该函数内将打印imag头信息“Image Name: mark Created: 2010-07-02 15:37:07 UTC Image Type: ARM Linux Kernel Image (uncompressed) Data Size: 1800624 Bytes = 1.7 MB Load Address: 30008000 Entry Point: 30008040”if (verify) puts ( Verifying Checksum . ); /出现在U-Boot启动信息中if (!image_check_dcrc (hdr) /校验image数据printf (Bad Data CRCn);show_boot_progress (-3);return NULL;puts (OKn); /出现在U-Boot启动信息中show_boot_progress (4);if (!image_check_target_arch (hdr) /ARM、i386、MIPS等架构检查printf (Unsupported Architecture 0x%xn, image_get_arch (hdr);show_boot_progress (-4);return NULL;return hdr;/打印image头信息void image_print_contents (const void *ptr)const image_header_t *hdr = (const image_header_t *)ptr;const char *p; #ifdef USE_HOSTCCp = ;#elsep = ; /打印空格#endif /打印image名字printf (%sImage Name: %.*sn, p, IH_NMLEN, image_get_name (hdr);#if defined(CONFIG_TIMESTAMP) | defined(CONFIG_CMD_DATE) | defined(USE_HOSTCC) printf (%sCreated: , p); /打印image创建日期genimg_print_time (time_t)image_get_time (hdr);#endifprintf (%sImage Type: , p); /打印image类型image_print_type (hdr);printf (%sData Size: , p); /打印image大小genimg_print_size (image_get_data_size (hdr);printf (%sLoad Address: %08xn, p, image_get_load (hdr); /打印image加载地址printf (%sEntry Point: %08xn, p, image_get_ep (hdr); /打印image入口指针typedef struct bootm_headers /* * Legacy os image header, if it is a multi component image * then boot_get_ramdisk() and get_fdt() will attempt to get * data from second and third component accordingly. */image_header_t*legacy_hdr_os;/* image header pointer */image_header_tlegacy_hdr_os_copy;/* header copy */ulonglegacy_hdr_valid;#ifndef USE_HOSTCCimage_info_tos;/* os image info */ulongep;/* entry point of OS */ulongrd_start, rd_end;/* ramdisk start/end */ulongft_len;/* length of flat device tree */ulonginitrd_start;ulonginitrd_end;ulongcmdline_start;ulongcmdline_end;bd_t*kbd;#endifintverify;/* getenv(verify)0 != n */#defineBOOTM_STATE_START(0x00000001)#defineBOOTM_STATE_LOADOS(0x00000002)#defineBOOTM_STATE_RAMDISK(0x00000004)#defineBOOTM_STATE_FDT(0x00000008)#defineBOOTM_STATE_OS_CMDLINE(0x00000010)#defineBOOTM_STATE_OS_BD_T(0x00000020)#defineBOOTM_STATE_OS_PREP(0x00000040)#defineBOOTM_STATE_OS_GO(0x00000080)intstate;#ifndef USE_HOSTCCstruct lmblmb;/* for memory mgmt */#endif bootm_headers_t;bootm_load_osstatic int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)uint8_t comp = p; /获取image压缩类型ulong load = os.load; ulong blob_start = os.start; /os.start为bootm后面的地址,如果bootm后面没有参数,则默认为u-boot中加载地址ulong blob_end = os.end;ulong image_start = os.image_start; /os.image_start为os.start+u-boot头,即内核所处内存的起始地址ulong image_len = os.image_len; /os.image_len为内核长度uint unc_len = CONFIG_SYS_BOOTM_LEN;switch (comp) case IH_COMP_NONE: /image未压缩if (load = blob_start) printf ( XIP %s . , type_name); /如果U-Boot头中的加载地址与bootm后面的地址相同,则打印包含“XIP”的字符串,分析u-boot代码发现load就是u-boot头中的加载地址,blob_start是bootm后面的地址。这种情况对应的是使用mkimage工具生成包含u-boot头时加载地址为0x30008000,入口指针为0x30008040,tftp 30008000。此种情况下load并不等于ep,即u-boot头中的加载地址和入口指针不相同。 else printf ( Loading %s . , type_name); /如果U-Boot头中的加载地址与bootm后面的地址不相同。此种情况对应的是使用mkimage工具生成的u-boot头时加载地址和入口指针都为0x30008000,tftp。此种情况下load等于ep,即u-boot头中的加载地址等于入口指针。if (load != image_start) /因为u-boot头中的加载地址等于入口指针,这里等于是判断u-boot头中的加载地址或入口指针是否等于内存中内核映像所处的位置,因为如果入口指针等于内核所处的内存地址,那么就不用下面的将内存中内核所处的位置的值复制到加载地址或入口指针处,然后从入口指针处执行内核程序。memmove_wd (void *)load,(void *)image_start, image_len, CHUNKSZ);*load_end = load + image_len;puts(OKn);break;case IH_COMP_GZIP: /image采用gzip压缩printf ( Uncompressing %s . , type_name);if (gunzip (void *)load, unc_len, /解压压缩过的映像(uchar *)image_start, &image_len) != 0) puts (GUNZIP: uncompress, out-of-mem or overwrite error - must RESET board to recovern);if (boot_progress)show_boot_progress (-6);return BOOTM_ERR_RESET;*load_end = load + image_len;break;#ifdef CONFIG_BZIP2case IH_COMP_BZIP2: /image采用bzip2压缩printf ( Uncompressing %s . , type_name);/* * If weve got less than 4 MB of malloc() space, * use slower decompression algorithm which requires * at most 2300 KB of memory. */int i = BZ2_bzBuffToBuffDecompress (char*)load, /解压压缩过的映像&unc_len, (char *)image_start, image_len,CONFIG_SYS_MALLOC_LEN (4096 * 1024), 0);if (i != BZ_OK) printf (BUNZIP2: uncompress or overwrite error %d - must RESET board to recovern, i);if (boot_progress)show_boot_progress (-6);return BOOTM_ERR_RESET;*load_end = load + unc_len;break;#endif /* CONFIG_BZIP2 */#ifdef CONFIG_LZMAcase IH_COMP_LZMA: /image采用LZMA压缩printf ( Uncompressing %s . , type_name);int ret = lzmaBuffToBuffDecompress( /解压压缩过的映像(unsigned char *)load, &unc_len,(unsigned char *)image_start, image_len);if (ret != SZ_OK) printf (LZMA: uncompress or overwrite error %d - must RESET board to recovern, ret);show_boot_progress (-6);return BOOTM_ERR_RESET;*load_end = load + unc_len;break;#endif /* CONFIG_LZMA */default:printf (Unimplemented compression type %dn, comp);return BOOTM_ERR_UNIMPLEMENTED;puts (OKn);debug ( kernel loaded at 0x%08lx, end = 0x%08lxn, load, *load_end);if (boot_progress)show_boot_progress (7);if (load blob_start) debug (images.os.start = 0x%lX, images.os.end = 0x%lxn, blob_start, blob_end);debug (images.os.load = 0x%lx, load_end = 0x%lxn, load, *load_end);return BOOTM_ERR_OVERLAP;return 0;关于bootm_load_os函数,个人的理解是之所以叫它是load os,是因为一些image的起始地址和加载地址相同的话就直接运行,但是一些image的起始地址和加载地址不相同的话,要把image搬运到加载地址开始处,然后执行。do_bootm_linuxint do_bootm_linux(int flag, int argc, char *argv, bootm_headers_t *images) bd_t*bd = gd-bd;char*s;intmachid = bd-bi_arch_number;void(*theKernel)(int zero, int arch, uint params);#ifdef CONFIG_CMDLINE_TAG char *commandline = getenv (bootargs); /启动参数标记,如果在include/configs/mini2440.h中定义CONFIG_CMDLINE_TAG宏,则boottargs将会传递给内核#endifif (flag != 0) & (flag != BOOTM_STATE_OS_GO)return 1;theKernel = (void (*)(int, int, uint)images-ep; / image入口地址赋值给theKernel指针s = getenv (machid);
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年建筑声环境工程师执业资格考试试题及答案解析
- 课件中对话模式设置
- 2025年互联网金融分析师专业素质测评试题及答案解析
- 2025年软件开发工程师高级考试预测题库
- 2025年广告创意设计师职业资格考试试题及答案解析
- 2025年动画设计师创意实践考试试卷及答案解析
- 山歌好比春江水教学课件
- 2025年安全生产责任制面试题与答案
- 2025年喷漆作业安全培训题及答案
- 课件不合规问题分析
- 医疗器械生产企业GMP培训专家讲座
- 2023年中远海运船员管理有限公司招聘笔试题库及答案解析
- 辐射及其安全防护(共38张PPT)
- 金风15兆瓦机组变流部分培训课件
- 膀胱镜检查记录
- 沈阳终止解除劳动合同证明书(三联)
- 化工装置静设备基本知识
- 电脑节能环保证书
- 美国共同基金SmartBeta布局及借鉴
- 露天矿山危险源辨识汇总
- 国家城镇救援队伍能力建设与分级测评指南
评论
0/150
提交评论