1:選擇三星移植好的uboot,首先進行配置
因為我們用的是210的cpu所以選擇三星的210開發板的配置:
在開始移植之前我們首先要把不相關的cpu、board、lib目錄刪除
首先來看board目錄下:把不相關的開發板的文件全部刪除只保留:board->samsung->common文件夾以及board->samsung->smdkc110文件夾
cpu目錄下:只保留s5pc11x文件夾,其他全部刪除;
include目錄下:asm-開頭的文件只保留asm-arm;asm-arm目錄下arch-開頭的文件只保留s5pc11x;
include/configs目錄下:只保留smdkv210single.h文件
lib-開頭文件夾保留lib_arm、lib_generic
然后在用sourceinsight生成project
2:在uboot根目錄下進行配置make smdkv210single_config,然后make,生成uboot.bin文件。
接下來就是把生成的uboot.bin文件燒錄到sd卡中。
打開sd_fusing文件,
make clean
make
sd_fusing文件中有幾個關鍵文件:
./mkbl1 ../u-boot.bin SD-bl1-8k.bin 8192
C110-EVT1-mkbl1:這個文件是用來復制uboot.bin的前8k 復制到這個文件中SD-bl1-8k.bin
sd_fdisk 這個文件是用來對sd卡進行分區的;
然后使用sd_fusing.sh腳本燒錄到sd卡中;
bl1_position=1
uboot_position=49 這里的49扇區,要和uboot重定位的時復制的扇區一致;
我們執行這個sd_fusing.sh腳本即可把bl1、uboot.bin燒錄到sd卡中。
啟動開發板 會發現電源置鎖,只有一句SD checksum Error並沒有打印出ok
通過這里分析一定是在電源置鎖之后,串口初始化之前代碼發生了錯誤;
看下面代碼:
在lowlevel_init函數中有一段代碼:
PMIC_InitIp有這么一個函數:這個函數的作用是用來管理電源的,因為我們的210開發板沒有用到這個功能所以程序卡在這個函數中了,只要把這個函數注釋掉即可
/* PS_HOLD pin(GPH0_0) set to high */ ldr r0, =(ELFIN_CLOCK_POWER_BASE + PS_HOLD_CONTROL_OFFSET) ldr r1, [r0] orr r1, r1, #0x300 orr r1, r1, #0x1 str r1, [r0] /* when we already run in ram, we don't need to relocate U-Boot. * and actually, memory controller must be configured before U-Boot * is running in ram. */ ldr r0, =0xff000fff bic r1, pc, r0 /* r0 <- current base addr of code */ ldr r2, _TEXT_BASE /* r1 <- original base addr in ram */ bic r2, r2, r0 /* r0 <- current base addr of code */ cmp r1, r2 /* compare r0, r1 */ beq 1f /* r0 == r1 then skip sdram init */
/* init PMIC chip */ bl PMIC_InitIp /* init system clock */ bl system_clock_init
接下來編譯執行:
串口輸出信息如下:

開始打印U-BOOT的版本號,說明在啟動的第一階段已經沒有問題了,下面打印出版本號是在
display_banner 這個函數中

我們要修改for SMDKV210這個信息只需在smdkv210single.h中修改這個定義即可
時鍾的信息是正確的,時鍾信息是在print_cpuinfo這個函數中打印出來的

這個信息是在checkboard函數中打印的,如果要修改這個信息可以在這個函數中修改;

下面看一下dram的打印信息
dram的配置在smdkv210single.h中進行配置的:

因為我們實際接的是512MB
修改#define SDRAM_BANK_SIZE 0x10000000 /* 256 MB */
#define PHYS_SDRAM_2 0x40000000
復制編譯;現在dram 大小可以了並且可用了,可以用md命令來測試;

但是我們的起始內存起始地址為0x3000_0000——0x4FFF_FFFF
所以要修改這些地址;
(1)修改內存初始化時候的內存地址:看下面幾句代碼在這里是設置內存初始化的相關寄存器的,我們在裸機中講到過這些寄存器
詳細可以看這篇博客http://www.cnblogs.com/biaohc/p/6346949.html

