为了正常的体验网站,请在浏览器设置里面开启Javascript功能!
首页 > Uboot引导加载程序Bootloader源代码分析与移植

Uboot引导加载程序Bootloader源代码分析与移植

2021-06-08 7页 doc 2MB 23阅读

用户头像 个人认证

蓉蓉

暂无简介

举报
Uboot引导加载程序Bootloader源代码分析与移植U-boot引导加载程序(Bootloader)源代码分析与移植PAGEPAGE3U-boot引导加载程序(Bootloader)源代码分析与移植目录TOC\o"1-3"\h\z\uHYPERLINK\l"_Toc251572132"第一章绪论PAGEREF_Toc251572132\h3HYPERLINK\l"_Toc251572133"1.1U-boot简介PAGEREF_Toc251572133\h3HYPERLINK\l"_Toc251572134"1.2U-boot源码树...
Uboot引导加载程序Bootloader源代码分析与移植
U-boot引导加载程序(Bootloader)源代码分析与移植PAGEPAGE3U-boot引导加载程序(Bootloader)源代码分析与移植目录TOC\o"1-3"\h\z\uHYPERLINK\l"_Toc251572132"第一章绪论PAGEREF_Toc251572132\h3HYPERLINK\l"_Toc251572133"1.1U-boot简介PAGEREF_Toc251572133\h3HYPERLINK\l"_Toc251572134"1.2U-boot源码树PAGEREF_Toc251572134\h4HYPERLINK\l"_Toc251572135"1.3U-boot支持的主要功能PAGEREF_Toc251572135\h5HYPERLINK\l"_Toc251572136"第二章U-boot源代码详细分析PAGEREF_Toc251572136\h6HYPERLINK\l"_Toc251572137"2.1U-boot的启动流程PAGEREF_Toc251572137\h6HYPERLINK\l"_Toc251572138"2.1.1第一阶段(Stage1)PAGEREF_Toc251572138\h6HYPERLINK\l"_Toc251572139"2.1.2第二阶段(Stage2)PAGEREF_Toc251572139\h9HYPERLINK\l"_Toc251572140"2.2U-boot的初始化PAGEREF_Toc251572140\h13HYPERLINK\l"_Toc251572141"2.2.1私有数据global_dataPAGEREF_Toc251572141\h13HYPERLINK\l"_Toc251572142"2.2.2初始化序列init_sequencePAGEREF_Toc251572142\h14HYPERLINK\l"_Toc251572143"2.2.3NANDFlash初始化PAGEREF_Toc251572143\h20HYPERLINK\l"_Toc251572144"2.2.4DataFlash初始化PAGEREF_Toc251572144\h22HYPERLINK\l"_Toc251572145"2.2.5环境变量重定位PAGEREF_Toc251572145\h23HYPERLINK\l"_Toc251572146"2.2.6初始化设备PAGEREF_Toc251572146\h25HYPERLINK\l"_Toc251572147"2.2.7控制台初始化PAGEREF_Toc251572147\h27HYPERLINK\l"_Toc251572148"2.2.8单板后期初始化PAGEREF_Toc251572148\h30HYPERLINK\l"_Toc251572149"2.3命令处理PAGEREF_Toc251572149\h33HYPERLINK\l"_Toc251572150"2.3.1命令数据结构PAGEREF_Toc251572150\h33HYPERLINK\l"_Toc251572151"2.3.2命令查找PAGEREF_Toc251572151\h35HYPERLINK\l"_Toc251572152"2.3.3主循环PAGEREF_Toc251572152\h35HYPERLINK\l"_Toc251572153"2.4Linux的引导PAGEREF_Toc251572153\h42HYPERLINK\l"_Toc251572154"2.4.1映象格式PAGEREF_Toc251572154\h42HYPERLINK\l"_Toc251572155"2.4.2linux引导PAGEREF_Toc251572155\h42HYPERLINK\l"_Toc251572156"2.4.3linux的内核参数传递PAGEREF_Toc251572156\h52HYPERLINK\l"_Toc251572157"第三章U-boot在S3C2410上的移植分析PAGEREF_Toc251572157\h58HYPERLINK\l"_Toc251572158"3.1对ARM-920T内核的支持PAGEREF_Toc251572158\h58HYPERLINK\l"_Toc251572159"3.2配置自己的开发板PAGEREF_Toc251572159\h58HYPERLINK\l"_Toc251572160"3.3实现网卡的驱动程序PAGEREF_Toc251572160\h60HYPERLINK\l"_Toc251572161"3.4从NANDFlash启动PAGEREF_Toc251572161\h61HYPERLINK\l"_Toc251572162"3.4.1修改cpu/arm920t/start.s添加NANDFlash启动跳转代码PAGEREF_Toc251572162\h61HYPERLINK\l"_Toc251572163"3.4.2添加从NANDFlash启动代码PAGEREF_Toc251572163\h63HYPERLINK\l"_Toc251572164"3.4.3添加上述代码中引用的宏定义PAGEREF_Toc251572164\h65HYPERLINK\l"_Toc251572165"3.5修改Makefile文件PAGEREF_Toc251572165\h65HYPERLINK\l"_Toc251572166"3.6搭建编译环境PAGEREF_Toc251572166\h66HYPERLINK\l"_Toc251572167"3.7生成目标文件并进行测试PAGEREF_Toc251572167\h67HYPERLINK\l"_Toc251572168"3.8测试PAGEREF_Toc251572168\h69第一章绪论1.1U-boot简介U-Boot,全称UniversalBootLoader,是遵循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软件工程中心WolfgangDenk[以下简称W.D]本人精湛专业水平和持着不懈的努力。当前,U-Boot项目正在他的领军之下,众多有志于开放源码BOOTLOADER移植工作的嵌入式开发人员正如火如荼地将各个不同系列嵌入式处理器的移植工作不断展开和深入,以支持更多的嵌入式操作系统的装载与引导。  U-Boot的优点:  ①开放源码;  ②支持多种嵌入式操作系统内核,如Linux、NetBSD,VxWorks,QNX,RTEMS,ARTOS,LynxOS;  ③支持多个处理器系列,如PowerPC、ARM、x86、MIPS、XScale;  ④较高的可靠性和稳定性;  ⑤高度灵活的功能设置,适合U-Boot调试、操作系统不同引导要求、产品发布等;  ⑥丰富的设备驱动源码,如串口、以太网、SDRAM、FLASH、LCD、NVRAM、EEPROM、RTC、键盘等;  ⑦较为丰富的开发调试文档与强大的网络技术支持;1.2U-boot源码树从根目录树中可以看出,U-boot源代码主要包含以下几个部分board目标板相关文件,主要包含SDRAM、FLASH驱动;common独立于处理器体系结构的通用代码,如内存大小探测与故障检测;cpu与处理器相关的文件。如mpc8xx子目录下含串口、网口、LCD驱动及中断初始化等文件;driver通用设备驱动,如CFIFLASH驱动(目前对INTELFLASH支持较好)docU-Boot的说明文档;examples可在U-Boot下运行的示例程序;如hello_world.c,timer.c;includeU-Boot头文件;尤其configs子目录下与目标板相关的配置头文件是移植过程中经常要修改的文件;lib_xxx处理器体系相关的文件,如lib_ppc,lib_arm目录分别包含与PowerPC、ARM体系结构相关的文件;net与网络功能相关的文件目录,如bootp,nfs,tftp;post上电自检文件目录。尚有待于进一步完善;rtcRTC驱动程序;tools用于创建U-BootS-RECORD和BIN镜像文件的工具;U-boot的这些目录结构可以大致的划分成如下层次:1.3U-boot支持的主要功能U-Boot可支持的主要功能列表系统引导支持NFS挂载、RAMDISK(压缩或非压缩)形式的根文件系统支持NFS挂载、从FLASH中引导压缩或非压缩系统内核;基本辅助功能强大的操作系统接口功能;可灵活设置、传递多个关键参数给操作系统,适合系统在不同开发阶段的调试要求与产品发布,尤Linux支持最为强劲;支持目标板环境参数多种存储方式,如FLASH、NVRAM、EEPROM;CRC32校验,可校验FLASH中内核、RAMDISK镜像文件是否完好;设备驱动串口、SDRAM、FLASH、以太网、LCD、NVRAM、EEPROM、键盘、USB、PCMCIA、PCI、RTC等驱动支持;上电自检功能SDRAM、FLASH大小自动检测;SDRAM故障检测;CPU型号;特殊功能XIP内核引导;第二章U-boot源代码详细分析2.1U-boot的启动流程U-boot的启动流程包括两个阶段,第一阶段进行一些基本的初始化动作,为启动第二阶段的主体做准备,此阶段代码由汇编代码写成。第二阶段是进行系统的初始化工作,并准备引导操作系统。下面我们对这两个阶段进行详细的分析。2.1.1第一阶段(Stage1)第一阶段的启动代码在cpu\\start.s中,完成的工作主要有:CPU自身初始化:包括MMU,Cache,时钟系统,SDRAM控制器等的初始化重定位:把自己从非易失性存储器搬移到RAM中分配堆栈空间,设置堆栈指针清零BSS数据段跳转到第二阶段入口函数start_armboot()AT91SAM9260EK的启动代码在cpu\arm926ejs\start.s中,精简后的代码如下:[cpu\arm926ejs\start.s];ARM的向量表.globl_start_start:bresetldrpc,_undefined_instructionldrpc,_software_interruptldrpc,_prefetch_abortldrpc,_data_abortldrpc,_not_usedldrpc,_irqldrpc,_fiq_undefined_instruction:.wordundefined_instruction_software_interrupt:.wordsoftware_interrupt_prefetch_abort:.wordprefetch_abort_data_abort:.worddata_abort_not_used:.wordnot_used_irq:.wordirq_fiq:.wordfiq;全局符号定义_TEXT_BASE:.wordTEXT_BASE.globl_armboot_start_armboot_start:.word_start/**Thesearedefinedintheboard-specificlinkerscript.*/.globl_bss_start_bss_start:.word__bss_start.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;复位入口reset:;CPU设为SVC32模式mrsr0,cpsrbicr0,r0,#0x1forrr0,r0,#0xd3msrcpsr,r0;如果需要,调用cpu_init_crit进行CPU关键初始化;在AT91SAM9260EK板上没有使用。这部分工作在Bootstrap中完成。#ifndefCONFIG_SKIP_LOWLEVEL_INITblcpu_init_crit#endif;如果需要,对U-boot进行重定位(从Flash搬移到SDRAM中);在AT91SAM9260EK板上没有使用。U-boot在运行之前已经被Bootstrap加载到了SDRAM中。#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*/;为irq,fiq,abt模式分配堆栈stack_setup:ldrr0,_TEXT_BASE;指向U-boot起始点subr0,r0,#CFG_MALLOC_LEN;留出malloc内存空间subr0,r0,#CFG_GBL_DATA_SIZE;留出u-boot私有数据的空间;如果使用中断机制,分配irq,fiq模式的堆栈;AT91SAM9260EK不使用中断#ifdefCONFIG_USE_IRQsubr0,r0,#(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)#endif;分配abt模式堆栈空间(12bytes),设置svc模式SPsubsp,r0,#12/*leave3wordsforabort-stack*/;清零BSS数据段clear_bss:ldrr0,_bss_start/*findstartofbsssegment*/ldrr1,_bss_end/*stophere*/movr2,#0x00000000/*clear*/clbss_l:strr2,[r0]/*clearloop...*/addr0,r0,#4cmpr0,r1bleclbss_l;跳转到第二阶段入口start_armboot()ldrpc,_start_armboot_start_armboot:.wordstart_armboot;以下是cpu_init_crit函数#ifndefCONFIG_SKIP_LOWLEVEL_INITcpu_init_crit:;FlushCache,TLBmovr0,#0mcrp15,0,r0,c7,c7,0/*flushv3/v4cache*/mcrp15,0,r0,c8,c7,0/*flushv4TLB*/;禁止MMU,打开I-Cachemrcp15,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)Align*/orrr0,r0,#0x00001000/*setbit12(I)I-Cache*/mcrp15,0,r0,c1,c0,0;调用lowlevel_init完成底层初始化(时钟系统,SDRAM控制器,片选设置等等)movip,lr/*perservelinkregacrosscall*/bllowlevel_init/*gosetuppll,mux,memory*/movlr,ip/*restorelink*/movpc,lr/*backtomycaller*/#endif2.1.2第二阶段(Stage2)第二阶段是u-boot的主体,入口点是lib_arm\board.c中的start_armboot()函数,完成的主要工作包括:为U-boot内部私有数据分配存储空间,并清零依次调用函数指针数组init_sequence中定义的函数进行一系列的初始化如果系统支持NORFlash,调用flash_init()和display_flash_config()初始化并显示检测到的器件信息(AT91SAM9260EK不需要)如果系统支持LCD或VFD,调用lcd_setmem()或vfd_setmem()计算帧缓冲(Framebuffer)大小,然后在BSS数据段之后为Framebuffer分配空间,初始化gd->fb_base为Framebuffer的起始地址(AT91SAM9260EK不需要)调用mem_malloc_init()进行存储分配系统(类似于C语言中的堆)的初始化和空间分配如果系统支持NANDFlash,调用nand_init()进行初始化如果系统支持DataFlash,调用AT91F_DataflashInit()和dataflash_print_info()进行初始化并显示检测到的器件信息调用env_relocate()进行环境变量的重定位,即从Flash中搬移到RAM中如果系统支持VFD,调用drv_vfd_init()进行VFD设备初始化(AT91SAM9260EK不需要)从环境变量中读取IP地址和MAC地址,初始化gd->bd->bi_ip_addr和gd->bd->bi_enetaddr调用jumptable_init()进行跳转表初始化,跳转表在global_data中,具体用途尚不清楚调用console_init_r()进行控制台初始化如果需要,调用misc_init_r()进行杂项初始化调用enable_interrupts()打开中断如果需要,调用board_late_init()进行单板后期初始化,对于AT91SAM9260EK,主要是以太网初始化进入主循环:根据用户的选择启动linux,或者进入命令循环执行用户输入的命令源代码:[lib_arm\board.c]voidstart_armboot(void){DECLARE_GLOBAL_DATA_PTR;/*在include/asm-arm/global_data.h中定义:#defineDECLARE_GLOBAL_DATA_PTRregistervolatilegd_t*gdasm("r8")声明了一个变量gd,保存在寄存器r8中,类型为gd_t(即structglobal_data)指针*/ulongsize;init_fnc_t**init_fnc_ptr;char*s;#ifdefined(CONFIG_VFD)||defined(CONFIG_LCD)unsignedlongaddr;#endif/*为global_data分配空间,并清零*/gd=(gd_t*)(_armboot_start-CFG_MALLOC_LEN-sizeof(gd_t));/*compileroptimizationbarrierneededforGCC>=3.4*/__asm____volatile__("":::"memory");memset((void*)gd,0,sizeof(gd_t));gd->bd=(bd_t*)((char*)gd-sizeof(bd_t));memset(gd->bd,0,sizeof(bd_t));monitor_flash_len=_bss_start-_armboot_start;/*依次调用函数指针数组init_sequence中定义的函数,如果中途出错,调用hung()进入死循环*/for(init_fnc_ptr=init_sequence;*init_fnc_ptr;++init_fnc_ptr){if((*init_fnc_ptr)()!=0){hang();}}/*初始化NORFlash,AT91SAM9260EK不需要*/#if(CONFIG_COMMANDS&CFG_CMD_FLASH)/*configureavailableFLASHbanks*/size=flash_init();display_flash_config(size);#endif/*为LCD或VFD分配Framebuffer,AT91SAM9260EK不需要*/#ifdefCONFIG_VFD#ifndefPAGE_SIZE#definePAGE_SIZE4096#endif/**reservememoryforVFDdisplay(alwaysfullpages)*//*bss_endisdefinedintheboard-specificlinkerscript*/addr=(_bss_end+(PAGE_SIZE-1))&~(PAGE_SIZE-1);size=vfd_setmem(addr);gd->fb_base=addr;#endif/*CONFIG_VFD*/#ifdefCONFIG_LCD#ifndefPAGE_SIZE#definePAGE_SIZE4096#endif#if!defined(CONFIG_MACH_AT91SAM9261EK)&&!defined(CONFIG_MACH_NADIA2VB)/**reservememoryforLCDdisplay(alwaysfullpages)*//*bss_endisdefinedintheboard-specificlinkerscript*/addr=(_bss_end+(PAGE_SIZE-1))&~(PAGE_SIZE-1);size=lcd_setmem(addr);gd->fb_base=addr;#endif#endif/*CONFIG_LCD*//*初始化存储分配系统(简化的堆)*/mem_malloc_init(_armboot_start-CFG_MALLOC_LEN);/*初始化NANDFlash*/#if(CONFIG_COMMANDS&CFG_CMD_NAND)nand_init();/*goinittheNAND*/#endif/*初始化DataFlash*/#ifdefCONFIG_HAS_DATAFLASHAT91F_DataflashInit();dataflash_print_info();#endif/*环境变量重定位*//*initializeenvironment*/env_relocate();/*VFD设备初始化,AT91SAM9260EK不需要*/#ifdefCONFIG_VFD/*mustdothisaftertheframebufferisallocated*/drv_vfd_init();#endif/*CONFIG_VFD*/puts("IPAddress\n");/*从环境变量"ipaddr"中读取IP地址,初始化gd->bd->bi_ip_addr*/gd->bd->bi_ip_addr=getenv_IPaddr("ipaddr");/*从环境变量"ethaddr"中读取MAC地址,初始化gd->bd->bi_enetaddr*/{inti;ulongreg;char*s,*e;uchartmp[64];i=getenv_r("ethaddr",tmp,sizeof(tmp));s=(i>0)?tmp:NULL;for(reg=0;reg<6;++reg){gd->bd->bi_enetaddr[reg]=s?simple_strtoul(s,&e,16):0;if(s)s=(*e)?e+1:e;}}/*初始化设备*/devices_init();/*getthedeviceslistgoing.*/#ifdefCONFIG_CMC_PU2load_sernum_ethaddr();#endif/*CONFIG_CMC_PU2*//*初始化跳转表*/jumptable_init();/*初始化控制台*/console_init_r();/*fullyinitconsoleasadevice*//*杂项初始化*/#ifdefined(CONFIG_MISC_INIT_R)/*miscellaneousplatformdependentinitialisations*/misc_init_r();#endif/*开中断*//*enableexceptions*/enable_interrupts();/*Performnetworkcardinitialisationifnecessary*//*CS8900网卡,SMC91111初始化,AT91SAM9260EK不需要*/#ifdefCONFIG_DRIVER_CS8900cs8900_get_enetaddr(gd->bd->bi_enetaddr);#endif#ifdefined(CONFIG_DRIVER_SMC91111)||defined(CONFIG_DRIVER_LAN91C96)if(getenv("ethaddr")){smc_set_mac_addr(gd->bd->bi_enetaddr);}#endif/*CONFIG_DRIVER_SMC91111||CONFIG_DRIVER_LAN91C96*//*读取环境变量"loadaddr"到loadaddr变量*//*Initializefromenvironment*/if((s=getenv("loadaddr"))!=NULL){load_addr=simple_strtoul(s,NULL,16);}/*读取环境变量"bootfile"到BootFile变量*/#if(CONFIG_COMMANDS&CFG_CMD_NET)if((s=getenv("bootfile"))!=NULL){copy_filename(BootFile,s,sizeof(BootFile));}#endif/*CFG_CMD_NET*//*单板后期初始化*/#ifdefBOARD_LATE_INITboard_late_init();#endif#if(CONFIG_COMMANDS&CFG_CMD_NET)#ifdefined(CONFIG_NET_MULTI)puts("Net:");#endifeth_initialize(gd->bd);#endif/*主循环*//*main_loop()canreturntoretryautoboot,ifsojustrunitagain.*/for(;;){main_loop();}/*NOTREACHED-nowayoutofcommandloopexceptbooting*/}2.2U-boot的初始化2.2.1私有数据global_dataglobal_data在include\asm-arm\global_data.h中定义:[include\asm-arm\global_data.h]typedefstructglobal_data{bd_t*bd;/*bd_info结构,包含更多的信息*/unsignedlongflags;unsignedlongbaudrate;/*波特率*/unsignedlonghave_console;/*有无控制台*/unsignedlongreloc_off;/*重定位的偏移量*/unsignedlongenv_addr;/*环境变量块的地址*/unsignedlongenv_valid;/*环境变量是否有效*/unsignedlongfb_base;/*Framebuffer地址*/#ifdefCONFIG_VFDunsignedcharvfd_type;/*VFD类型*/#endifvoid**jt;/*跳转表*/}gd_t;bd_info在include\asm-arm\u-boot.h中定义:[include\asm-arm\u-boot.h]typedefstructbd_info{intbi_baudrate;/*串行口波特率*/unsignedlongbi_ip_addr;/*IP地址*/unsignedcharbi_enetaddr[6];/*MAC地址*/structenvironment_s*bi_env;/*环境变量块地址*/ulongbi_arch_number;/*机器类型*/ulongbi_boot_params;/*传递给linux的参数块地址*/struct/*RAMconfiguration*/{ulongstart;ulongsize;}bi_dram[CONFIG_NR_DRAM_BANKS];/*DRAM区间列表:起始地址和大小*/}bd_t;2.2.2初始化序列init_sequenceInit_sequence是一个函数指针数组,数组中每一个元素都指向一个初始化函数。[lib_arm/board.c]typedefint(init_fnc_t)(void);init_fnc_t*init_sequence[]={cpu_init,/*basiccpudependentsetup*/board_init,/*basicboarddependentsetup*/interrupt_init,/*setupexceptions*/env_init,/*initializeenvironment*/init_baudrate,/*initialzebaudratesettings*/serial_init,/*serialcommunicationssetup*/console_init_f,/*stage1initofconsole*/display_banner,/*saythatwearehere*/dram_init,/*configureavailableRAMbanks*/display_dram_config,#ifdefined(CONFIG_VCMA9)||defined(CONFIG_CMC_PU2)checkboard,#endifNULL,};对于AT91SAM9260EK,这些函数的位置和完成的功能如表1所示:表1init_sequence中初始化函数说明函数名称位置(所在的文件)功能概述cpu_initcpu/arm926ejs/cpu.c堆栈初始化board_initboard/at91sam9260ek/at91sam9260ek.c复位PHY芯片;设置GPIO口;设置机器类型和启动参数块地址到global_data中相关数据成分中interrupt_initcpu/arm926ejs/at91sam9260/interrupts.c初始化PIT(可编程间隔定时器)env_initcommon/env_dataflash.c初始化Dataflash;判断DataFlash中环境变量快的有效性(计算比较CRC),设置gd->env_valid;设置环境变量快的起始地址gd->env_addrinit_baudratelib_arm/board.c从环境变量中读取波特率,初始化gd->bd->bi_baudrateserial_initcpu/arm926ejs/at91sam9260/serial.c初始化串行口console_init_fcommon/console.c控制台初始化第一阶段:初始化gd->have_console和gd->flagsdisplay_bannerlib_arm/board.c输出版本信息和代码/数据段/堆栈信息到控制台dram_initboard/at91sam9260ek/at91sam9260ek.c初始化SDRAM区间信息:gd->bd->bi_dramdisplay_dram_configlib_arm/board.c输出SDRAM区间信息信息到控制台checkboard-AT91SAM9260EK未使用下面重点分析cpu_init,board_init,interrupt_init,env_init,serial_init等几个函数,其它几个比较简单,这里不再分析。(1)cpu_init这个函数的功能是设置irq和fiq模式的堆栈起始点。AT91SAM9260EK没有使用U-boot的中断机制,所以这个函数实际上什么也没做。[cpu/arm926ejs/cpu.c]intcpu_init(void){/**setupupstacksifnecessary*/#ifdefCONFIG_USE_IRQDECLARE_GLOBAL_DATA_PTR;IRQ_STACK_START=_armboot_start-CFG_MALLOC_LEN-CFG_GBL_DATA_SIZE-4;FIQ_STACK_START=IRQ_STACK_START-CONFIG_STACKSIZE_IRQ;#endifreturn0;}(2)board_init[board/at91sam9260ek/at91sam9260ek.c]intboard_init(void){DECLARE_GLOBAL_DATA_PTR;/*复位PHY芯片,复位脉冲宽度500ms*/AT91C_BASE_RSTC->RSTC_RMR=(AT91C_RSTC_KEY&((unsignedint)0xA5<<24))|(AT91C_RSTC_ERSTL&(0x0D<<8));AT91C_BASE_RSTC->RSTC_RCR=(AT91C_RSTC_KEY&((unsignedint)0xA5<<24))|AT91C_RSTC_EXTRST;/*等待复位完成*//*Waitforendhardwarereset*/while(!(AT91C_BASE_RSTC->RSTC_RSR&AT91C_RSTC_NRSTL));/*控制台初始化第一阶段*/console_init_f();/*打开系统控制模块和PIOC模块的时钟*///EnableclocksforSMCandPIOCAT91C_BASE_PMC->PMC_PCER=1<PMC_PCER=1<fb_base=(unsignedlong)AT91C_IRAM;#elsegd->fb_base=(unsignedlong)AT91C_EXT_SDRAM;#endif#endif/*设置机器类型,MACH_TYPE_AT91SAM9260EK在include/asm-arm/mach-types.h中定义为848*/gd->bd->bi_arch_number=MACH_TYPE_AT91SAM9260EK;/*设置引导参数块地址0x20000100*/gd->bd->bi_boot_params=PHYS_SDRAM+0x100;return0;}(3)interrupt_init[cpu/arm926ejs/at91sam9260/interrupts.c]intinterrupt_init(void){p_pitc=AT91C_BASE_PITC;/*打开系统控制模块的时钟*/*AT91C_PMC_PCER=1<PITC_PIMR=AT91C_PITC_PITEN;/*设置PIT的计数初始值*/p_pitc->PITC_PIMR|=TIMER_LOAD_VAL;/*复位PIT*/reset_timer_masked();return0;}(4)env_init[common/env_dataflash.c]intenv_init(void){DECLARE_GLOBAL_DATA_PTR;ulongcrc,len,new;unsignedoff;ucharbuf[64];intDataflashExists;if(gd->env_valid==0){/*DataFlash初始化,检测DataFlash是否存在*/if((DataflashExists=AT91F_DataflashInit())){/*prepareforDATAFLASHread/write*///printf("Dataflashisnotpluggedornotsupported\n");//return1;//}/*从DataFlash读入环境变量块的CRC值*/read_dataflash(CFG_ENV_ADDR+offsetof(env_t,crc),sizeof(ulong),&crc);/*分段从DataFlash读入环境变量块,每次读取64字节,计算CRC*/new=0;len=ENV_SIZE;off=offsetof(env_t,data);while(len>0){intn=(len>sizeof(buf))?sizeof(buf):len;read_dataflash(CFG_ENV_ADDR+off,n,buf);new=crc32(new,buf,n);len-=n;off+=n;}/*如果CRC正确(计算结果和读取的值相等),设置gd->env_valid=1,gd->env_addr指向环境变量数据区起始地址(注意此时环境变量尚未读入RAM)*/if(crc==new){gd->env_addr=offsetof(env_t,data);gd->env_valid=1;}/*否则,设置gd->env_valid=0,gd->env_addr指向缺省环境变量*/else{gd->env_addr=(ulong)&default_environment[0];gd->env_valid=0;}}}return0;}缺省环境变量default_environment在common/env_common.c中被定义为:uchardefault_environment[]={#ifdefCONFIG_BOOTARGS"bootargs="CONFIG_BOOTARGS"\0"#endif#ifdefCONFIG_BOOTCOMMAND"bootcmd="CONFIG_BOOTCOMMAND"\0"#endif#ifdefCONFIG_RAMBOOTCOMMAND"ramboot="CONFIG_RAMBOOTCOMMAND"\0"#endif#ifdefCONFIG_NFSBOOTCOMMAND"nfsboot="CONFIG_NFSBOOTCOMMAND"\0"#endif#ifdefined(CONFIG_BOOTDELAY)&&(CONFIG_BOOTDELAY>=0)"bootdelay="MK_STR(CONFIG_BOOTDELAY)"\0"#endif#ifdefined(CONFIG_BAUDRATE)&&(CONFIG_BAUDRATE>=0)"baudrate="MK_STR(CONFIG_BAUDRATE)"\0"#endif#ifdefCONFIG_LOADS_ECHO"loads_echo="MK_STR(CONFIG_LOADS_ECHO)"\0"#endif#ifdefCONFIG_ETHADDR"ethaddr="MK_STR(CONFIG_ETHADDR)"\0"#endif#ifdefCONFIG_ETH1ADDR"eth1addr="MK_STR(CONFIG_ETH1ADDR)"\0"#endif#ifdefCONFIG_ETH2ADDR"eth2addr="MK_STR(CONFIG_ETH2ADDR)"\0"#endif#ifdefCONFIG_ETH3ADDR"eth3addr="MK_STR(CONFIG_ETH3ADDR)"\0"#endif#ifdefCONFIG_IPADDR"ipaddr="MK_STR(CONFIG_IPADDR)"\0"#endif#ifdefCONFIG_SERVERIP"serverip="MK_STR(CONFIG_SERVERIP)"\0"#endif#ifdefCFG_AUTOLOAD"autoload="CFG_AUTOLOAD"\0"#endif#ifdefCONFIG_PREBOOT"preboot="CONFIG_PREBOOT"\0"#endif#ifdefCONFIG_ROOTPATH"rootpath="MK_STR(CONFIG_ROOTPATH)"\0"#endif#ifdefCONFIG_GATEWAYIP"gatewayip="MK_STR(CONFIG_GATEWAYIP)"\0"#endif#ifdefCONFIG_NETMASK"netmask="MK_STR(CONFIG_NETMASK)"\0"#endif#ifdefCONFIG_HOSTNAME"hostname="MK_STR(CONFIG_HOSTNAME)"\0"#endif#ifdefCONFIG_BOOTFILE"bootfile="MK_STR(CONFIG_BOOTFILE)"\0"#endif#ifdefCONFIG_LOADADDR"loadaddr="MK_STR(CONFIG_LOADADDR)"\0"#endif#ifdefCONFIG_CLOCKS_IN_MHZ"clocks_in_mhz=1\0"#endif#ifdefined(CONFIG_PCI_BOOTDELAY)&&(CONFIG_PCI_BOOTDELAY>0)"pcidelay="MK_STR(CONFIG_PCI_BOOTDELAY)"\0"#endif#ifdefCONFIG_EXTRA_ENV_SETTINGSCONFIG_EXTRA_ENV_SETTINGS#endif"\0"};可以看出,这是所有环境变量的缺省值,可以由用户定义。重要的环境变量如表2所示:表2环境变量缺省值环境变量名称环境变量值Bootargs"mem=64Mconsole=ttyS0,115200initrd=0x21100000,17000000root=/dev/ram0rw"bootcmd"nandread204000000200000;nandread21100000200000400000;bootm20400000"bootdelay"3"baudrate"115200"ethaddr"22.34.56.78.99.aa"ipaddr"192.168.12.138"serverip"192.168.12.66"autoload"tftp20400000ulmage9260;tftp21100000ramdisk9260.gz;bootm20400000"(5)serial_init[cpu/arm926ejs/at91sam9260/serial.c]intserial_init(void){/*如果使用调试串口,配置调试串口的管脚*/#ifdefCONFIG_DBGU*AT91C_PIOB_PDR=AT91C_PB15_DTXD|AT91C_PB14_DRXD;/*PA10&9*/*AT91C_PMC_PCER=1<US_CR=AT91C_US_RSTRX|AT91C_US_RSTTX;us->US_CR=AT91C_US_RXEN|AT
/
本文档为【Uboot引导加载程序Bootloader源代码分析与移植】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索