您的位置:首页 > 编程语言

u-boot-2017.07移植到S5PV210单板

2017-10-29 15:34 281 查看
下面教程的源代码见此链接,点击打开链接http://download.csdn.net/download/qq_15015097/10043644,

一、添加单板信息
1、
cp -r board/samsung/smdkc100 board/samsung/smdkv210

2、进入smdkv210下
cd board/samsung/smdkv210/
mv smdkc100.c smdkv210.c

3、修改Kconfig
if TARGET_SMDKV210

config SYS_BOARD
default "smdkv210"

config SYS_VENDOR
default "samsung"

config SYS_SOC
default "s5pv2xx"

config SYS_CONFIG_NAME
default "smdkv210"

endif

4、修改MAINTAINERS
SMDKV210 BOARD
M:      Minkyu Kang <mk7.kang@samsung.com>
S:      Maintained
F:      board/samsung/smdkv210/
F:      include/configs/smdkv210.h
F:      configs/smdkv210_defconfig

5、修改Makefile
obj-y   := smdkv210.o
obj-$(CONFIG_SAMSUNG_ONENAND)   += onenand.o
obj-y   += lowlevel_init.o

6、根据MAINTAINERS修改includ/configs/smdkv210.h 和configs/smdkv210_defconfig
cp include/configs/smdkc100.h include/configs/smdkv210.h
cp configs/smdkc100_defconfig configs/smdkv210_defconfig

7、修改smdkv210_defconfig
CONFIG_ARM=y
CONFIG_ARCH_S5PV2XX=y
CONFIG_TARGET_SMDKV210=y
CONFIG_IDENT_STRING=" for SMDKV210"
CONFIG_DEFAULT_DEVICE_TREE="s5pv2xx-smdkv210"
CONFIG_BOOTDELAY=3
CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="root=/dev/mtdblock5 ubi.mtd=4 rootfstype=cramfs console=ttySAC0,115200n8 mem=128M  mtdparts=s3c-onenand:256k(bootloader),128k@0x40000(params),3m@0x60000(kernel),16m@0x360000(test),-(UBI)"
CONFIG_HUSH_PARSER=y
CONFIG_SYS_PROMPT="SMDKV210 # "
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
CONFIG_CMD_ONENAND=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_CACHE=y
CONFIG_CMD_FAT=y
CONFIG_CMD_MTDPARTS=y
CONFIG_ENV_IS_IN_ONENAND=y
# CONFIG_MMC is not set

8、修改smdkv210.h
#define CONFIG_SAMSUNG		1	/* in a SAMSUNG core */
#define CONFIG_S5P		1	/* which is in a S5P Family */
#define CONFIG_S5PV210		1	/* which is in a S5PV210 */
#define CONFIG_SMDKV210		1	/* working with SMDKV210 */

/* DRAM Base */
#define CONFIG_SYS_SDRAM_BASE		0x20000000

/* Text Base */
#define CONFIG_SYS_TEXT_BASE		0x20000000
#define PHYS_SDRAM_1_SIZE	(1024 << 20)	/*1024 MB Bank #1 */
#define CONFIG_SYS_INIT_SP_ADDR	(CONFIG_SYS_SDRAM_BASE + PHYS_SDRAM_1_SIZE)

二、添加S5PV210信息
1、进入arch/arn目录下
cd arch/arm

vim Kconfig

/*add by xcl*/
config ARCH_S5PV2XX
bool "Samsung S5PV2XX"
select CPU_V7
select DM
select DM_SERIAL
select DM_GPIO
select DM_I2C

/*add by xcl*/
source "arch/arm/mach-s5pv2xx/Kconfig"

2、修改Makefile
vim Makefile

/*add by xcl*/
machine-$(CONFIG_ARCH_S5PV2XX)		+= s5pv2xx

3、复制mach-s5pc1xx
cp -r mach-s5pc1xx mach-s5pv2xx

4、修改mach-s5pv210目录下Kconfig
cd mach-s5pv210/

vim Kconfig

if ARCH_S5PV2XX

