《ARM嵌入式系统原理及应用开发》课件第7章0815_第1页
《ARM嵌入式系统原理及应用开发》课件第7章0815_第2页
《ARM嵌入式系统原理及应用开发》课件第7章0815_第3页
《ARM嵌入式系统原理及应用开发》课件第7章0815_第4页
《ARM嵌入式系统原理及应用开发》课件第7章0815_第5页
已阅读5页,还剩58页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第7章嵌入式系统的BootLoader7.1BootLoader概述7.2BootLoader与嵌入式系统的关系7.3BootLoader的主要功能及典型结构7.4S3C44B0X的BootLoader分析7.5U-Boot启动流程及相关代码分析 7.1BootLoader概述

7.1.1BootLoader的作用和任务

嵌入式系统的BootLoader程序,即系统的引导装载程序,简单地说,就是在操作系统内核或用户应用程序之前运行的一段小程序。通过这段小程序可以初始化硬件设备和建立内存空间的映射图,将系统的软、硬件环境带到一个合适的状态,以便为最终调用操作系统内核或用户应用程序准备好正确的环境。BootLoader的主要任务如图7.1所示。图7.1BootLoader的主要任务7.1.2常用嵌入式BootLoader介绍

常用的嵌入式BootLoader有vivi、U-Boot、RedBoot、ARMBoot、Blob和DIY。

1. vivi

vivi是由韩国MIZI公司开发的一种专门用于ARM产品线的BootLoader。因为vivi目前只支持使用串口与主机通信,所以必须使用一条串口电缆来连接目标板和主机。vivi的源代码下载地址为/developer/s3c2410x/download/vivi.html。

2. U-Boot

U-Boot是德国DENX小组开发的用于多种嵌入式CPU的BootLoader程序,它可以运行在PowerPC、ARM、MIPS等多种嵌入式开发板上。从/或

ftp://ftp.denx.de/pub/u-boot/站点均可以下载U-Boot的源代码。

3.RedBoot

RedBoot是一个专门为嵌入式系统定制的引导启动工具,最初由RedHat公司开发。在/redboot站点可以下载RedBoot源码,Redboot在嵌入式体系中应用非常广泛。

RedBoot是集BootLoader、调试和Flash烧写于一体的,支持串口、网络下载的可执行嵌入式应用程序。它既可以用在产品的开发阶段(调试功能),也可以用在最终的产品上(Flash更新、网络启动)。

4. ARMBoot

ARMBoot是一个以ARM或StrongARM为CPU内核的嵌入式系统的BootLoader固件程序,该软件的主要目标是使新的平台更容易被移植,并且尽可能地发挥其强大性能。它只基于ARM固件,但是它支持多种类型的启动,如Flash,网络下载通过BOOTP、DHCP、TFTP等。它也是开源项目,可以从/projects/armboot网站获得最新的ARMBoot源码和详细资料,它在ARM处理器方面应用非常广泛。

5. Blob

Blob是BootLoaderObject的缩写,是一款功能强大的BootLoader,其源代码在/

projects/blob上可以获取。

6. DIY

DIY(DoItYourself),即自己制作。用DIY的方式自己编写针对目标的BootLoader,不但代码量短小,而且灵活性很大,最重要的是将来容易维护。所以在实际嵌入式产品的开发中大多都选择DIY的方式编写BootLoader。

7.2BootLoader与嵌入式系统的关系

系统加电复位后,所有的处理器都从处理器制造商预先安排的地址上取指令,如基于S3C44B0X的处理器在复位时通常都从地址0x00000000上取它的第一条指令。而且基于处理器构建的嵌入式系统通常都有某种类型的固态存储设备(如ROM、E2PPOM、Flash等)被映射到这个预先安排的地址上,因此在系统加电后,处理器将首先执行BootLoader程序。

装有BootLoader内核的启动参数、内核映像和根文件系统映像的固态存储设备的典型空间分配结构如图7.2所示。图7.2存储设备典型空间分配结构7.2.1BootLoader的操作模式

1.启动加载(BootLoading)模式

BootLoader从目标机的某个固态存储设备上将操作系统加载到RAM中运行,整个过程并没有用户的介入。该模式是BootLoader的正常工作模式。

2.下载(DownLoading)模式

目标机的BootLoader将通过串口连接、网络连接等通信手段从主机上下载文件。从主机下载的文件通常先被BootLoader保存到目标机的RAM中,然后再被BootLoader写到目标机上的固态存储设备中。该模式通常在系统更新时使用。7.2.2BootLoader的总体设计

