您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 项目/工程管理 > Uboot启动和移植
Uboot启动和移植1.提纲bootloader综述u-boot介绍u-boot编译及配置u-boot启动过程及工作原理u-boot命令使用过程u-boot移植过程2.启动模式介绍大多数BootLoader都包含两种不同的操作模式:启动加载模式和下载模式,这种区别仅对于开发人员才有意义。但从最终用户的角度看,BootLoader的作用就是用来操作系统,而并不存在所谓的启动加载模式与下载工作模式的区别。启动加载(Bootloading)模式:这种模式也称为自主(Autonomous)模式。也即BootLoader从目标机上的某个固态存储设备上将操作系统加载到RAM中运行,整个过程并有用户的介入。这种模式是BootLoader的正常工作模式,因此在嵌入式产品发布的时侯,BootLoader显然必须工作在这种模式下。下载(Downloading)模式:在这种模式下,目标机上的BootLoader将通过串口连接或网络连接等通信手段从主机(Host)下载文件,比如:下载内核映像和根文件系统映像等。从主机下载的文件通常首先被BootLoader保存到目标机的RAM中,然后再被BootLoader写到目标机上的FLASH类固态存储设备中。BootLoader的这种模式通常在第一次安装内核与根文件系统时被使用;此外,以后的系统更新也会使用BootLoader的这种工作模式。工作于这种模式下的BootLoader通常都会向它的终端用户提供一个简单的命令行接口。UBoot这样功能强大的BootLoader同时支持这两种工作模式,而且允许用户在这两种工作模式之间进行切换。3.源码框架大多数bootloader都分为阶段1(stage1)和阶段2(stage2)两大部分,uboot也不例外。依赖于CPU体系结构的代码(如CPU初始化代码等)通常都放在阶段1中且通常用汇编语言实现,而阶段2则通常用C语言来实现,这样可以实现复杂的功能,而且有更好的可读性和移植性。3.1.阶段1(stage1)介绍Uboot的stage1代码通常放在start.s文件中,它用汇编语言写成,其主要代码部分如下:3.1.1.定义入口由于一个可执行的Image必须有一个入口点,并且只能有一个全局入口,通常这个入口放在ROM(Flash)的0x0地址,因此,必须通知编译器以使其知道这个入口,该工作可通过修改链接器脚本来完成。1、board/smdk2410/uboot.lds:ENTRY(_start)==cpu/arm920t/start.o(.text)2、uboot在ram的代码区(TEXT_BASE=0x33F80000)定义在board/smdk2410/config.mk3.1.2.设置异常向量.globl_start_start:bresetldrpc,_undefined_instructionldrpc,_software_interruptldrpc,_prefetch_abortldrpc,_data_abortldrpc,_not_usedldrpc,_irqldrpc,_fiq当异常发生时,执行cpu/arm920t/interrupts.c中定义的中断处理函数。3.1.3.设置CPU的模式为SVC模式mrsr0,cpsrbicr0,r0,#0x1forrr0,r0,#0xd3msrcpsr,r03.1.4.关闭看门狗,禁掉所有中断,设置CPU的频率#ifdefined(CONFIG_S3C2400)||defined(CONFIG_S3C2410)ldrr0,=pWTCONmovr1,#0x0strr1,[r0]/**maskallIRQsbysettingallbitsintheINTMR-default*/movr1,#0xffffffffldrr0,=INTMSKstrr1,[r0]#ifdefined(CONFIG_S3C2410)ldrr1,=0x3ffldrr0,=INTSUBMSKstrr1,[r0]#endif/*FCLK:HCLK:PCLK=1:2:4*//*defaultFCLKis120MHz!*/ldrr0,=CLKDIVNmovr1,#3strr1,[r0]#endif/*CONFIG_S3C2400||CONFIG_S3C2410*/3.1.5.与内存管理相关寄存器的设置,cp15协处理器,配置内存区控制寄存器cpu_init_crit:/**flushv4I/Dcaches*/movr0,#0mcrp15,0,r0,c7,c7,0/*失效I/Dcache,见S3C2410手册附录的2-16*/mcrp15,0,r0,c8,c7,0/*失效TLB,见S3C2410手册附录的2-18*//**disableMMUstuffandcaches*/mrcp15,0,r0,c1,c0,0bicr0,r0,#0x00002300/*清除bits13,9:8(--V---RS)*Bit8:DisableSystemProtection*Bit9:DisableROMProtection*Bit13:异常向量表基地址:0x00000000*/bicr0,r0,#0x00000087/*清除bits7,2:0(B----CAM)*Bit0:MMUdisabled*Bit1:AlignmentFaultcheckingdisabled*Bit2:Datacachedisabled*Bit7:0=Little-endianoperation*/orrr0,r0,#0x00000002@setbit2(A)Alignorrr0,r0,#0x00001000@setbit12(I)I-Cachemcrp15,0,r0,c1,c0,0/**beforerelocating,wehavetosetupRAMtiming*becausememorytimingisboard-dependend,youwill*findalowlevel_init.Sinyourboarddirectory.*/movip,lrbllowlevel_init/*寄存器的具体值的设置需要对总线周期及外围芯片非常熟悉,根据所采用的内存芯片确定*/movlr,ipmovpc,lr3.1.6.把u-boot.lds定义的text段,rodata段,data段,got段,__u_boot_cmd_start段搬移到ram区#ifndefCONFIG_SKIP_RELOCATE_UBOOTrelocate:/*relocateU-BoottoRAM*/adrr0,_start/*r0-currentpositionofcode*/ldrr1,_TEXT_BASE/*testifwerunfromflashorRAM*/cmpr0,r1/*don'trelocduringdebug*/beqstack_setupldrr2,_armboot_startldrr3,_bss_startsubr2,r3,r2/*r2-sizeofarmboot*/addr2,r0,r2/*r2-sourceendaddress*/copy_loop:ldmiar0!,{r3-r10}/*copyfromsourceaddress[r0]*/stmiar1!,{r3-r10}/*copytotargetaddress[r1]*/cmpr0,r2/*untilsourceendaddreee[r2]*/blecopy_loop#endif/*CONFIG_SKIP_RELOCATE_UBOOT*/3.1.7.建立stack空间/*Setupthestack*/stack_setup:ldrr0,_TEXT_BASE/*upper128KiB:relocateduboot*/subr0,r0,#CFG_MALLOC_LEN/*mallocarea*/subr0,r0,#CFG_GBL_DATA_SIZE/*bdinfo*/#ifdefCONFIG_USE_IRQsubr0,r0,#(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)#endifsubsp,r0,#12/*leave3wordsforabort-stack*/3.1.8.bss段清0clear_bss:ldrr0,_bss_start/*findstartofbsssegment*/ldrr1,_bss_end/*stophere*/movr2,#0x00000000/*clear*/clbss_l:strr2,[r0]/*clearloop...*/addr0,r0,#4cmpr0,r1bleclbss_l3.1.9.进入C代码部分ldrpc,_start_armboot_start_armboot:.wordstart_armboot3.2.阶段2(stage2)的C语言代码部分lib_arm/board.c中的start_armboot是C语言开始的函数,也就是整个启动代码中C语言的主函数,同时还是整个uboot(armboot)的主函数,该函数完成以下操作:3.2.1.调用一系列的初始化函数1、指定初始函数表:init_fnc_t*init_sequence[]={cpu_init,/*cpu的基本设置*/board_init,/*开发板的基本初始化*/interrupt_init,/*初始化中断*/env_init,/*初始化环境变量*/init_baudrate,/*初始化波特率*/serial_init,/*串口通讯初始化*/console_init_f,/*控制台初始化第一阶段*/display_banner,/*通知代码已经运行到该处*/dram_init,/*配置可用的内存区*/display_dram_config,#ifdefined(CONFIG_VCMA9)||defined(CONFIG_CMC_PU2)checkboard,#endifNULL,};执行初始化函数的代码如下:for(init_fnc_ptr=init_sequence;*init_fnc_ptr;++init_fnc_ptr){if((*init_fnc_ptr)()!=0){hang();}}2、配置可用的Flash区flash_init()3、初始化内存分配函数mem_malloc_init()4、Nandflash初始化#if(CONFIG_COMMANDS&CFG_CMD_NAND)puts(NAND:);nand_init();/*goinittheNAND*/#endif5、初始化环境变量env_relocate();6、外围设备初始化devices_init()7、I2C总线初始化i2c_init()8、LCD初始化drv_lcd_init()9、VIDEO初始化drv_keyboard_init()10、键盘初始化drv_keyboard_init()11、系统初始化drv_system_init()3.2.2.初始化网络设备初始化相关网络设备,填写IP、MAC地址等3.2.3.进入主uboot命令行进入命令循环(即整个boot的工作循环),接收用户从串口输入的命令,然后进行相应的工作。/*main_loop()canreturntoretryautoboot,ifsojustrunitagain.*/for(;;){main_loop();}4.U-boot命令使用说明4.1.命令配置4.2.命令帮助获取通过help可以获得当前开发板的UBOOT中支持的命令。#help?-aliasfor'help'autoscr-runscriptfrommemorybase-printorsetaddressoffsetbdinfo-printBoardInfostructureboot-bootdefault,i.e.,run'bootcmd'bootd-bootdefault,i
本文标题:Uboot启动和移植
链接地址:https://www.777doc.com/doc-2912388 .html