S3C2410vivi详解.docx
- 文档编号:20969259
- 上传时间:2023-04-25
- 格式:DOCX
- 页数:23
- 大小:23.21KB
S3C2410vivi详解.docx
《S3C2410vivi详解.docx》由会员分享,可在线阅读,更多相关《S3C2410vivi详解.docx(23页珍藏版)》请在冰豆网上搜索。
S3C2410vivi详解
s3c2410的Bootloader(Vivi)源代码分析
----基于S3C2410处理器
作者:
forkchen
Email:
chenjunbupt-bcnl.
QQ:
56155986
欢迎广大嵌入式之友多多交流
1.1Vivi简介...2
1.2vivi的配置与编译...3
1.2.1建立交叉开发环境...3
1.2.2配置和编译vivi4
1.3vivi代码分析...4
1.4vivi的运行...5
1.4.1vivi的第一阶段...5
1.4.2vivi的第二阶段...15
1.5启动代码执行流程图...17
1.6vivi的配置文件...19
1.1Vivi简介
Vivi是国mizi公司开发的bootloader,适用于ARM9处理器。
Vivi有两种工作模式:
启动加载模式和下载模式。
启动加载模式可以在一段时间后(这个时间可更改)自行启动linux核,这时vivi的默认模式。
在下载模式下,vivi为用户提供一个命令行接口,通过接口可以使用vivi提供的一些命令,见下表:
命令
功能
Load
把二进制文件载入Flash或RAM
Part
操作MTD分区信息。
显示、增加、删除、复位、保存MTD分区
Param
设置参数
Boot
启动系统
Flash
管理Flash,如删除Flash的数据
1.2vivi的配置与编译
1.2.1建立交叉开发环境
1、在宿主机上安装标准Linux操作系统:
Redhat9.0(主机系统为win2000,用虚拟机vmware安装的Redhat9.0,核版本为2.4.18)。
2、宿主机上安装交叉编译器。
我这边的2410开发板提供的光盘上已附交叉编译器工具:
arm-linux-gcc-2.95.3(源码为cross-2.95.3.tar.bz2)。
先以root用户的身份登陆到linux下。
进入/usr/local目录,创建名为arm的目录:
cd/usr/local
mkdirarm
将光盘提供的cross-2.95.3.tar.bz2解压到/usr/local/arm目录:
tarjxvfcross-2.95.3.tar.bz2–C/usr/local/arm
然后修改修改PATH变量:
为了可以方便使用arm-linux-gcc编译器系统,把arm-linux工具链目录加入到环境变量PATH中:
修改/etc/profile文件,添加pathmunge/usr/local/arm/2.95.3/bin即可。
#Pathmanipulation
if[`id-u`=0];then
pathmunge/sbin
pathmunge/usr/sbin
pathmunge/usr/local/sbin
pathmunge/usr/local/arm/2.95.3/bin
fi
pathmunge/usr/X11R6/binafter
设置环境变量后,最好是重启或注销一下,这样设置的环境变量才能生效。
1.2.2配置和编译vivi
如果vivi的源代码已根据开发板作了相应改动,则需要对源代码进行配置和编译,以生成烧入flash的vivi二进制映象文件。
由于vivi要用到kernel的一些头文件,所以需要kernel的源代码,所以先要把linux的kernel准备好。
将vivi和kernel都解到相应目录下(例如我将光盘提供的vivi源代码解压到/home/chenjun目录下,光盘提供的Linuxkernel源码kernel-h2410eb.041024.tar.gz也解压到/home/chenjun目录下,解压后的文件名为kerne-h2410eb)。
然后需修改/vivi/Makefile里的一些变量设置:
ØLINUX_INCLUDE_DIR=/kernel/include/
(LINUX_INCLUDE_DIR为kernel/include的对应目录,我的是/home/chen/kerne-h2410eb/include/)
因此修改为:
LINUX_INCLUDE_DIR=/home/chenjun/kerne-h2410eb/include/
ØCROSS_COMPILE=/usr/local/arm/2.95.3/bin/arm-linux-
(CROSS_COMPILE为arm-linux安装的相应目录,我的是/usr/local/arm/2.95.3/bin/arm-linux-)
因此修改为:
CROSS_COMPILE=/usr/local/arm/2.95.3/bin/arm-linux-
ØARM_GCC_LIBS=/usr/local/arm/2.95.3/lib/gcc-lib/arm-linux/2.95.3
(需根据你arm-linux的安装目录修改,我的是/usr/local/arm/2.95.3/lib/gcc-lib/arm-linux/2.95.3)
进入/vivi目录执行makedistclean。
(目的是确保编译的有效性,在编译之前将vivi里所有的“*.o”和“*.o.flag”文件删掉)
进入/vivi目录里,输入“makemenuconfig”,开始选择配置。
可以Load一个写好的配置文件也可以自己修改试试。
注意Exit时一定要选“Yes”保存配置。
再输入“make”正式开始编译,一会儿就完了。
如果不报错,在/vivi里面就有你自己的“vivi”了。
这个就是后面要烧写到flash中的bootloader。
1.3vivi代码分析
vivi的代码包括arch,init,lib,drivers和include等几个目录,共200多条文件。
Vivi主要包括下面几个目录:
arch:
此目录包括了所有vivi支持的目标板的子目录,例如s3c2410目录。
drivers:
其中包括了引导核需要的设备的驱动程序(MTD和串口)。
MTD目录下分map、nand和nor三个目录。
init:
这个目录只有main.c和version.c两个文件。
和普通的C程序一样,vivi将从main函数开始执行。
lib:
一些平台公共的接口代码,比如time.c里的udelay()和mdelay()。
include:
头文件的公共目录,其中的s3c2410.h定义了这块处理器的一些寄存器。
Platform/smdk2410.h定义了与开发板相关的资源配置参数,我们往往只需要修改这个文件就可以配置目标板的参数,如波特率、引导参数、物理存映射等。
1.4vivi的运行
vivi的运行也可以分为两个阶段:
1.4.1vivi的第一阶段
完成含依赖于CPU的体系结构硬件初始化的代码,包括禁止中断、初始化串口、复制自身到RAM等。
相关代码集中在head.S(\vivi\arch\s3c2410目录下):
Head.S:
#include"config.h"
#include"linkage.h"
#include"machine.h"
Startofexecutablecode
ENTRY(_start)
ENTRY(ResetEntryPoint)
Exceptionvectortable(physicaladdress=0x00000000);异常向量表物理地址
0x00:
Reset;复位
bReset
0x04:
Undefinedinstructionexception;未定义的指令异常
UndefEntryPoint:
bHandleUndef
0x08:
Softwareinterruptexception;软件中断异常
SWIEntryPoint:
bHandleSWI
0x0c:
PrefetchAbort(InstructionFetchMemoryAbort);存操作异常
PrefetchAbortEnteryPoint:
bHandlePrefetchAbort
0x10:
DataAccessMemoryAbort;数据异常
DataAbortEntryPoint:
bHandleDataAbort
0x14:
Notused;未使用
NotUsedEntryPoint:
bHandleNotUsed
0x18:
IRQ(InterruptRequest)exception;慢速中断处理
IRQEntryPoint:
bHandleIRQ
0x1c:
FIQ(FastInterruptRequest)exception;快速中断处理
FIQEntryPoint:
bHandleFIQ
VIVImagics
0x20:
magicnumbersowecanverifythatweonlyput
.long0
0x24:
.long0
0x28:
wherethisviviwaslinked,sowecanputitinmemoryintherightplace
.long_start
0x2C:
thiscontainstheplatform,cpuandmachineid
.longARCHITECTURE_MAGIC
0x30:
vivicapabilities
.long0
#ifdefCONFIG_PM;vivi考虑不需要使用电源管理
0x34:
bSleepRamProc
#endif
#ifdefCONFIG_TEST
0x38:
bhmi
#endif
StartVIVIhead
Reset:
disablewatchdogtimer;禁止看门狗计时器
movr1,#0x53000000;WTCON寄存器地址是
0x53000000,清0
movr2,#0x0
strr2,[r1]
#ifdefCONFIG_S3C2410_MPORT3;不符合条件,跳到下面的关中断
/****在/vivi/include/autoconf.h中#undefCONFIG_S3C2410_MPORT3******/
movr1,#0x56000000;GPACON寄存器地址是
0x56000000
movr2,#0x00000005
strr2,[r1,#0x70];配置GPHCON寄存器
movr2,#0x00000001
strr2,[r1,#0x78];配置GPHUP寄存器
movr2,#0x00000001
strr2,[r1,#0x74];配置GPHDAT寄存器
#endif
disableallinterrupts;禁止全部中断
movr1,#INT_CTL_BASE
movr2,#0xffffffff
strr2,[r1,#oINTMSK];掩码关闭所有中断
ldrr2,=0x7ff
strr2,[r1,#oINTSUBMSK]
initialisesystem;初始化系统时钟
movr1,#CLK_CTL_BASE
mvnr2,#0xff000000
strr2,[r1,#oLOCKTIME]
ldrr2,mpll_50mhz
strr2,[r1,#oMPLLCON]
#ifndefCONFIG_S3C2410_MPORT1;满足条件,向下执行
/****在/vivi/include/autoconf.h中#undefCONFIG_S3C2410_MPORT1******/
1:
2:
4
movr1,#CLK_CTL_BASE
movr2,#0x3
strr2,[r1,#oCLKDIVN]
mrcp15,0,r1,c1,c0,0readctrlregister
orrr1,r1,#0xc0000000Asynchronous
mcrp15,0,r1,c1,c0,0writectrlregister
now,CPUclockis200Mhz;CPU的频率是200MHz
movr1,#CLK_CTL_BASE
ldrr2,mpll_200mhz
strr2,[r1,#oMPLLCON]
#else
1:
2:
2
movr1,#CLK_CTL_BASE
ldrr2,clock_clkdivn
strr2,[r1,#oCLKDIVN]
mrcp15,0,r1,c1,c0,0readctrlregister
orrr1,r1,#0xc0000000Asynchronous
mcrp15,0,r1,c1,c0,0writectrlregister
now,CPUclockis100Mhz;CPU的频率是100MHz
movr1,#CLK_CTL_BASE
ldrr2,mpll_100mhz
strr2,[r1,#oMPLLCON]
#endif
bl;跳转到memsetup函数
/*****************************
Memsetup函数的实现:
ENTRY(memsetup)
initialisethestaticmemory
setmemorycontrolregisters;设置存控制寄存器的初值
movr1,#MEM_CTL_BASE
adrlr2,mem_cfg_val
/*******************
DataArea
Memoryconfigurationvalues
.align4
mem_cfg_val:
;定义好的13*4=52个字节初值
.longvBWSCON;在/vivi/include/platform/smdk2410.h中赋值
/******SDRAM从32位变成16位,需要修改vBWSCON的值******/
.longvBANKCON0
.longvBANKCON1
.longvBANKCON2
.longvBANKCON3
/**********网卡控制器vBANKCON3的值可能需要修改**************/
.longvBANKCON4
.longvBANKCON5
.longvBANKCON6
/******SDRAM从32位变成16位,可能需要修改vBANKCON6的值******/
.longvBANKCON7
.longvREFRESH
.longvBANKSIZE
/******SDRAM从64MB变成32MB,需要修改vBANKSIZE的值******/
.longvMRSRB6
.longvMRSRB7
********************/
addr3,r1,#52
1:
ldrr4,[r2],#4
strr4,[r1],#4
cmpr1,r3
bne1b;循环操作,直到13个寄存器赋值完成
movpc,lr
*******************************/
#ifdefCONFIG_PM;vivi考虑不需要使用电源管理
Checkifthisisawake-upfromsleep
ldrr1,PMST_ADDR
ldrr0,[r1]
tstr0,#(PMST_SMR)
bneWakeupStart;查看状态,判断是否需要跳转到WakeupStart
#endif
#ifdefCONFIG_S3C2410_SMDK;SMDK开发板使用
AllLEDon;点亮开发板上的LED
movr1,#GPIO_CTL_BASE
addr1,r1,#oGPIO_F;LED使用GPIOF组的管脚
ldrr2,=0x55aa;使能EINT0,EINT1,EINT2,EINT3,
;另四个管脚配置成输出,屏蔽EINT4,5,6,7
strr2,[r1,#oGPIO_CON]
movr2,#0xff
strr2,[r1,#oGPIO_UP];disablethepull-upfunction
movr2,#0x00
strr2,[r1,#oGPIO_DAT]
#endif
#if0
SVC
mrsr0,cpsr
bicr0,r0,#0xdf
orrr1,r0,#0xd3
msrcpsr_all,r1
#endif
setGPIOforUART;设置串口
movr1,#GPIO_CTL_BASE
addr1,r1,#oGPIO_H;设置GPIO_H组管脚为串口
ldrr2,gpio_con_uart
strr2,[r1,#oGPIO_CON]
ldrr2,gpio_up_uart
strr2,[r1,#oGPIO_UP]
/*************************
initalvaluesforGPIO
gpio_con_uart:
.longvGPHCON;vGPHCON在/vivi/include/platform/smdk2410.h中赋值
;#definevGPHCON0x0016faaa
;GPIO_H配置为nCTS0,nRTS0,RXD0,TXD0,RXD1,
;TXD1,nCTS1,nRTS1,
/****三个串口都使能,可能需要修改#definevGPHCON0x0016aaaa****/
gpio_up_uart:
.longVgphup;同上#definevGPHUP0x000007ff
;Thepull-upfunctionisdisabled.
************************/
blInitUART;跳转到InitUART串口初始化函数
/*******InitializeUART
r0=numberofUARTport
InitUART:
ldrr1,SerBase
/*******************
.align4;缺省情况下在vivi中只初始化了UART0
SerBase:
#ifdefined(CONFIG_SERIAL_UART0)
.longUART0_CTL_BASE;基地址在/vivi/include/s3c2410.h中定义
#elifdefined(CONFIG_SERIAL_UART1)
.longUART1_CTL_BASE
#elifdefined(CONFIG_SERIAL_UART2)
.longUART2_CTL_BASE
#else
#errornotdefinedbaseaddressofserial
#endif
********************/
movr2,#0x0
strr2,[r1,#oUFCON]
strr2,[r1,#oUMCON]
movr2,#0x3
strr2,[r1,#oULCON]
ldrr2,=0x245
strr2,[r1,#oUCON]
#defineUART_BRD((50000000/(UART_BAUD_RATE*16))-1)
movr2,#UART_BRD
strr2,[r1,#oUBRDIV]
movr3,#100
movr2,#0x0
1:
subr3,r3,#0x1
tstr2,r3
bne1b
#if0
movr2,#'U'
strr2,[r1,#oUTXHL]
1:
ldrr3,[r1,#oUTRSTAT]
andr3,r3,#UTRSTAT_TX_EMPTY
tstr3,#UTRSTAT_TX_EMPTY
bne1b
movr2,#'0'
strr2,[r1,#oUTXHL]
1:
ldrr3,[r1,#oUTRSTAT]
andr3,r3,#UTRSTAT_TX_EMPTY
tstr3,#UTRSTAT_TX_EMPTY
bne1b
#endif
movpc,lr
****************************************************/
#ifdefCONFIG_DEBUG_LL;打印调试信息,缺省未定义
PrintcurrentProgramCounter
ldrr1,SerBase
movr0,#'\r'
blPrintChar
movr0,#'\n'
blPrintChar
movr0,#''
blPrintChar
movr0,pc
blPrintHexWord
#endif
#ifdefCONFIG_BOOTUP_MEMTEST
simplememorytesttofindsomeDRAMflaults.
blmemtest
#endif
#ifdefCONFIG_S3C2410_NAND_BOOT;从NANDFlash启动
blcopy_myself;跳转到copy_myself函数
/**********************************************
copy_myself:
copyvivitoram
copy_myself:
movr10,lr
resetNAND
movr1,#NAND_CTL_BASE
ldrr2,=0xf830initialvalue
strr2,[r1,#oNFCONF]
ldrr2,[r1,#oNFCONF]
bicr2,r2,#0x800enablechip
strr2,[r1,#oNFCONF]
movr2,#0xffRESETcommand
strbr2,[r1,#oNFCMD]
movr3,#0wait
1:
addr3,r3,#0x1
cmpr3,#0xa
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- S3C2410vivi 详解