历史上的今天
返回首页

历史上的今天

今天是:2024年12月20日(星期五)

正在发生

2021年12月20日 | tiny4412 裸机程序 七、重定位代码到DRAM

2021-12-20 来源:eefocus

一、关于DRAM

上一章我们讲解了如何对代码进行重定位,但是将代码重定位到只有256K IRAM中作用不大。

正确的做法是将代码重定位到容量更大的主存中,即DRAM。Exynos4412中有两个独立的DRAM控制器,分别叫DMC0和DMC1。DMC0和DMC1分别支持最大1.5G的DRAM,它们都支持DDR2/DDR3和LPDDR2等,512 Mb, 1 Gb, 2 Gb, 4 Gb and 8 Gbit的内存设备,支持16/32bit的位宽。DRAM0 对应的地址是0x4000_0000~0xAFFF_FFF共1.5GB,DRAM1 对应的地址是0xA000_000~0x0000_0000共1.5GB。

 

图7-1、DRAM控制地址图

查阅Tiny4412的原理图:

 

图7-2、DRAM电路原理样图

Tiny4412的512M的DRAM是由4片大小为128M的DDR3芯片组合而成(上图仅为其中一片),观察片选引脚可知4片DRAM芯片都是挂接到DMC0处。

如何才能使用DRAM?对应Tiny4412而言,由于它只用到了DMC0,所有我们只需要初始化DMC0和DDR3 DRAM芯片即可,本实验所有的初始化代码全部来自于U-BOOT程序。需要说明一点的,我在写这个裸机程序文档之前,已经看了一段时间U-BOOT程序,U-BOOT程序中对DRAM也做了相应的初始化工作,我就直接拿来用了,在参考学习U-BOOT过程中,我也记录了一份学习文档,里面有比较详细的DRAM初始化说明,等我U-BOOT实验成功后,我会整理一份相应文档。

Linux平台下Mini210S裸机程序开发指南》文档从我现有资料中找到他所说的类似的芯片说明。我只能参考着他的说明,从U-BOOT中找到一个函数,从他那里COPY了一些代码,来实现这个函数。大家先来一遍《linux平台下Mini210S裸机程序开发指南》文档关于此函数的说明 ,我在说一下我是怎么写的这个函数的。

 

经过mem_init函数对DRAM的初始化后,我们就可以拷贝代码到DRAM中然后跳转到DRAM中继续运行了,由BL1目录下的mmc_relocate.c来实现这部分功能,mmc_relocate.c的代码如下:

void copy_code_to_dram(void)

{

unsigned long ch;

void (*BL2)(void);

ch = *(volatile unsigned int *)(0xD0037488);

copy_sd_sd_to_mem copy_bl2 =(copy_sd_sd_to_mem) (*(unsigned int *) (0xD0037F98));

unsigned int ret;

// 通道0

if (ch == 0xEB000000)

{

// 0:channel 0

// 49:源,代码位于扇区49,1 sector = 512 bytes

// 32:长度,拷贝32 sector,既16K

// 0x23E00000:目的,链接地址0x23E00000

ret = copy_bl2(0, 49, 32,(unsigned int*)0x23E00000, 0);

}

// 通道2

else if (ch == 0xEB200000)

{

ret = copy_bl2(2, 49, 32,(unsigned int*)0x23E00000, 0);

}

else

return;

// 跳转到DRAM中

BL2 = (void *)0x23E00000;

(*BL2)();

}

首先我们定义了一个函数指针copy_bl2,将其赋值为0xD0037F98。为什么要这么做,是因为IROM内部固化的代码已经帮我们实现了一类拷贝函数,其中就包括从sd卡拷贝内容到DRAM的函数,这类函数所位于的地址见下图:

 

 

由上图可知,External Copy Function位于0xD0037F80~0xD0038000处,其中sd卡拷贝内容到DRAM的函数就位于地址0xD0037F98,其函数原型如下:

 

其中:

StartBlkAddress:从第几个扇区开始拷贝,一个扇区为512byte

blockSize:拷贝多少个扇区

memoryPtr:拷贝到DRAM的哪个地址上

with_init:是否需要初始化sd卡