choice
prompt "S5PV2XX board select"
optional

config TARGET_SMDKV210
bool "Support smdkv210 board"
select OF_CONTROL

endchoice

config SYS_SOC
default "s5pv2xx"

source "board/samsung/smdkv210/Kconfig"

endif

5、修改cpu.h
cd include/mach

vim cpu.h
#ifndef _S5PV210_CPU_H
#define _S5PV210_CPU_H

#define S5P_CPU_NAME            "S5P"
#define S5PV210_ADDR_BASE       0xE0000000

/* S5PV210 */
#define S5PV210_PRO_ID          0xE0000000
#define S5PV210_CLOCK_BASE      0xE0100000
#define S5PV210_GPIO_BASE       0xE0200000
#define S5PV210_PWMTIMER_BASE   0xE2500000
#define S5PV210_WATCHDOG_BASE   0xE2700000
#define S5PV210_UART_BASE       0xE2900000
#define S5PV210_MMC_BASE        0xEB000000
#define S5PV210_SROMC_BASE      0xE8000000
#define S5PV210_DMC0_BASE       0xF0000000
#define S5PV210_DMC1_BASE       0xF1400000
#define S5PV210_VIC0_BASE       0xF2000000
#define S5PV210_VIC1_BASE       0xF2100000
#define S5PV210_VIC2_BASE       0xF2200000
#define SPPV210_VIC3_BASE       0xF2300000
#define S5PV210_NAND_BASE       0xB0E00000
/*modified by xcl*/
static inline void s5p_set_cpu_id(void)
{
int id = 0;
s5p_cpu_id = readl(S5PV210_PRO_ID);
s5p_cpu_rev = s5p_cpu_id & 0x000000FF;
id = (s5p_cpu_id & 0xFFFFF000) >> 12;
if (id == 0x43110) {
id = s5p_cpu_id & 0x0F;
switch (id){
case 0x00:
s5p_cpu_id = 0x56210;
break;

case 0x01:
s5p_cpu_id = 0xc110;
break;

case 0x02:
s5p_cpu_id = 0xc111;
break;

default :
break;
}
}
}
/*add by xcl*/
IS_SAMSUNG_TYPE(s5pv210, 0x56210)

/*modified by xcl*/
#define SAMSUNG_BASE(device, base)				\
static inline unsigned int samsung_get_base_##device(void)	\
{								\
if (cpu_is_s5pc100())					\
return S5PC100_##base;				\
else if (cpu_is_s5pc110())				\
return S5PC110_##base;				\
else if (cpu_is_s5pv210())\
return S5PV210_##base;\
else\
return 0;					\
}

5、修改board/samsung/smdkv210/lowlevel_init.S 将里面S5PC100全部替换为S5PV210

6、添加soc
cd arch/arm/cpu/armv7
vim Makefile
/*modified by xcl*/
ifneq (,$(filter s5pv2xx s5pc1xx exynos,$(SOC)))
obj-y += s5p-common/
endif

7、添加设备树
cd arch/arm/dts/
cp s5pc1xx-smdkc100.dts  s5pv2xx-smdkv210.dts
cp s5pc110-pinctrl.dtsi  s5pv210-pinctrl.dtsi

8、修改Makefile
vim Makefile
/*add by xcl*/
dtb-$(CONFIG_S5PV210) += s5pv2xx-smdkv210.dtb

9、修改设备树
vim s5pv2xx-smdkv210.dts

#include "skeleton.dtsi"
#include "s5pv210-pinctrl.dtsi"

/ {
model = "Samsung SMDKV210 based on S5PV210";
compatible = "samsung,smdkv210", "samsung,s5pv210";

aliases {
serial0 = "/serial@e2900000";
console = "/serial@e2900000";
pinctrl0 = &pinctrl0;
};

pinctrl0: pinctrl@e0200000 {
compatible = "samsung,s5pv210-pinctrl";
reg = <0xe0200000 0x1000>;
};

serial@e2900000 {
compatible = "samsung,exynos4210-uart";
reg = <0xe2900000 0x100>;
interrupts = <0 51 0>;
id = <0>;
};

};
这样基本就算添加了单板信息,回到uboot主目录,为了支持SPL故修改
vim common/spl/Kconfig