1.阶段设计

BootLoader的启动是可以分阶段的,因此在设计时也可将BootLoader分为阶段1和阶段2。

(1)基于编程语言的考虑。阶段1主要用汇编语言编写,这是因为它主要进行与CPU核心及存储设备密切相关的处理工作和进行一些必要的初始化工作,是依赖于CPU体系结构的代码,这部分直接在Flash中执行。阶段2可以用C语言编写,主要实现一般的流程以及对板级的一些驱动支持,这部分会被复制到RAM中执行。

(2)为了使代码具有更好的可读性与可移植性。对于相同的CPU以及存储设备,若要增加外设支持,阶段1的代码可以维持不变,只对阶段2的代码进行修改;而对于不同的CPU,则只需在阶段1中修改基础代码。

2.地址规划设计

当BootLoader的阶段设计完成之后,需要考虑的是镜像存储的地址分配,如总镜像保存在什么地方、阶段2对应的镜像会被复制到什么地方、内核镜像原先存放在什么地方及BootLoader会把它又重新加载到什么地方、如何进行准确的地址规划以保证没有相互冲突等。

3.模式设计

普通用户:启动加载模式;开发者:下载模式。

既支持启动加载模式又支持下载模式的具体思路:在BootLoader完成一些硬件初始化工作之后、在加载内核镜像之前,判断一定的时间内有没有用户的键盘输入。如果没有,则为启动加载模式,直接加载内核镜像进行启动;如果有,则进入命令行格式,这时开发者就可以根据自己的需要以及BootLoader的支持情况,做一些其他的工作。模式的转换设计主要在阶段2中实现。

7.3BootLoader的主要功能及典型结构

7.3.1BootLoader的阶段1

1.基本的硬件初始化

(1)屏蔽所有的中断。

(2)设置处理器的速度和时钟频率。

(3)初始化RAM,包括正确地设置系统内存控制器的功能寄存器以及各内存控制寄存器。

(4)初始化LED。

(5)关闭处理器内部指令/数据缓存。

2.加载阶段2的RAM空间

为了获得更快的执行速度,通常把阶段2加载到RAM空间中来执行,因此必须为加载BootLoader的阶段2准备好一段可用的RAM空间。由于阶段2通常用C语言来执行,因此在考虑空间大小时,除了阶段2可执行映像的大小外,还必须把堆栈空间也考虑进来。此外,空间大小最好是页面文件大小(通常是4 KB)的倍数。将阶段2安排到整个RAM最顶层的1 MB空间是一种最常用的方法。

3.复制阶段2到RAM

复制阶段2到RAM时要确定以下两点:

(1)阶段2的可执行映像在固态存储设备的存放起始地址和终止地址。

(2) RAM空间的起始地址。

4.设置堆栈指针(SP)

堆栈指针的设置是为执行C语言代码作准备的。通常可以把SP的值设置为stage2_end-4,即在7.3.2节中提到的那个1MB的RAM空间的最顶端(堆栈向下生长)。

5.跳转到阶段2的C程序入口点

在上述一切都就绪后,就可以跳转到BootLoader的阶段2去执行了。比如,在ARM系统中,就可以通过修改寄存器PC为合适的地址来实现。BootLoader在Flash和RAM中的系统布局如图7.3所示。图7.3BootLoader在Flash和RAM中的系统布局7.3.2BootLoader的阶段2

阶段2的代码通常用C语言来实现,以便实现更复杂的功能和取得更好的代码可读性及可移植性。

1.初始化阶段2要使用的硬件设备

初始化阶段2通常包括初始化一个串行口,以便和终端用户进行I/O输出信息;初始化计时器等。

2.检测系统内存映射

所谓内存映射就是指整个物理地址空间中那些分配用来寻址系统的RAM单元。在S3C44B0X处理器中,从0x0C000000到0x10000000之间的64MB地址空间被用作系统的RAM地址空间。

BootLoader的阶段2必须在执行操作之前检测整个系统的内存映射情况,即它必须知道处理器预留的全部RAM地址空间哪些被真正映射到RAM地址单元,哪些是处于“未使用”状态的。

3.加载内核映像和根文件系统映像

(1)规划内存占用的布局。在规划内存占用的布局时,主要考虑内核映像所占用的内存范围和根文件系统所占用的内存范围两个方面。