有了上面这些知识,也就很容易看懂copy_code_to_dram 函数了。通过读地址0xD0037488上的值来确定是使用通道0还是通道1,芯片手册上明确指出“sd/MMC/eMMC boot – MMC Channel 0 is used for first boot. And Channel 2 is used forSecond boot”,我们的BL1.bin就是first boot,所以会使用通道0,调用CopysdMMCtoMem函数将BL2.bin从sd卡的扇区49拷贝到DRAM的0x23E00000处,拷贝的长度是16K。最后给BL2这个函数指针赋值0x23E0000,然后调用BL2函数即可跳转到0x23E0000处运行BL2.bin里的代码了。

 

大家看明白了,一句话三星的芯片内部已经有一个函数是用为从外部存储COPY东西内部iRAM或者DRAM中了,但是我在现有三星手册上没有找到类似的函数说明,没办法,我们这些学习者,是很难拿全芯片厂商的资料的。但也不是就没有办法实现这个实验了,U-BOOT中总会干这么个事吧,里面肯定有相关代码,所以我只能去分析U-BOOT的代码了,里面有一个文件叫/arch/arm/cpu/armv7/exynos/irom_copy.c的文件,里面的一个函数movi_uboot_copy(),就是将U-BOOT复制到DRAM中的,好了从这里复制必要代码实现自己的函数吧,我们的函数主要内容如下:

下面内容是定义了我们将要使用的COPY函数,这个函数就是实现了Mini210S中的copy_bl2的功能。

#defineISRAM_ADDRESS   0x02020000

#defineSECURE_CONTEXT_BASE 0x02023000

#defineEXTERNAL_FUNC_ADDRESS   (ISRAM_ADDRESS +0x0030)

#defineEXT_eMMC43_BL2_ByCPU_ADDRESS    (EXTERNAL_FUNC_ADDRESS+ 0x4)

#defineMSH_ReadFromFIFO_eMMC_ADDRESS   (EXTERNAL_FUNC_ADDRESS+ 0x14)

#defineMSH_EndBootOp_eMMC_ADDRESS  (EXTERNAL_FUNC_ADDRESS+ 0x18)

#defineLoadImageFromUsb_ADDRESS    (EXTERNAL_FUNC_ADDRESS+ 0x40)

#defineSDMMC_ReadBlocks(uStartBlk, uNumOfBlks, uDstAddr)  

\定义COPY函数的原型。

    (((void(*)(unsigned int, unsigned int,unsigned int*))(*((unsigned int *)EXTERNAL_FUNC_ADDRESS)))(uStartBlk,uNumOfBlks, uDstAddr))

 

下面开始复制代码到DRAM中,首先声明了两个串口输出函数,实现这两个函数是为了调试用的。因为我说过,我现在程序不一定能执行成功,有时LED灯闪烁了,有时又没有。所以我打出了必要东西来调试用,大家也当学习嘛。

externvoid uart_asm_putc(int c);

externvoid uart_asm_putx(int x);

voidcopy_code_to_dram(void)

