目录
SD卡
内存(RAM)与外存(ROM)的区别:
RAM:random access memory.随机访问存储器.特点是任意字节读写(随机访问),掉电丢失.
ROM:read only memory.只读存储器.用于存储东西. 用来存储东西,掉电不丢失,不能随机地址访问,只能以块为单位来访问)叫外存.
5类外存:
原理工作方式 | 典型应用 | 速度 | 可靠性 | 价格 | 应用方面 | ||
电磁 | 磁存储.物理运动,摩擦,有损耗 | 磁带,软盘,CD,光盘,机械硬盘 | 慢 | 差 | 便宜 | PC机 | |
flash | 闪存设备:利用电学原理来存储,无损耗 | nandflash,norflash | |||||
SD卡,MMC卡,MicroSD卡,TF卡 | |||||||
inand,movinand,TF卡,ESSD | |||||||
SSD |
SD卡相关分区内容设置
注:
1个block为512个byte.
2048block 为 1M
SD卡存储规则
第一个block(block0) 不能使用.
BL1必须从block1开始写起.长度为16kb(32个block)
BL2,KERNEL长度自己定.
BL1与BL2,BL2与kernel之间最好留有一定的空白区域(隔离安全带).
SD卡相关功能代码
Device Copy Function
iROM中事先内置了一些代码去初始化外部SD卡/NandFlash,并且内置了读取各种SD卡/NandFlash的代码在iROM中。BL0执行时就是通过调用这些device copy function来读取外部SD卡/NandFlash中的BL1的。这些函数代码我们是不知道具体的源码,只知道这些函数的首地址存储在IROM中的特定位置:
IROM里面有一些连续区域,存放着相关Device Copy Function相关类型启动介质函数的首地址.
Device Copy Function使用方法:
由于每种启动介质的函数类型不同,故在使用时候要注意:
1.定义的函数指针类型(输入参数类型及个数,返回值类型)不同.
2.以上图里面存放的仅仅是函数的首地址,类型为uint型,正确的使用方法是先定义一个正确的符合要求的函数指针变量p,
如:
1.*(uint *)0xd0037f98 //按照uint类型读取读取内存地址为0xd0037f98里面的值,.这个值是CopySDMMCtoMem函数代码地址的首地址
2.定义一个函数指针类型pF,其类型是CopySDMMCtoMem函数类型.用以指向CopySDMMCtoMem函数.
3.定义一个函数指针变量p1,并指向CopySDMMCtoMem函数
pF p1=(pF)( *(uint*)0xd0037f98) 将内存里面的值强制转化为pF型
4.调用p1
*p1;或p1;
宏定义方法:
#define CopySDMMCtoMem(z,a,b,c,e)(((bool(*)(int, unsigned int, unsigned short, unsigned int*,bool))(*((unsigned int *)0xD0037F98)))(z,a,b,c,e))
函数指针调用方法:
( ( bool(*)(int, unsigned int, unsigned short, unsigned int*, bool))(*((unsigned int *)0xD0037F98)) )
makefile 调用子文件夹下的makefile
第一种方式:
cd lib; make; cd...
进入lib文件夹,执行make命令,再cd出来.
第二种方式:
make –C ./BL1 :表示进入到BL1文件夹里执行里面的makefile命令
make clean –C ./BL2 :表示进入到BL2文件夹里执行里面的make clean命令
ubuntu在目标文件夹中中输入 write2sd命令,执行write2sd这个脚本.
write2sd脚本内容:
#!/bin/sh
sudo dd iflag=dsync oflag=dsync if=./BL1/BL1.bin of=/dev/sdb seek=1
sudo dd iflag=dsync oflag=dsync if=./BL2/BL2.bin of=/dev/sdb seek=45
烧录SD卡命令
dd:linux烧录,读写磁盘命令
if:in file
of:out file
seek:第几个扇区开始.
以上语句表明要烧录2次.
SD卡在ubuntu中烧录的方法:
SD卡通过读卡器连接到PC上,此时进入ubuntu,
点击”断开连接”.如果可移动设备中没有SD卡出现,则需要在XP中开启VMware USB Arbitration Service服务.
XP中开启VMware USB Arbitration Service服务
注:如果ubuntu中没有SD选项,则需要开启此项服务.
开启方法:
XP系统>控制面板>管理工具,开启VMware USB Arbitration Service服务
如何确定有SD卡插入:
ubuntu在目标文件夹中中输入 dev/sd*命令:
dev/sd*:一切设备都是文件,此目录下存放着sd卡的文件描述符.
sdb1:
b位为a,b,c,d,e,,f,代表存储设备的编号.一般SD卡为b,硬盘为a .
1代表第几个分区.
注意:烧录脚本中的sd*要和实际中的一致.
如果里面的/dev/sdb 文件类型不对(看颜色),则需要删除它(rm –f /dev/sdb),再重新插入SD卡后即可.
烧录:直接在目录中执行 ./write2sd,直到出现以下信息表明烧录完成
注意:有些生成的镜像文件很大,(如LCD显示图片等程序),大于16kb,这时候就必须要进行代码重定位,实现分步加载.BL1仅仅做一些初始化工作,BL2则是真正运行的主程序代码.分步加载的时候还要注意SD卡烧写的扇区个数要达到整个程序的文件大小.
SD卡重定位
SD卡重定位copy到DDR中的代码(BL2)必须放在已经初始化过的DDR中
S5PV210中DDR内存地址范围:
DRAM0:0x20000000~0x3FFFFFFF(512MB),对应引脚是Xm1xxxx
DRAM1:0x40000000~0x7FFFFFFF(1024MB),对应引脚是Xm2xxxx
X210中DDR内存地址范围:
DRAM0:0x20000000~0x2FFFFFFF(256MB)
DRAM1:0x40000000~0x4FFFFFFF(256MB)
DDR初始化
SDRAM(DDR)初始化使用一个函数sdram_asm_init,函数在sdram_init.S文件中实现,是一个汇编函数。
分散加载SD卡
文件结构
BL1:包含
link.lds 链接脚本.链接到0xd0020010
start.S:汇编文件.主要功能是
关看门狗,
设置SVC栈,设置完成后就可以调用C函数了
开关icache
初始化DDR(bl sdram_asm_init函数),初始化DDR后就可以把代码拷贝至DDR中运行了.
重定位: bl copy_bl2_2_ddr 将SD卡中的BL2拷贝至DDR某处.并跳转到此处运行
makefile:设置编译规则,其中
bootloader1.bin:可以用USB烧录.
BL1.bin:是复制到SD卡中用SD卡烧录. BL1.bin是bootloader1.bin经过mkv210加工转化增加头文字校验信息得到的专门用于SD卡烧录的镜像文件.
mkv210_image.c:加工文件.
s5pv210.h: s5pv210头文件.
sd_relocate.c:SD卡复制及跳转函数
其中
p1(2, SD_START_BLOCK, SD_BLOCK_CNT, (unsigned int *)DDR_START_ADDR, 0); // 读取SD卡相关内容到DDR指定位置中
//2:代表SD卡通道号.
//SD_START_BLOCK:SD卡复制的起始扇区号.
//SD_BLOCK_CNT:SD卡要复制扇区的个数.
//DDR_START_ADDR:0x23E00000 //为长跳转的地址,与重定位的链接脚本地址要一致
pBL2Type p2 = (pBL2Type)DDR_START_ADDR;//实现强制长跳转.
BL2:包含
start.S:汇编文件,实现长跳转ldr pc, =main
link.lds 链接脚本.链接到长跳转的地址0x23E00000并从此处开始运行
makefile:设置编译规则,此makefile已经不需要将生成的bin文件再通过mkv210加工转化增加头文字校验信息得到的专门用于SD卡烧录的镜像文件.
开机,IROM自动将SD卡中的block1-block32扇区的内容(BL1)加载至iram中运行,当DDR初始化完毕的时候,就可以将SD卡其他内容复制到DDR中.
复制完毕后,用一长跳转指令,跳转到DDR中去执行BL2.
拓展阅读
1.SD卡编程接口
2.SD卡