初始化(时钟初始化/内存初始化/steppingstone to SDRAM/bss段初始化)
1. 时钟初始化
1.1 时钟初始化分析
1)晶振频率
2)有几个PLL
3)PLL会产生那些时钟
4)产生的时钟是干什么的
eg:
S3C2440:
1)晶振12MHz
2)有MPLL、UPLL
3)MPLL产生FCLK、HCLK、PCLK
UPLL产生UCLK
4)

S3C6410:
1)晶振12MHz
2)有APLL、MPLL、EPLL
3)APLL产生ARMCLK
MPLL产生HCLKx2、HCLK、PCLK、CLKJPEG、CLKSECUP
EPLL产生CLKUART、CLKAUDIO0、CLKAUDIO1、CLKAUDIO2...
4)

S5PV210:
1)晶振24MHz
2)有APLL、MPLL、EPLL、VPLL
3)产生3大体系:MSYS(主系统时钟体系)、DSYS(显示相关的时钟)、PSYS(外围设备的时钟)
4)

1.2 时钟初始化软件要完成的工作
S3C2440:
1)设置分频系数
2)设置FCLK
3)设置CPU到异步工作模式

4)设置LOCK TIME
2 内存初始化
主要从硬件的角度分析内存的工作
2.1 内存分类
内存具备访问速度快、访问方式简单等优点。

DRAM:它的基本原件是小电容,电容可以在两个极板上保留电荷,但需要定期的充电(或者叫刷新),否则数据会丢失。缺点:由于要定期刷新存储介质,存取速度较慢。
SRAM:它是一种具有静止存取功能的内存,不需要定期刷新存储介质就能保存它内部的存储数据。优点:存取速度快;缺点:功耗大,成本高。常用作存储容量不高,但需要存取速度快的场合,比如steppingstone。
SDRAM:同步动态随机存储器
同步:内存工作需要有同步时钟,内部的命令的发送与数据的传送都以该时钟为基准
动态:存储整列需要不断的刷新来保证数据的不丢失
随机:数据不是线性依次存储,而是自由指定地址进行读写
注:S3C2440内存通常使用SDRAM
DDR与DDR2:与SDRAM相比,DDR不仅可以在时钟脉冲的上升沿传输数据,还可以在下降沿传输数据。在意味着在相同的工作频率下,DDR的理论传输速率是SDRAM的两倍。DDR2则在DDR的基础上再次进行了改进,使得数据传输速率在DDR的基础上再次翻倍。
注:S3C6410内存通常使用DDR
S5PV210内存通常使用DDR2
2.2 内存内部结构

2.2.1 表结构
内存的内部如同表格,数据就存放在每个单元格中。数据读写时,先指定行号(行地址),再指定列号(列地址),就可以准确找到所需要的单元格。而这张表格称为Logical Bank(L_bank).

由于技术、成本等原因,一块内存不可能把所有的单元格都做到一个L_bank中,现在内存内部基本都会分割成4个L_bank。一块芯片分成4个L_bank,每个L_bank都可以保存相应的数据信息。
2.2.2 内存容量计算
内存容量=4*L_bank内存容量
=4*单元格数目*每个单元格容量
注:4:芯片有4个L_bank
eg:4bank*4M*16bit=32Mbyte(32M字节)
注:4bank:芯片有4个L_bank
4M:每个L_bank包含4M个单元格
16bit:每个单元格存放的数据
2.3 内存初始化
S3C2440:
对外提供27根地址线(0~26),有8个片选信号(8个bank[ngcs0-ngcs7]),内存一般在ngcs6和ngcs7。每个bank 128M容量,总共1G容量。
在处理器上访问设备只会给出一个地址:比如在*30008000=5是对应内存、norflash或者网卡芯片,CPU本身是不知道的,它只管访问这一个地址。CPU通过存储控制器进行一些相应的处理之后才能访问内存、norflash或者网卡芯片。存储控制器会分解出L_bank选择信号、行地址、列地址再去访问内存。初始化内存实际是对存储控制器初始化,然后才能访问相应的芯片。
0x22000000 0x00000700 0x00000700 0x00000700 0x00000700 0x00000700 0x00000700 0x00018001 0x00018001 0x008c04f5 0x000000b1 0x00000030 0x00000030
要把这13个数值填写到相应的13个寄存器中,可以使用循环。数值可以用类似于数组的表把它存起来,寄存器也是一个递增的关系,只要找到data1对应register1的基地址,然后p1指针指向data1,p2指针指向register1,然后把p1所指向的值写入p2所指向的寄存器中,然后同时移动p1和p2,一次类推,p2有一个起始值和一个结束值,p2移动到register13结束。

