imx6dl芯片手冊中內存映射(Memory Maps)章節自我理解


在解析內存映射章節之前,先明確以下幾個定義說明

物理地址: CPU地址總線上發出的地址,即CPU進行地址空間尋址的地址(作用:用於cpu地址空間尋址).

物理內存: 主板上的物理內存條所提供的內存空間定義為物理內存(嵌入式中一般指DRAM的空間), 它屬於物理地址的一部分, 也就是說每個物理內存單元的實際地址就是物理地址

IO內存: 對外設寄存器的編址方式, 將物理地址的一部分划分出來用作IO地址空間(在這里指, 一類CPU(如Power PC、ARM等)把這些外設寄存器看做是內存的一部分、寄存器參與內存統一編址,通過一般的內存指令來訪問這些外設寄存器,稱為“I/O內存”), 比如imx6dl中gpio寄存器(0x209c000-0x20b7fff), MMDC寄存器(0x21b0000-0x21b3fff)(這里MMDC是DDR控制器)等等都看成IO內存

虛擬地址: 應用程序看到的內存空間定義為虛擬地址空間, 其地址就叫做虛擬地址. 虛擬地址是硬件MMU與軟件內存管理結合的產物,方便更高效率的使用RAM. 即需要MMU(內存管理單元)的支持.

  注意: 不管是在linux還是windows下編程,程序所操作地址都是虛擬地址。

這里以imx6dl芯片為例, imx6dl系統內存映射如下圖

 

 從圖中可知系統內存映射共4G: 0x00000000 - 0xFFFFFFFF, 即CPU可尋址范圍為0 - 4G, 也就是說物理地址為0 - 4G

 物理內存范圍是0x10000000 - 0xFFFFFFFF共3G, 即理論上可外接3G內存DDR, 實際接多大看具體應用, 比如外接了1G內存DDR

 IO內存比如GPIO的寄存器范圍是0x2090000 - 0x20B7FFF, I2C, SPI, IPU等等IO內存

 這里着重分析下物理內存, 即CPU是如何尋址DDR的, 以下是項目中系統外接了1GB的DDR, 注意下面第一張是CPU內部的DDR控制器, 第二張是DDR(NT5CC256M16DP有DRAM_A14 pin腳, 但是原理圖中用的NT5CC128M16DP封裝, 所以少了DRAM_A14 pin腳, 實際PCB中DRAM_A14也連接上了DDR控制器, 只是原理圖的封裝沒畫出來)

由此可知, DDR控制器外接了兩片DDR, DDR型號為NT5CC256M16DP, 硬件連接如下:

第一片16bit DDR3BA0,BA1,BA2連接CPU DDR控制器BA0, BA1, BA2
第二片16bit DDR3 BA0,BA1,BA2連接CPU DDR控制器BA0, BA1, BA2
第一片16bit DDR3A0~A14連接CPU DDR控制器A0~A14
第二片16bit DDR3A0~A14連接CPU DDR控制器A0~A14
第一片16bit DDR3D0~D15連接CPU DDR控制器D0~D15
第二片16bit DDR3D0~D15連接CPUD16~D31

由型號可知一片DDR大小為:4Gbit, 分析如下

有8個banks ---> 3根bank地址線, BA0, BA1, BA2 ---> 8 = 2^3

從datasheet分析有15bit row行地址, 10bit coloumn列地址, 所以每個bank有32M(2^15*2^10)個單元格(基本存儲單位), 即每個bank有32M個地址可尋, 且每個單元格占16bit

所以一片DDR共有32M * 8 = 256M個地址可尋

所以一片DDR總大小為32M * 16bit * 8 = 4Gbit

由型號可知一片DDR大小為:4Gbit, 分析如下
bank地址線是3bit所以單個16bit DDR3內部有8個bank(BA0, BA1, BA2 ---> 8 = 2^3)
行地址(row)A0~A14共15bit說明每個bank有2^15行
列地址(column)A0~A9共10bit說明每個bank有2^10列

每個bank有32M(2^15*2^10)個單元格(基本存儲單位), 也就是每個bank有32M個地址可尋, 每個bank大小是2^15 * 2^10 * 16bit = 32M * 16bit = 64MB

所以一片DDR共有32M * 8 = 256M個地址可尋

所以單個16bit DDR3芯片容量總大小是32M * 16bit * 8 = 4Gbit

從前面的連線可知兩塊16bit DDR3的BA0~BA2和A0~A13是並行連接到內存控制器,所以內存控制器認為只有一塊內存,訪問的時候按照BA0~BA2和A0~A13給出地址。兩塊16bit DDR3都收到了該地址,給出的反應是要么將給定地址上的2個字節讀到數據線上,要么是將數據線上的兩個字節寫入到指定的地址。

此時內存控制器認為自己成功的訪問的了一塊32bit的內存,

所以內存控制器每給出一個地址,將訪問4個字節的數據,讀取/寫入。這4字節數據對應到內存控制器的D0~D31,又分別被連接到兩片DDR3芯片的D0~D15,這樣32bit就被拆成了兩個16bit分別去訪問單個DDR3芯片的基本存儲單元。 所以說這種接法只能4字節(32位)訪問(Only 32-bit access is supported), 與GPIO內存映射一樣的, 就是說內存訪問地址只能+4, 比如GPIO內存地址是0x209c000 -> 0x209c004 -> 0x209c008... 地址只能4字節增加. 這里這種DDR接法也限定了訪問內存地址只能4字節增加