config SUPPORT_SPL
bool "enable spl"
help
add by xcl

执行make smdkv210_defconfig
make menuconfig将SPL编译选项选上
make

将上面编译生成的u-boot.bin下载到开发板发现没有现象,然后我通过点灯调试发现问题出现了
common/board_f.c的函数数组static const init_fnc_t init_sequence_f[]里面的timer_init函数
于是继续跟踪到arch/arm/mach-s5pv2xx/clock.c的s5pc1xx_get_pwm_clk函数,发现这个函数是这样的
static unsigned long s5pc1xx_get_pwm_clk(void)
{
if (cpu_is_s5pc110())
return s5pc110_get_pclk();
else
return s5pc100_get_pclk();
}
很明显返回的是s5pc100_get_pclk(),所以有问题;类似的函数还有很多个修改的方法有两个。
方法1:把刚开始修改的arch/arm/mach-s5pv2xx/include/mach/cpu.h里面的s5p_set_cpu_id()
修改成u-boot原来的样子,然后再修改arch/arm/mach-s5pv2xx/include/mach/cpu.h的
#define SAMSUNG_BASE(device, base)				\
static inline unsigned int samsung_get_base_##device(void)	\
{								\
return S5PV210_##base;\
}

方法2:
修改arch/arm/mach-s5pv2xx/clock.c
改为:
/*
* Copyright (C) 2009 Samsung Electronics
* Minkyu Kang <mk7.kang@samsung.com>
* Heungjun Kim <riverful.kim@samsung.com>
*
* SPDX-License-Identifier:	GPL-2.0+
*/

#include <common.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
#include <asm/arch/clk.h>

#define CLK_M	0
#define CLK_D	1
#define CLK_P	2

#ifndef CONFIG_SYS_CLK_FREQ_C100
#define CONFIG_SYS_CLK_FREQ_C100	12000000
#endif
#ifndef CONFIG_SYS_CLK_FREQ_C110
#define CONFIG_SYS_CLK_FREQ_C110	24000000
#endif
/*add by xcl*/
#ifndef CONFIG_SYS_CLK_FREQ_V210
#define CONFIG_SYS_CLK_FREQ_V210	24000000
#endif

/* s5pc110: return pll clock frequency */
static unsigned long s5pc100_get_pll_clk(i
4000
nt pllreg)
{
struct s5pc100_clock *clk =
(struct s5pc100_clock *)samsung_get_base_clock();
unsigned long r, m, p, s, mask, fout;
unsigned int freq;

switch (pllreg) {
case APLL:
r = readl(&clk->apll_con);
break;
case MPLL:
r = readl(&clk->mpll_con);
break;
case EPLL:
r = readl(&clk->epll_con);
break;
case HPLL:
r = readl(&clk->hpll_con);
break;
default:
printf("Unsupported PLL (%d)\n", pllreg);
return 0;
}

/*
* APLL_CON: MIDV [25:16]
* MPLL_CON: MIDV [23:16]
* EPLL_CON: MIDV [23:16]
* HPLL_CON: MIDV [23:16]
*/
if (pllreg == APLL)
mask = 0x3ff;
else
mask = 0x0ff;

m = (r >> 16) & mask;

/* PDIV [13:8] */
p = (r >> 8) & 0x3f;
/* SDIV [2:0] */
s = r & 0x7;

/* FOUT = MDIV * FIN / (PDIV * 2^SDIV) */
freq = CONFIG_SYS_CLK_FREQ_C100;
fout = m * (freq / (p * (1 << s)));

return fout;
}

