首页 uboot详解

uboot详解

举报
开通vip

uboot详解UBOOT详解大多数bootloader都分为stage1和stage2两部分,u-boot也不例外。依赖于CPU体系结构的代码(如设备初始化代码等)通常都放在stage1且可以用汇编语言来实现,而stage2则通常用C语言来实现,这样可以实现复杂的功能,而且有更好的可读性和移植性。1、Stage1start.S代码结构u-boot的stage1代码通常放在start.S文件中,他用汇编语言写成,其主要代码部分如下:(1)定义入口。由于一个可执行的Image必须有一个入口点,并且只能有一个全局入口,通常这个入口放在...

uboot详解
UBOOT详解大多数bootloader都分为stage1和stage2两部分,u-boot也不例外。依赖于CPU体系结构的代码(如设备初始化代码等)通常都放在stage1且可以用汇编语言来实现,而stage2则通常用C语言来实现,这样可以实现复杂的功能,而且有更好的可读性和移植性。1、Stage1start.S代码结构u-boot的stage1代码通常放在start.S文件中,他用汇编语言写成,其主要代码部分如下:(1)定义入口。由于一个可执行的Image必须有一个入口点,并且只能有一个全局入口,通常这个入口放在ROM(Flash)的0x0地址,因此,必须通知编译器以使其知道这个入口,该工作可通过修改连接器脚本来完成。(2)设置异常向量(ExceptionVector)。(3)设置CPU的速度、时钟频率及终端控制寄存器。(4)初始化内存控制器。(5)将ROM中的程序复制到RAM中。(6)初始化堆栈。(7)转到RAM中执行,该工作可使用指令ldrpc来完成。2、Stage2C语言代码部分lib_arm/board.c中的startarmboot是C语言开始的函数也是整个启动代码中C语言的主函数,同时还是整个u-boot(armboot)的主函数,该函数只要完成如下操作:(1)调用一系列的初始化函数。(2)初始化Flash设备。(3)初始化系统内存分配函数。(4)如果目标系统拥有NAND设备,则初始化NAND设备。(5)如果目标系统有显示设备,则初始化该类设备。(6)初始化相关网络设备,填写IP、MAC地址等。(7)进去命令循环(即整个boot的工作循环),接受用户从串口输入的命令,然后进行相应的工作。3、U-Boot的启动顺序(示例,其他u-boot版本类似)cpu/arm920t/start.S/****************************************************************************Jumpvectortableasintable3.1in[1]***************************************************************************/;定义变量_start,然后跳转到处理器复位代码.globl_start//u-boot启动入口_start:breset;产生中断则利用pc来跳转到对应的中断处理程序中ldrpc,_undefined_instructionldrpc,_software_interruptldrpc,_prefetch_abortldrpc,_data_abortAdministrator铅笔Administrator铅笔Administrator铅笔ldrpc,_not_usedldrpc,_irq//中断向量ldrpc,_fiq//快速中断向量;利用.word来在当前位置放置一个值,这个值实际上就用对应的中断处理函数的地址;.word的意义为在当前地址处放入一个16bits值_undefined_instruction:.wordundefined_instruction_software_interrupt:.wordsoftware_interrupt_prefetch_abort:.wordprefetch_abort_data_abort:.worddata_abort_not_used:.wordnot_used_irq:.wordirq_fiq:.wordfiq.balignl16,0xdeadbeef/****************************************************************************StartupCode(resetvector)**doimportantinitonlyifwedon'tstartfrommemory!*relocatearmboottoram*setupstack*jumptosecondstage***************************************************************************/;定义变量_TEXT_BASE:.wordTEXT_BASE.globl_armboot_start_armboot_start:.word_start/**Thesearedefinedintheboard-specificlinkerscript.*/.globl_bss_start_bss_start:.word__bss_startAdministrator铅笔Administrator铅笔Administrator铅笔Administrator铅笔Administrator铅笔Administrator铅笔Administrator铅笔.globl_bss_end_bss_end:.word_end#ifdefCONFIG_USE_IRQ/*IRQstackmemory(calculatedatrun-time)*/.globlIRQ_STACK_STARTIRQ_STACK_START:.word0x0badc0de/*IRQstackmemory(calculatedatrun-time)*/.globlFIQ_STACK_STARTFIQ_STACK_START:.word0x0badc0de#endif/**theactualresetcode*/;实际处理代码reset:/**setthecputoSVC32mode*/mrsr0,cpsr;bic清除指定为1的位bicr0,r0,#0x1f;orr逻辑或操作orrr0,r0,#0xd3;经过以上两步r0值控制位位11010011,第0~4位标识处理器当前所处模式为10011(32位管理模式),第6、7位;为1标识禁止IRQ和FIQ中断,第5位为0标识程序运行为arm状态,若其为1则运行在thumb状态;设置处理器为32位管理模式,并运行与arm状态msrcpsr,r0/*turnoffthewatchdog*/#ifdefined(CONFIG_S3C2400)#definepWTCON0x15300000#defineINTMSK0x14400008/*Interupt-Controllerbaseaddresses*/#defineCLKDIVN0x14800014/*clockdivisorregister*/#elifdefined(CONFIG_S3C2410);看门狗寄存器地址#definepWTCON0x53000000;中断掩码寄存器,决定那个中断源被屏蔽,某位为1则屏蔽中断源,初始值为0xFFFFFFFF,屏蔽所有中断#defineINTMSK0x4A000008/*Interupt-Controllerbaseaddresses*/;中断子掩码寄存器,该寄存器只能屏蔽11个中断源,因此其仅低11位有效,初始值为0x7FF#defineINTSUBMSK0x4A00001C;时钟分频控制寄存器#defineCLKDIVN0x4C000014/*clockdivisorregister*/#endif#ifdefined(CONFIG_S3C2400)||defined(CONFIG_S3C2410);将看门狗寄存器清空,其各位含义为,第0位为1则当看门狗定时器溢出时重启,为0则不重启,初值为1;第2位为中断使能位,初值为0;第3、4位为时钟分频因子,初值为00,;第5位为看门狗的使能位初值为1;第8~15位为比例因子,初值为0x80ldrr0,=pWTCONmovr1,#0x0;将看门狗寄存器所有位置零,关闭看门狗,其实只要将第5位置0即可strr1,[r0];屏蔽所有中断,实际上中断屏蔽掩码寄存器初值即为0xFFFFFFFmovr1,#0xffffffffldrr0,=INTMSKstrr1,[r0]#ifdefined(CONFIG_S3C2410);设置子中断掩码寄存器ldrr1,=0x3ffldrr0,=INTSUBMSKstrr1,[r0]#endif;设置时钟寄存器,CLKDIVN第0位为PDIVN,为0则PCLK=HCLK,为1则PCLK=HCLK/2;第1位为HDIVN,为0则HCLK=FCLK,为1则HCLK=FCLK/2;这里两位均为1,则FCLK:HCLK:PCLK=4:2:1/*defaultFCLKis120MHz!*/ldrr0,=CLKDIVNmovr1,#3strr1,[r0]#endif/*CONFIG_S3C2400||CONFIG_S3C2410*//**wedosys-criticalinitsonlyatreboot,*notwhenbootingfromram!*/;对临界寄存器的初始化,如果从ram中启动则不执行,如果重启则执行#ifndefCONFIG_SKIP_LOWLEVEL_INITblcpu_init_crit#endif;重定向代码,也就是从flash中复制到ram中#ifndefCONFIG_SKIP_RELOCATE_UBOOTrelocate:/*relocateU-BoottoRAM*/;当前代码地址,adr获取当前代码的地址信息,若从ram运行则_start=TEXT_BASE,否则_start=0x00000000adrr0,_start/*r0<-currentpositionofcode*/;获取_TEXT_BASEldrr1,_TEXT_BASE/*testifwerunfromflashorRAM*/cmpr0,r1/*don'trelocduringdebug*/;两者相等, 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf 示从ram运行则跳转到堆栈设置beqstack_setup;不相等则表示从flash中运行,重定向代码ldrr2,_armboot_start;获取未初始化数据段地址ldrr3,_bss_start;计算代码段大小subr2,r3,r2/*r2<-sizeofarmboot*/;计算代码段终止地址addr2,r0,r2/*r2<-sourceendaddress*/;复制代码,r0为代码的起始地址,r1为ram中地址,r2为代码的终止地址;每次copy后将r0值递增同r2比较来判断是否复制完成copy_loop:ldmiar0!,{r3-r10}/*copyfromsourceaddress[r0]*/stmiar1!,{r3-r10}/*copytotargetaddress[r1]*/cmpr0,r2/*untilsourceendaddreee[r2]*/blecopy_loop#endif/*CONFIG_SKIP_RELOCATE_UBOOT*//*Setupthestack*/stack_setup:;获取_TEXT_BASEldrr0,_TEXT_BASE/*upper128KiB:relocateduboot*/;获取分配区域起始指针,CFG_MALLOC_LEN=128*1024+CFG_ENV_SIZE=128*1024+0x10000=192Ksubr0,r0,#CFG_MALLOC_LEN/*mallocarea*/;另外分配128bytes来存储开发板信息subr0,r0,#CFG_GBL_DATA_SIZE/*bdinfo*/#ifdefCONFIG_USE_IRQsubr0,r0,#(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)#endif;再减去12bytes用于栈起点subsp,r0,#12/*leave3wordsforabort-stack*/;清空未初始化数据段clear_bss:ldrr0,_bss_start/*findstartofbsssegment*/ldrr1,_bss_end/*stophere*/movr2,#0x00000000/*clear*/clbss_l:strr2,[r0]/*clearloop...*/addr0,r0,#4cmpr0,r1bleclbss_l#if0;关闭看门狗/*trydoingthisstuffaftertherelocation*/ldrr0,=pWTCONmovr1,#0x0strr1,[r0]/**maskallIRQsbysettingallbitsintheINTMR-default*/;禁止中断movr1,#0xffffffffldrr0,=INTMRstrr1,[r0];设置时钟/*FCLK:HCLK:PCLK=1:2:4*//*defaultFCLKis120MHz!*/ldrr0,=CLKDIVNmovr1,#3strr1,[r0]/*ENDstuffafterrelocation*/#endif;完成复制后跳转到start_armboot,到这里就进入函数lib_arm/board.c的start_armboot函数中ldrpc,_start_armboot_start_armboot:.wordstart_armboot;这里指的从flash中运行是指的从flashrom中运行,也就是常说的从norflash中运行程序,现在有很多开发板;都是利用SDRAM和NAND-FLASH共同工作,所以需要添加从nandflash启动的代码。在ldrpc,_start_armboot前;;添加如下代码:#ifdefCONFIG_S3C2410_NAND_BOOTblcopy_myself@jumptoramldrr1,=on_the_ramaddpc,r1,#0nopnop1:b1b@infiniteloopon_the_ram:#endif;开始就跳转到函数copy_myself中,#ifdefCONFIG_S3C2410_NAND_BOOTcopy_myself:;保存断点地址movr10,lr@resetNAND;NAND_CTRL_BASE为nandflash的寄存器基址为0x4E000000;根据flash手册来复位flashmovr1,#NAND_CTL_BASE;通过nandflash配置寄存器配置nandflash,该寄存器仅低16位有效;第15位为nandflash控制器使能位,第12位为初始化ECC使能位,第11位为nandfalshmemorynFCE使能ldrr2,=0xf830@initialvaluestrr2,[r1,#oNFCONF]ldrr2,[r1,#oNFCONF];将第11位清零,使能芯片bicr2,r2,#0x800@enablechipstrr2,[r1,#oNFCONF];写入命令movr2,#0xff@RESETcommandstrbr2,[r1,#oNFCMD];循环延时movr3,#0@wait1:addr3,r3,#0x1cmpr3,#0xablt1b;利用状态寄存器测试flash内部操作是否完成,如果完成则其状态寄存器将返回1;等待flash操作完成2:ldrr2,[r1,#oNFSTAT]@waitreadytstr2,#0x1Administrator铅笔beq2b;禁止芯片ldrr2,[r1,#oNFCONF]orrr2,r2,#0x800@disablechipstrr2,[r1,#oNFCONF]@getreadtocallCfunctions(fornand_read());建立堆栈,栈起点为0x33f00000,大小为0x8000ldrsp,DW_STACK_START@setupstackpointermovfp,#0@nopreviousframe,sofp=0@copyU-BOOTtoRAM;UBOOT_RAM_BASE应该同TEXT_BASE相同ldrr0,=UBOOT_RAM_BASEmovr1,#0x0@addressmovr2,#0x30000@size;这里设置大小为192K,为什么取这个值?为什么这三个寄存器的值就作为参数传递进去了?;跳转到board/smdk2410/nand_read.c中的nand_read_ll函数,代码见后面;该函数需要三个参数,r0为其在ram中的起始地址,r1为在源地址也就是flash中的起始地址,r2为需要;复制的中大小blnand_read_lltstr0,#0x0;r0为返回值;如果成功完成复制则跳转到ok_nand_readbeqok_nand_read#ifdefCONFIG_DEBUG_LLbad_nand_read:ldrr0,STR_FAILldrr1,SerBaseblPrintWord1:b1b@infiniteloop#endif;打印信息ok_nand_read:#ifdefCONFIG_DEBUG_LLldrr0,STR_OKldrr1,SerBaseblPrintWord#endif;校验,因为从nandflash启动只需要将bootloader的前4K代码复制到steppingstone处即可@verifymovr0,#0ldrr1,=UBOOT_RAM_BASEmovr2,#0x400@4bytes*1024=4K-bytesgo_next:ldrr3,[r0],#4ldrr4,[r1],#4teqr3,r4bnenotmatchsubsr2,r2,#4beqdone_nand_readbnego_nextnotmatch:#ifdefCONFIG_DEBUG_LLsubr0,r0,#4ldrr1,SerBaseblPrintHexWordldrr0,STR_FAILldrr1,SerBaseblPrintWord#endif1:b1bdone_nand_read:#ifdefCONFIG_DEBUG_LLldrr0,STR_OKldrr1,SerBaseblPrintWord#endif;恢复断点,程序继续运行movpc,r10;内存清零???@clearmemory@r0:startaddress@r1:lengthmem_clear:movr2,#0movr3,r2movr4,r2movr5,r2movr6,r2movr7,r2movr8,r2movr9,r2clear_loop:stmiar0!,{r2-r9}subsr1,r1,#(8*4)bneclear_loopmovpc,lr#endif@CONFIG_S3C2410_NAND_BOOT/****************************************************************************CPU_init_criticalregisters**setupimportantregisters*setupmemorytiming***************************************************************************/;对临界寄存器的初始化#ifndefCONFIG_SKIP_LOWLEVEL_INITcpu_init_crit:/**flushv4I/Dcaches*/;清空指令和数据cachesmovr0,#0mcrp15,0,r0,c7,c7,0/*flushv3/v4cache*/mcrp15,0,r0,c8,c7,0/*flushv4TLB*//**disableMMUstuffandcaches*/mrcp15,0,r0,c1,c0,0bicr0,r0,#0x00002300@clearbits13,9:8(--V---RS)bicr0,r0,#0x00000087@clearbits7,2:0(B----CAM)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.*/;在重定向代码之前,必须初始化内存时序,因为重定向时需要将flash中的代码复制到内存中;内存初始化的代码在开发板目录下movip,lrbllowlevel_initmovlr,ipmovpc,lr#endif/*CONFIG_SKIP_LOWLEVEL_INIT*//****************************************************************************Interrupthandling***************************************************************************/;中断处理@@IRQstackframe.@#defineS_FRAME_SIZE72#defineS_OLD_R068#defineS_PSR64#defineS_PC60#defineS_LR56#defineS_SP52#defineS_IP48#defineS_FP44#defineS_R1040#defineS_R936#defineS_R832#defineS_R728#defineS_R624#defineS_R520#defineS_R416#defineS_R312#defineS_R28#defineS_R14#defineS_R00#defineMODE_SVC0x13#defineI_BIT0x80/**usebad_save_user_regsforabort/prefetch/undef/swi...*useirq_save_user_regs/irq_restore_user_regsforIRQ/FIQhandling*/.macrobad_save_user_regssubsp,sp,#S_FRAME_SIZEstmiasp,{r0-r12}@Callingr0-r12ldrr2,_armboot_startsubr2,r2,#(CONFIG_STACKSIZE+CFG_MALLOC_LEN)subr2,r2,#(CFG_GBL_DATA_SIZE+8)@setbase2wordsintoabortstackldmiar2,{r2-r3}@getpc,cpsraddr0,sp,#S_FRAME_SIZE@restoresp_SVCaddr5,sp,#S_SPmovr1,lrstmiar5,{r0-r3}@savesp_SVC,lr_SVC,pc,cpsrmovr0,sp.endm.macroirq_save_user_regssubsp,sp,#S_FRAME_SIZEstmiasp,{r0-r12}@Callingr0-r12addr8,sp,#S_PCstmdbr8,{sp,lr}^@CallingSP,LRstrlr,[r8,#0]@SavecallingPCmrsr6,spsrstrr6,[r8,#4]@SaveCPSRstrr0,[r8,#8]@SaveOLD_R0movr0,sp.endm.macroirq_restore_user_regsldmiasp,{r0-lr}^@Callingr0-lrmovr0,r0ldrlr,[sp,#S_PC]@GetPCaddsp,sp,#S_FRAME_SIZEsubspc,lr,#4@return&movespsr_svcintocpsr.endm.macroget_bad_stackldrr13,_armboot_start@setupourmodestacksubr13,r13,#(CONFIG_STACKSIZE+CFG_MALLOC_LEN)subr13,r13,#(CFG_GBL_DATA_SIZE+8)@reservedacouplespotsinabortstackstrlr,[r13]@savecallerlr/spsrmrslr,spsrstrlr,[r13,#4]movr13,#MODE_SVC@prepareSVC-Mode@msrspsr_c,r13msrspsr,r13movlr,pcmovspc,lr.endm.macroget_irq_stack@setupIRQstackldrsp,IRQ_STACK_START.endm.macroget_fiq_stack@setupFIQstackldrsp,FIQ_STACK_START.endm/**exceptionhandlers*/.align5undefined_instruction:get_bad_stackbad_save_user_regsbldo_undefined_instruction.align5software_interrupt:get_bad_stackbad_save_user_regsbldo_software_interrupt.align5prefetch_abort:get_bad_stackbad_save_user_regsbldo_prefetch_abort.align5data_abort:get_bad_stackbad_save_user_regsbldo_data_abort.align5not_used:get_bad_stackbad_save_user_regsbldo_not_used#ifdefCONFIG_USE_IRQ.align5irq:get_irq_stackirq_save_user_regsbldo_irqirq_restore_user_regs.align5fiq:get_fiq_stack/*someoneoughttowriteamoreeffictionfiq_save_user_regs*/irq_save_user_regsbldo_fiqirq_restore_user_regs#else.align5irq:get_bad_stackbad_save_user_regsbldo_irq.align5fiq:get_bad_stackbad_save_user_regsbldo_fiq#endif#ifdefCONFIG_S3C2410_NAND_BOOT.align2DW_STACK_START:.wordSTACK_BASE+STACK_SIZE-4#endif//该函数来自于board/smdk2410/nand_read.c//通过r0,r1,r2三个寄存器传递参数过来,返回值为r0intnand_read_ll(unsignedchar*buf,unsignedlongstart_addr,intsize){inti,j;if((start_addr&NAND_BLOCK_MASK)||(size&NAND_BLOCK_MASK)){return-1;/*invalidalignment*/}//按照芯片的时序来进行读写操作/*chipEnable*/NFCONF&=~0x800;for(i=0;i<10;i++);for(i=start_addr;i<(start_addr+size);){/*READ0*/NFCMD=0;/*WriteAddress*/NFADDR=i&0xff;NFADDR=(i>>9)&0xff;NFADDR=(i>>17)&0xff;NFADDR=(i>>25)&0xff;wait_idle();for(j=0;j<NAND_SECTOR_SIZE;j++,i++){*buf=(NFDATA&0xff);buf++;}}/*chipDisable*/NFCONF|=0x800;/*chipdisable*/return0;}board/qt2410/lowlevel_init.S;总线宽度和等待寄存器#defineBWSCON0x48000000;宽度8bits、16bits、32bits/*BWSCON*/#defineDW8(0x0)#defineDW16(0x1)#defineDW32(0x2);等待#defineWAIT(0x1<<2);UBLB标识引脚信号的类型,为0则为nWBE,为1则为nBE#defineUBLB(0x1<<3);定义总线类型#defineB1_BWSCON(DW32)#defineB2_BWSCON(DW16)#defineB3_BWSCON(DW16+WAIT+UBLB)#defineB4_BWSCON(DW16)1#defineB5_BWSCON(DW16)#defineB6_BWSCON(DW32)#defineB7_BWSCON(DW32);bank0寄存器/*BANK0CON*/#defineB0_Tacs0x0/*0clk*/#defineB0_Tcos0x0/*0clk*/#defineB0_Tacc0x7/*14clk*/#defineB0_Tcoh0x0/*0clk*/#defineB0_Tah0x0/*0clk*/#defineB0_Tacp0x0#defineB0_PMC0x0/*normal*/;bank1寄存器/*BANK1CON*/#defineB1_Tacs0x0/*0clk*/#defineB1_Tcos0x0/*0clk*/#defineB1_Tacc0x7/*14clk*/#defineB1_Tcoh0x0/*0clk*/#defineB1_Tah0x0/*0clk*/#defineB1_Tacp0x0#defineB1_PMC0x0;bank2寄存器#defineB2_Tacs0x0#defineB2_Tcos0x0#defineB2_Tacc0x7#defineB2_Tcoh0x0#defineB2_Tah0x0#defineB2_Tacp0x0#defineB2_PMC0x0;bank3寄存器#defineB3_Tacs0x0/*0clk*/#defineB3_Tcos0x3/*4clk*/#defineB3_Tacc0x7/*14clk*/#defineB3_Tcoh0x1/*1clk*/#defineB3_Tah0x0/*0clk*/#defineB3_Tacp0x3/*6clk*/#defineB3_PMC0x0/*normal*/;bank4寄存器#defineB4_Tacs0x0/*0clk*/#defineB4_Tcos0x0/*0clk*/#defineB4_Tacc0x7/*14clk*/#defineB4_Tcoh0x0/*0clk*/#defineB4_Tah0x0/*0clk*/#defineB4_Tacp0x0#defineB4_PMC0x0/*normal*/;bank5寄存器#defineB5_Tacs0x0/*0clk*/#defineB5_Tcos0x0/*0clk*/#defineB5_Tacc0x7/*14clk*/#defineB5_Tcoh0x0/*0clk*/#defineB5_Tah0x0/*0clk*/#defineB5_Tacp0x0#defineB5_PMC0x0/*normal*/;bank6寄存器#defineB6_MT0x3/*SDRAM*/#defineB6_Trcd0x1#defineB6_SCAN0x1/*9bit*/;bank7寄存器#defineB7_MT0x3/*SDRAM*/#defineB7_Trcd0x1/*3clk*/#defineB7_SCAN0x1/*9bit*//*REFRESHparameter*/#defineREFEN0x1/*Refreshenable*/#defineTREFMD0x0/*CBR(CASbeforeRAS)/Autorefresh*/#defineTrp0x0/*2clk*/#defineTrc0x3/*7clk*/#defineTchr0x2/*3clk*/#defineREFCNT1113/*period=15.6us,HCLK=60Mhz,(2048+1-15.6*60)*//**************************************/_TEXT_BASE:.wordTEXT_BASE.globllowlevel_initlowlevel_init:/*memorycontrolconfiguration*//*maker0relativethecurrentlocationsothatit*//*readsSMRDATAoutofFLASHratherthanmemory!*/ldrr0,=SMRDATAldrr1,_TEXT_BASEsubr0,r0,r1ldrr1,=BWSCON/*BusWidthStatusController*/addr2,r0,#13*4/*addedbykyle*/lmovr3,pclldrr4,=0x3FFF0000landr3,r3,r4laadr0,r0,r3laddr2,r2,r30:ldrr3,[r0],#4strr3,[r1],#4cmpr2,r0bne0b/*everythingisfinenow*/movpc,lr.ltorg/*theliteralpoolsorigin*/SMRDATA:.word(0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28)).word((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC)).word((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC)).word((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC)).word((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC)).word((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC)).word((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC)).word((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN)).word((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)).word((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT).word0x32.word0x30.word0x30;定义函数指针typedefint(init_fnc_t)(void);;定义函数指针数组,对硬件初始化按照该数组进行init_fnc_t*init_sequence[]={cpu_init,//cpu/arm920t/cpu.c中定义,该函数为空,因为没有采用IRQ或FIQ模式board_init,//board/smdk2410/smdk2410.cinterrupt_init,//cpu/arm920t/s3c24x0/interrupt.cenv_init,//tools/env/FW_env.cinit_baudrate,//lib_arm/board.cserial_init,//cpu/arm920t/s3c24x0/serial.cconsole_init_f,//common/console.cdisplay_banner,//lib_arm/board.c#ifdefined(CONFIG_DISPLAY_CPUINFO)print_cpuinfo,//#endif#ifdefined(CONFIG_DISPLAY_BOARDINFO)checkboard,//#endifdram_init,//board/smdk2410/smdk2410.cdisplay_dram_config,//lib_arm/board.cNULL,};intboard_init(void){;将时间相关的寄存器定义为结构体S3C24X0_CLOCK_POWER,S3C24X0_GPIO也是一样S3C24X0_CLOCK_POWER*constclk_power=S3C24X0_GetBase_CLOCK_POWER();S3C24X0_GPIO*constgpio=S3C24X0_GetBase_GPIO();;设置cpu时钟/*toreducePLLlocktime,adjusttheLOCKTIMEregister*/clk_power->LOCKTIME=0xFFFFFF;/*configureMPLL*///M_MDIV=0xA1,M_PDIV=0x3,M_SDIV=0x1//这样系统时钟为202.80Mclk_power->MPLLCON=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV);/*somedelaybetweenMPLLandUPLL*/delay(4000);;USB时钟为48M/*configureUPLL*/clk_power->UPLLCON=((U_M_MDIV<<12)+(U_M_PDIV<<4)+U_M_SDIV);/*somedelaybetweenMPLLandUPLL*/delay(8000);;设置GPIO/*setuptheI/Oports*/gpio->GPACON=0x007FFFFF;gpio->GPBCON=0x00044555;gpio->GPBUP=0x000007FF;gpio->GPCCON=0xAAAAAAAA;gpio->GPCUP=0x0000FFFF;gpio->GPDCON=0xAAAAAAAA;gpio->GPDUP=0x0000FFFF;gpio->GPECON=0xAAAAAAAA;gpio->GPEUP=0x0000FFFF;gpio->GPFCON=0x000055AA;gpio->GPFUP=0x000000FF;gpio->GPGCON=0xFF95FFBA;gpio->GPGUP=0x0000FFFF;gpio->GPHCON=0x002AFAAA;gpio->GPHUP=0x000007FF;;初始化bd结构体中的bi_arch_number和bi_boot_params/*archnumberofSMDK2410-Board*/gd->bd->bi_arch_number=MACH_TYPE_SMDK2410;/*adressofbootparameters*/gd->bd->bi_boot_params=0x30000100;;启用指令和数据cache;通过对协处理器的操作了实现cache的使能icache_enable();dcache_enable();return0;}intinterrupt_init(void){;获取计时控制寄存器S3C24X0_TIMERS*consttimers=S3C24X0_GetBase_TIMERS();;使用PWM定时器4/*usePWMTimer4becauseithasnooutput*//*prescalerforTimer4is16*/timers->TCFG0=0x0f00;if(timer_load_val==0){/**for10msclockperiod@PCLKwith4bitdivider=1/2*(default)andprescaler=16.Shouldbe10390*@33.25MHzand15625@50MHz*/timer_load_val=get_PCLK()/(2*16*100);}/*loadvaluefor10mstimeout*/lastdec=timers->TCNTB4=timer_load_val;/*autoload,manualupdateofTimer4*/timers->TCON=(timers->TCON&~0x0700000)|0x600000;/*autoload,startTimer4*/timers->TCON=(timers->TCON&~0x0700000)|0x500000;timestamp=0;return(0);}staticintenv_init(void){intcrc1,crc1_ok;uchar*addr1;intcrc2,crc2_ok;ucharflag1,flag2,*addr2;//解析参数,定义了两个envdev_t型变量//typedefstructenvdev_s{//uchardevname[16];/*Devicename*///ulongdevoff;/*Deviceoffset*///ulongenv_size;/*environmentsize*///ulongerase_size;/*deviceerasesize*///}envdev_t;//程序中定义了/dev/mtd1和/dev/mtd2两个,parse_config函数用来初始化这两个结构体,并利用stat函数//初始化一个structstat结构体if(parse_config())/*shouldfillenvdevices*/return1;//为参数分配空间,ENV_SIZE=CFG_ENV_SIZE-ENV_HEADER_SIZE=0x10000-sizeof(unsignedlong)if((addr1=calloc(1,ENV_SIZE))==NULL){fprintf(stderr,"Notenoughmemoryforenvironment(%ldbytes)n",ENV_SIZE);return(errno);}//从flash中读取参数//typedefstructenvironment_s{//ulongcrc;/*CRC32overdatabytes*///ucharflags;/*activeorobsolete*///uchar*data;//}env_t;/*readenvironmentfromFLASHtolocalbuffer*///确定其指针environment.data=addr1;curdev=0;;该函数用来将旧的参数从flash中擦除,然后将新的参数写入flashif(flash_io(O_RDONLY)){return(errno);};进行crc校验crc1_ok=((crc1=crc32(0,environment.data,ENV_SIZE))==environment.crc);if(!HaveRedundEnv){if(!crc1_ok){fprintf(stderr,"Warning:BadCRC,usingdefaultenvironmentn");memcpy(environment.data,default_environment,sizeofdefault_environment);}}else{flag1=environment.flags;curdev=1;if((addr2=calloc(1,ENV_SIZE))==NULL){fprintf(stderr,"Notenoughmemoryforenvironment(%ldbytes)n",ENV_SIZE);return(errno);}environment.data=addr2;if(flash_io(O_RDONLY)){return(errno);}crc2_ok=((crc2=crc32(0,environment.data,ENV_SIZE))==environment.crc);flag2=environment.flags;if(crc1_ok&&!crc2_ok){environment.data=addr1;environment.flags=flag1;environment.crc=crc1;curdev=0;free(addr2);}elseif(!crc1_ok&&crc2_ok){environment.data=addr2;environment.flags=flag2;environment.crc=crc2;curdev=1;free(addr1);}elseif(!crc1_ok&&!crc2_ok){fprintf(stderr,"Warning:BadCRC,usingdefaultenvironmentn");memcpy(environment.data,default_environment,sizeofdefault_environment);curdev=0;free(addr1);}elseif(flag1==active_flag&&flag2==obsolete_flag){environment.data=addr1;environment.flags=flag1;environment.crc=crc1;curdev=0;free(addr2);}elseif(flag1==obsolete_flag&&flag2==active_flag){environment.data=addr2;environment.flags=flag2;environment.crc=crc2;curdev=1;free(addr1);}elseif(flag1==flag2){environm
本文档为【uboot详解】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_024492
暂无简介~
格式:pdf
大小:279KB
软件:PDF阅读器
页数:47
分类:互联网
上传时间:2013-09-06
浏览量:197