(2)从Flash上复制。由于像ARM这样的嵌入式处理器通常都是在统一的内存地址空间中寻找Flash等固态存储设备的,因此从Flash上读取数据与从RAM单元中读取数据并没有什么不同。用一个简单的循环就可以完成从Flash设备上拷贝映像的工作,程序代码如下:

/*拷贝Flash地址0x10000内核到RAM0xC300000中*/

ldrR0, =0x10000

ldrR1, =0xC300000

addR2, R0,#(1536*1024)

copy_kernel:

ldmia R0!,{R3-R10}

stmia R1!,{R3-R10}

cmp

R0,R2

ble

copy_kernel

4.调用内核

所有硬件的设置完成之后,就可以跳转到内核,并开始运行内核了。调用内核的程序代码如下:

/*跳转到RAM中执行内核*/

ldrR0,=0xC30000 ;0xC30000正是前面拷贝kernel函数中的目的地址

movPC,R0;修改程序地址寄存器,完成跳转

7.4S3C44B0X的BootLoader分析

S3C44B0X下的μCLinux的BootLoader只是一个比较简单的BootLoader,所以它的阶段1和阶段2是一起由汇编完成的,程序流程如图7.4所示。图7.4简单的BootLoader工作流程图以下是该BootLoader的完整程序:

/**********************************************************

*File:boot.s

**********************************************************/

WTCONEQU0x01D30000

;以下的几个定义均是为了设置相应的控制寄存器,请注意查阅各位所对应的作用,

;理解所作的设置

PCONEEQU0x01D20028

LOCKTIMEEQU0x01D8000C

PLLCONEQU0x01D80000

CLKCONEQU0x01D80004

GLOBAL_start

_start:

breset;程序的第一条指令,在烧写时,它将会被烧写在0x00000000地址

addpc,pc,#0x0C000000

addpc,pc,#0x0C000000

addpc,pc,#0x0C000000

addpc,pc,#0x0C000000

addpc,pc,#0x0C000000

addpc,pc,#0x0C000000

addpc,pc,#0x0C000000

MEMORY_CONFIG: ;定义一组数据用来设置后面的存储器,可以把它看做一个数组

DCD0x11110102

DCD0x600

DCD0x7FFC

DCD0x7FFC

DCD0x7FFC

DCD0x7FFC

DCD0x7FFC

DCD0x18000

DCD0x18000

DCD0x860459

DCD0x10

DCD0x20

DCD0x20

;复位地址

reset:

;关看门狗

ldrr0,=WTCON

ldrr1,=0x0

strr1,[r0]

;设置端口控制寄存器PortE,打开RxD0和TxD0(串口输入功能)

ldrr1,=PCONE

ldrr0,=0x25529

strr0,[r1]

;设置时钟控制寄存器

ldrr1,=LOCKTIME

ldrr0,=0xFFF

strr0,[r1]

ldrr1,=PLLCON

ldrr0,=0x78061

strr0,[r1]

ldrr1,=CLKCON

ldrr0,=0x7FF8

strr0,[r1]

;设置寄存器

memsetup:

ldrr0,=MEMORY_CONFIG ;注意不用一个一个设置,通过前面已经定义好的数

;组用4条指令就可以完成设置

ldmiar0,{r1-r13}

ldrr0,=0x01C80000

stmiar0,{r1-r13}

;拷贝Flash地址0x1000内核到RAM0xC300000中

ldrr0,=0x10000

ldrr1,=0xC300000

addr2,r0,#(1536*1024) ;计算内核的终点地址

copy_kernel:

ldmiar0!,{r3-r10}

stmiar1!,{r3-r10}

cmpr0,r2

blecopy_kernel

;跳转到RAM中执行内核

ldrr0,=0xC300000 ;0xC300000正是前面拷贝内核函数中的目的地址

movpc,r0 ;修改程序地址寄存器,完成跳转

7.5U-Boot启动流程及相关代码分析

7.5.1U-Boot启动流程

U-Boot作为ARM平台常用的引导程序,具有结构强大和功能强大的特点。下载u-boot-1.2.0.tar.bz2源码包,解压后会生成u-boot-1.2.0目录,该目录主要包括三类子目录:与处理器或硬件电路板相关的文件目录,如cpu、board、libarm等;存放通用文件和设备驱动的目录,如common、inculde、drivers等;存放U-Boot应用程序、工具和文档的目录,如examples、tools等。下面来分析U-Boot的启动流程。