/* s5pc100: return pll clock frequency */
static unsigned long s5pc110_get_pll_clk(int pllreg)
{
struct s5pc110_clock *clk =
(struct s5pc110_clock *)samsung_get_base_clock();
unsigned long r, m, p, s, mask, fout;
unsigned int freq;

switch (pllreg) {
case APLL:
r = readl(&clk->apll_con);
break;
case MPLL:
r = readl(&clk->mpll_con);
break;
case EPLL:
r = readl(&clk->epll_con);
break;
case VPLL:
r = readl(&clk->vpll_con);
break;
default:
printf("Unsupported PLL (%d)\n", pllreg);
return 0;
}

/*
* APLL_CON: MIDV [25:16]
* MPLL_CON: MIDV [25:16]
* EPLL_CON: MIDV [24:16]
* VPLL_CON: MIDV [24:16]
*/
if (pllreg == APLL || pllreg == MPLL)
mask = 0x3ff;
else
mask = 0x1ff;

m = (r >> 16) & mask;

/* PDIV [13:8] */
p = (r >> 8) & 0x3f;
/* SDIV [2:0] */
s = r & 0x7;

freq = CONFIG_SYS_CLK_FREQ_C110;
if (pllreg == APLL) {
if (s < 1)
s = 1;
/* FOUT = MDIV * FIN / (PDIV * 2^(SDIV - 1)) */
fout = m * (freq / (p * (1 << (s - 1))));
} else
/* FOUT = MDIV * FIN / (PDIV * 2^SDIV) */
fout = m * (freq / (p * (1 << s)));

return fout;
}

/* s5pc100: return pll clock frequency(add by xcl) */
static unsigned long s5pv210_get_pll_clk(int pllreg)
{
struct s5pv210_clock *clk =
(struct s5pv210_clock *)samsung_get_base_clock();
unsigned long r, m, p, s, mask, fout;
unsigned int freq;

switch (pllreg) {
case APLL:
r = readl(&clk->apll_con);
break;
case MPLL:
r = readl(&clk->mpll_con);
break;
case EPLL:
r = readl(&clk->epll_con);
break;
case VPLL:
r = readl(&clk->vpll_con);
break;
default:
printf("Unsupported PLL (%d)\n", pllreg);
return 0;
}

/*
* APLL_CON: MIDV [25:16]
* MPLL_CON: MIDV [25:16]
* EPLL_CON: MIDV [24:16]
* VPLL_CON: MIDV [24:16]
*/
if (pllreg == APLL || pllreg == MPLL)
mask = 0x3ff;
else
mask = 0x1ff;

m = (r >> 16) & mask;

/* PDIV [13:8] */
p = (r >> 8) & 0x3f;
/* SDIV [2:0] */
s = r & 0x7;

freq = CONFIG_SYS_CLK_FREQ_V210;
if (pllreg == APLL) {
if (s < 1)
s = 1;
/* FOUT = MDIV * FIN / (PDIV * 2^(SDIV - 1)) */
fout = m * (freq / (p * (1 << (s - 1))));
} else
/* FOUT = MDIV * FIN / (PDIV * 2^SDIV) */
fout = m * (freq / (p * (1 << s)));

return fout;
}

/* s5pc110: return ARM clock frequency */
static unsigned long s5pc110_get_arm_clk(void)
{
struct s5pc110_clock *clk =
(struct s5pc110_clock *)samsung_get_base_clock();
unsigned long div;
unsigned long dout_apll, armclk;
unsigned int apll_ratio;

div = readl(&clk->div0);

/* APLL_RATIO: [2:0] */
apll_ratio = div & 0x7;

dout_apll = get_pll_clk(APLL) / (apll_ratio + 1);
armclk = dout_apll;

return armclk;
}

/* s5pv210: return ARM clock frequency (add by xcl)*/
static unsigned long s5pv210_get_arm_clk(void)
{
struct s5pv210_clock *clk =
(struct s5pv210_clock *)samsung_get_base_clock();
unsigned long div;
unsigned long dout_apll, armclk;
unsigned int apll_ratio;

div = readl(&clk->div0);

/* APLL_RATIO: [2:0] */
apll_ratio = div & 0x7;

dout_apll = get_pll_clk(APLL) / (apll_ratio + 1);
armclk = dout_apll;

return armclk;
}

