uboot移植——使用三星移植好的uboot開始移植


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

具體為什么這么修改可以看上面那篇博客;

 ------------------------------------------------------------------------------------------

未完待續。。。

 


免責聲明!

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



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