{

    void (*user_bin)(void);

    //这里怕DRAM没有初始化完成,等待了一会

    volatile unsigned long  count=0x100000;

    while(count>0){

        count--;}

 

    uart_asm_putc('C');

    uart_asm_putc('O');

    uart_asm_putc('P');

    uart_asm_putc('Y');

    uart_asm_putc('r');

    uart_asm_putc('n');

    //从SD卡扇区49处复制32个扇区的内容到内存地址0x43e00000处

推荐阅读

史海拾趣

普芯达电子(Chipswinner)公司的发展小趣事

普芯达电子的“中国风”系列产品是公司发展历程中的一个重要里程碑。该系列产品经过严格的质量控制和品质检测,以其优异的性能和可靠的品质赢得了市场的广泛认可。通过一系列的市场推广活动,“中国风”品牌逐渐深入人心,成为国产集成电路产品的代表之一。同时,普芯达电子还通过不断创新和优化产品,满足了客户日益增长的需求,进一步巩固了市场地位。

ABLIC公司的发展小趣事

在过去的六年里,ABLIC实现了高盈利,这得益于其不断创新的产品线和市场策略。为了进一步拓展业务,ABLIC将目光投向了欧洲市场。欧洲作为全球电子产业的重要区域,对于模拟半导体的需求持续增长。ABLIC凭借其在小型、低功耗和精确模拟半导体产品方面的优势,积极在欧洲市场寻求合作机会,为公司的长远发展奠定了坚实基础。

FASTRAX公司的发展小趣事

随着公司业务的不断发展,FASTRAX开始积极拓展海外市场,并与多家国际知名企业建立了战略合作关系。通过与这些企业的合作,FASTRAX不仅获得了更多的市场份额,也学习到了先进的管理经验和技术知识。这些合作经验为FASTRAX的持续发展奠定了坚实的基础。

E Connector Solutions公司的发展小趣事

随着公司业务的不断发展,E Connector Solutions公司开始积极拓展市场。公司通过参加国际展会、与海外客户建立合作关系等方式,逐步打开了国际市场的大门。同时,公司还积极实施国际化战略,通过设立海外研发中心、生产基地等方式,加强与全球客户的合作与交流。这些举措不仅拓宽了公司的业务范围,还提升了公司的国际竞争力。

洲光源(Chau Light)公司的发展小趣事

在洲光源公司的发展历程中,品质一直是其核心竞争力之一。公司始终坚持严格的质量控制标准,从原材料采购到产品生产、检测的每一个环节都严格把关。同时,洲光源还注重品牌塑造和市场推广,通过参加各种行业展会、举办技术交流会等方式,不断提升品牌知名度和影响力。这些努力使得洲光源的红外LED产品逐渐在市场上脱颖而出,成为众多客户的首选品牌。

BERGQUIST公司的发展小趣事

为了进一步提升竞争力,BERGQUIST公司开始寻求产业链整合和战略合作。公司与上游原材料供应商建立了长期稳定的合作关系,确保原材料的质量和供应稳定性。同时,公司还与下游电子设备制造商开展深度合作,共同研发定制化的热管理解决方案。这些举措不仅降低了公司的运营成本,还提高了产品的市场竞争力。

问答坊 | AI 解惑

单片机MCS-51系列指令快速记忆法

单片机MCS-51系列指令快速记忆法 单片机MCS-51系列指令快速记忆法 随着微电子技术和超大规模集成电路技术的发展,单片微型计算机以其体积小、性价比高、功能强、可*性高等独有的特点,在各个领域(如工业控制、家电产品、汽车电子、通信、智能仪 ...…

查看全部问答>

LIUNX系统移植

LIUNX系统移植 很好的啊…

查看全部问答>

关于加速计和陀螺仪的测试

各位高手有没有测试过加速计和陀螺仪这两颗的功能阿,三轴加速计有X,Y,Z三个电压输出,都是经过其内部的AD转换后输出的,不知道这三个方向上的电压是怎么变化的,是有加速度的时候变化呢,还是位置改变了变化啊? 陀螺仪有X,Y两个电压输出,也是 ...…

查看全部问答>

关于MTD驱动的问题

很多MTD驱动都有调用simple_map_init()函数来初始化read,write等函数,不知道这个函数的用法,请大虾帮忙讲一讲啊,如果我需要改变这些read,write函数,该怎么办啦?…

查看全部问答>

XILINX CPLD求助

各位高手,高手,高高手们:新手使用XILINX的 XC95288,有个问题求助:我从一块XC95288上readback后,保存成.jed文件,然后再烧入到另外一个片子后,另外这个片子就不能readback了,然后我擦除写入的这个文件后,就又能readback了,这是为什么呢? ...…

查看全部问答>

英蓓特STM32ARM开发板的初级改造(有图)

上周在研讨会上买了英蓓特的开发板,试了下,感觉有几个地方不爽,所以就自己动手DIY了:1)USB供电问题,必须插2条USB线,可怜我的本本一共才3个,鼠标用了一个,被他全占了,其它USB-232就没法用了;2)板子附带的1602没有接背光,而实际这 ...…

查看全部问答>

时钟配置问题

1  TIM_TimeBaseStructure.TIM_Period = 999;       //当定时器从0计数到999,即为1000次,为一个定时周期 2  TIM_TimeBaseStructure.TIM_Prescaler = 0;     //设置预分频: 3&nbs ...…

查看全部问答>

關於LMF232H5QD的UART問題

各位高手大家好,小妹我用此板子的UART出了一點問題,大家可以幫幫我嗎? 感激不盡 問題是這樣的,我開啟了八個UART,為了使輸入資料可以做辨識,個別在UART4跟UART5的地方 加了三個#字號跟一個通道編號 例如:UART4是  ###Edata 這樣 ...…

查看全部问答>

今年会出功率放大类的吗?

本帖最后由 paulhyde 于 2014-9-15 03:16 编辑 今年会出功率放大类的吗    …

查看全部问答>