/* s5pc100: return ARM clock frequency */
static unsigned long s5pc100_get_arm_clk(void)
{
struct s5pc100_clock *clk =
(struct s5pc100_clock *)samsung_get_base_clock();
unsigned long div;
unsigned long dout_apll, armclk;
unsigned int apll_ratio, arm_ratio;

div = readl(&clk->div0);

/* ARM_RATIO: [6:4] */
arm_ratio = (div >> 4) & 0x7;
/* APLL_RATIO: [0] */
apll_ratio = div & 0x1;

dout_apll = get_pll_clk(APLL) / (apll_ratio + 1);
armclk = dout_apll / (arm_ratio + 1);

return armclk;
}

/* s5pc100: return HCLKD0 frequency */
static unsigned long get_hclk(void)
{
struct s5pc100_clock *clk =
(struct s5pc100_clock *)samsung_get_base_clock();
unsigned long hclkd0;
uint div, d0_bus_ratio;

div = readl(&clk->div0);
/* D0_BUS_RATIO: [10:8] */
d0_bus_ratio = (div >> 8) & 0x7;

hclkd0 = get_arm_clk() / (d0_bus_ratio + 1);

return hclkd0;
}

/* s5pc100: return PCLKD1 frequency */
static unsigned long get_pclkd1(void)
{
struct s5pc100_clock *clk =
(struct s5pc100_clock *)samsung_get_base_clock();
unsigned long d1_bus, pclkd1;
uint div, d1_bus_ratio, pclkd1_ratio;

div = readl(&clk->div0);
/* D1_BUS_RATIO: [14:12] */
d1_bus_ratio = (div >> 12) & 0x7;
/* PCLKD1_RATIO: [18:16] */
pclkd1_ratio = (div >> 16) & 0x7;

/* ASYNC Mode */
d1_bus = get_pll_clk(MPLL) / (d1_bus_ratio + 1);
pclkd1 = d1_bus / (pclkd1_ratio + 1);

return pclkd1;
}

/* s5pc110: return HCLKs frequency */
static unsigned long get_hclk_sys(int dom)
{
struct s5pc110_clock *clk =
(struct s5pc110_clock *)samsung_get_base_clock();
unsigned long hclk;
unsigned int div;
unsigned int offset;
unsigned int hclk_sys_ratio;

if (dom == CLK_M)
return get_hclk();

div = readl(&clk->div0);

/*
* HCLK_MSYS_RATIO: [10:8]
* HCLK_DSYS_RATIO: [19:16]
* HCLK_PSYS_RATIO: [27:24]
*/
offset = 8 + (dom << 0x3);

hclk_sys_ratio = (div >> offset) & 0xf;

hclk = get_pll_clk(MPLL) / (hclk_sys_ratio + 1);

return hclk;
}

/* s5pc110: return PCLKs frequency */
static unsigned long get_pclk_sys(int dom)
{
struct s5pc110_clock *clk =
(struct s5pc110_clock *)samsung_get_base_clock();
unsigned long pclk;
unsigned int div;
unsigned int offset;
unsigned int pclk_sys_ratio;

div = readl(&clk->div0);

/*
* PCLK_MSYS_RATIO: [14:12]
* PCLK_DSYS_RATIO: [22:20]
* PCLK_PSYS_RATIO: [30:28]
*/
offset = 12 + (dom << 0x3);

pclk_sys_ratio = (div >> offset) & 0x7;

pclk = get_hclk_sys(dom) / (pclk_sys_ratio + 1);

return pclk;
}

/* s5pc110: return peripheral clock frequency */
static unsigned long s5pc110_get_pclk(void)
{
return get_pclk_sys(CLK_P);
}

/* s5pc110: return peripheral clock frequency */
static unsigned long s5pv210_get_pclk(void)
{
return get_pclk_sys(CLK_P);
}

/* s5pc100: return peripheral clock frequency */
static unsigned long s5pc100_get_pclk(void)
{
return get_pclkd1();
}

