欢迎来到天天文库
浏览记录
ID:39469053
大小:63.50 KB
页数:11页
时间:2019-07-04
《U-Boot启动内核分析》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库。
1、U-Boot启动内核分析先来引用一下这篇介绍“ARMLinux内核启动要求”的文章ARMLinuxKernelBootRequirements,是ARMLinux内核的维护者RussellKing写的。·CPUregistersettingsor0=0.or1=machinetypenumber.or2=physicaladdressoftaggedlistinsystemRAM.·CPUmodeoAllformsofinterruptsmustbedisabled(IRQsandFIQs.)oTheCPUmus
2、tbeinSVCmode.(AspecialexceptionexistsforAngel.)·Caches,MMUsoTheMMUmustbeoff.oInstructioncachemaybeonoroff.oDatacachemustbeoffandmustnotcontainanystaledata.·DevicesoDMAto/fromdevicesshouldbequiesced.·Thebootloaderisexpectedtocallthekernelimagebyjumpingdirectly
3、tothefirstinstructionofthekernelimage.大致就是以上条件了,请特别关注一下第一条,这个基本上就是U-Boot的go命令和bootm命令之间的本质区别所在了。先来看看bootm命令的实现,在common/cmd_bootm.c的第119行开始有:#ifdefCONFIG_PPCstaticboot_os_Fcndo_bootm_linux;#elseexternboot_os_Fcndo_bootm_linux;#endif这里的预编译宏说明了,非PPC体系结构的CPU的do_b
4、ootm_linux()函数都不是在这个文件内实现的(extern)。可想而知,这个函数的实现应该是和体系结构相关的,具体到arm体系结构的实现就是在lib_arm/armlinux.c这个文件当中。可以看到从lib_arm/armlinux.c中的第77行开始就是do_bootm_linux()函数的实现。 其中第85行声明了这样一个函数指针theKernel:void(*theKernel)(intzero,intarch,uintparams);看看它的名字和参数的命名我们也可以猜到这个其实就是内核的入口函
5、数的指针了。几个参数的命名也说明了上文提到的ARMLinux内核启动要求的第一条,因为根据ACPS(ARM/ThumbProcedureCallStandard)的规定,这三个参数就是依次使用r0,r1和r2来传递的。 接下来第93行就是给这个函数指针赋值:theKernel=(void(*)(int,int,uint))ntohl(hdr->ih_ep);可以看到theKernel被赋值为hdr->ih_ep,这个hdr是指使用tools/mkimage工具程序制作uImage时加在linux.bin.gz前面
6、的一个头部,而ih_ep结构体成员保存的就是使用mkimage时指定的-e参数的值,即内核的入口点(EntryPoint)。知道了hdr->ih_ep的意义之后,给theKernel赋这个值也就是理所当然的了。 最后是对内核入口函数的调用,发生在第270行:theKernel(0,bd->bi_arch_number,bd->bi_boot_params);调用的时候对参数进行赋值,r0=0,r1=bd->bi_arch_number,r2=bd->bi_boot_params,一个都不少。至此U-Boot的使命
7、完成,开始进入ARMLinux的美丽新世界。 ==================================================================== 要知道哪个地址是启动内核,哪个地址启动文件系统,要分析common/cmd_bootm.c中的函数do_bootm,因为引导kernel就是bootm这条命令的工作,do_bootm是命令bootm的执行函数。现在我们来分析一下common/cmd_bootm.c中的函数do_bootm,这是bootm命令的处理函数。……image
8、_header_theader;ulongload_addr=CFG_LOAD_ADDR;/*DefaultLoadAddress*/intdo_bootm(cmd_tbl_t*cmdtp,intflag,intargc,char*argv[]){ulongiflag;ulongaddr;ulongdata,len,checksum;ulong*len_ptr;uintu
此文档下载收益归作者所有