本文主要探讨从ubboot官方移植uboot到x210。
基础
确定设备的配置文件
            通过board.cfg中的cpu型号(s5pc1xx)确定设备的配置文件
             头文件:include/configs/s5p_goni.h
            cpu:    u-boot-2013.10\arch\arm\cpu\armv7
             board:    u-boot-2013.10\board\samsung\goni

清除多余文件
cd arch/
ls |grep -v 'arm'|xargs -I {} rm -r {}
cd arch/arm/cpu/
ls |grep -v u-boot-spl.lds |grep -v u-boot.lds|grep -v armv7|xargs -I {} rm -r {}
cd armv7
rm -r am33xx at91  highbank  exynos mx5  mx6 omap* rmobile socfpga tegra* u8500 vf610 zynq
cd board
ls|grep -v 'samsung'|xargs -I {} rm -rf {}
cd samsung
|grep -v 'goni'|grep -v 'common'|xargs -I {} rm -rf {}mkconfig脚本
编译配置
make s5p_goni_config
                调用主Makefile:
 %_config::    unconfig
        @$(MKCONFIG) -A $(@:_config=)
               定义参数
make s5p_goni_config调用mkconfig脚本传参(-A,s5p_goni)
if [ \( $# -eq 2 \) -a \( "$1" = "-A" \) ] ; then
    # Automatic mode
    line=`awk '($0 !~ /^#/ && $7 ~ /^'"$2"'$/) { print $1, $2, $3, $4, $5, $6, $7, $8 }' boards.cfg`
    if [ -z "$line" ] ; then
        echo "make: *** No rule to make target \`$2_config'.  Stop." >&2
        exit 1
    fi
    set ${line}
    # add default board name if needed
    [ $# = 3 ] && set ${line} ${1}
fi
                 查找boards.cfg中与$1(s5p_goni)匹配的配置行赋值给$1-$8并赋值
$1 = Active
$2 = arm
$3 = armv7
$4 = s5pc1xx
$5 = samsung
$6 = goni
$7 = s5p_goni
$8 = - 
arch=arm   
cpu=armv7
vendor=samsung
soc=s5pc1xx
                 创建符号链接
include/asm  -> arch/arm/include/asm
include/asm/arch -> include/asm/arch-s5pc1xx
include/asm/proc -> include/asm/proc-armv
                 创建头文件include/config.h
cat config.h
/* Automatically generated - do not edit */
#define CONFIG_SYS_ARCH  "arm"
#define CONFIG_SYS_CPU   "armv7"
#define CONFIG_SYS_BOARD "goni"
#define CONFIG_SYS_VENDOR "samsung"
#define CONFIG_SYS_SOC    "s5pc1xx"
#define CONFIG_BOARDDIR board/samsung/goni
#include <config_cmd_defaults.h>
#include <config_defaults.h>
#include <configs/s5p_goni.h>
#include <asm/config.h>
#include <config_fallbacks.h>
#include <config_uncmd_spl.h>修改交叉编译工具链
vim Makefile
# set default to nothing for native builds
ifeq ($(HOSTARCH),$(ARCH))
#CROSS_COMPILE ?=
CROSS_COMPILE = /root/arm-2009q3/bin/arm-none-linux-gnueabi-
endif添加编译脚本
vim mk
#!/bin/bash
make distclean
make s5p_goni_config
make -j4
chmod +x mk添加烧录脚本(从拷贝smdk210文件)
cd u-boot-samsung-dev
cp -r  sd_fusing ../u-boot-2013.10初次编译烧录
./mk
./sd_fusing.sh /dev/sdb 
                SD checksum Error:启动设备SD0(iNand)校验和失败
                 SD checksum Error:启动设备SD2(SD卡)校验和失败
                 Uart negotiation Error:串口启动失败
                 Insert an OTG cable into the connector!:usb启动失败
start.S未空出前16个字节存储校验和(mkbl1计算并存储校验和)
修改start.S
//添加16字节校验头存储
        .word 0x2000
        .word 0x0
        .word 0x0
        .word 0x0一阶段
start.S
uboot连接地址是0x34800000
.globl _TEXT_BASE
_TEXT_BASE:
#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_TEXT_BASE)
    .word    CONFIG_SPL_TEXT_BASE
#else
    .word    CONFIG_SYS_TEXT_BASE
#endif
                 save_boot_params是空函数
reset:
    bl    save_boot_params
ENTRY(save_boot_params)
    bx    lr            @ back to my caller
ENDPROC(save_boot_params)
    .weak    save_boot_params                cpu_init_cp15设置MMU、cache(未使用虚拟地址关掉MMU)
                 cpu_init_crit短跳转到lowlevel_init
                 lowlevel_init(board/samsung/goni)是关看门狗、调用uart_asm_init来初始化串口
   lowlevel_init.S
         添加开发板制锁
        //添加开发板置锁
        lldr r0, =0xE010E81C
        ldr r1, =0x301
        str r1, [r0]
         串口打印字符"O",测试串口
200:
        串口2打印'O'
        ldr     r1, =0x4f4f4f4f
        ldr r2, =0xE2900820
        str     r1, [r2]                @'O'
        mov     pc, lr添加lowlevel_init到前8kb
.text :
        {
                *(.__image_copy_start)
                CPUDIR/start.o (.text*)
                board/samsung/goni/lowlevel_init.o (.text*)
                *(.text*)
        }210的BL1为8KB,一阶段代码必须在uboot前8KB内,添加lowlevel_init到前8kb
编译出现重复定义问题
lowlevel_init函数在board/samsung/gon下生成libgoni.o时链接,生成u-boot时又链接
修改board/samsung/goni/Makefile(保证在该Makefile只编译不链接lowlevel_init)
COBJS-y := goni.o onenand.o
#SOBJS  := lowlevel_init.o
LOW     := lowlevel_init.o
SRCS    := $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
OBJS    := $(addprefix $(obj),$(COBJS-y))
SOBJS   := $(addprefix $(obj),$(SOBJS))
all:    $(obj).depend $(LOW) $(LIB)
$(LIB): $(obj).depend $(SOBJS) $(OBJS)
        $(call cmd_link_o_target, $(SOBJS) $(OBJS))
DDR初始化和重定位
    /* the mask ROM code should have PLL and others stable */
    #ifndef CONFIG_SKIP_LOWLEVEL_INIT
    bl    cpu_init_cp15
    bl    cpu_init_crit
    #endif
    bl    _main                cpu_init_crit函数成功初始化串口、时钟后进入_main(arch/arm/lib/crt0.S)
                 (crt0.S设置栈,调用board_init_f函数进行板级初始化(arch/arm/lib/board.c)
                 二阶段start_armboot:board_init_f和board_init_r
                 cpu_init_crit中添加DDR初始化和uboot重定位
          移植smdk210的DDR初始化
                 拷贝smdk210的cpu_init.S,s5pc110.h
cp ../u-boot-samsung-dev/include/s5pc110.h include/
cp ../u-boot-samsung-dev/cpu/s5pc11x/s5pc110/cpu_init.S board/samsung/goni/
                 修改Makefile(cpu_init在前8kb)
cd  board/samsung/goni/
vim makefile
LIB     = $(obj)lib$(BOARD).o
COBJS-y := goni.o onenand.o
#SOBJS  := lowlevel_init.o
LOW     := lowlevel_init.o cpu_init.o
SRCS    := $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
OBJS    := $(addprefix $(obj),$(COBJS-y))
SOBJS   := $(addprefix $(obj),$(SOBJS))
all:    $(obj).depend $(LOW) $(LIB)
$(LIB): $(obj).depend $(SOBJS) $(OBJS)
        $(call cmd_link_o_target, $(SOBJS) $(OBJS))cd arch/arm/cpu
vim  u-boot.lds 
.text :
        {
                *(.__image_copy_start)
                CPUDIR/start.o (.text*)
                board/samsung/goni/lowlevel_init.o (.text*)
                board/samsung/goni/cpu_init.o (.text*)
                *(.text*)
        }
                 s5p_goni.h添加宏定义
//DDR
#define CONFIG_MCP_SINGLE       1
#define CONFIG_EVT1             1               /* EVT1 */
#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修改s5pc110.h(宏定义来自smdk210的hardware.h),注释点未定义的宏(si显示未定义)
//#include <asm/hardware.h>
#define __REG(x)        (*(vu_long *)(x))
#define __REGl(x)       (*(vu_long *)(x))
#define __REGw(x)       (*(vu_short *)(x))
#define __REGb(x)       (*(vu_char *)(x))
#define __REG2(x,y)     (*(vu_long *)((x) + (y)))               删除s5pc110.h(无用函数体)
  
#ifndef __ASSEMBLY__
typedef enum {
        S5PC11X_UART0,
        S5PC11X_UART1,
        S5PC11X_UART2,
        S5PC11X_UART3,
} S5PC11X_UARTS_NR;
#include <s5pc11x.h>
#endi打印K,测试DDR
 /* for UART */
        bl      uart_asm_init
        // DDR init
        bl mem_ctrl_asm_init
        //串口2打印'K'
        ldr     r1, =0x4b4b4b4b
        ldr r2, =0xE2900820
        str     r1, [r2]                @'K'
        mov     lr, r11
        mov     pc, lr
        //bl      internal_ram_init
                 打印完'K'后,跳出,防止进入无意义死循环,编译烧录,出现'OK'则DDR初始化成功
         重定位代码移植
                start.S添加bss地址和重定位(移植于smdk210)
                 添加bss地址
/*
 * These are defined in the board-specific linker script.
 */
.globl _bss_start_ofs
_bss_start_ofs:
        .word __bss_start - _start
.globl _bss_end_ofs
_bss_end_ofs:
        .word __bss_end - _start
.globl _end_ofs
_end_ofs:
        .word _end - _start
.globl _bss_start
_bss_start:
        .word __bss_start
.globl _bss_end
_bss_end:
        .word _end
                 添加重定位       
 //重定位
        /* get ready to call C functions */
        ldr sp, _TEXT_BASE      /* setup temp stack pointer */
        sub sp, sp, #12
        mov fp, #0                      /* no previous frame, so fp=0 */
        /* 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     after_copy              /* r0 == r1 then skip flash copy   */
        #if defined(CONFIG_EVT1)
        /* If BL1 was copied from SD/MMC CH2 */
        ldr r0, =0xD0037488
        ldr r1, [r0]
        ldr r2, =0xEB200000
        cmp r1, r2
        beq     mmcsd_boot
        #endif
        mmcsd_boot:
        #if DELETE
                ldr     sp, _TEXT_PHY_BASE
                sub     sp, sp, #12
                mov     fp, #0
        #endif
                bl              movi_bl2_copy
                b               after_copy
        after_copy:
        clear_bss:
                ldr r0, _bss_start              /* find start of bss segment            */
                ldr r1, _bss_end                /* stop here                                            */
                mov     r2, #0x00000000         /* clear                                                        */
        clbss_l:
                str r2, [r0]            /* clear loop...                                        */
                add r0, r0, #4
                cmp r0, r1
                ble clbss_l
        //bl    _main
        //一阶段与二阶段分界
        ldr pc,__main
        __main : .word _main移植movi_bl2_copy
    cp -f /root/u-boot-samsung-dev/cpu/s5pc11x/movi.c /root/u-boot-2013.10/board/samsung/goni
    cp -f /root/u-boot-samsung-dev/include/movi.h /root/u-boot-2013.10/include修改movi.c
    //#include <regs.h>
    //extern raw_area_t raw_area_control;
    注释掉除movi_bl2_copy外的其他函数
                 movi重定位置于前8K    
vim Makefile
COBJS-y := goni.o onenand.o
#SOBJS  := lowlevel_init.o
LOW     := lowlevel_init.o cpu_init.o movi.o
SRCS    := $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
OBJS    := $(addprefix $(obj),$(COBJS-y))
SOBJS   := $(addprefix $(obj),$(SOBJS))
all:    $(obj).depend $(LOW) $(LIB)
$(LIB): $(obj).depend $(SOBJS) $(OBJS)
        $(call cmd_link_o_target, $(SOBJS) $(OBJS))   cd arch/arm/cpu
        vim  u-boot.lds 
        .text :
        {
                *(.__image_copy_start)
                CPUDIR/start.o (.text*)
                board/samsung/goni/lowlevel_init.o (.text*)
                board/samsung/goni/cpu_init.o (.text*)
                board/samsung/goni/movi.o (.text*)
                *(.text*)
        }注释掉crt0.S中的重定位
#if 0
        ldr     sp, [r9, #GD_START_ADDR_SP]     /* sp = gd->start_addr_sp */
        bic     sp, sp, #7      /* 8-byte alignment for ABI compliance */
        ldr     r9, [r9, #GD_BD]                /* r9 = gd->bd */
        sub     r9, r9, #GD_SIZE                /* new GD is below bd */
        adr     lr, here
        ldr     r0, [r9, #GD_RELOC_OFF]         /* r0 = gd->reloc_off */
        add     lr, lr, r0
        ldr     r0, [r9, #GD_RELOCADDR]         /* r0 = gd->relocaddr */
        b       relocate_code
        #endif添加movi.c需要的宏定义
// ENV
#define CFG_ENV_SIZE            0x4000
/* Text Base */
#define CONFIG_SYS_TEXT_BASE            0x34800000
#define CFG_PHY_UBOOT_BASE              CONFIG_SYS_TEXT_BASE注释Makefile的编译规则(解决编译规则错误)
# ARM relocations should all be R_ARM_RELATIVE.
checkarmreloc: $(obj)u-boot
#        @if test "R_ARM_RELATIVE" != \
                "`$(CROSS_COMPILE)readelf -r $< | cut -d ' ' -f 4 | grep R_ARM | sort -u`"; \
                then echo "$< contains relocations other than \
                R_ARM_RELATIVE"; false; fi
时钟移植
iRom默认初始化的APLL为800Mhz,210的最佳频率为1000Mhz
修改原有的时钟初始化(low_level_init.S添头文件s5pc110.h)
* system_clock_init: Initialize core clock and bus clock.
         * 
         */
system_clock_init:
        ldr     r0, =ELFIN_CLOCK_POWER_BASE     @0xe0100000
        /* Set Mux to FIN */
        ldr     r1, =0x0
        str     r1, [r0, #CLK_SRC0_OFFSET]
        ldr     r1,     =APLL_LOCKTIME_VAL
        str     r1,     [r0, #APLL_LOCK_OFFSET]
        /* Disable PLL */
retryloop:
        ldr     r1, =0x0
        str     r1, [r0, #APLL_CON0_OFFSET]
        ldr     r1, =0x0
        str     r1, [r0, #MPLL_CON_OFFSET]
        ldr     r1, =0x0
        str     r1, [r0, #MPLL_CON_OFFSET]
        ldr     r1, [r0, #CLK_DIV0_OFFSET]
        ldr     r2, =CLK_DIV0_MASK
        bic     r1, r1, r2
        ldr     r2, =CLK_DIV0_VAL
        orr     r1, r1, r2
        str     r1, [r0, #CLK_DIV0_OFFSET]
        ldr     r1, =APLL_VAL
        str     r1, [r0, #APLL_CON0_OFFSET]
        ldr     r1, =MPLL_VAL
str     r1, [r0, #MPLL_CON_OFFSET]
        ldr     r1, =VPLL_VAL
        str     r1, [r0, #VPLL_CON_OFFSET]
#if defined(CONFIG_EVT1)
        ldr     r1, =AFC_ON
        str     r1, [r0, #APLL_CON1_OFFSET]
#endif
        mov     r1, #0x10000
1:      subs    r1, r1, #1
        bne     1b
        /* MPLL software workaround */
        ldr     r1, [r0, #MPLL_CON_OFFSET]
        orr     r1, r1, #(1<<28)
        str     r1, [r0, #MPLL_CON_OFFSET]
        mov     r1, #0x100
1:      subs    r1, r1, #1
        bne     1b
        ldr     r1, [r0, #MPLL_CON_OFFSET]
        and     r1, r1, #(1<<29)
        cmp     r1, #(1<<29)
        bne     retryloop
        /* H/W lock detect disable */
        ldr     r1, [r0, #MPLL_CON_OFFSET]
        bic     r1, r1, #(1<<28)
        str     r1, [r0, #MPLL_CON_OFFSET]
        ldr     r1, [r0, #CLK_SRC0_OFFSET]
        ldr     r2, =0x10001111
        orr     r1, r1, r2
        str     r1, [r0, #CLK_SRC0_OFFSET]
        /* CLK_DIV6 */
        ldr     r1, [r0, #CLK_DIV6_OFFSET]
        bic     r1, r1, #(0x7<<12)      @; ONENAND_RATIO: 0
        str     r1, [r0, #CLK_DIV6_OFFSET]
        mov     pc, lr                添加在串口前,方便验证
        
 /* for UART */
        bl      uart_asm_init
        // clock init
        bl system_clock_init
        // DDR init
        bl mem_ctrl_asm_init
        //串口2打印'K'
        ldr     r1, =0x4b4b4b4b
        ldr r2, =0xE2900820
        str     r1, [r2]                @'K'
        mov     lr, r11
        mov     pc, lr
                 添加时钟宏定义(s5p_goni.h)
//clock
#define APLL_LOCKTIME_VAL       0x2cf
#if defined(CONFIG_EVT1)
/* Set AFC value */
#define AFC_ON          0x00000000
#define AFC_OFF         0x10000010
#endif
#define APLL_MDIV       0x7d
#define APLL_PDIV       0x3
#define APLL_SDIV       0x1
#define MPLL_MDIV       0x29b
#define MPLL_PDIV       0xc
#define MPLL_SDIV       0x1
#define EPLL_MDIV       0x60
#define EPLL_PDIV       0x6
#define EPLL_SDIV       0x2
#define VPLL_MDIV       0x6c
#define VPLL_PDIV       0x6
#define VPLL_SDIV       0x3
/* CLK_DIV0 */
#define APLL_RATIO      0
#define A2M_RATIO       4
#define HCLK_MSYS_RATIO 8
#define PCLK_MSYS_RATIO 12
#define HCLK_DSYS_RATIO 16
#define PCLK_DSYS_RATIO 20
#define HCLK_PSYS_RATIO 24
#define PCLK_PSYS_RATIO 28
#define CLK_DIV0_MASK   0x7fffffff
#define set_pll(mdiv, pdiv, sdiv)       (1<<31 | mdiv<<16 | pdiv<<8 | sdiv)
#define APLL_VAL        set_pll(APLL_MDIV,APLL_PDIV,APLL_SDIV)
#define MPLL_VAL        set_pll(MPLL_MDIV,MPLL_PDIV,MPLL_SDIV)
#define EPLL_VAL        set_pll(EPLL_MDIV,EPLL_PDIV,EPLL_SDIV)
#define VPLL_VAL        set_pll(VPLL_MDIV,VPLL_PDIV,VPLL_SDIV)
#define CLK_DIV0_VAL    ((0<<APLL_RATIO)|(4<<A2M_RATIO)|(4<<HCLK_MSYS_RATIO)|(1<<PCLK_MSYS_RATIO)\
                        |(3<<HCLK_DSYS_RATIO)|(1<<PCLK_DSYS_RATIO)|(4<<HCLK_PSYS_RATIO)|(1<<PCLK_PSYS_RATIO))
#define CLK_DIV1_VAL    ((1<<16)|(1<<12)|(1<<8)|(1<<4))
#define CLK_DIV2_VAL    (1<<0)二阶段
初始化init_sequence中的函数
_main(crt0.S)->board_init_f(board.c)
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
                if ((*init_fnc_ptr)() != 0) {
                        hang ();
                }
        }banner修改(display_banner)
修改(s5p_goni.h)
//banner
#define         CONFIG_IDENT_STRING     "for  CXB210"
依据
static int display_banner(void)
{
        printf("\n\n%s\n\n", version_string);
        debug("U-Boot code: %08lX -> %08lX  BSS: -> %08lX\n",
               _TEXT_BASE,
               _bss_start_ofs + _TEXT_BASE, _bss_end_ofs + _TEXT_BASE);
#ifdef CONFIG_MODEM_SUPPORT
        debug("Modem Support enabled\n");
#endif
#ifdef CONFIG_USE_IRQ
        debug("IRQ Stack: %08lx\n", IRQ_STACK_START);
        debug("FIQ Stack: %08lx\n", FIQ_STACK_START);
#endif
        return (0);
}
const char __weak version_string[] = U_BOOT_VERSION_STRING;
#ifndef CONFIG_IDENT_STRING
#define CONFIG_IDENT_STRING ""
#endif
#define U_BOOT_VERSION_STRING U_BOOT_VERSION " (" U_BOOT_DATE " - " \
        U_BOOT_TIME ")" CONFIG_IDENT_STRING
         修改cpu时钟(print_cpuinfo,cpu_info.c)
int print_cpuinfo(void)
{
        char buf[32];
        //printf("CPU:\t%s%X@%sMHz\n",s5p_get_cpu_name(), s5p_cpu_id,strmhz(buf, get_arm_clk()));
        printf("CPU:\tS5pv210@%sMHz\n",strmhz(buf, get_arm_clk()));
        return 0;
}修改开发板名称(goni.c)
int checkboard(void)
{
        puts("Board:\tS5pv210\n");
        return 0;
}修改i2c(210 uboot未使用)
static int init_func_i2c(void)
{
        puts("I2C:   ");
#ifdef CONFIG_SYS_I2C
        i2c_init_all();
#else
        i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
#endif
        //puts("ready\n");
        puts("not use in x210\n");
        return (0);
}
         dram显示大小修改(goni.c)
int dram_init(void)
{
        //gd->ram_size = PHYS_SDRAM_1_SIZE + PHYS_SDRAM_2_SIZE + PHYS_SDRAM_3_SIZE;
        gd->ram_size = PHYS_SDRAM_1_SIZE + PHYS_SDRAM_2_SIZE;
        return 0;
}
void dram_init_banksize(void)
{
        gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
        gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
        gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
        gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
        //gd->bd->bi_dram[2].start = PHYS_SDRAM_3;
        //gd->bd->bi_dram[2].size = PHYS_SDRAM_3_SIZE;
}
修改宏定义(s5p_goni.h)
/* 210 has 2 banks of DRAM, but swap the bank */
//#define CONFIG_NR_DRAM_BANKS  3
#define CONFIG_NR_DRAM_BANKS    2
#define PHYS_SDRAM_1            CONFIG_SYS_SDRAM_BASE   /* OneDRAM Bank #0 */
//#define PHYS_SDRAM_1_SIZE     (80 << 20)              /* 80 MB in Bank #0 */
#define PHYS_SDRAM_1_SIZE       (256 << 20)             /* 256 MB in Bank #0 */
#define PHYS_SDRAM_2            0x40000000              /* mDDR DMC1 Bank #1 */
#define PHYS_SDRAM_2_SIZE       (256 << 20)             /* 256 MB in Bank #1 */
//#define PHYS_SDRAM_3          0x50000000              /* mDDR DMC2 Bank #2 */
//#define PHYS_SDRAM_3_SIZE     (128 << 20)             /* 128 MB in Bank #2 */
         修改机器码(board.c)
添加宏定义(s5p_goni.h)
// machine type
#define         CONFIG_MACH_TYPE        2456
依据
#ifdef CONFIG_MACH_TYPE
        gd->bd->bi_arch_number = CONFIG_MACH_TYPE; /* board id for Linux */
#endif修改(goni.c,宏定义所有机器码(mach-types.h))
int board_init(void)
{
        /* Set Initial global variables */
        s5pc110_gpio = (struct s5pc110_gpio *)S5PC110_GPIO_BASE;
        //gd->bd->bi_arch_number = MACH_TYPE_GONI;
        gd->bd->bi_arch_number = MACH_TYPE_SMDKV210;
        gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
        return 0;
}
         禁止无用功能(修改board_init_r)
/* Enable caches */
//enable_caches();
//power_init_board();
         禁止onenand 
修改onenand宏(s5p_goni.h)
//#define CONFIG_CMD_ONENAND
/* FLASH and environment organization */
//#define CONFIG_ENV_IS_IN_ONENAND      1
//#define CONFIG_ENV_SIZE                       (256 << 10)     /* 256 KiB, 0x40000 */
#define CONFIG_ENV_SIZE                 0x40000    /* 256 KiB, 0x40000 */
//#define CONFIG_ENV_ADDR                       (1 << 20)       /* 1 MB, 0x100000 */
//#define CONFIG_USE_ONENAND_BOARD_INIT
//#define CONFIG_SAMSUNG_ONENAND                1
//#define CONFIG_SYS_ONENAND_BASE               0xB0000000
#define CONFIG_ENV_IS_IN_MMC    1
#define CONFIG_SYS_MMC_ENV_DEV          0 //inand
#define CONFIG_DOS_PARTITION            1修该Makefile(goni)
#COBJS-y        := goni.o onenand.o
COBJS-y := goni.o 移植inand(移植于smdkv210)
拷贝驱动文件
cp ../u-boot-samsung-dev/drivers/mmc/mmc.c ./drivers/mmc/ -f
cp ../u-boot-samsung-dev/drivers/mmc/s3c_hsmmc.c ./drivers/mmc/ -f
cp ../u-boot-samsung-dev/include/mmc.h  ./include/ -f
cp ../u-boot-samsung-dev/include/s3c_hsmmc.h include/ -f
cp ~/u-boot-samsung-dev/cpu/s5pc11x/setup_hsmmc.c board/samsung/goni -f
cp ../u-boot-samsung-dev/common/cmd_mmc.c common/ -f修改mmc的soc初始化(goni.c)
cd board/samsung/goni
#ifdef CONFIG_GENERIC_MMC
int board_mmc_init(bd_t *bis)
{
        #ifdef CONFIG_S3C_HSMMC
        setup_hsmmc_clock();
        setup_hsmmc_cfg_gpio();
        return smdk_s3c_hsmmc_init();
        #else
                return 0;
        #endif
}
修改setup_hmmc.c的时钟(函数)
#include <asm/arch/clk.h>
        /* MMC0 clock div */
        tmp = CLK_DIV4_REG & ~(0x0000000f);
        //clock = get_MPLL_CLK()/1000000;
        clock = get_pll_clk(MPLL)/1000000;vim Makefile
#COBJS-y        := goni.o onenand.o
COBJS-y := goni.o setup_hsmmc.o修改mmc的驱动初始化(goni.c)
cd drivers/mm
修改Makefiel(mmc/Makefile)
COBJS-$(CONFIG_S3C_HSMMC) += s3c_hsmmc.o
COBJS-$(CONFIG_SDHCI) += sdhci.o
COBJS-$(CONFIG_BCM2835_SDHCI) += bcm2835_sdhci.o
COBJS-$(CONFIG_S5P_SDHCI) += s5p_sdhci.o
COBJS-$(CONFIG_SH_MMCIF) += sh_mmcif.o
COBJS-$(CONFIG_SPEAR_SDHCI) += spear_sdhci.o
COBJS-$(CONFIG_TEGRA_MMC) += tegra_mmc.o
COBJS-$(CONFIG_DWMMC) += dw_mmc.o
COBJS-$(CONFIG_EXYNOS_DWMMC) += exynos_dw_mmc.o
COBJS-$(CONFIG_ZYNQ_SDHCI) += zynq_sdhci.o
ifdef CONFIG_SPL_BUILD
COBJS-$(CONFIG_SPL_MMC_BOOT) += fsl_esdhc_spl.o
else
#COBJS-$(CONFIG_GENERIC_MMC) += mmc_write.o
修改s3c_hsmmc.c 头文件
//#include <regs.h>
#include <s5pc110.h>添加宏定义
/* MMC */
#define CONFIG_GENERIC_MMC
#define CONFIG_MMC
//#define CONFIG_SDHCI
//#define CONFIG_S5P_SDHCI
#define CONFIG_S3C_HSMMC                        
/* IROM specific data */
#define SDMMC_BLK_SIZE        (0xD003A500)
#define COPY_SDMMC_TO_MEM     (0xD003E008)
/* The macro for MMC channel 0 is defined by default and can't be undefined */
#define USE_MMC0
#define USE_MMC2
#define MMC_MAX_CHANNEL         4环境变量移植
修改默认环境变量(注释点旧的,s5p_goni.h)
//env default
#define CONFIG_ENV_OVERWRITE
#define CONFIG_SYS_CONSOLE_IS_IN_ENV
//env boot
#define CONFIG_BOOTARGS         "console=ttySAC2,115200 root=/dev/mmcblk0p2 rw init=/linuxrc rootfstype=ext3"
#define CONFIG_BOOTCOMMAND      "tftp 30008000 zImage; bootm 30008000"
//env net
#define CONFIG_ETHADDR          00:40:5c:26:0a:5b
#define CONFIG_NETMASK          255.255.255.0
#define CONFIG_IPADDR           192.168.100.27
#define CONFIG_SERVERIP         192.168.100.100
#define CONFIG_GATEWAYIP        192.168.100.1
                 uboot的SD2扇区0空闲,1-16为BL1,17-48为环境变量(16K),49开始依次是BL2,内核、rootfs
static inline int write_env(struct mmc *mmc, unsigned long size,
                unsigned long offset, const void *buffer)
 写环境变量,mmc为mmc设备,size大小,offset为扇区去,buffer是内容#define MOVI_BL2_POS        ((eFUSE_SIZE / MOVI_BLKSIZE) + MOVI_BL1_BLKCNT + MOVI_ENV_BLKCNT)                    宏用于拷贝BL2到DDR时计算BL2扇区的起始地址
                 eFUSE_SIZE / MOVI_BLKSIZE = 1 (扇区0,空闲)
                 MOVI_BL1_BLKCNT = 16(扇区1-16,BL1)
                 MOVI_ENV_BLKCNT = 32(扇区17-48,ENV)
修改环境变量初始扇区
CONFIG_ENV_OFFSET宏决定扇区偏移量,默认为0,修改为17
// ENV
#define CFG_ENV_SIZE            0x4000
#define CONFIG_ENV_OFFSET               (17*512)测试环境变量写入扇区
擦除inand的0-48扇区 :mmc write 0 30000000 0# 49
修改环境变量: set num 10
保存环境变量: save
重启uboot: reset
读取环境变量: mmc read 0 30000000 17# 32
对比环境变量:md 30000000 50
网卡驱动移植
添加网卡配置宏(smdkv210)
//dm9000
#define DM9000_16BIT_DATA
#define CONFIG_DRIVER_DM9000    1
#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
                 添加dm900初始化函数(eth.c)
默认使用board_eth_init,cpu_eth_init两函数初始化网卡,故套壳函数初始化网卡
// dm9000 include by cxb
static int board_eth_init(bd_t *bis)
{
        return dm9000_initialize(bis);
}
static int __def_eth_init(bd_t *bis)
{
        return -1;
}
int cpu_eth_init(bd_t *bis) __attribute__((weak, alias("__def_eth_init")));
//int board_eth_init(bd_t *bis) __attribute__((weak, alias("__def_eth_init")));
依据
        /*
         * If board-specific initialization exists, call it.
         * If not, call a CPU-specific one
         */
        if (board_eth_init != __def_eth_init) {
                if (board_eth_init(bis) < 0)
                        printf("Board Net Initialization Failed\n");
        } else if (cpu_eth_init != __def_eth_init) {
                if (cpu_eth_init(bis) < 0)
                        printf("CPU Net Initialization Failed\n");
        } else
                printf("Net Initialization Skipped\n");
        if (!eth_devices) {
                puts("No ethernet found.\n");
                bootstage_error(BOOTSTAGE_ID_NET_ETH_START);
        } else {
                struct eth_device *dev = eth_devices;
                char *ethprime = getenv("ethprime");
         bootstage_mark(BOOTSTAGE_ID_NET_ETH_INIT);
                do {
                        if (dev->index)
                                puts(", ");
                        printf("%s", dev->name);
                        if (ethprime && strcmp(dev->name, ethprime) == 0) {
                                eth_current = dev;
                                puts(" [PRIME]");
                        }
                        if (strchr(dev->name, ' '))
                                puts("\nWarning: eth device name has a space!"
                                        "\n");
        if (eth_write_hwaddr(dev, "eth", dev->index))
                                puts("\nWarning: failed to set MAC address\n");
                        dev = dev->next;
                        num_devices++;
                } while (dev != eth_devices);
                eth_current_changed();
                putc('\n');
        }
        return num_devices;
}   
添加soc网卡初始化(修改goni.c )
#include <s5pc110.h>
DECLARE_GLOBAL_DATA_PTR;
static struct s5pc110_gpio *s5pc110_gpio;
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);
        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;
}
int board_init(void)
{
        /* Set Initial global variables */
        s5pc110_gpio = (struct s5pc110_gpio *)S5PC110_GPIO_BASE;
        gd->bd->bi_arch_number = MACH_TYPE_SMDKV210;
        gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
        //dm9000 init
        #ifdef CONFIG_DRIVER_DM9000
                dm9000_pre_init();
        #endif
        return 0;
}  
                 添加网卡命令(ping,tftp)
注释tftp命令取消定义宏,添加ping命令
/* Command definition */
#include <config_cmd_default.h>
//ping command
#define CONFIG_CMD_PING
#undef CONFIG_CMD_FPGA
#undef CONFIG_CMD_MISC
//#undef CONFIG_CMD_NET    //tftp启动内核
 
 


