1.阶段1

U-Boot的阶段1(Stage1)代码通常放在u-boot-1.2.0\cpu\arm920t\start.s文件中,用汇编语言写成,其主要代码功能如下:

●定义入口。由于一个可执行的Image必须有一个入口点,并且只能有一个全局入口,通常这个入口放在ROM(Flash)的0x0地址,因此,必须使编译器知道这个入口。该工作可通过修改链接器脚本来完成。

●设置异常向量(ExceptionVector)。

●设置CPU的速度、时钟频率及终端控制寄存器。

●初始化内存控制器。

●将ROM中的程序复制到RAM中。

●初始化堆栈。

●转到RAM中执行,该工作可使用指令ldrpc来完成。

2.阶段2

对于ARM平台来说,U-Boot的阶段2(Stage2)代码在u-boot-1.2.0\lib_arm\board.c文件中。文件中的start_armboot函数是整个C语言启动代码中的主函数,同时还是整个U-Boot(针对ARM平台)的主函数,该函数将完成如下操作:

●调用一系列的初始化函数。

●初始化Flash设备。

●初始化系统内存分配函数。

●如果目标系统拥有NAND设备,则初始化NAND设备。

●如果目标系统有显示设备,则初始化该设备。

●初始化相关网络设备,填写IP、MAC地址等。

●进入命令循环(即整个boot的工作循环),接收用户从串口输入的命令,然后进行相应的工作。图7.5U-Boot启动代码顺序图7.5.2U-Boot代码分析

U-Boot代码分析如下:

//U-Boot的start.S

//定义变量_start,然后跳转到处理器复位代码

.glob1_start;U-Boot启动入口

_start:breset

//若产生中断则利用pc来跳转到对应的中断处理程序中

ldrpc,_undefined_instruction //未定义指令向量

ldrpc,_software_interrupt //软件中断向量

ldrpc,_prefetch_abort //预取指中止向量

ldrpc,_data_abort //数据中止向量

ldrpc,_not_used //保留

ldrpc,_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

/************************↓reset代码***********************/

reset:

mrsr0,cpsr

bicr0,r0,#0x1f//bic清除指定为1的位

orrr0,r0,#0xd3//orr逻辑或操作

//经过以上两步r0值控制位为11010011,第0~4位表示处理器当前所处模式为10011(32

//位管理模式);第6、7位为1表示禁止IRQ和FIQ中断;第5位为0表示程序在ARM

//状态,若其为1则运行在Thumb状态

msrcpsr,r0 //设置处理器为32位管理模式

/*关闭看门狗*/

#definepWTCON0x53000000 //看门狗寄存器地址

#defineINTMSK0x4A00008 //中断掩码寄存器,决定哪个中断源被屏蔽,某位为1则

//屏蔽中断源,初始值为0xffffffff,屏蔽所有中断

#defineINTSUBMSK0x4A00001C //中断子掩码寄存器,该寄存器只能屏蔽11个中断源,

//因此其仅低11位有效,初始值为0x7ff

#defineCLKDIVN0x4C000014//时钟分频控制寄存器

//将看门狗寄存器清空,其各位含义为:第0位为1则当看门狗定时器溢出时重启,为

//0则不重启,初值为1

//第2位为中断使能位,初值为0

//第3、4位为时钟分频因子,初值为00

//第5位为看门狗的使能位,初值为1

//第8~15位为比例因子,初值为0x80

ldrr0,=pWTCON

movr1,#0x0

strr1,[r0] //将看门狗寄存器所有位置0,关闭看门狗,其实只要将第5位置0即可

movr1,#0xFFFFFFFF

ldrr0,=INTMSK

strr1,[r0] //屏蔽所有中断,实际上中断掩码寄器初值即为0xFFFFFFF

ldrr1,=0x3FF

ldrr0,=INTSUBMSK

strr1,[r0] //设置中断子掩码寄存器

//设置时钟寄存器,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

ldrr0,=CLKDIVN

movri,#3

strr1,[r0]

/***********************↑reset代码**********************/

/*********************↓cpu_init_crit代码******************/

//对关键寄存器的初始化,如果从RAM中启动则不执行cpu_init_crit段代码

cpu_init_crit:

//清空指令和数据caches

movr0,#0

mcrp15,0,r0,c7,c7,0

mcrp15,0,r0,c8,c7,0

/*disableMMUstuffandcaches*/

