1、S3c2440 启动是从文件 vivi/arch/s3c2440/head.S 开始的1. 在这个文件中,做了这样的工作:(1) 关闭看门狗(2) 禁止所有中断(3) 初始化 system clock(4) 初始化串口(5) 初始化 nand flash 相关的控制寄存器(6) 把 vivi copy 到 SDRAM 上,最后把 pc 指向 ram(7) 设置堆栈(8) call 一个叫做 main 的函数。这个函数是 c 写的2. main()这个函数在 vivi/init/main.c 中(1) 程序正常跳转到这里后,首先打印一些进本信息(2) 调用若干个初始化的函数reset_handl
2、er() vivi/lib/reset_handler.c 中(主要做了 clear memory 的工作)board_init() (没找到)mem_map_init() vivi/arch/mmu.c 中(如果使用 nand flash,会在这里使它看起来线性化;清空cache;invalidate I =; NAME: 2440INIT.S; DESC: C start up codes; Configure memory, ISR ,stacks; Initialize C-variables; HISTORY:; 2002.02.25:kwtark: ver 0.0; 2002.03
3、.20:purnnamu: Add some functions for testing STOP,Sleep mode; 2003.03.14:DonGo: Modified for 2440.; 2009.02.19:PuHao: Comments;=;=; ENTRY 这里是关键的入口,正文数量超过最大限制,只有忽略其他我没看懂的了,等下能不能把那个文件传上来,好恶心的规定;=ResetHandler;WTCON 定义在 2440addr.inc 里面,WTCON EQU 0x53000000;把 WTCON 地址放到 R0 里,然后在设置 r1 为 0,最后把 r1 中的 0 值;拷贝
4、到 r0 所指向的地址里面,即禁用 watch dogldr r0,=WTCON ;watch dog disableldr r1,=0x0str r1,r0;基本同上,INTMSK 0x4A000008 R/W Interrupt mask controlldr r0,=INTMSKldr r1,=0xffffffff ;all interrupt disablestr r1,r0;基本同上ldr r0,=INTSUBMSKldr r1,=0x3ff ;all sub interrupt disable,0x3ff = 0000 0011 1111 1111str r1,r0;由于条件为 F
5、ALSE,我觉得这段根本就不会执行 FALSE; rGPFDAT = (rGPFDAT ldr r0,=MPLLCONldr r1,=(M_MDIV top of initialised dataCMP r0, r1 ; Check that they are differentBEQ %F21 CMP r1, r3 ; Copy init dataLDRCC r2, r0, #4 ; LDRCC r2, r0 + ADD r0, r0, #4 STRCC r2, r1, #4 ; STRCC r2, r1 + ADD r1, r1, #4BCC %B12 LDR r1, =|Image$ZI
6、$Limit| ; Top of zero init segmentMOV r2, #03 CMP r3, r1 ; Zero initSTRCC r2, r3, #4BCC %B3 :LNOT:THUMBCODEbl Main ;Dont use main() because .because what?b . THUMBCODE ;for start-up code for Thumb modeorr lr,pc,#1bx lrCODE16bl Main ;Dont use main() because .because what?b .CODE32;function initializi
7、ng stacks;初始化堆栈的代码还没仔细研究,正文字数超过最大限制,只有不贴下面的了一:地址空间的分配1:s3c2440 是 32 位的,所以可以寻址 4GB 空间,内存(SDRAM)和端口(特殊寄存器),还有 ROM 都映射到同一个 4G 空间里.2:开发板上一般都用 SDRAM 做内存 flash(nor、nand)来当做 ROM。其中 nand flash 没有地址线,一次至少要读一页(512B).其他两个有地址线 3:norflash 不用来运行代码,只用来存储代码,NORflash,SDRAM 可以直接运行代码)4:s3c2440 总共有 8 个内存 banks6 个内存 ban
8、k 可以当作 ROM 或者 SRAM 来使用留下的 2 个 bank 除了当作 ROM 或者 SRAM,还可以用 SDRAM(各种内存的读写方式不一样)7 个 bank 的起始地址是固定的还有一个灵活的 bank 的内存地址,并且 bank 大小也可以改变5:s3c2440 支持两种启动模式:NAND 和非 NAND(这里是 nor flash)。具体采用的方式取决于 OM0、OM1 两个引脚OM1:0 所决定的启动方式 OM1:0=00 时,处理器从 NAND Flash 启动OM1:0=01 时,处理器从 16 位宽度的 ROM 启动OM1:0=10 时,处理器从 32 位宽度的 ROM
9、启动。OM1:0=11 时,处理器从 Test Mode 启动。当从 NAND 启动时cpu 会自动从 NAND flash 中读取前 4KB 的数据放置在片内 SRAM 里(s3c2440是 soc),同时把这段片内 SRAM 映射到 nGCS0 片选的空间(即 0x00000000)。cpu 是从 0x00000000 开始执行,也就是 NAND flash 里的前 4KB 内容。因为NAND FLASH 连地址线都没有,不能直接把 NAND 映射到 0x00000000,只好使用片内 SRAM 做一个载体。通过这个载体把 nandflash 中大代码复制到 RAM(一般是 SDRAM)中
10、去执行当从非 NAND flash 启动时nor flash 被映射到 0x00000000 地址(就是 nGCS0,这里就不需要片内 SRAM 来辅助了,所以片内 SRAM 的起始地址还是 0x40000000). 然后 cpu 从0x00000000 开始执行(也就是在 Norfalsh 中执行)。总结:Arm 的启动都是从 0 地址开始,所不同的是地址的映射不一样。在 arm 开电的时候,要想让 arm 知道以某种方式(地址映射方式)运行,不可能通过你写的某段程序控制,因为这时候你的程序还没启动,这时候 arm 会通过引脚的电平来判断。 1 当引脚 OM0 跟 OM1 有一个是高电平时,
11、这时地址 0 会映射到外部 nGCS0 片选的空间,也就是 Norflash,程序就会从 Norflash 中启动,arm 直接取Norflash 中的指令运行。 2 当 OM0 跟 OM1 都为低电平,则 0 地址内部 bootbuf(一段 4k 的 SRAM)开始。系统上电,arm 会自动把 NANDflash 中的前 4K 内容考到 bootbuf(也就是 0 地址),然后从 0 地址运行。这时 NANDFlash 中的前 4K 就是启动代码(他的功能就是初始化硬件然后在把NANDFlash 中的代码复制到 RAM 中,再把相应的指针指向该运行的地方) 为什么会有这两种启动方式,关键还是
12、两种 flash 的不同特点造成,NOR FLASH 容量小,速度快,稳定性好,输入地址,然后给出读写信号即可从数据口得到数据,适合做程序存储器。NAND FLASH 总容量大,但是读写都需要复杂的时序,更适合做数据存储器。这种不同就造成了 NORflash 可以直接连接到arm 的总线并且可以运行程序,而 NANDflash 必须搬移到内存(SDRAM)中运行。在实际的开发中,一般可以把 bootloader 烧入到 Norflash,程序运行可以通过串口交互,进行一定的操作,比如下载,调试。这样就很可以很方便的调试你的一些代码。Norflash 中的 Bootloader 还可以烧录内核到 Norflash 等等功能。