本文主要探讨从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
启动内核