S3C6410開發全紀錄(二)《如何計算記憶體大小,並在UBOOT中調整記憶體大小》
前章我們已經可以製作出用來啟動的SD卡了,並將自己編譯的UBOOT燒錄到了SD卡中
這份UBOOT程式碼中的記憶體配置肯定和手頭的開發板不一致,這裡我們將搞清楚如何修改記憶體大小,並說清楚記憶體大小到底是如何計算的
一、關於記憶體大小的計算
1)硬體的型號,在飛凌的開發板中
128M記憶體 採用的是 K4X51163PC 可以看出來 這顆晶片是 總大小為512 bit 位寬 為16
256M記憶體 採用的是 K4X1G163PC 可以看出來 這顆晶片是 總大小為1G bit 位寬 為16
2)貼片數量2,都是用2DDR,來構成32位
3)檢視DDR的晶片手冊
128M記憶體 總共有 4 個 BANK 行列地址線數量分別為 Row = 13 Col = 10
256M記憶體 總共有 4 個 BANK 行列地址線數量分別為 Row = 14 Col = 10
4)以256M記憶體為例,記憶體大小的計算為
每個BANK的儲存單元個數 = (2^Row)*(2^Col) = 2^(Row+Col)
每個儲存單元 可以存放 16 位 的資料
總容量 = 晶片個數 * 每個晶片的BANK數量 * 位寬 * 行地址線數量 * 列地址線數量 (這裡的單位都是bit)
= 2*4*16*(2^14)*(2^10) = 2^(1+2+4+14+10)= 2^31 bit
轉換為 位元組 2^28 轉換為兆 2^8 M = 256 M
這裡需要說明的是 行列地址線的總數是 > 16 的,行列地址線在實際的使用過程中是分時複用的。
二、記憶體大小的修改
修改用來顯示的記憶體大小
./include/configs/smdk6410.h:#define PHYS_SDRAM_1_SIZE 0x10000000 /* 256 MB */
修改CPU中對應的暫存器配置
《s3c6410_rev12.pdf》196頁,5.5.4 MEMORY CONFIGURATION REGISTER
P1MEMCFG 0x7E00100C R/W 32-bit DRAM controller memory config register 0x01_0020
Active chips [22:21] 00 = 1 chip 01 = 2 chips 10 = Reserved 11 = Reserved
這裡我們是2片所以要選成 01
Row bits [5:3]
000 = 11 bits
001 = 12 bits
010 = 13 bits
011 = 14 bits
100 = 15 bits
101 = 16 bits
Column bits [2:0]
000 = 8 bits
001 = 9 bits
010 = 10 bits
011 = 11 bits
100 = 12 bits
以256M記憶體晶片的引數為例
《K4X1G163PC.pdf》晶片手冊中描述如下:
32M x16 BA0,BA1 A0 - A13 A0 - A9
這裡我們需要將Row設定為011將Column設定為010
uboot程式碼中我們可以看到
./include/s3c6410.h:#define ELFIN_DMC1_BASE 0x7e001000
./include/s3c6410.h:#define INDEX_DMC_MEMORY_CFG (0x0C)
./include/s3c6410.h:#define DMC1_MEM_CFG 0x00010012
實際上,如果通過讀CPU的手冊而將記憶體配置正確,是件挺困的事情,還好我們有很多可參考的程式碼,但我們需要弄清楚這些程式碼為什麼要這樣修改
修改行列地址線的配置
#define DMC1_MEM_CFG 0x0001001A
1A轉換為二進位制為00011010,可以看到,是我們查到的Row,Column的暫存器配置的值
在有些程式碼中也修改了 #define DMC1_CHIP0_CFG 0x150F8 這個暫存器的值,為 #define DMC1_CHIP0_CFG 0x150F0
翻遍了資料也不知道這個值是做什麼用的,為什麼要修改,所以我這裡並沒有修改這個值,也希望有經驗的朋友能告訴我為什麼。
修改UBOOT的自舉地址
一般考慮修改UBOOT自舉地址都會去修改 board/samsum/smdk6410/config.mk 中的 TEXT_BASE 的值,但這裡不能做
網上下來資料看了下,目前大多數的s3c6410開發板都沒有去修改UBOOT的自舉地址,這裡記錄了下查詢及修改的過程
cpu/s3c64xx/start.S 中看到
#ifdef CONFIG_BOOT_MOVINAND
ldr sp, _TEXT_PHY_BASE
bl movi_bl2_copy
b after_copy
#endif
_TEXT_PHY_BASE:
.word CFG_PHY_UBOOT_BASE
修改 include/configs/smdk6410.h
#define CFG_MEMTEST_END MEMORY_BASE_ADDRESS + 0x7e00000 /* 128 MB in DRAM */
#define CFG_MEMTEST_END MEMORY_BASE_ADDRESS + 0xfe00000 /* 256 MB in DRAM */
#ifdef CONFIG_ENABLE_MMU
// #define CFG_UBOOT_BASE 0xc7e00000
#define CFG_UBOOT_BASE 0xcfe00000
#else
//#define CFG_UBOOT_BASE 0x57e00000
#define CFG_UBOOT_BASE 0x5fe00000
#endif
//#define CFG_PHY_UBOOT_BASE MEMORY_BASE_ADDRESS + 0x7e00000
#define CFG_PHY_UBOOT_BASE MEMORY_BASE_ADDRESS + 0XFE00000
修改 board/samsung/smdk6410/config.mk
//TEXT_BASE = 0xc7e00000
TEXT_BASE = 0xcfe00000
修改 include/movi.h
//#define BL2_BASE 0x57E00000
#define BL2_BASE 0x5FE00000
這巨集只作用於movi_bl2_copy函式,因為我們需要將UBOOT自舉到256的最頂端
修改MMU地址對映規則
修改 board/samsung/smdk6410/lowlevel_init.S
找到 mmu_table:將
// 128MB for SDRAM 0xC0000000 -> 0x50000000
.set __base, 0x500
.rept 0xC80 - 0xC00
FL_SECTION_ENTRY __base,3,0,1,1
.set __base,__base+1
.endr
// access is not allowed.
.rept 0x1000 - 0xc80
.word 0x00000000
.endr
修改為:
// 256MB for SDRAM 0xC0000000 -> 0x50000000
.set __base, 0x500
.rept 0xd00 - 0xC00
FL_SECTION_ENTRY __base,3,0,1,1
.set __base,__base+1
.endr
// access is not allowed.
.rept 0x1000 - 0xd00
.word 0x00000000
.endr
UBOOT啟動起來,敲入 md cfe00000,打印出記憶體的資料,可以檢視到跟我們編譯出來的u-boot.bin是一致的
三、參考資料
專家詳解:記憶體工作原理及發展歷程(值得一看)
6410平臺上配置Linux的DDR引數(直接給出了結果,可以有個參考)
S3C6410的DRAM控制器(羅列的非常清楚)
《s3c6410_rev12.pdf》
《OK6410開發板硬體手冊2.1.pdf》
《K4X51163PC.pdf》
《K4X1G163PC.pdf》