Tiny4412裸机程序之代码在DDR SDRAM中运行
轉載:http://www.techbulo.com/1509.html
Tiny4412裸機程序之代碼在DDR SDRAM中運行
2014年11月13日???裸機程序?? 共 8647字 ? 字號?小?中?大???評論 17 條?? 閱讀 2,762 次上一此實驗我們講解了如何對代碼進行重定位,但是將代碼重定位到只有256K的IRAM中作用不大。正確的做法是將代碼重定位到容量更大的主存中,即DRAM中。
Exynos4412中有兩個獨立的DRAM控制器,分別叫DMC0和DMC1。DMC0和DMC1分別支持最大1.5GB的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。
DRAM控制器地址映射
Tiny4412的1GB的DRAM是由4片大小為128MX16的DDR3芯片組合而成,下面看一下Tiny4412的原理圖:
Tiny4412 DDR電路圖
Tiny4412 DDR電路圖
從上兩圖可以看出,這四片DDR 芯片被分成了兩兩一組,組成32位數據,四片都是掛接到DMC0處。
如何才能使用DRAM?對應Tiny4412而言,由于用到了DMC0,所有我們需要初始化DMC0和DDR3 DRAM芯片。
聲明一下:
從這一節開始我們的程序結構發生了一些變化,前幾個實驗我們只生成一個文件,從這個實驗開始我們生成兩個文件,BL2.bin和main.bin,其中BL2.bin文件的鏈接地址是0x02023400;(使用的是位置無關碼,程序可以在任意可用的內存中運行),main.bin 文件的鏈接地址是0x43E00000(使用的并不是位置無關碼,所有程序必須位于該地址處才能正常運行)。需要在SD卡上燒寫三部分程序,分別是:
1.BL1(由三星提供):實現一些初始化
2.BL2(我們自己編寫源碼,用mkbl2工具生成):板級初始化,并完成代碼重定位到DDR SDRAM,完成跳轉
3.主代碼:實現我們想要的功能
三部分代碼在SD卡的位置如下:
程序在SD卡的位置分布
從圖中可以看出,BL1.bin燒寫到SD卡扇區1,BL2.bin燒寫到sd卡的扇區17,main.bin燒寫到sd卡的扇區49處。
整個程序的運行過程大致如下:系統上電后,首先將sd卡扇區1處的bl1拷貝到IRAM的0x02020000地址處,然后運行該部分代碼,該部分代碼首先又會加載BL2.bin,BL2.bin會進行時鐘和DRAM初始化,然后把位于sd卡中扇區49處的main.bin拷貝到DRAM的0x43E00000地址處,最后跳轉到該地址處繼續運行。
?
一、程序說明
DDR的初始化順序在前一篇文章Tiny4412裸機程序之DDR3初始化流程我們已經經過,下面就根據前面提及的步驟一一來進行設置。
注:看到這么多設置步驟,實在太繁瑣了,我們參考u-boot for Tiny4412中的代碼,搞明白它設置了哪些東西:
| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 | /** (C) Copyright 2011 Samsung Electronics Co. Ltd** See file CREDITS for list of people who contributed to this* project.** This program is free software; you can redistribute it and/or modify* it under the terms of the GNU General Public License version 2 as* published by the Free Software Foundation.**/#include <config.h>#include <asm/arch/cpu.h>#define MCLK_400.globl mem_ctrl_asm_initmem_ctrl_asm_init:/* Async bridge configuration at CPU_core:* 1: half_sync* 0: full_sync */ldr r0, =0x10010350mov r1, #1str r1, [r0]/*這幾行代碼不知道什么意思,以及這樣做的原因*//*****************************************************************//*DREX0***********************************************************//*****************************************************************/ldr r0, =APB_DMC_0_BASEldr r1, =0xe0000086str r1, [r0, #DMC_PHYCONTROL1]/*2. If on die termination is required, enable PhyControl1.term_write_en,PhyControl1.term_read_en.*/ldr r1, =0xE3854C03str r1, [r0, #DMC_PHYZQCONTROL]/*3. If ZQ calibration is required, disable PhyZQControl.ctrl_zq_mode_noterm and enable PhyZQCon-trol.ctrl_zq_start so that the PHY automatically calibratesthe I/Os to match the driving and termination impedanceby referencing resistor value of an external resistorand updates the matched value during auto re-fresh cycles.*/mov r2, #0x1000001: subs r2, r2, #1bne 1bldr r1, =0x7110100Astr r1, [r0, #DMC_PHYCONTROL0]/*4. Set the PhyControl0.ctrl_start_point and PhyControl0.ctrl_inc bit-fields to correct value according to clock frequency.Set the PhyControl0.ctrl_dll_on bit-field to "1" to activate the PHY DLL.*/ldr r1, =0xe0000086str r1, [r0, #DMC_PHYCONTROL1]/*5. DQS Cleaning: set the PhyControl1.ctrl_shiftc and PhyControl1.ctrl_offsetc bit-fields to the proper value according to clock frequency,board delay and memory tDQSCK parameter.*/ldr r1, =0x7110100Bstr r1, [r0, #DMC_PHYCONTROL0]/*6. Set the PhyControl0.ctrl_start bit-field to "1".*/ldr r1, =0x00000000str r1, [r0, #DMC_PHYCONTROL2]/*DQS offset*//*實驗了一下可以省略,默認值就是全零*/ldr r1, =0x0FFF301Astr r1, [r0, #DMC_CONCONTROL]/*7. Set the ConControl. At this moment,an auto refresh counter should be off.*/ldr r1, =0x00312640str r1, [r0, #DMC_MEMCONTROL]/*8. Set the MemControl. At this moment,all power down modes and periodic ZQ(pzq_en) should be off.*/ldr r1, =0x40e01323str r1, [r0, #DMC_MEMCONFIG0]ldr r1, =0x60e01323str r1, [r0, #DMC_MEMCONFIG1]/*9. Set the MemConfig0 register. If there are two external memory chips,also set the MemConfig1 register.*/ldr r1, =(0x80000000 | CONFIG_IV_SIZE)str r1, [r0, #DMC_IVCONTROL]/*Memory Channel Interleaving*//*實驗了一下可以省略,用默認值就可以*/ldr r1, =0xff000000str r1, [r0, #DMC_PRECHCONFIG]/*10. Set the PrechConfig and PwrdnConfig registers.*/ldr r1, =0x000000BBstr r1, [r0, #DMC_TIMINGAREF] @TimingArefldr r1, =0x4046654fstr r1, [r0, #DMC_TIMINGROW] @TimingRowldr r1, =0x46400506str r1, [r0, #DMC_TIMINGDATA] @TimingDataldr r1, =0x52000a3cstr r1, [r0, #DMC_TIMINGPOWER] @TimingPower/*11. Set the TimingAref, TimingRow, TimingData andTimingPower registers according to memory AC parame-ters.*//* chip 0 */ldr r1, =0x07000000str r1, [r0, #DMC_DIRECTCMD]/*19. Issue a NOP command using the DirectCmd register to assert and to hold CKE to a logic high level.*/mov r2, #0x1000002: subs r2, r2, #1bne 2b/*20. Wait for tXPR(max(5nCK,tRFC(min)+10ns)) or set tXP to tXPR value before step 17. If the system set tXP to tXPR, then the system must set tXP to proper value before normal memory operation.*/ldr r1, =0x00020000str r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00030000str r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00010002str r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00000328str r1, [r0, #DMC_DIRECTCMD]/*沒搞明白這里發的什么指令*/mov r2, #0x1000003: subs r2, r2, #1bne 3bldr r1, =0x0a000000str r1, [r0, #DMC_DIRECTCMD]/*26. Issues a ZQINIT commands using the DirectCmd register.*/mov r2, #0x1000004: subs r2, r2, #1bne 4b/*27. If there are two external memory chips, perform steps 19 ~ 26 procedures for chip1 memory device.*/#if 1/* chip 1 */ldr r1, =0x07100000str r1, [r0, #DMC_DIRECTCMD]mov r2, #0x1000005: subs r2, r2, #1bne 5bldr r1, =0x00120000str r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00130000str r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00110002str r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00100328str r1, [r0, #DMC_DIRECTCMD]mov r2, #0x1000006: subs r2, r2, #1bne 6bldr r1, =0x0a100000str r1, [r0, #DMC_DIRECTCMD]mov r2, #0x1000007: subs r2, r2, #1bne 7b#endifldr r1, =0xe000008estr r1, [r0, #DMC_PHYCONTROL1]ldr r1, =0xe0000086str r1, [r0, #DMC_PHYCONTROL1]mov r2, #0x1000008: subs r2, r2, #1bne 8b/*****************************************************************//*DREX1***********************************************************//*****************************************************************/ldr r0, =APB_DMC_1_BASEldr r1, =0xe0000086str r1, [r0, #DMC_PHYCONTROL1]ldr r1, =0xE3854C03str r1, [r0, #DMC_PHYZQCONTROL]mov r2, #0x1000001: subs r2, r2, #1bne 1bldr r1, =0xe000008estr r1, [r0, #DMC_PHYCONTROL1]ldr r1, =0xe0000086str r1, [r0, #DMC_PHYCONTROL1]ldr r1, =0x71101008str r1, [r0, #DMC_PHYCONTROL0]ldr r1, =0x7110100Astr r1, [r0, #DMC_PHYCONTROL0]ldr r1, =0xe0000086str r1, [r0, #DMC_PHYCONTROL1]ldr r1, =0x7110100Bstr r1, [r0, #DMC_PHYCONTROL0]ldr r1, =0x00000000str r1, [r0, #DMC_PHYCONTROL2]ldr r1, =0x0FFF301Astr r1, [r0, #DMC_CONCONTROL]ldr r1, =0x00312640str r1, [r0, #DMC_MEMCONTROL]ldr r1, =0x40e01323 @Interleaved?str r1, [r0, #DMC_MEMCONFIG0]ldr r1, =0x60e01323str r1, [r0, #DMC_MEMCONFIG1]ldr r1, =(0x80000000 | CONFIG_IV_SIZE)str r1, [r0, #DMC_IVCONTROL]ldr r1, =0xff000000str r1, [r0, #DMC_PRECHCONFIG]ldr r1, =0x000000BBstr r1, [r0, #DMC_TIMINGAREF] @TimingArefldr r1, =0x4046654fstr r1, [r0, #DMC_TIMINGROW] @TimingRowldr r1, =0x46400506str r1, [r0, #DMC_TIMINGDATA] @TimingDataldr r1, =0x52000a3cstr r1, [r0, #DMC_TIMINGPOWER] @TimingPower/* chip 0 */ldr r1, =0x07000000str r1, [r0, #DMC_DIRECTCMD]mov r2, #0x1000002: subs r2, r2, #1bne 2bldr r1, =0x00020000str r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00030000str r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00010002str r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00000328str r1, [r0, #DMC_DIRECTCMD]mov r2, #0x1000003: subs r2, r2, #1bne 3bldr r1, =0x0a000000str r1, [r0, #DMC_DIRECTCMD]mov r2, #0x1000004: subs r2, r2, #1bne 4b#if 1/* chip 1 */ldr r1, =0x07100000str r1, [r0, #DMC_DIRECTCMD]mov r2, #0x1000005: subs r2, r2, #1bne 5bldr r1, =0x00120000str r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00130000str r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00110002str r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00100328str r1, [r0, #DMC_DIRECTCMD]mov r2, #0x1000006: subs r2, r2, #1bne 6bldr r1, =0x0a100000str r1, [r0, #DMC_DIRECTCMD]mov r2, #0x1000007: subs r2, r2, #1bne 7b#endifldr r1, =0xe000008estr r1, [r0, #DMC_PHYCONTROL1]ldr r1, =0xe0000086str r1, [r0, #DMC_PHYCONTROL1]mov r2, #0x1000008: subs r2, r2, #1bne 8b/*****************************************************************//*Finalize********************************************************//*****************************************************************/ldr r0, =APB_DMC_0_BASEldr r1, =0x0FFF303Astr r1, [r0, #DMC_CONCONTROL]/*28. Set the ConControl to turn on an auto refresh counter.*/ldr r0, =APB_DMC_1_BASEldr r1, =0x0FFF303Astr r1, [r0, #DMC_CONCONTROL]/*28. Set the ConControl to turn on an auto refresh counter.*/mov pc, lr |
二、編譯、燒寫、運行
1.編譯
通過FTP或者其他工具將文件上傳到服務器上去,輸入make命令進行編譯將得到make_bl2.bin和main.bin文件。
2.燒寫
將SD卡插入電腦,并讓VmWare里的Ubuntu識別出來,然后執行如下命令:
| 1 | sudo ./sd_fusing.sh /dev/sdb ../9_reload_ddr/BL2/make_bl2.bin ../9_reload_ddr/MAIN/main.bin |
程序燒寫
二、運行現象
將SD卡插入Tiny4412開發板,連接串口工具,上電,你會看到和上一節的運行效果一樣(因為我們沒有修改LED的顯示效果,只是修改了程序的運行地址,這個對外是看不出區別的)。
串口可以看到如下顯示信息;
運行效果
從圖的信息室打印的地址0x43E00000處的內容(main.bin文件的鏈接地址)
我們將上述打印的信息和main.bin文件進行對比,發現完全一樣,說明代碼已經拷貝到了正確的鏈接地址。
文件對比
?
完整的程序下載地址(解壓密碼:WWW.techbulo.Com):
總結
以上是生活随笔為你收集整理的Tiny4412裸机程序之代码在DDR SDRAM中运行的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何零基础零费用的在30分钟内用hugo
- 下一篇: PS-图像颜色调节