#define DMC0_MEMCONFIG_0 0x20E01323 // MemConfig0 256MB config, 8 banks,Mapping Method[12:15]0:linear, 1:linterleaved, 2:Mixed
#define DMC0_MEMCONFIG_1 0x40F01323 // MemConfig1
#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
#define DMC1_MEMCONTROL 0x00202400 // MemControl BL=4, 2 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down off
#define DMC1_MEMCONFIG_0 0x40C01323 // MemConfig0 512MB config, 8 banks,Mapping Method[12:15]0:linear, 1:linterleaved, 2:Mixed
#define DMC1_MEMCONFIG_1 0x00E01323 // MemConfig1
#define DMC1_TIMINGA_REF 0x00000618 // TimingAref 7.8us*133MHz=1038(0x40E), 100MHz=780(0x30C), 20MHz=156(0x9C), 10MHz=78(0x4
#define DMC1_TIMING_ROW 0x28233289 // TimingRow for @200MHz
#define DMC1_TIMING_DATA 0x23240304 // TimingData CL=3
#define DMC1_TIMING_PWR 0x08280232 // TimingPower
(2)MEMORY_BASE_ADDRESS為0x

(3) 因為uboot開啟了mmu,虛擬地址物理地址映射的時候把0xc000_0000映射到了0x20000000
所以我們在這里要修改虛擬地址映射
這里的代碼把0xc000_0000 到0xd000_0000映射到 0x3000_0000處
(4):之后繼續執行出現下圖,SD/MMC初始化失敗,

打開mmu以后,這里有一個虛擬地址到物理地址的映射的函數,

這里要改成0x30000000

修改以后打印出現,下列錯誤

查找EXT_CSD,在下面這個函數中,讀取版本號如果版本號 > 5的話打印下面信息,我們直接把5修改為8

(5):初始化dm9000網卡
因為我們用的是dm9000網卡芯片,所以在driver目錄下的dm9000網卡驅動部分不用修改
只要修改dm9000初始化部分的代碼即可:
dm9000初始化的代碼在start_armboot最開始初始化的一堆函數數組中的board_init函數中,其中調用的是dm9000_pre_init這個函數
詳細內容如下:
具體代碼的函數可以看我的這篇博客:http://www.cnblogs.com/biaohc/p/6413547.html
static void dm9000_pre_init(void) { unsigned int tmp; #if defined(DM9000_16BIT_DATA) SROM_BW_REG &= ~(0xf << 20); SROM_BW_REG |= (0<<23) | (0<<22) | (0<<21) | (1<<20); #else SROM_BW_REG &= ~(0xf << 20); SROM_BW_REG |= (0<<19) | (0<<18) | (0<<16); #endif SROM_BC5_REG = ((0<<28)|(1<<24)|(5<<16)|(1<<12)|(4<<8)|(6<<4)|(0<<0)); tmp = MP01CON_REG; tmp &=~(0xf<<20); tmp |=(2<<20); MP01CON_REG = tmp; }
第一步修改上面代碼為:
static void dm9000_pre_init(void) { unsigned int tmp; #if defined(DM9000_16BIT_DATA)
//SROM_BW_REG &= ~(0xf << 20); //SROM_BW_REG |= (0<<23) | (0<<22) | (0<<21) | (1<<20);
SROM_BW_REG &= ~(0xf << 4);
/*
** 注意下面這里要修改為1111
*/
SROM_BW_REG |= (1<<7) | (1<<6) | (1<<5) | (1<<4); #else SROM_BW_REG &= ~(0xf << 20); SROM_BW_REG |= (0<<19) | (0<<18) | (0<<16); #endif
//SROM_BC5_REG = ((0<<28)|(1<<24)|(5<<16)|(1<<12)|(4<<8)|(6<<4)|(0<<0));
SROM_BC1_REG = ((0<<28)|(1<<24)|(5<<16)|(1<<12)|(4<<8)|(6<<4)|(0<<0)); tmp = MP01CON_REG; //tmp &=~(0xf<<20); //tmp |=(2<<20);
tmp &=~(0xf<<4); tmp |=(2<<4); MP01CON_REG = tmp; }
第二步:頭文件中的關於dm9000網卡的代碼也要做修改

#ifdef CONFIG_DRIVER_DM9000 //#define CONFIG_DM9000_BASE (0xA8000000)
#define CONFIG_DM9000_BASE (0x88000300)
#define DM9000_IO (CONFIG_DM9000_BASE)
#if defined(DM9000_16BIT_DATA)
//#define DM9000_DATA (CONFIG_DM9000_BASE+2)
#define DM9000_DATA (CONFIG_DM9000_BASE+4)
#else
#define DM9000_DATA (CONFIG_DM9000_BASE+1)
#endif
#endif
具體為什么這么修改可以看上面那篇博客;
------------------------------------------------------------------------------------------
未完待續。。。