注意:盡管每個DDR3芯片識別的地址只有256M(由上面可知2^15 * 2^10 * 8= 256M)個,但由於內存控制器每訪問一個內存地址,將訪問4個字節數據,所以對於內存控制器來說,能訪問的內存大小仍是1GB,只不過在內存控制器將地址傳給DDR3芯片時,低兩位被忽略,也就是說DDR3芯片識別的地址只有256M個。
比如內存控制器訪問地址0x000000000x000000010x000000020x00000003,但對DDR3來說,都是訪問地址0x00000000

我們可以通過以下命令獲取到內存映射表(其實就是對應用戶應用手冊中的memory map章節):

cat /proc/iomem

00110000-00111fff : /soc/dma-apbh@00110000          
00120000-00128fff : 120000.hdmi_core
00905000-0091ffff : /soc/sram@00905000
02008000-0200bfff : /soc/aips-bus@02000000/spba-bus@02000000/ecspi@02008000
0200c000-0200ffff : /soc/aips-bus@02000000/spba-bus@02000000/ecspi@0200c000
02020000-02023fff : /soc/aips-bus@02000000/spba-bus@02000000/serial@02020000
02080000-02083fff : /soc/aips-bus@02000000/pwm@02080000
02084000-02087fff : /soc/aips-bus@02000000/pwm@02084000
02088000-0208bfff : /soc/aips-bus@02000000/pwm@02088000
0208c000-0208ffff : /soc/aips-bus@02000000/pwm@0208c000
02090000-02093fff : /soc/aips-bus@02000000/can@02090000
0209c000-0209ffff : /soc/aips-bus@02000000/gpio@0209c000
020a0000-020a3fff : /soc/aips-bus@02000000/gpio@020a0000
020a4000-020a7fff : /soc/aips-bus@02000000/gpio@020a4000
020a8000-020abfff : /soc/aips-bus@02000000/gpio@020a8000
020ac000-020affff : /soc/aips-bus@02000000/gpio@020ac000
020b0000-020b3fff : /soc/aips-bus@02000000/gpio@020b0000
020b4000-020b7fff : /soc/aips-bus@02000000/gpio@020b4000
020c0000-020c3fff : /soc/aips-bus@02000000/wdog@020c0000
020c9000-020c9fff : /soc/aips-bus@02000000/usbphy@020c9000
020ca000-020cafff : /soc/aips-bus@02000000/usbphy@020ca000
020cc034-020cc08b : /soc/aips-bus@02000000/snvs@020cc000/snvs-rtc-lp@34
020e0000-020e3fff : /soc/aips-bus@02000000/iomuxc@020e0000
020ec000-020effff : 20ec000.sdma
020f0000-020f3fff : /soc/aips-bus@02000000/pxp@020f0000
02184000-021841ff : /soc/aips-bus@02100000/usb@02184000
  02184000-021841ff : /soc/aips-bus@02100000/usb@02184000
02184200-021843ff : /soc/aips-bus@02100000/usb@02184200
  02184200-021843ff : /soc/aips-bus@02100000/usb@02184200
02184800-021849ff : /soc/aips-bus@02100000/usbmisc@02184800
02188000-0218bfff : /soc/aips-bus@02100000/ethernet@02188000
02198000-0219bfff : mmc2
0219c000-0219ffff : mmc3
021a0000-021a3fff : /soc/aips-bus@02100000/i2c@021a0000
021a4000-021a7fff : /soc/aips-bus@02100000/i2c@021a4000
021a8000-021abfff : /soc/aips-bus@02100000/i2c@021a8000
021b8000-021bbfff : /soc/aips-bus@02100000/weim@021b8000
021bc000-021bffff : /soc/aips-bus@02100000/ocotp-fuse@021bc000
021d8000-021dbfff : /soc/aips-bus@02100000/audmux@021d8000
021e4000-021e7fff : /soc/aips-bus@02100000/vdoa@021e4000
021ec000-021effff : /soc/aips-bus@02100000/serial@021ec000
021f4000-021f7fff : /soc/aips-bus@02100000/serial@021f4000
02400000-027fffff : 2400000.ipu
10000000-4fffffff : System RAM
  10008000-1088e217 : Kernel code
  108e2000-1099e69b : Kernel data

“System RAM” 就是物理內存(DRAM)的空間, 0x10000000 - 0x4fffffff共1GB(就是實際DRAM接了1GB的內存條)

另注意: 市面上說的手機內存有兩種含義, 一種是系統內存RAM, 一種是存儲內存ROM, 手機的運行速度跟系統內存RAM大小有關, 而系統存放文件大小跟存儲內存ROM有關. 還有系統   內存理論大小跟CPU處理器地址線位寬有關, 比如32位的處理器, 它的理論系統內存可達到4G, 64位的處理器, 他的理論系統內存可達到2^64bit(足夠大). 還有就是說手機系統內存4G, 其實手機運行內存肯定不足4G, 因為系統會占用一部分內存(比如外設會占用IO內存), 而真正划分給運行內存的大小(即外接DDR的大小)會小於4G. 因為應用程序代碼是運行在DDR上的,所以真正影響手機速度的是運行內存大小.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM