U-Boot分析报告
u-boot_mips移植分析
u-boot/mips移植分析1.引言文章是2年前移植u-boot时候分析的,u-boot方面文章比较多,但是mips方面的稍微少一点,因此贴上来就当资料搜集贴吧.(Note:图片上传后和原图有些出入,不知道什么原因,不过总体框图还是正确的)1.1.参考资料詹荣开<Bootloader技术内幕>原作者未考证<au1500(mips)及yamon启动过程>2.需求分析Bootloader在嵌入式系统中一般起硬件初始化和内核引导的作用,在产品中使用的Bootloader只要保证基本的功能和引导速度即可,而作为开发使用的Bootloader,要求能提供灵活的配置方式和调试手段,一般选择已有的开源软件作为移植,下面主要分析Bootloader移植的需求2.1.基本功能需求基本功能包括:1.硬件初始化:根据具体的硬件环境,初始化必要的寄存器和外设2.内核引导从存储介质中读取内核映象,并引导3.代码下载提供一种或几种机制能从主机直接下载文件到SDRAM中2.2.扩展功能需求扩展功能主要是为了提供调试手段的多样化和便利化做的一些工作,包括:1.环境变量的保存:提供一种能将用户定制的一些参数和脚本保存的机制;2.文件写入存储介质:提供将SDRAM中文件写入存储介质的功能;B调试手段:提供使用USB作为控制终端和下载方式的调试开发功能;4.文件系统解析:提供文件系统解析功能,使Bootloader能从存储介质的文件系统目录里读取文件。
3.原理分析3.1.Bootloader原理分析(1)Boot Loader简介Bootloader就是在操作系统内核运行之前运行的一段小程序。
通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好正确的环境。
(2)Boot Loader的操作模式(Operation Mode)大多数Boot Loader都包含两种不同的操作模式:"启动加载"模式和"下载"模式,这种区别仅对于开发人员才有意义。
U-Boot分析报告
cpu_init_f
其中cpu_init_f位于\cpu\mcf5227x\ 其中cpu_init_f位于\cpu\mcf5227x\cpu_init.c cpu_init_f位于 主要完成以下工作: 主要完成以下工作:
/* * Breath some life into the CPU * * Set up the memory map, * initialize a bunch of registers, * initialize the UPM's */
2.\lib_m68k\board.c系统初始化分析 2.\lib_m68k\board.c系统初始化分析
主要包括刚才涉及的两个函数: 主要包括刚才涉及的两个函数: 1. cpu_init_f 2. board_init_r 下面我们简要分析一下board.c 下面我们简要分析一下board.c
U-Boot的后续工作 Boot的后续工作
进入u boot主循环,并循环调用调用main_loop 进入u-boot主循环,并循环调用调用main_loop 主循环 Bootdelay到期后,会调用run_command函数, Bootdelay到期后,会调用run_command函数,自动执 到期后 run_command函数 bootcmd命令 行bootcmd命令 在run_command函数中调用函数指针cmdtp->cmd来启 run_command函数中调用函数指针cmdtp->cmd来启 函数中调用函数指针cmdtp do_bootm命令 动do_bootm命令 解析镜像的头部,需要解压的就调用解压缩函数解压, 解析镜像的头部,需要解压的就调用解压缩函数解压,就调 do_bootm_linux()去调用去加载linux系统镜像 去调用去加载linux 用do_bootm_linux()去调用去加载linux系统镜像 获取并设置Linux启动参数列表和机器号, 获取并设置Linux启动参数列表和机器号,最后调用函数指 Linux启动参数列表和机器号 针theKernel(0,machid,bd->bi_boot_params) theKernel(0,machid,bd-
u-boot应用分析
嵌入式系统工程师u-boot应用分析大纲常用嵌入式Bootloader介绍u-boot介绍配置编译控制命令命令实现启动过程模块分析u-boot应用分析常用嵌入式Bootloader介绍u-boot介绍配置编译控制命令命令实现启动过程模块分析vivi简介:vivi是由韩国MIZI公司开发的专门用于ARM产品线的一种Bootloader,主要参考Linux2.4内核开发特点:主要支持Samsung系列芯片,命令简单方便,其配置原理与编译过程与Linux非常相似,通过对其源码的分析可以加深对Linux配置过程的理解功能:初始版本只支持串口下载,速度较慢,在网上出现了各种改进版本,主要支持:常见的串口协议、网络协议、USB下载、YAFFS镜像烧写等HBOOT简介:HTC智能手机中常用的Bootloader,也可能是前几种Bootloader的一种或者几种的融合体,被HTC定制,是典型的两阶段启动,分别是:IPL和SPL。
IPL:即Initial Program Loader,是硬件上电后启动第一段程序,负责最初硬件(Nand Flash,CPU,SDRAM)初始化,然后再把SPL程序装到RAM指定位置。
SPL:完成更多更复杂的硬件初始化,且往往支持很多复杂命令,比如网络、USB下载(fastboot线刷)、SD升级(卡刷)等,最终将操作系统装入到RAM中运行。
特点:主要支持HTC系列手机PPCBoot简介:是德国DENX小组开发的用于多种嵌入式CPU的Bootloader引导程序,主要由德国工程师Wolfgang Denk和Internet上的一群自由开发人员对其进行维护和开发特点:支持PowerPC、ARM、MIPS、M68K等多种处理器平台,易于裁剪和调试ARMBoot简介:armboot主要是针对ARM或者StrongARM CPU等相关嵌入式系统所设计的特点:它支持多种类型的Flash,网络下载协议支持bootp和tftpu-boot简介:u-boot最初是由PPCBoot发展而来的,可以引导多种操作系统、支持多种架构的CPU,它对PowerPC系列处理器的支持最为完善,而操作系统则对Linux系统的支持最好目前已成为Armboot和PPCboot的替代品特点:主要支持操作系统:Linux、NetBSD、 VxWorks、QNX、RTEMS、ARTOS、LynxOS等主要支持处理器架构:PowerPC、MIPS、x86、ARM、NIOS、XScale等u-boot目前最新版本是:http://ftp.denx.de/pub/u-boot/u-boot应用分析常用嵌入式Bootloader介绍u-boot介绍配置编译控制命令命令实现启动过程模块分析源码目录目录结构介绍:board:开发板相关,根据厂商进行分类,如当前平台board\samsung\unsp210,包含第一阶段要用到的一些初始化程序:lowlevel_init.Scpu:体系结构相关,按架构进行分类,如当前架构cpu\s5pc11x,第一阶段启动代码start.S就在这里common:各种命令的实现,通常一个命令就是一个C文件include:各种头文件和开发板配置文件,如include\configs\unsp210.h目录结构介绍:api/api_examples:用于演示测试用的代码,通常不参与工程编译disk:硬盘接口程序,disk驱动分区处理代码,嵌入式不常用doc:开发使用文档,主要介绍不同平台的配置编译方法drivers:设备驱动,如:网卡、SD卡、USB等examples:一些独立运行的实例,通常不参与工程编译fs:所能支持的文件系统,如fat、ubifs等,用于访问带文件系统的存储设备目录结构介绍:lib_arm:用于存放平台依赖文件,如第二阶段代码入口(start_armboot())、中断处理、启动相关等,其它以“lib_”开头的也是类似lib_generic:存放通用且不依赖于平台的库,如一些C库,终端操作接口等nand_spl:一些配置参考文件net:独立于网卡驱动的网络协议,如用于下载传输的TFTP协议,网络文件系统中的NFS协议等onenand_bl1:onenand启动的第一阶段代码onenand_ipl:onenand启动时,IPL和SPL过程中的第一个过程,即初始化阶段目录结构介绍:post:上电自检程序,与旧的PPC相关,当前平台下未编译到工程sd_fusing:一些操作SD卡的脚本,主要用于制作SD引导启动相关tools:工具软件,如mkimage用于制作内核镜像,scripts用于生成指定的config.mk配置文件,还有支持GDB的调试工具等u-boot的配置编译需要经过以下步骤:1、在u-boot的根目录下执行:#make unsp210_config //对应开发板配置Makefile 会构建编译结构,如:架构、cpu、开发板、厂商、芯片、目录等,为下一步真正编译链接做准备。
u-boot启动分析
ldr r1, [r0]
orr r1, r1, #0x300
orr r1, r1, #0x0
str r1, [r0]
/***********************************************************/
-> rcode = (cmdtp->cmd)(cmdtp, flag,child->argc-i,&child->argv[i]); (common/hush.c 1710行)
2.关闭中断:
u-boot/cpu/s5pc11x/start.S (141行)
3.初始化系统时钟:
u-boot/board/samsung/unsp210/lowlevel_init.S (122行)
u-boot/board/samsung/unsp210/lowlevel_init.S (209行)
u-boot 第一阶段:
涉及两个文件:(1).u-boot/cpu/s5pc11x/start.S (2).u-boot/board/samsung/unsp210/lowlevel_init.S
根据PPT内容进行跟踪u-boot源码:
1.禁用看门狗:
u-boot/board/samsung/unsp210/lowlevel_init.S (61行)
u-boot/cpu/s5pc11x/movi.c (19行)
9.初始化堆栈:
u-boot/cpu/s5pc11x/start.S (389行)
清除bss段:
u-boot/cpu/s5pc11x/入第二阶段
u-boot启动分析
背景:Board →ar7240(ap93)Cpu →mips1、首先弄清楚什么是u-bootUboot是德国DENX小组的开发,它用于多种嵌入式CPU的bootloader程序, uboot不仅支持嵌入式linux系统的引导,当前,它还支持其他的很多嵌入式操作系统。
除了PowerPC系列,还支持MIPS,x86,ARM,NIOS,XScale。
2、下载完uboot后解压,在根目录下,有如下重要的信息(目录或者文件):以下为为每个目录的说明: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。
U-boot命令分析报告
Uboot命令的解释及添加方法Baods2012.03.22一、分析uboot命令的执行过程在uboot启动的第二段代码start_armboot函数最后面会进入死循环,在这个死循环中调用main_loop函数,其中main_loop函数在common/main.c中定义在这里面查看是否设置环境变量参数,如果设置了则看串口在bootdelay秒内有没有输入,若没有则执行bootcmd命令/****************************************************************************/ void main_loop(void){......#if defined(CONFIG_BOOTDELAY)&&(CONFIG_BOOTDELAY>=0)char*s;int bootdelay;#endif....../**在这里获得环境变量参数bootdelay,如果环境变量中有定义,则将值赋给bootdelay,*没有则赋值给CONFIG_BOOTDELAY.*/#if defined(CONFIG_BOOTDELAY)&&(CONFIG_BOOTDELAY>=0)s=getenv("bootdelay");bootdelay=s?(int)simple_strtol(s,NULL,10):CONFIG_BOOTDELAY;debug("###main_loop entered:bootdelay=%d\n\n",bootdelay);......s=getenv("bootcmd");获取bootcmddebug("###main_loop:bootcmd=\"%s\"\n",s?s:"<UNDEFINED>");if(bootdelay>=0&&s&&!abortboot(bootdelay)){run_command(s,0);/*执行bootcmd中的命令*/....../*Main Loop for Monitor Command Processing*/#ifdef CFG_HUSH_PARSERparse_file_outer();/*This point is never reached*/for(;;);#elsefor(;;){len=readline(CFG_PROMPT);/*首先显示CFG_PROMPT定义的字符串"U-boot>"然后等待键盘输入....之后对一些特别字符进行处理,对于正常字符将存放到console_buffer中*/flag=0;/*assume no special flags for now*/if(len>0)strcpy(lastcommand,console_buffer);else if(len==0)flag|=CMD_FLAG_REPEAT;#ifdef CONFIG_BOOT_RETRY_TIMEelse if(len==-2){/*返回值等于-2则timeout*/puts("\nTimed out waiting for command\n");#ifdef CONFIG_RESET_TO_RETRY/*Reinit board to run initialization code again*/do_reset(NULL,0,0,NULL);#elsereturn;/*retry autoboot*/#endif}#endifif(len==-1)/*返回值等于-1则break*/puts("<INTERRUPT>\n");elserc=run_command(lastcommand,flag);读取到命令后交给run_command处理if(rc<=0){/*invalid command or not repeatable,forget it*/lastcommand[0]=0;}}#endif/*CFG_HUSH_PARSER*/}接下来看看run_command函数做了什么工作?int run_command(const char*cmd,int flag){cmd_tbl_t*cmdtp;char cmdbuf[CFG_CBSIZE];/*working copy of cmd*/char*str=cmdbuf;......clear_ctrlc();/*forget any previous Control C*/if(strlen(cmd)>=CFG_CBSIZE){/*判断输入的命令是否太长*/ puts("##Command too long!\n");return-1;}strcpy(cmdbuf,cmd);/*复制命令到cmdbuf*//*Process separators and check for invalid repeatable commands*/ while(*str){/*char*str=cmdbuf*//**Find separator,or string end*Allow simple escape of';'by writing"\;"*/for(inquotes=0,sep=str;*sep;sep++){if((*sep=='\'')&&(*(sep-1)!='\\'))inquotes=!inquotes;if(!inquotes&&(*sep==';')&&/*separator*/(sep!=str)&&/*past string start*/(*(sep-1)!='\\'))/*and NOT escaped*/break;}/*Limit the token to data between separators*/token=str;if(*sep){str=sep+1;/*start of command for next pass*/*sep='\0';}elsestr=sep;/*no more commands for next pass*//*find macros in this token and replace them*/process_macros(token,finaltoken);/*Extract arguments*/if((argc=parse_line(finaltoken,argv))==0){rc=-1;/*no command at all*/continue;}/*这里调用到了find_cmd函数,查找命令表、进入一个命令*/if((cmdtp=find_cmd(argv[0]))==NULL){printf("Unknown command'%s'-try'help'\n",argv[0]);rc=-1;/*give up after bad command*/continue;}if(argc>cmdtp->maxargs){/*检查最大的参数变量*/printf("Usage:\n%s\n",cmdtp->usage);rc=-1;continue;}#if(CONFIG_COMMANDS&CFG_CMD_BOOTD)/*avoid"bootd"recursion*/if(cmdtp->cmd==do_bootd){#ifdef DEBUG_PARSERprintf("[%s]\n",finaltoken);#endifif(flag&CMD_FLAG_BOOTD){puts("'bootd'recursion detected\n");rc=-1;continue;}else{flag|=CMD_FLAG_BOOTD;}}#endif/*CFG_CMD_BOOTD*//*OK接下来调用cmd_tbl_t结构体中注册的cmd函数*/if((cmdtp->cmd)(cmdtp,flag,argc,argv)!=0){rc=-1;}repeatable&=cmdtp->repeatable;/*Did the user stop this?*/if(had_ctrlc())return0;/*if stopped then not repeatable*/}return rc?rc:repeatable;}从上面的分析知道XXX命令的执行过程如下:1.在U-Boot中输入“XXX”命令执行时,U-Boot接收输入的字符串“XXX”,然后传递给run_command函数;2.run_command函数调用find_cmd函数在__u_boot_cmd_start与__u_boot_cmd_end间查找命令,并返回“XXX”命令的cmd_tbl_t结构;3.run_command函数使用返回的cmd_tbl_t结构中的函数指针调用“XXX”命令的响应函数“do_XXX”,从而完成了命令的执行。
U-boot启动流程分析(三)
U-boot 启动流程(Linux 内核)的分析(三)U-boot 属于两阶段的Bootloader ,第一阶段的文件为cpu/arm920t/start.S 和board\samsung\smdk2410/lowlevel_init.S,前者是平台相关的,后者是开发板相关的。
1.U-Boot 第一阶段代码分析(1)硬件设备初始化依次完成如下设置:将CPU 的工作模式设为管理模式(SVC ),关闭WATCHDOG ,设置FCLK ,HCLK ,PCLK 的比例,关闭MMU ,CACHE 。
代码在cpu/arm920t/start.S 中,(2)为加载Bootloader 的第二阶段代码准备RAM 空间。
所谓准备RAM 空间,就是初始化内存芯片,使它可用,对于S3C24x0,通过在Start.S 中调用lowlevel_init 函数来设置存储控制器,使得外接 SDRAM 可用,lowlevel_init.S,文件是与开发板相关的,这表示如果外接的设备不一样,可以修改lowlevel_init.S 文件中的相关的宏。
(3)复制Bootloader 的第二阶段代码到RAM 空间中 这里将整个U-Boot 代码都复制到SDRAM 中,这在cpu/arm920t/start.s 中实现上面这段程序,在使用NANDFlash 启动时,需要修改。
(4)设置好栈 /*栈的设置灵活性很大,只要让sp 寄存器指向一段没有使用的内存即可*/.word TEXT_BASE //这里是获得代码段的起始地址,我的是0x33F80000(在board/xxx/config.mk中//可到找到“TEXT_BASE=0x33F80000”.globl lowlevel_init //这里相当于定义一个全局的lowlevel_init以方便调用lowlevel_init :/* memory control configuration *//* make r0 relative the current location so that it *//* reads SMRDATA out of FLASH rather than memory ! */ldr r0, =SMRDATA //SMDATA表示这 13个寄存器的值存放的开始地址,值为0x33F8xxxx,处于内//存中,这一句的作用是把其值加载到r0中ldr r1, _TEXT_BASE // 把代码的起始地址(0x33F80000)加载到r1中sub r0, r0, r1 //r0减去r1其结果存入r0,也即SMDATA中的起始地址0x33F8xxxx减去//0x33F80000,其结果就是13个寄存器的值在NOR Flash存放的开始地址ldr r1, =BWSCON /* Bus Width Status Controller */ //存储控制器的基地址add r2, r0, #13*4 //在计算出来的存放地址加上#13*4,然后其结果保存在r2中//13 个寄存器,每个寄存器占4个字节0:ldr r3, [r0], #4 //内存中r0的值加载到r3中,然后r0加4,即下一个寄存器的str r3, [r1], #4 //读出寄存器的值保存到r1中,然后r1也偏移4cmp r2, r0 //比较r0与r2的值,如果不等继续返回0:执行,也即13个寄存器的值// 是否读完bne 0b/* everything is fine now */mov pc , lr //程序跳转,返回到cpu_init_crit中.ltorg/* the literal pools origin */SMRDATA :...................relocate : /* 将U-Boot复制到RAM中 */adr r0, _start /* r0:当前代码的开始地址 */ldr r1, _TEXT_BASE /* r1:代码段的连接地址*/cmp r0, r1 /* 测试现在是在FLash中,还在是RAM中,如果要从NandFlash启动的话,这里要根据需要修改 */beq stack_setup /*如果已经在RAM中,则不需要复制*/ldr r2, _armboot_start /*_armboot_start在前面定义,是第一条指令的运行地址*/ldr r3, _bss_start /*在连接脚本U-Boot.lds中定义,是代码段的结束地址*/sub r2, r3, r2 /* r2 <- 代码段长度 */add r2, r0, r2 /* r2 <-代码段的结束地址 */copy_loop :ldmia {r3-r10} /* 从地址[r0]处获得数据 */stmia {r3-r10} /* 复制到地址[r1]处 */cmp r0, r2 /* 判断是否复制完毕 */ble copy_loop /*没有复制完,则继续*/#endif /* CONFIG_SKIP_RELOCATE_UBOOT */ldr r0, _TEXT_BASE /* _TEXT_BASE 为代码段的开始地址,值为0x33F80000 */sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* 代码段下面,留出一段内存以实现malloc */sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* 再留出一段内存,存一些全局参数 */#ifdef CONFIG_USE_IRQsub r0, r0, #(CONFIG_STACKSIZE_IRQ +CONFIG_STACKSIZE_FIQ )#endifsub sp , r0, #12 /* 最后,留出12字节的内存给abort异常 */clear_bss :(5)跳转到第二阶段代码的C 入口点 在跳转之前,还要清除BSS 段(初始值0,无初始值的全局变量,静态变量放在BSS 段。
u-boot的分析
源码基于u-boot1.1.4版本。
先看board/smsk2410/u-boot.lds这个链接脚本,可以知道目标程序的各部分链接顺序。
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") /*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/ OUTPUT_ARCH(arm)ENTRY(_start)SECTIONS{. = 0x00000000; /*指定可执行image文件的全局入口点,通常这个地址都放在ROM(flash)0x0位置。
必须使编译器知道这个地址,通常都是修改此处来完成*/. = ALIGN(4);.text :{cpu/arm920t/start.o (.text)*(.text)}. = ALIGN(4);.rodata : { *(.rodata) }. = ALIGN(4);.data : { *(.data) }. = ALIGN(4);.got : { *(.got) }. = .;__u_boot_cmd_start = .;.u_boot_cmd : { *(.u_boot_cmd) }__u_boot_cmd_end = .;. = ALIGN(4);__bss_start = .;.bss : { *(.bss) }_end = .;}第一个要链接的是cpu/arm920t/start.o,那么U-Boot的入口指令一定位于这个程序中。
下面详细分析一下程序跳转和函数的调用关系以及函数实现。
1.Stage1:cpu/arm920t/start.S这个汇编程序是U-Boot的入口程序,开头就是复位向量的代码。
U-boot源代码全分析系列(基于PowerPC)
U-boot源代码全分析系列(基于PowerPC)一、概述U-Boot,全称Universal Boot Loader,是遵循GPL条款的开放源码项目,是从FADSROM、8xxROM、PPCBOOT逐步发展演化而来的。
其源码目录、编译形式与Linux内核很相似,事实上,不少U-Boot源码就是相应的Linux内核源程序的简化,尤其是一些设备的驱动程序,这从U-Boot源码的注释中能体现这一点。
但是U-Boot不仅仅支持嵌入式Linux系统的引导,当前,它还支持NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS嵌入式操作系统。
其目前要支持的目标操作系统是OpenBSD, NetBSD, FreeBSD,4.4BSD, Linux, SVR4, Esix, Solaris, Irix, SCO, Dell, NCR, VxWorks, LynxOS, pSOS, QNX, RTEMS, ARTOS。
这是U-Boot中Universal的一层含义,另外一层含义则是U-Boot除了支持PowerPC系列的处理器外,还能支持MIPS、x86、ARM、NIOS、XScale等诸多常用系列的处理器。
这两个特点正是U-Boot项目的开发目标,即支持尽可能多的嵌入式处理器和嵌入式操作系统。
就目前来看,U-Boot对PowerPC系列处理器支持最为丰富,对Linux的支持最完善。
其它系列的处理器和操作系统基本是在2002年11 月PPCBOOT改名为U-Boot后逐步扩充的。
从PPCBOOT向U-Boot的顺利过渡,很大程度上归功于U-Boot的维护人德国DENX软件工程中心Wolfgang Denk[以下简称W.D]本人精湛专业水平和持着不懈的努力。
当前,U-Boot项目正在他的领军之下,众多有志于开放源码BOOT LOADER移植工作的嵌入式开发人员正如火如荼地将各个不同系列嵌入式处理器的移植工作不断展开和深入,以支持更多的嵌入式操作系统的装载与引导。
U-Boot启动分析
U-Boot启动流程(Linux内核)的分析(一)前面一段时间一直在移植U-Boot,Linux内核和构建根文件系统,其中有些地方还不是很明白,现在回过头来,理解一下U-boot的启动流程,以及u-Boot是如何加载引导内核启动的。
这里的分析也都是以U-Boot-2009.08版本为基础的,可能会和以前的版本有所不同。
在这里也不打算一句句分析U-Boot的源码,只是想把U-Boot一步一步怎么最终能够加载Linux内核的过程,分析一下。
首先,我们应该理解Bootloader是什么?它有什么作用?其实它就是系统上电后运行的和小段程序。
1 BootLoader的概念在系统上电后,需要一段程序来进行初始化:关闭WATCHDOG,改变系统时钟,初始化存储控制器,将更多的代码复制到内存中。
并将操作系统内核复制到内存中运行,这就段程序代码就叫做Bootloader。
没有一个Bootloader完全支持所有CPU,所以我们要想使用Bootloaser 一般情况下要自己进行修改,我们可以增强Bootloader的功能,让它具有网络功能,可以通过NFS远程下载Linux内核和根文件系统,可以烧写Linux内核和根文件系统到NandFlash中,而这些功能对于最终的用户来说是没有什么意义的,它们看到的只是Bootloader引导Linux内核启动这一个功能,而其余的功能只对开发人员很有用处。
也就是说在开发期间这些功能是必不可少的。
(1)启动加载模式:这种模式也称为“自主”模式。
也就是Bootloader从目标机上的某个固态存储设备上将操作系统加载到RAM中运行,整个过程并没有用户的介入,这种模式是在嵌入式产品发布里的通用模式。
(2)下载模式:在这种模式下,目标机上的Bootloader将通过串口连接或网络连接等通信手段从主机下载文件,例如:下载内核映像和根文件系统映像等。
从主机下载的文件通常首先被Bootloader保存到目标机的RAM中,然后再被Bootloader写到目标上的Flash类的固态存储设备中,Bootloader的这种模式是在在开发时使用的工作于这种模式的Bootloader通常都会向它的终端用户提供一个简单的命令行接口。
U-boot的启动过程分析
U-boot的启动过程分析可执行文件及内存映射我们可以把可执行文件分为2种情况:存放态和运行态1.存放态:可执行文件经过烧到存储介质上(flash或磁盘)的分布,此时可执行文件通常有2部分组成,代码段和数据段,代码段又分为可执行代码段(.text)和只读数据段(.rodata),数据段可以分为初始化数据段(.data)和未初始化代码段(.bss),如下:+-------------+-----------|.bss|(ZI)+-------------+--数据段|.data|(RW)+-------------+-----------|.rodata||_____________|代码段(RO)|.text|+-------------+-----------2.运行态:可执行文件经过装载后就变成为运行态,当可执行文件装载后,在RAM中的分布如下:|...|+-------------+--ZI段结束地址|ZI段|+-------------+--ZI段起始地址|保留区2|+-------------+--RW段结束地址|RW段|+-------------+--RW段起始地址|保留区1|+-------------+--RO段结束地址|RO段|+-------------+--RO段起始地址所以装载过程必须完成把可执行文件的各个段搬移到RAM的指定位置,这个装载过程则是由启动程序来完成的。
而可执行代码在RAM中的地址则是由链接脚本来指定的。
一个可执行的image必须有一个入口点,并且只能有一个全局入口点,所以要通知编译器这个入口在哪里。
这个是有链接脚本来实现的,由此我们可以找到程序的入口点是在/board/lpc2210/u-boot.lds中指定的,其中ENTRY(_start)说明程序从_start开始运行,而他指向的是cpu/arm7tdmi/start.o文件。
因为我们用的是ARM7TDMI的cpu架构,在复位后从地址0x00000000取它的第一条指令,所以我们将Flash映射到这个地址上,这样在系统加电后,cpu将首先执行u-boot程序。
u-boot源码分析
[在此处输入文章标题]U-Boot启动内核的过程可以分为两个阶段,两个阶段的功能如下:(1)第一阶段的功能硬件设备初始化加载U-Boot第二阶段代码到RAM空间设置好栈跳转到第二阶段代码入口(2)第二阶段的功能初始化本阶段使用的硬件设备检测系统内存映射将内核从Flash读取到RAM中为内核设置启动参数调用内核1.1.1U-Boot启动第一阶段代码分析第一阶段对应的文件是cpu/arm920t/start.S和board/samsung/mini2440/lowlevel_init.S。
U-Boot启动第一阶段流程如下:图 2.1 U-Boot启动第一阶段流程(先列出u-boot在ARM 处理器启动中的几个关键点:系统上电:_start标号 cpu/arm920t/start.Scpu/arm920t/start.S标号 cpu/arm920t/start.S标号 board/smdk2410/low_level_init.S标号cpu/arm920t/start.S_start_arm_boot标号cpu/arm920t/start.S函数lib_arm/board.c函数common/main.c命令行㈠Start.S是u-boot整个程序的入口,该文件使用汇编语言编写,不同体系结构的启动代码是不同的;low_level_init.S是特定开发板的设置代码;board.S包含开发板底层设备驱动;main.C是一个与平台无关的代码,u-boot应用程序的入口在此文件中。
)根据caojing/u-boot-1.1.6/board/TX2440/u-boot.lds中指定的连接方式:OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/OUTPUT_ARCH(arm)ENTRY(_start)SECTIONS{. = 0x00000000;. = ALIGN(4);.text :{cpu/arm920t/start.o (.text)board/TX2440/lowlevel_init.o (.text) board/TX2440/nand_read.o (.text)*(.text)}. = ALIGN(4);.rodata : { *(.rodata) }. = ALIGN(4);.data : { *(.data) }. = ALIGN(4);.got : { *(.got) }. = .;__u_boot_cmd_start = .;.u_boot_cmd : { *(.u_boot_cmd) }__u_boot_cmd_end = .;. = ALIGN(4);__bss_start = .;.bss : { *(.bss) }_end = .;} 第一个链接的是cpu/arm920t/start.o,因此u-boot.bin的入口代码在cpu/arm920t/start.o中,其源代码在cpu/arm920t/start.S中。
实验报告-U-Boot的分析与移植
实验报告--------- U-Boot的分析与移植实验目的●了解嵌入式开发的基本思想和过程●深入理解BootLoader,通过分析一款具体的BootLoader -- U-boot ,掌握BootLoader的作用,及其运行过程。
实验内容●本次实验具体分析uboot中基于arm9 系列为内核的开发板的bootloader的相关代码;●分析在uboot中,bootloader怎么与linux内核进行交互;●搭建交叉编译环境,将bootloader编译成在开发平台上能用的二进制文件,并将其烧入flash中,为做下一步实验进行准备。
实验设备及工具●硬件:ARM 嵌入式开发平台、PC 机Pentium100 以上、用于ARM920T 的JTAG 仿真器、串口线。
●软件:PC 机操作系统Win2000 或WinXP、Linux 9 ,交叉编译环境,仿真器驱动程序、超级终端通讯程序,第一章实验板的基本了解1.1嵌入式开发平台本次实验的硬件平台是基于ARM体系结构,由北京博创兴业科技有限公司开发的UP-NetARM2410-S实验仪器。
UP-NetARM2410-S的CPU为ARM920T 内核的三星S3c2410芯片,有MMU可以运行标准的ARM-LINUX内核。
该硬件平台的基本架构如图1.1所示;在图1.1中,2410核心板的结构为:●CPU: ARM920T结构芯片:工作频率202MHz ,SAMSUNG公司的S3c2410X ●FLASH:64M NAND型,SAMSUNG的K9F1208●RAM:64MB SDRAM,HY57V561620AT-H●200管脚精密插座S3c2410X芯片集成了大量的功能单元,包括:1).内部1.8V,存储器3.3V,外部IO3.3V,16KB数据CACHE,16KB指令CACHE,MMU;2).内置外部存储器控制器(SDRAM 控制和芯片选择逻辑);3). LCD控制器(最高4K色 STN和256K彩色TFT),一个LCD专用DMA;4). 4路带外部请求线的DMA;5).三个通用异步串行端口(IrDA1.0, 16-Byte Tx FIFO, and 16-Byte Rx FIFO),2通道SPI;6).一个多主IIC总线,一个IIS总线控制器;7). SD主接口版本1.0和多媒体卡协议版本2.11兼容;8). 2个USB HOST ,一个USB DEVICE(VER1.1);9). 4个PWM定时器和一个内部定时器;10).看门狗定时器;11).117个通用IO;12).24个外部中断;13).电源控制模式:标准、慢速、休眠、掉电;14).8通道10位ADC和触摸屏接口;15).带日历功能的实时时钟;16).芯片内置PLL;图1.1 UP-NetARM2410-S的架构示意图17).设计用于手持设备和通用嵌入式系统;18).16/32位RISC体系结构,使用ARM920T CPU核的强大指令集;19).ARM带MMU的先进的体系结构支持WINCE、EPOC32、LINUX;20).指令缓存(cache)、数据缓存、写缓冲和物理地址TAG RAM,减小了对主存储器带宽和性能的影响;21).ARM920T CPU 核支持 ARM 调试的体系结构;22).内部先进的位控制器总线(AMBA2.0, AHB/APB) .图1.2 S3c2410X芯片1.2嵌入式Linux 开发流程嵌入式Linux 开发,根据应用需求的不同有不同的配置开发方法,但是一般都要经过以下过程:1.建立开发环境操作系统一般使用REDHAT-LINUX,版本7 到9 都可以,选择定制安装或全部安装,通过网络下载相应的GCC 交叉编译器进行安装(比如arm-linux-gcc、arm-uclibc-gcc),或者安装产品厂家提供的交叉编译器。
u-boot启动分析
u-boot启动分析一、reset标签############################################# ######################################## reset:mtc0 zero, CP0_WATCHLOmtc0 zero, CP0_WATCHHI############################################# ######################################## 把CP0的WATCHLO和WATCHHI寄存器清0,这两个寄存器能够确定一个物理地址,每次读数据或者写数据时,都与这个地址进行比较,如果地址匹配,则发生一个陷阱异常。
############################################# ######################################## #ifdef CONFIG_ClxRISC/** CU0=UM=EXL=IE=0, BEV=ERL=1, IP2~7=1*/li t0, 0x0040fc04li t0, 0x00400004mtc0 t0, CP0_STATUS#else#ifdef CONFIG_TB0229li k0, ST0_CU0#elsemfc0 k0, CP0_STATUS#endifli k1, ~ST0_IEand k0, k1mtc0 k0, CP0_STATUS#endif############################################# ########################################设置CP0的STATUS寄存器,由于分析的是CQ8401的代码,所以定义了CONFIG_ClxRISC 宏(include/configs/mingddie.h)。
u-boot实现原理完全分析
U-BOOT作者:***邮箱:***************博客:/目录一U-BOOT目录结构 (1)二U-BOOT的启动与内核引导 (3)1、U-BOOT的启动分析 (3)1.1设置异常向量表 (3)1.2 U-BOOT的存储映射 (4)1.3 硬件设备的初始化 (5)1.4 硬件平台前期初始化 (9)1.5代码重定位 (13)1.6 硬件平台后期初始化 (16)2、内核引导 (20)2.1 u-boot命令实现原理 (20)2.2内核引导 (24)三U-BOOT编译流程分析 (35)1、U-BOOT编译命令 (35)2、U-BOOT配置流程 (35)2.1环境初始化 (35)2.2 make smdk2410_config命令的执行过程 (38)2.3 make smdk2410命令的执行过程 (42)2.4 U-BOOT的编译流程 (43)U-BOOT原理分析一U-BOOT目录结构apiapi目录对应于一些扩展应用的独立的apiarcharch存放与CPU架构有关的目录,下面每一个目录就代表一种架构的CPUboardboard目录是与硬件平台相关的目录,特定于某种硬件平台的文件以子目录的形式存放在该目录下commoncommon目录存放了u-boot所支持的所有命令diskdisk目录存放了磁盘驱动和相关的代码docdoc目录存放了u-boot的参考文档driversu-boot支持的所有驱动都存放在driver目录下,这些驱动大都根据linux驱动改写而来dtsdts目录包含一个平台设备树相关的makefile,可编译生成设备树镜像文件examplesexample下时一些在u-boot上运行的事例程序fsfs目录下是u-boot所支持的文件系统includeinclude目录包含了u-boot的头文件以及各种硬件平台的系统配置文件liblib目录下是u-boot的库文件nand_spl支持从nand flash启动的相关代码netu-boot的网络子系统onenand_ipl支持从onenand 启动的代码postPost下是支持上电自检功能的目录spl与nand_spl相关的makefile,编译支持从nand flash启动的u-boot二进制文件toolstools目录下是u-boot的一些辅助工具,比如生成u-boot镜像文件等二U-BOOT的启动与内核引导1、U-BOOT的启动分析u-boot支持多种架构类型的cpu,支持多种硬件平台,本文以smdk2410为例来讲解u-boot 的功能原理。
8 u-boot程序分析
阶段二详细分析
board_init_f()
A.gd_t数据结构空间分配 B.回调一组初始化函数 C.对gd_t数据结构进行初始化 D.relocate_code(U-Boot重定义代码,即自搬移)
阶段二详细分析
阶段二详细分析
board_init_r()详细分析
简化board_init_r()函数后,如下:
u-boot是通过命令来操作的,等待用户输入命 令,然后执行命令
cmd_tbl_t命令的执行分析 类型的定义如下
run_command()函数是查找并执行用户输入的命 令,分析器代码如下:
•解析用户输入的字符串; •经过解释后,用户输入的命令 以及命令后面的参数分割成独立 的字符串,并保存在argv数组中 •argc是命令+参数的个数 以命令名字查找对应的cmd_tbl_t结构体; cmdtp指向命令对应的该结构体; 通过指针cmdtp,执行命令对应的函数 cmdtp->cmd();
阶段一源码分析
load_uboot
根据不同启动设备,调用对应启动函数
阶段一源码分析
load_uboot
根据不同启动设备,调用对应启动函数
阶段一源码分析
把uboot代码从启动设备拷贝内存,跳转到 after_copy,在内存中执行
阶段一源码分析
after_copy
主要工作是点亮LED,保存启动信息,调board_init_f
教学要求
熟悉u-boot的代码 理解u-boot源码的两个阶段主要完成的工作 理解用户输入命令后u-boot执行的流程 掌握向u-boot添加自定义命令的方法
u-boot的启动流程
分析u-boot的链接脚本 (board/samsung/tiny4412/u-boot.lds)可以知道, u-boot的入口是start.S start.S(arch/arm/cpu/armv7/start.S)
U-Boot启动过程--详细版的完全分析
(一)U—Boot启动过程-—详细版的完全分析我们知道,bootloader是系统上电后最初加载运行的代码.它提供了处理器上电复位后最开始需要执行的初始化代码。
在PC机上引导程序一般由BIOS开始执行,然后读取硬盘中位于MBR(Main Boot Record,主引导记录)中的Bootloader(例如LILO或GRUB),并进一步引导操作系统的启动。
然而在嵌入式系统中通常没有像BIOS那样的固件程序,因此整个系统的加载启动就完全由bootloader来完成.它主要的功能是加载与引导内核映像一个嵌入式的存储设备通过通常包括四个分区:第一分区:存放的当然是u-boot第二个分区:存放着u-boot要传给系统内核的参数第三个分区:是系统内核(kernel)第四个分区:则是根文件系统如下图所示:u—boot是一种普遍用于嵌入式系统中的Bootloader。
Bootloader介绍Bootloader是进行嵌入式开发必然会接触的一个概念,它是嵌入式学院<嵌入式工程师职业培训班〉二期课程中嵌入式linux系统开发方面的重要内容。
本篇文章主要讲解Bootloader的基本概念以及内部原理,这部分内容的掌握将对嵌入式linux系统开发的学习非常有帮助!Bootloader的定义:Bootloader是在操作系统运行之前执行的一小段程序,通过这一小段程序,我们可以初始化硬件设备、建立内存空间的映射表,从而建立适当的系统软硬件环境,为最终调用操作系统内核做好准备.意思就是说如果我们要想让一个操作系统在我们的板子上运转起来,我们就必须首先对我们的板子进行一些基本配置和初始化,然后才可以将操作系统引导进来运行。
具体在Bootloader中完成了哪些操作我们会在后面分析到,这里我们先来回忆一下PC的体系结构:PC机中的引导加载程序是由BIOS和位于硬盘MBR 中的OS Boot Loader(比如LILO和GRUB等)一起组成的,BIOS在完成硬件检测和资源分配后,将硬盘MBR 中的Boot Loader读到系统的RAM中,然后将控制权交给OS Boot Loader。
6.Uboot启动分析
6.Uboot启动分析展开全文6. Uboot启动分析6.1. 硬件引导通常在上电后,一旦CPU电源稳定期结束,它则开始从某个固定的地址(通常为FLASH的0地址)开始执行程序,为何方便代码的引导,一些CPU支持多种方式/地址处的引导,比如设置跳线,可以选择NOR Flash,或者NAND FLASH等。
S3C6410就是这样一款功能强大的CPU。
S3C6410 具备了一个内部SRAM缓冲器,大小为8K,叫做“STEPPINGSTONE”,如果跳线设置为从Nand Flash启动,则当系统启动时,Nand Flash存储器的前4KB 将被自动载入到STEPPINGSTONE中,然后系统自动执行这些载入的引导代码。
而Nand Flash的开始就是放置的U-boot的镜像。
对于S3C6410来说,起始代码位于:cpu/s3c64xx/start.S.globl _start /* uboot启动入口*/_start: b reset /* 复位向量*/ldr pc, _undefined_instructionldr pc, _software_interruptldr pc, _prefetch_abortldr pc, _data_abortldr pc, _not_usedldr pc, _irq /* 中断向量 */ldr pc, _fiq /* 中断向量 */......第一跳指令就是复位:/* 系统上电或reset后,cpu的PC一般都指向0x0地址,在0x0地址上的指令是 */reset:/** set the cpu to SVC32 mode*/mrs r0, cpsr/**把CPSR内容存入r0.使用了mrs指令:专用寄存器到通过寄存器的存取.*CPSR当前程序状态寄存器格式如下:** 31 30 29 28 27 26 25 24 ~ ~ ~ 8 7 6 5 4 3 2 1 0*___ ___ ___ ___ ___ ___ ___ ___ _ _ _ _ ___ ___ ___ ____ ____ ____ ____ ____*| N | Z | C | V | * | * | * | * | * * * | I | F | T | M4 | M3 | M2 | M1 | M0 |**//* bic指令(bit clear): r0:= r0 and (not op2).上边的指令目的是把bit0~bit4清零.*/bic r0,r0,#0x1forr r0,r0,#0xd3/* r0:= r0 or 0xd3 . 以上三条指令执行后r0值为:**** **** **** **** **** ***** 11*1 0011 */msr cpsr,r0msr把r0存于cpsr.注意:msr指令是专用的通用寄存器到特殊功能寄存器的指令与mrs对应说明:通过上边的指令可以看到,实现了两个功能.1,disable 外部中断(IRQ)与快速中断(FIR).2,把系统设为SVC32状态(超级保护)即M4~M1=10011。
U Boot编译过程完全分析
U Boot编译过程完全分析u-boot编译过程完全分析2.1u-bootmakefile分析2.1.1u-boot编程命令对于mini2440开发板,编译u-boot需要执行如下的命令:$makemini2440_config$makeall使用上面的命令编译u-boot,编译生成的所有文件都保存在源代码目录中。
为了保持源代码目录的干净,可以使用如下命令将编程分解成的文件输入至一个外部目录,而不是在源代码目录中,下面的2种方法都将编程分解成的文件输入至/tmp/build目录:$exportbuild_dir=/tmp/build$makemini2440_config$makeall或$makeo=/tmp/buildmini2440_config(特别注意就是字母o,而不是数字0)$makeall为了简化分析过程,方便读者理解,这里主要针对第一种编译方式(目标输出到源代码所在目录)进行分析。
2.1.2u-boot布局、编程、相连接过程u-boot开头有一些跟主机软硬件环境相关的代码,在每次执行make命令时这些代码都被执行一次。
1.u-boot布局过程(1)定义主机系统架构hostarch:=$(shelluname-m|\\sed-es/i.86/i386/\\-es/sun4u/sparc64/\\-es/arm.*/arm/\\-es/sa110/arm/\\-es/powerpc/ppc/\\-es/ppc64/ppc/\\-es/macppc/ppc/)“sedce”则表示后面跟的就是一串命令脚本,而表达式“s/abc/def/”则表示必须从标准输出中,搜寻至内容为“abc”的,然后替换成“def”。
其中“abc”表达式用可以使用“.”作为通配符。
命令“unamecm”将输入主机cpu的体系架构类型。
作者的电脑采用intelcore2系列的cpu,因此“unamecm”输入“i686”。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
U-Boot的配置 Boot的配置
U-Boot的配置文件位于\include\configs\<开发板名> Boot的配置文件位于\include\configs\ 开发板名> 的配置文件位于 它是U Boot移植中经常需要修改的文件, 移植中经常需要修改的文件 它是U-Boot移植中经常需要修改的文件,可以根据开发 板的要求来修改相关配置 对于MCF52277是在\include\configs\ MCF52277是在 对于MCF52277是在\include\configs\M52277EVB CONFIG_”开头的是配置 开头的是配置选项 以“CONFIG_ 开头的是配置选项 CFG_”开头的是配置设置, 具体硬件相关 开头的是配置设置 以“CFG_ 开头的是配置设置,与具体硬件相关 例如:#define CONFIG_CMD_I2C 是添加I2C I2C支持选项 例如:#define CONFIG_Ce CFG_SDRAM_BASE 0x40000000 是设置 SDRAMD的基地址 SDRAMD的基地址
U-Boot主要目录结构 Boot主要目录结构
目标板相关文件,主要包含SDRAM、FLASH驱动; 驱动; board 目标板相关文件,主要包含 、 驱动 独立于处理器体系结构的通用代码, common 独立于处理器体系结构的通用代码,如内存大小探测与故障检 测; cpu 与处理器相关的文件。如mpc8xx子目录下含串口、网口、LCD驱动 与处理器相关的文件。 mpc8xx子目录下含串口、网口、LCD驱动 子目录下含串口 及中断初始化等文件; 及中断初始化等文件; 通用设备驱动, 驱动; drivers 通用设备驱动,如CFI、FLASH驱动; 、 驱动 说明文档; doc 说明文档; examples示例程序 示例程序, examples示例程序,如hello_world.c、timer.c; 、 ; include U-Boot头文件(尤其configs子目录下与目标板相关的配置头文 Boot头文件(尤其configs子目录下与目标板相关的配置头文 头文件 configs 件是移植过程中经常要修改的文件); 件是移植过程中经常要修改的文件); 处理器体系相关的文件, lib_arm目录分别包含与 lib_xxx 处理器体系相关的文件,如lib_ppc, lib_arm目录分别包含与 PowerPC、ARM体系结构相关的文件; 体系结构相关的文件; 、 体系结构相关的文件 与网络功能相关的文件目录, bootp、nfs、tftp; net 与网络功能相关的文件目录,如bootp、nfs、tftp; post 上电自检文件目录。尚有待于进一步完善; 上电自检文件目录。尚有待于进一步完善; 用于创建U-Boot S-RECORD和BIN镜像文件的工具; 镜像文件的工具; tools 用于创建 和 镜像文件的工具
U-Boot分析 Boot分析
尉志刚 安徽大学 电子学院 2010.6
U-Boot简介 Boot简介
U-Boot ,全称Universal BootLoader,是由德国DENX小组的开 发,并遵循GPL条款的开放源码项目。 Bootloader,对于计算机系统来说,从开机上电到操作系统启动需 要一个引导过程。嵌入式Linux系统同样离不开引导程序,这个引 导程序就叫作Bootloader。 Bootloader是在操作系统运行之前执行的一段小程序。 它的主要 功能是引导操作系统启动.通过这段小程序,我们可以初始化硬件 设备、建立内存空间的映射表,从而建立适当的系统软硬件环境 ,为最终调用操作系统内核做好准备。 U-Boot的主要功能是完成硬件设备的初始化、操作系统代码的搬 运,并提供一个控制台及一个命令集在操作系统运行前操控硬件 设备。
1.cpu\mcf5227x\start.s启动分析 1.cpu\mcf5227x\start.s启动分析 cpu
它的启动流程图如下: 它的启动流程图如下:
禁止中断 设置向量基址寄存器 初始化通用内部ram 为C代码获取堆栈空间 跳转到cpu_init_f 跳转到board_init_f 搬运u-boot代码到RAM 清堆栈段,跳转到board_init_r
board_init_f
board_init_f位于\lib_m68k\ board_init_f位于\lib_m68k\board.c 位于
/********************************************** This is the first part of the initialization sequence that is implemented in C, but still running from ROM. The main purpose is to provide a (serial) console interface as soon as possible (so we can see any error messages), and to initialize the RAM so that we can relocate the monitor code to RAM **********************************************/
Bootloader的启动 Bootloader的启动
系统加电或复位后,所有的CPU通常都从某个由CPU 制造商预先安排的地址上取指令。 而基于CPU构建的嵌入式系统通常都有某种类型的固 态存储设备(比如ROM、EEPROM或Flash等)被映射 到这个预先安排的地址上。 因此在系统加电后,CPU将首先执行Bootloader程序 。
Bootloader的启动过程 Bootloader的启动过程
Bootloader的 Bootloader的stage2:stage2的代码通常用C语言来实现,目的
是实现更复杂的功能和取得更好的代码可读性和可移植性。
在stage2中Bootloader主要完成以下工作: stage2中Bootloader主要完成以下工作: 主要完成以下工作
Bootloader的启动过程 Bootloader的启动过程
Bootloader启动过程分为两个部分: Bootloader的stage1: Bootloader的stage1
基本的硬件初始化,包括屏蔽所有的中断、设置CPU的 速度和时钟频率、RAM初始化、初始化外围设备、关闭 CPU内部指令和数据cache等。 为加载stage2准备RAM空间,通常为了获得更快的执行 速度,通常把stage2加载到RAM空间中来执行,因此必 须为加载Bootloader的stage2准备好一段可用的RAM空 间。 复制stage2到RAM中 设置堆栈指针sp,这是为执行stage2的C语言代码做好 准备。
U-Boot的特点 Boot的特点
开放源码,较高的可靠性和稳定性; 支持多种嵌入式操作系统内核,如Linux、VxWorks, LynxOS等; 支持多种处理器,如PowerPC、ARM、x86、MIPS、 XScale; 高度灵活的功能设置; 丰富的设备驱动源码,如串口、以太网、SDRAM、 FLASH、LCD等; 较为丰富的开发调试文档与强大的网络技术支持; 支持软件的自动更新。
board_init_r
位于\lib_m68k\ 位于\lib_m68k\board.c
This is the next part of the initialization sequence: we are now running from RAM and have a "normal" C environment
进入u boot主循环,并循环调用调用main_loop 进入u-boot主循环,并循环调用调用main_loop 主循环 Bootdelay到期后,会调用run_command函数, Bootdelay到期后,会调用run_command函数,自动执 到期后 run_command函数 bootcmd命令 行bootcmd命令 在run_command函数中调用函数指针cmdtp->cmd来启 run_command函数中调用函数指针cmdtp->cmd来启 函数中调用函数指针cmdtp do_bootm命令 动do_bootm命令 解析镜像的头部,需要解压的就调用解压缩函数解压, 解析镜像的头部,需要解压的就调用解压缩函数解压,就调 do_bootm_linux()去调用去加载linux系统镜像 去调用去加载linux 用do_bootm_linux()去调用去加载linux系统镜像 获取并设置Linux启动参数列表和机器号, 获取并设置Linux启动参数列表和机器号,最后调用函数指 Linux启动参数列表和机器号 针theKernel(0,machid,bd->bi_boot_params) theKernel(0,machid,bd-
配置方式
配置方式: 配置方式: #define #undef #ifdef/ #ifdef/#if defined #endif 这样我们就可以根据开发板的特定要求, 这样我们就可以根据开发板的特定要求,量身定做 备注: 如果对相关配置选项不了解,可以参考u-boot的 备注: 如果对相关配置选项不了解,可以参考u boot的 README文档 它也是学习u boot的入门文档 文档, README文档,它也是学习u-boot的入门文档
U-Boot支持的主要功能 Boot支持的主要功能
1)系统引导:支持NFS挂载,RAMDISK(压缩或非压缩) 形式的根文件系统;支持NFS挂载,从FLASH中引导压 缩或非压缩的内核; 2)基本辅助功能:强大的操作系统接口功能,可灵活设 置、传递多个关键参数给操作系统,适合系统在不同 开发阶段的调试要求与产品发布,尤其对Linux支持最 为功能强劲 支持目标板环境参数多种存储方式,如FLASH、 NVRAM、 EEPROM CRC32校验:可校验FLASH中内核、RAMDISK镜像文件 是否完好; 3)设备驱动:串口、SDRAM、FLASH、以太网、LCD、 EEPROM、键盘、USB、RTC等驱动支持; 4)上电自检功能: SDRAM、FLASH大小自动检测、 SDRAM故障检测、CPU型号;