|
本帖最后由 star_66666 于 2018-4-28 17:33 编辑
前段时间忙着工作和研究lwip、usb等,本周正式开始研究Linux,今天终于完成了uboot移植的第一步,先上图
这就是超级终端的输出
输入bdinfo后显示
uboot算是在SD卡里面正式运行了
下面说明一下移植过程
首先我们移植了 u-boot-spl.bin 和 u-boot.bin。
1) S5PV210 上电运行 iROM 里的代码(BL0),执行一系列初始化,然后从 SD 卡的扇区 1 拷贝
u-boot-spl.bin(BL1)到 iRAM,然后跳转到 u-boot-spl.bin 的起始地址 0xD0020010 执行 u-boot-spl.bin
2) u-boot-spl.bin 初始化时钟、 DDR,然后从 SD 卡的扇区 32 拷贝 u-boot.bin(BL2)到 DDR 的起始
地址 0x20000000,然后跳转到 0x20000000 执行 u-boot.bin
3) u-boot.bin 执行一系列初始化(定时器、串口等),然后从 DDR 的最高地址 0x60000000 开始计算
需要重定位的地址和用户栈指针地址(SP),然后把自己(u-boot.bin)拷贝到前面计算出的重定
位地址,再然后根据修正表(.rel.dyn 和 .dynsym)修正重定位后的 u-boot.bin 的链接地址为其运
行地址,最后跳转到重定位后的 u-boot.bin 去执行。
其次开始在u-boot-2014.04/arch/arm/cpu/armv7/s5pc1xx/clock.c 中 添加和更改相应代码
需要更改的代码有下面2个函数,大家只要把原来的函数直接换成下面所示即可
unsigned long get_pll_clk(int pllreg)
{
return s5pv210_get_pll_clk(pllreg);
}
unsigned long get_arm_clk(void)
{
return s5pv210_get_arm_clk();
}
需要增加的代码如下
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;
}
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_con0);
break;
case MPLL:
r = readl(&clk->mpll_con);
break;
case EPLL:
r = readl(&clk->epll_con0);
break;
case VPLL:
r = readl(&clk->vpll_con);
break;
default:
printf("Unsupported PLL (%d)\n", pllreg);
return 0;
}
/*
* APLL_CON0: MIDV [25:16]
* MPLL_CON: MIDV [25:16]
* EPLL_CON0: 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;
}
由于上面的代码里面用到了
CONFIG_SYS_CLK_FREQ_V210这个宏定义,需要在u-boot-2014.04\include\configs\smdkv210.h里面添加
#define CONFIG_SYS_CLK_FREQ_V210 24000000
顺便把下面的宏定义依次更改
#define CONFIG_SYS_PROMPT "SMDKV210 # "
#define PHYS_SDRAM_1_SIZE (1024 << 20)
#define CONFIG_IDENT_STRING " for SMDKV210"
在u-boot-2014.04\arch\arm\lib\board.c里面把下面函数调用注释掉,目前用不到,而且编译会出错。
/*onenand_init();*/
使用make all生成uboot.bin后需要使用ll -h u-boot.bin 查看uboot.bin文件大小
然后更改u-boot-2014.04/board/samsung/smdkv210/smdkv210.c 里面的函数
int checkboard(void)
{
printf("Board:\tSMDKV210\n");
return 0;
}
void copy_bl2_to_ram(void)函数里面的调用更改为下面
CopySDMMCtoMem(ch, 32, 400, (unsigned int *)CONFIG_SYS_SDRAM_BASE, 0);
再次执行make all
编译完成后,结果见图
|
|