#define mem_control 0x48000000 init_sdram: ldr r0,=mem_control add r3,r0,#4*13 @r0+52表示13个数值存储到这个区间的地址,从0x48000000开始 adrl r1,mem_data @adrl作用类似于ldr,只是适用范围不同 0: ldr r2,[r1],#4 str r2,[r0],#4 cmp r0,r3 bne 0b @b:before表示往前跳转 mov pc,lr mem_data: .long 0x22000000 .long 0x00000700 .long 0x00000700 .long 0x00000700 .long 0x00000700 .long 0x00000700 .long 0x00000700 .long 0x00018001 .long 0x00018001 .long 0x008c04f5 .long 0x000000b1 .long 0x00000030 .long 0x00000030
S3C6410:
S3C6410可以分为内部空间和外设空间,总共加起来4GB大小,其中外设空间只有1GB大,这1GB又被分为8个bank,每个bank有128M。

3 代码搬移(copy steppingstone to SDRAM)
2440:nand flash启动
自动复制4KB到steppingstone中.

6410:nand flash启动
上电后运行srom中的BootLoader0(bl0),bl0是三星公司烧写到srom中的程序,bl0从nand flash中拷贝8KB的内容到steppingstone中,8KB无法满足大型BootLoader的要求,利用这8KB把剩下的拷贝到内存中,

210:nand flash启动
上电后运行srom中的BootLoader0(bl0),bl0是三星公司烧写到srom中的程序,bl0从nand flash中拷贝8KB的内容到iram(有96KB)中,如果96KB无法满足大型BootLoader的要求,把剩下的拷贝到内存中

搬移是将nand flash中的BootLoader搬移到内存中,起点应该是nand flash,但现在起点是SRAM(即steppingstone):
原因:1:如果从nand flash读取数据需要对nand flash进行初始化,(现在还没有对其做过任何初始化),所以没办法直接从nand flash中访问到数据,
2:自己编写的BootLoader远远小于4KB(6410:8KB/210:96KB),上电后nand flash拷贝到SRAM中,由于不够4KB所以都拷贝进去了。基于这两个原因可以直接从SRAM(steppingstone)中搬运。
Steppingstone起始地址:(2440:0x00/6410:0x0c000000/210:0xd0020000)
链接地址:(就是函数入口地址)

内存起始地址:(2440:0x30008000/64100:0x50008000/210:0x20008000)
绝对跳转:c语言调用函数都是绝对跳转
4 初始化bss段
未初始化的全局变量存放在bss段;
初始化原理:找到bss的起始地址和结束地址,然后把这段地址赋值为0;
4.1 实例
#include <stdio.h> int beautifule; int main() { return 0; }
/************************************* 查看方法 *************************************/ /*arm-linux-objreadelf -a beautifule >dump /*vim dump /*/year
找到beautifule地址,看其是否在bss_en地址和bss_start地址之间。
4.2 汇编初始化
bss_clean: ldr r0,=bss_start ldr r1,=bss_end cmp r0,r1 moveq pc,lr bss_clean_loop: mov r2,#0x00 str r2,[r0],#4 bne bss_clean_loop mov pc,lr