已阅读5页,还剩4页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
背景:Boardar7240(ap93)Cpumips1、首先弄清楚什么是u-bootUboot是德国DENX小组的开发,它用于多种嵌入式CPU的bootloader程序,uboot不仅支持嵌入式linux系统的引导,当前,它还支持其他的很多嵌入式操作系统。除了PowerPC系列,还支持MIPS,x86,ARM,NIOS,XScale。2、下载完uboot后解压,在根目录下,有如下重要的信息(目录或者文件):根目录(u-boot)boardcommoncpudiskDocdriversfsincludeLib_xxxnettools以下为为每个目录的说明:Board:和一些已有开发板有关的文件。每一个开发板都以一个子目录出现在当前目录中,子目录存放和开发板相关的配置文件。它的每个子文件夹里都有如下文件(以ar7240/ap93为例):MakefileConfig.mkAp93.c和板子相关的代码Flash.c Flash操作代码u-boot.lds对应的链接文件common:实现uboot命令行下支持的命令,每一条命令都对应一个文件。例如bootm命令对应就是cmd_bootm.ccpu:与特定CPU架构相关目录,每一款Uboot下支持的CPU在该目录下对应一个子目录,比如有子目录mips等。它的每个子文件夹里都有入下文件:MakefileConfig.mkCpu.c和处理器相关的代码sInterrupts.c中断处理代码Serial.c串口初始化代码Start.s全局开始启动代码Disk:对磁盘的支持Doc:文档目录。Uboot有非常完善的文档。Drivers:Uboot支持的设备驱动程序都放在该目录,比如网卡,支持CFI的Flash,串口和USB等。Fs:支持的文件系统,Uboot现在支持cramfs、fat、fdos、jffs2和registerfs。Include:Uboot使用的头文件,还有对各种硬件平台支持的汇编文件,系统的配置文件和对文件系统支持的文件。该目下configs目录有与开发板相关的配置文件,如ar7240_soc.h。该目录下的asm目录有与CPU体系结构相关的头文件,比如说mips对应的有asm-mips。Lib_xxx:与体系结构相关的库文件。如与ARM相关的库放在lib_arm中。Net:与网络协议栈相关的代码,BOOTP协议、TFTP协议、RARP协议和NFS文件系统的实现。Tools:生成Uboot的工具,如:mkimage等等。3、mips架构u-boot启动流程u-boot的启动过程大致做如下工作:1、cpu初始化2、时钟、串口、内存(ddr ram)初始化3、内存划分、分配栈、数据、配置参数、以及u-boot代码在内存中的位置。4、对u-boot代码作relocate5、初始化malloc、flash、pci以及外设(比如,网口)6、进入命令行或者直接启动Linux kernel刚一开始由于参考网上代码,我一个劲的对基于smdk2410的板子,arm926ejs的cpu看了N久,启动过程和这个大致相同。整个启动中要涉及到四个文件:Start.Scpu/mips/start.SCache.Scpu/mips/cache.SLowlevel_init.Sboard/ar7240/common/lowlevel_init.SBoard.clib_mips/board.c整个启动过程分为两个阶段来看:Stage1:系统上电后通过汇编执行代码Stage2:通过一些列设置搭建了C环境,通过汇编指令跳转到C语言执行.Stage1:程序从Start.S的_start开始执行.(至于为什么,参考u-boot.lds分析.doc)先查看start.S文件吧!从_start标记开始会看到一长串莫名奇妙的代码:RVECENT(reset,0) /* U-boot entry point */*U-Boot开始执行的代码起始地址*/RVECENT(reset,1) /* software reboot */ /*软重启时U-Boot开始执行的起始地址*/RVECENT(romReserved,2)/*保留本代码所在的地址,重新映射调试异常向量时可以使用该空间*/RVECENT(romReserved,3)RVECENT(romReserved,4)RVECENT(romReserved,5)RVECENT(romReserved,6)RVECENT(romReserved,7)RVECENT(romReserved,8)RVECENT(romReserved,9)回过头看刚开始的定义有这样的代码:可以找到:#define RVECENT(f,n) b f; nop原来这只是一个简单的跳转指令,f为一个标记,b为跳转指令。然后看最后,发现:romReserved: b romReservedromExcHandle: b romExcHandle这两个标记都构建了无意义的死循环。通过_start标记处的语句RVECENT(reset,0) 代码跳转到标记reset的地方,该段代码的操作就是对寄存器的清零操作了。Mfc0和mtc0指令是对寄存器的一些读写.在接下来是对协处理器的操作了,其中包括:CP0_WATCHLO,CP0_WATCHHI,CP0_CAUSE,CP0_COUNT,CP0_COMPARE之后,配置寄存器CP0_STATUS,设置所使用的协处理器,中断以及cpu运行级别(核心级)。配置gp寄存器,把GOT段的地址赋给gp寄存器。(gp寄存器的用处会在后面relocate code部分详细解释)接下来执行lowlevle_init.S的lowlevel_init函数,主要目的是工作频率配置,比如cpu的主频,总线(AHB),DDR工作频率等。然后执行cache.S中的mips_cache_reset对cache进行初始化。接着调用mips_cache_lock(这个调用的目的:当代码执行到这个时候,ddr ram还没有配置好,而如果直接调用C语言的函数必须完成栈的设置,而栈必定要在ram中。所以,只有先把一部分cache拿来当做ram用。做法就是把一部分cache配置为栈的地址,锁定。这样,当读写栈的内存空间时,只会访问cache,而不会访问真的ram地址了。)这时,配置栈的地址,进行调用函数board_init_f (board.c)进入函数board_init_f后,首先做一些列的初始化:Timer_init时钟初始化Env_init环境变量初始化(取得环境变量存放的地址)Init_baudrate串口速率Serial_init串口初始化Console_init_f配置控制台Display_banner显示u-boot启动信息,版本号等。Checkboard执行board相关的操作Init_func_ram初始化内存,配置ddr controller这一系列工作完成后,串口和内存都已经可以用了。然后,就要把内存进行划分,在内存的最后一部分,留出u-boot代码大小的空间,准备把u-boot代码从flash搬移到这里。然后,是堆的空间,malloc的内存就来自于这里。紧接着放两个全局数据结构bd_infoglobal_data和环境变量boot_params。最后,是栈的空间。当内存划分好后,就准备进行relocate code了。(relocate code含义:通常u-boot的执行代码肯定是在flash上(调试可以在ram上).当启动起来之后,要把它从flash上搬移到ram里运行)但是,存在的问题是,flash地址和ram地址是不同的。当我们把代码从flash搬移到ram中后,当执行函数跳转时,代码里的函数地址还是flash的地址,一跳,又重新跳回去了(跳回了flash)。IPC(position-independent code) 由此引出了。原理:当使用IPC方式时,在用gcc编译时需要加上-fpic的选项。编译器会为你的可执行代码建立一个GOT(global offset table)的段。一个地址在GOT表中有一项,里面存放地址的信息,在使用这个地址时,只要根据这个地址的编号(也可以叫做偏移量offset)找到表中相应的项目,就可以取得那个地址了。而如果位置发生变化,只要对GOT 表中的地址进行修改就可以了。例:Lwt9,1088(gp)Jalrt9这里,gp存放的就是GOT表的起始地址,而1088就是要调用函数offset,也就说GOT表的那个位置存放着它的地址。Lwt9,1088(gp)把函数地址放入t9寄存器,然后调用就可以了。Relocate code说简单一点就是:把u-boot的执行代码直接从flash里copy到ram的相应区域。然后,把GOT表中的地址都加上一个偏移量,这个偏移量就是flash里的地址与ram里的地址差。这里完成的操作还有一些其他工作,比如:设置新的栈指针,从flash代码里跳转到ram代码里等等.之后,进入board.c的board_init_r函数。进入stage2。Stage2:在board_init_f函数中初始化malloc,flash,pci以及外设(如:网口),最后进入命令行或者直接启动Linux Kernel.这样,u-boot的启动工作完成。流程分析1、 最开始系统加电。ENTRY(_start)程序入口点是_start (原因参考u-boot.lds分析.doc)2、_start:cpu/mips/start.S3、lat9,board_init_f;将函数board_init_f地址赋给t9寄存器Jt9;程序调转到t9寄存器中保存的地址指向的指令注:(这里有点小疑问:代码运行到这里,pc指向的应该是cache中划分出来的临时ram?)a)board_inif_f()lib_mips/board.c初始化外部内存relocate_code()回到cpu/mps/start.S中继续执行4、lat9,board_init_r cpu/mips/start.S将函数board_init_r地址赋给t9寄存器Jt9跳转到t9寄存器中保存的地址指向的指令a)board_init_r()函数lib_mips/board.cb)main_loop()common/main.cs = getenv(“bootcmd”)取得环境变量中的启动命令行,如:bootcmd = bootm 0xbf020000run_command(s,0);/执行这个命令行,即bootmc)do_bootm()command/cmd_bootm.c/printf(“#Booting image at %08lxn”,addr);5、bootm启动内核a)do_bootm_linux()lib_mips/mips_linux.c函数解析1、 board_init_f()a) void board_init_f(ulong bootflag)For (init_fnc_ptr = init_sequence; *init_fnc_ptr; + init_fnc_ptr)If (*init_fnc_ptr)() != 0)Hang();/*调用init_sequence函数队列,对板子进行一些初始化,详细见后面初始化external memory,初始化堆栈用cache作堆栈*/relocate_code(addr_sp,id,addr);/回到cpu/mips/start.S中/*NOTREACHED-relocate_code() does not return*/b) typedef int (init_fnc_t) (void);init_fnc_t * init_sequence = /*Clx_board_init,/初始化GPIO,CPU速度,PLL,SDRAM等*/Timer_init,/时钟初始化Env_init,/环境变量初始化Incaip_set_cpuclk,/根据环境变量设置CPU时钟Init_baudrate,/初始化串口波特率Serial_init,/* serial communicatioins setup */Console_init_f,/串口初始化,后面才能显示Display_banner,/在屏幕上输出一些显示信息Checkboard,Init_func_ram,NULL,;2、 board_init_r()a) 调用一些列的初始化函数b) 初始化Flash设备c) 初始化系统内存分配函数d) 如果目标系统拥有NAND设备,则初始化NAND设备e) 如果目标系统有显示设备,则初始化该类设备f) 初始化相关网络设备,填写IP、MAC地址等g) 进去命令循环(即整个boot的工作循环),接受用户从串口输入的命令,然后进行相应的工作Void board_init_r(gd_t *id, ulong dest_addr)/*configure available FLASH banks*/配置可用的flash单元Size = flash_init();/初始化flashDisplay_flash_config(size);/显示flash的大小/*initialize malloc() area*/Mem_malloc_init();Malloc_bin_reloc();Puts(“NAND”);Nand_init();/*go init the NAND*/NAND初始化/*relocate environment function pointers etc.*/Env_relocate();/初始化环境变量 /*board MAC addresss*/S = getenv(“ethaddr”);/以太网MAC地址For (I = 0;I bi_enetaddri = s?simple_strtoul(s,&e,16):0;If (s)S = (*e)?e + 1:e;/*IP Address*/Bd-bi_ip_addr = getenv_IPaddr(“ipaddr”);Pci_init();/pci初始化配置/*leave this here (after malloc(),environment and PCI are working */*initialize devices*/Devices_init();Jumptable_init();/*initialize the console (after the relocation and deivces init)*/Console_init_t();/串口初始化/miscellaneous platform dependent initialisationss/Misc_init_r();Puts(“Net”);Eth_initialize(gd-bd);/*main_loop() can return to retry autoboot,if so just run it again.*/For (;)Main_loop();/*循环执行,试图自动启动,接受用户从串口输入的命令,然后进行相应的工作,设置延时时间,确定目标板是进入下载模式还是启动加载模式*/*NOTREACHED-no way out of command loop except booting*/3、 main_loop()void main_loop(void)S = getenv(“bootdelay”);/从环境变量中取得bootdelay内核等待延时Bootdelay = s ? (int)simple_strtol(s,NULL,10) : CONFIG_BOOTDELAY;Debug(“#main_loop entered:bootdelay = %dnn”, bootdelay);S = getenv(“bootcmd”);/从环境变量中取得bootcmd启动命令行/*例:bootcmd = tftp;bootm或者bootcmd = bootm 0xbf020000*/ Char *s1 = getenv(“bootargs”);/从环境变量中取得bootargs启动参数Debug(“#main_loop:bootcmd = ”%s”n”, s ? s : “”);Run_command(s, 0);/执行启动命令/手动输入命令For (;)Len = readline(CFG_PROMPT);/读取键入的命令道CFG_PROMPT中Rc = run_command(l
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 《电话沟通科顿》课件
- 移动支付系统漏洞挖掘与修复-洞察分析
- 星系早期形成理论-洞察分析
- 虚拟现实游戏教育应用-洞察分析
- 习惯性脱位微创手术并发症分析-洞察分析
- 游戏直播平台竞争策略-洞察分析
- 农村网格员先进事迹(6篇)
- 新闻真实性与伦理考量-洞察分析
- 虚拟协作空间设计-洞察分析
- 移植后心理护理路径构建-洞察分析
- 清华大学《大学物理》习题库试题及答案-08-电学习题答案
- -年级组长述职报告(四篇合集)
- 2024年全国初中数学联合竞赛试题参考答案及评分标准
- 个人分析报告优势与劣势
- 第五章-双水相萃取技术
- 上级制度宣贯培训方案
- 马克思主义基本原理概论第六章
- 受警告处分后的思想汇报
- 疼痛科护士的疼痛科病例分析和医学讨论
- 司法鉴定技术
- java万年历课程设计完成版Applet
评论
0/150
提交评论