mrcp15,0,r0,c1,c0,0

bicr0,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,c2,c0,0

//在重定向代码之前,必须初始化内存时序,因为重定向时需要将Flash中的代码复制

//到内存中

//内存初始化的代码在board/smdk2410/lowlevel_ini.S中

movip,lr

bllowlevel_init //调用lowlevel_init子程序(board/smdk2410/lowlevel_ini.S)

movlr,ip

movpc,lr //程序返回

/*********************↑cpu_init_crit代码*******************/

/************↓lowlevel_init代码(lowlevel_ini.S)**************/

lowlevel_init:

/*memorycontrolconfiguration*/

/*maker0relativethecurrentlocationsothatit*/

/*readsSMRDATAoutofFlashratherthanmemory!*/

ldr r0,=SMRDATA

ldr r1,_TEXT_BASE

sub r0,r0,r1

ldr r1,=BWSCON /*BusWidthStatusController*/

add r2,r0,#13*4

0b:

ldr r3,[r0],#4

str r3,[r1],#4

cmp r2,r0

bne 0b

/*everythingisfinenow*/

mov pc,lr

/**************↑lowlevel_init代码(lowlevel_ini.s)*************/

/**************↓relocate代码******************************/

relocate:/*relocateU-BoottoRAM*/

//当前代码地址,adr获取当前代码的地址信息,若从RAM运行,则_start=TEXT_BASE,

//否则_start=0x00000000

adrr0,_start/*r0<-currentpositionofcode*/

//获取_TEXT_BASE

ldrr1,_TEXT_BASE/*testifwerunfromflashorRAM*/

cmpr0,r1/*don‘treloctduringdebug*/

//两者相等,表示从RAM运行则跳转到堆栈设置

bepstack_setup

//不相等则表示从Flash中运行,重定向代码

ldrr2,_armboot_start

//获取未初始化数据段地址

Ldrr3,_bss_start

//计算代码段大小

subr2,r3,r2/*r2<-sizeofarmboot*/

//计算代码段终止地址

addr2,r0,r2/*r2<-sourceendaddress*/

//复制代码,r0为代码的起始地址,r1为RAM中地址,r2为代码的终止地址

//每次复制后将r0值递增同r2比较来判断是否复制完成

copy_loop:

ldmiar0!,{r3-r10}/*copyfromsourceaddress[r0]*/

stmiar1!,{r3-r10}/*copytotargetaddress[r1]*/

cmpr0,r2/*untilsourceendaddreee[r2]*/

blecopy_loop

/*******************↑relocate代码**************************/

/*******************↓stack_setup代码***********************/

stack_setup:

//获取_TEXT_BASE

ldrro,_TEXT_BASE/*upper128K/B:relocateduboot*/

//获取分配区域起始指针,CFG_MALLOC_LEN=128*1024+CFG_ENV_SIZE

//=128*1024+0X1000=192K

subr0,r0,#CFG_MALLOC_LEN/*mallocarea*/

//另外分配128B来存储开发板信息

subr0,r0,#(CFG_GBL_DATA_SIZE/*bdinfo*/

#ifdefCONFIG_USE_IRQ

subr0,r0,#(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)

#endif

//再减去12B用于栈起点

subsp,r0,#12/*leave3wordsforabort-stack*/

//清空未初始化数据段

clear_bss;

ldrr0,_bss_start/*findstartofbsssegment*/

ldrr1,_bss_end/*stophere*/

movr2,#0x00000000/*clear*/

clbss_1:strr2,[r0]/*clearloop…*/

addr0,r0,#4

cmpr0,r1

bleclbss_1

/*********************↑stack_setup代码********************/

//完成复制后跳转到start_armboot,到这里则进入lib_arm/board.c的start-armboot函数中

ldrpc,_start_armboot

_start_armboot:.wordstart_armboot

在lib_arm/board.c中,首先定义函数指针数组,代码如下:

typedefint(init_fnc_t)(void);

//定义函数指针数组,对硬件初始化按照该数组进行

