剛開始學習linux,今天來移植u-boot在友善smart210的板子上。官網擷取opencsbc-u-boot-mini210_linaro-2011.10-stable.tar.gz,mini210的u-boot。(指導老師:咕唧咕唧LK)
1, 在mini210解壓當前檔案下輸入命令:
$make ARCH=arm CROSS_COMPILE=/opt/FriendlyARM/toolschain/4.5.1/bin/arm-none-linux-gnueabi- tiny210_config
該句命令對總Makefile進行參數的傳遞。ARCH=arm 傳入參數對運行板級CPU進行配置,CROSS_COMPILE則是對其板級相應的交叉工具鏈的路徑。如果已經設定環境變數可以直接添加Makefile裡CROSS_COMPILE=arm-none-linux-gnueabi-
tiny210_config則是對運行在boards.cfg 對其相應參數進行賦值然後執行mkconfig。把兩步定義為tiny210_config。對上述設定後則後續調試就可直接輸入make tiny210_config。
2,對mini210_uboot進行編譯,make all spl。把相應的第一階段bin檔案mini210-spl.bin拷入SD卡的第一扇區,把第二階段的bin檔案u-boot.bin檔案拷入第49扇區。為什麼第二階段拷貝到49扇區,因為u-boot的第一階段代碼是被IROM的固話代碼搬移到IRAM裡的。根據手冊只搬移了24K到IRAM。每個扇區是512位元組,那麼前48個扇區正好是24K,第二階段就在24K之後,當然這個第二階段的扇區也可以改變,需要在第二階段搬移代碼的時候修改即可。拷入扇區的命令為:
$sudo dd iflag=dsync oflag=dsync if=spl/tiny210-spl.bin of=/dev/sdb seek=1
$sudo dd iflag=dsync oflag=dsync if=u-boot.bin of=/dev/sdb seek=49
3,板子上電SD卡運行可以看到顯示OK,那麼說明這個mini210的u-boot在smart210上的沒能夠運行起來。我們需要設定led燈來查看其可能出錯的地方。用在start.S裡設定點亮led等來查看其可能初始化錯誤的地方。發現led燈都可以點亮沒有問題,那麼出現可能的地方可能是搬移的部分,初始化記憶體或者搬移。我們在第二階段裡的board_init_r設定另外一個燈看其顯示的情況。證明是記憶體初始化有問題。
4,那麼我們開始查看mini210的記憶體初始化是否和自己的smart210記憶體相符合。進行記憶體初始化的核心代碼是/board/samsug/mini210/memsteup.S。這段代碼對於核心為同樣架構的ARMV7來說不存在代碼錯誤。那麼只可能出現在記憶體控制寄存器上,對mini210的記憶體配置從/include/configs/mini210.h。中進行修改。
/* memtest works on */
#define CONFIG_SYS_MEMTEST_START MEMORY_BASE_ADDRESS /*記憶體初始地址一樣不需要修改*/
#define CONFIG_SYS_MEMTEST_END (MEMORY_BASE_ADDRESS + 0x3E00000) /* 64 MB in DRAM ,此處沒做修改,對其意義待定,此處定義在get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE);
函數裡沒有用到,是一些老的版本遺留的只檢測64M,而新的檢測512M*/
#define CONFIG_SYS_LOAD_ADDR (PHYS_SDRAM_2 + 0x0100 0000) /* default load address 預設下載地址,可以不修改也可以修改為第一bank區*/這裡如果是bank2則是從0x3000 0000+0x0100 0000也就是0x3100 0000出開始,bank1是從0x2100 0000開始,用在命令裡例如串口傳輸命令。
/* MINI210 has 4 bank of DRAM */
#define CONFIG_NR_DRAM_BANKS 2 /*分為2部分*/
#define SDRAM_BANK_SIZE 0x10000000 /* 256256 MB */
#define PHYS_SDRAM_1 MEMORY_BASE_ADDRESS /*第一部分的起始地址*/
#define PHYS_SDRAM_1_SIZE SDRAM_BANK_SIZE
#define PHYS_SDRAM_2 (MEMORY_BASE_ADDRESS + 0x20000000) /* SDRAM Bank #2 該處為第二部分起始地址,因為我們只用了一個DRAM0所以此處地址應改為MEMORY_BASE_ADDRESS + 0x10000000正好把512M分為2部分*/
#define PHYS_SDRAM_2_SIZE SDRAM_BANK_SIZE
地址映射圖如下:
對相應控制寄存器進行修改(修改處紅筆顯示):
#if defined(CONFIG_MCP_SINGLE)
#define DMC0_MEMCONTROL 0x00202400 // MemControl BL=4, 1Chip, DDR2 Type, dynamic self refresh, force precharge, dynamic power down off
#define DMC0_MEMCONFIG_0 0x20E00323 // MemConfig0 256MB config, 8 banks,Mapping Method[12:15]0:linear, 1:linterleaved, 2:Mixed
#define DMC0_MEMCONFIG_1 0x00E00323 // MemConfig1
#if 0
#define DMC0_TIMINGA_REF 0x00000618 // TimingAref 7.8us*133MHz=1038(0x40E), 100MHz=780(0x30C), 20MHz=156(0x9C), 10MHz=78(0x4E)
#define DMC0_TIMING_ROW 0x28233287 // TimingRow for @200MHz
#define DMC0_TIMING_DATA 0x23240304 // TimingData CL=3
#define DMC0_TIMING_PWR 0x09C80232 // TimingPower
#else
#define DMC0_TIMINGA_REF 0x00000618 // TimingAref 7.8us*133MHz=1038(0x40E), 100MHz=780(0x30C), 20MHz=156(0x9C), 10MHz=78(0x4E)
#define DMC0_TIMING_ROW 0x2B34438A // TimingRow for @200MHz
#define DMC0_TIMING_DATA 0x24240000 // TimingData CL=3
#define DMC0_TIMING_PWR 0x0BDC0343 // TimingPower
#endif
S5PV210有兩個獨立的DRAM控制器,分別是DMC0和DMC1,其中,DMC0最大支援512MByte,DMC1最大支援1GByte,而DMC0和DMC1又同時支援兩個片選CS0和CS1。根據資料手冊對修改其異同地方。
chip_mask[23:16]
這8位是用來決定chip0在記憶體位址中的位移地址,也就是設定chip0所串連的DRAM容量。譬如,如果設定chip_mask=0xE0。把它換成二進位為:0b1110_0000,那麼它將屏蔽最高的三位[31:29],那麼得到的結果為:0b0001_1111,即為0x1F。其餘的低24位用1補齊,則串連DCM0的chip0上的DRAM的容量為0x1FFF_FFFF。得到chip0的位址範圍為:0x2000_0000~0x3FFF_FFFF。即容量為512MByte。
chip_map[15:12]
這8位的作用是決定DRAM的地址映射方式。
chip_col [11:8]
設定列地址的位元目。
chip_row[7:4]
設定行地址的位元目。
chip_bank[3:0]
邏輯bank的數目。
下一步移植tcpip。