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

具体为什么这么修改可以看上面那篇博客;

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

未完待续。。。

原文地址:https://www.cnblogs.com/biaohc/p/6460902.html