init_fnc_t*init_sequence[]={

cpu_init,//cpu/arm920t/cpu.c中定义,该函数为空,因为没有采用IPQ或FIQ模式

board_init,//board/smdk2410/smdk2410.c

interrupt_init,//cpu/arm920t/s3c24x0/interrupt.c

env_init,//tools/env/FW_env.c

init_baudrate,//lib_arm/board.c

serial_init,//cpu/arm920t/s3c24x0/serial.c

console_init_f,//common/console.c

display_banner,//lib_arm/board.c

#ifdefined(CONFIG_DISPLAY_BOARDINFO)

print_cpuinfo,//

#endif

#ifdefined(CONFIG_DISPLAY_BOARDINFO)

checkboard,//

#endif

dram_init,//board/smdk2410/smdk2410.c

display_dram_config,//lib_arm/board.c

NULL,

};

/*************↓start_armboot代码***************/

voidstar_armboot(void)

{

init_fnc_t**init_fnc_ptr;

char*s;

#ifndefCFG_NO_FLASH

ulongsize;

#endif

#ifdefined(CONFIG_VFD)||defined(CONFIG_LCD)

unsignedlongaddr;

#endif

/*Pointeriswritablesinceweallocatedaregisterforit*/

//获取全局gd指针

gd=(gd_t*)(_armboot_start-CFG_MALLOC_LEN-sizeof(gd_t));

/*compileroptimizationbarrierneededforGCC>=3.4*/

__asm__volatile__(**:::”memory”);

//清空该结构体

memset((void*)gd,0,sizeof(gd_t));

//获取bd_info结构体指针

gd->bd=(bd_t*)((char*)gd–sizeof(bd_t));

memset(gd->bd,0,sizeof(bd_t));

//整个代码区的长度

Monitor_flash_len=_bss_start-_armboot_start;

//调用初始化函数,用来初始化gd结构体

for(init_fnc_ptr=init_sequence;*init_fnc_ptr;++ini_fnc_ptr){

if((*init_fnc_ptr)()!=0){

hang();

}

}

#ifndefCFG_NO_FLASH

/*configureavailableFLASHbanks*/

//board/smdk2410/flash.c配置flash

//从其实现来看,好像只是配置NORFlash

//按页对其方式保留显存

addr=(_bss_end+(PAGE_SIZE-1))&~(PAGE_SIZE-1);

size=vfd_setmem(addr);

gd->fb_base=addr;

#endif /*CONFIG_VFD*/

//显示器为LCD,同上

#ifdefCONFIG_VFD

#ifndefPAGE_SIZE

#definePAGE_SIZE4096

#endif

/*reservememoryforLCDdisplay(alwaysfullpages)*/

/*bss_endisdefinedintheboard-specificlinkerscript*/

size=flash_init();

//显示Flash信息

display_flash_config(size);

#endif /*CFG_NO_FLASH*/

//定义显示类型

#ifdefCONFIG_VFD

#ifndefPAGE_SIZE

#definePAGE_SIZE4096

#endif

/*reservememoryforVFDdisplay(alwaysfullpages)*/

/*bss_endisdefinedintheboard-specificlinkerscript*/

addr=(_bss_end+(PAGE_SIZE-))&~(PAGE_SIZE-1);

size=lcd_setmem(addr);

gd->fb_base=addr;

#endif /*CONFIG_LCD*/

//初始化CFG_MALLOC_LEN大小空间

/*armboot_startisdefinedintheboard-specificlinkerscript*/

mem_malloc_init(_armboot_start–CFG_MALLOC_LEN);

//初始化NANDFlash,这是在NANDFlash启动的s3c2410移植U-Boot的关键,根据Flash

//时序编写函数即可

//在include/configs/smdk2410.h中的commanddefinition中增加CONFIG_COMMANDS

//和CFG_CMD_NAND命令

#if(CONFIG_COMMAND&CFG_CMD_NAND)

puts("NAND:");

nand_init();//board/smdk2410/smdk2410.c

#endif

#ifdefCONFIG_HAS_DATAFLASH

AT91F_DataflashInit();

dataflash_print_info();

#endif

/*initializeenvironment*/

//初始化环境参数

env_relocate();

//framebuffer初始化

#ifdefCONFIG_VFD

/*mustdothisaftertheframebufferisallocated*/

drv_vfd_init();

#endif/*CONFIG_VFD*/

//通过命令行参数传递获取IP地址

/*IPAdress*/

gd->bd->bi_ip_addr=getenv_IPaddr("ipaddr");

//通过命令行参数传递获取物理地址

/*MACAddress*/

{

inti

ulongreg

char*s,*e;

chartmp[64];

i=getenv_r("ethaddr",tmp,size(tmp));

s=(i>0)?tmp:NULL;

for(reg=0;reg<6;++reg)

{

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论