/* s5pc1xx: return uart clock frequency (modified by xcl)*/
static unsigned long s5pc1xx_get_uart_clk(int dev_index)
{
if (cpu_is_s5pc110())
return s5pc110_get_pclk();
else if (cpu_is_s5pv210())
return s5pv210_get_pclk();
else
return s5pc100_get_pclk();
}

/* s5pc1xx: return pwm clock frequency (modified by xcl) */
static unsigned long s5pc1xx_get_pwm_clk(void)
{
if (cpu_is_s5pc110())
return s5pc110_get_pclk();
else if(cpu_is_s5pv210())
return s5pv210_get_pclk();
else
return s5pc100_get_pclk();
}
/* (modified by xcl) */
unsigned long get_pll_clk(int pllreg)
{
if (cpu_is_s5pc110())
return s5pc110_get_pll_clk(pllreg);
else if(cpu_is_s5pv210())
return s5pv210_get_pll_clk(pllreg);
else
return s5pc100_get_pll_clk(pllreg);
}
/* (modified by xcl) */
unsigned long get_arm_clk(void)
{
if (cpu_is_s5pc110())
return s5pc110_get_arm_clk();
else if(cpu_is_s5pv210())
return s5pv210_get_arm_clk();
else
return s5pc100_get_arm_clk();
}

unsigned long get_pwm_clk(void)
{
return s5pc1xx_get_pwm_clk();
}

unsigned long get_uart_clk(int dev_index)
{
return s5pc1xx_get_uart_clk(dev_index);
}

void set_mmc_clk(int dev_index, unsigned int div)
{
/* Do NOTHING */
}

在arch/arm/mach-s5pv2xx/clock.h添加
struct s5pv210_clock {
unsigned int	apll_lock;
unsigned char	res1[0x4];
unsigned int	mpll_lock;
unsigned char	res2[0x4];
unsigned int	epll_lock;
unsigned char	res3[0xc];
unsigned int	vpll_lock;
unsigned char	res4[0xdc];
unsigned int	apll_con;
unsigned char	res5[0x4];
unsigned int	mpll_con;
unsigned char	res6[0x4];
unsigned int	epll_con;
unsigned char	res7[0xc];
unsigned int	vpll_con;
unsigned char	res8[0xdc];
unsigned int	src0;
unsigned int	src1;
unsigned int	src2;
unsigned int	src3;
unsigned char	res9[0xf0];
unsigned int	div0;
unsigned int	div1;
unsigned int	div2;
unsigned int	div3;
unsigned int	div4;
unsigned char	res10[0x1ec];
unsigned int	gate_d00;
unsigned int	gate_d01;
unsigned int	gate_d02;
unsigned char	res11[0x54];
unsigned int	gate_sclk0;
unsigned int	gate_sclk1;
};

这样修改后在timer_init函数就没有错误了。
接着在common/board_f.c的函数数组static const init_fnc_t init_sequence_f[]
里面的env_init函数出错,一直跟踪到env/env.c里面的env_get_default_location
函数出错,这个函数看上去像是u-boot环境变量出发介质的选择。然后我就去配置看
看能不能解决这个问题直接make menuconfig然后依次选择下去environment->select the location of the environment->
environment is not stord,保存编译,
然后用tftp下载到内存:tftp 20000000 u-boot.bin
去执行:go 20000000
哇!!!!!!!!打印出信息了

说明:我这儿用tftp下载bin文件,大家可能感觉奇怪,怎么移植uboot就有tftp下载了呢?
其实我这儿只是学习,所以我现在在移植uboot的时候开发板是从SD卡启动的,SD卡里面下载了开发板
厂家提供的移植好了的uboot,我用这个u-boot就能直接下载裸机程序到内存去运行,感觉比用dnw方便
快捷一些。值得注意的一点是现在现在进去的u-boot.bin是没有进行内存初始化的,如果通过这种方式
下载的裸机程序是不能进行内存初始化,不然会挂掉,所以我是将内存初始化放在SPL代码里面去进行的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息