U-BOOT-2016.07移植 (第一篇) 初步分析
U-BOOT-2016.07移植 (第二篇) 添加单板
U-BOOT-2016.07移植 (第三篇) 代码重定位
U-BOOT-2016.07移植 (第四篇) 修改代码,从NOR启动
目录
1. 修改lowlevel_init.S
- board/samsung/smdk2440/lowlevel_init.S,143行:
.word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
这里REFCNT是在HCLK=60MHz的基础上设置的,但一开始在start.S中时钟频率还没有设置,只设置了分频比例,所以HCLK=12MHz,这里需要修改,而且133~146行的其他参数最好也进行修改,改成适用于自己板子的存储控制器的参数。我的JZ2440v2参数是这样设置的(HCLK=100MHz):
// 存储控制器13个寄存器的设置值
.long 0x22011110 //BWSCON
.long 0x00000700 //BANKCON0
.long 0x00000700 //BANKCON1
.long 0x00000700 //BANKCON2
.long 0x00000700 //BANKCON3
.long 0x00000700 //BANKCON4
.long 0x00000700 //BANKCON5
.long 0x00018005 //BANKCON6
.long 0x00018005 //BANKCON7
.long 0x008c04f4 //REFRESH
.long 0x000000B1 //BANKSIZE
.long 0x00000030 //MRSRB6
.long 0x00000030 //MRSRB7
直接把原文件中的设置值替换掉就可以了。
2. 修改start.S
既然在lowlevel_init.S中是在HCLK=100MHz的情况下设置存储控制器的,那在调用lowlevel_init之前,就需要先进行时钟频率设置。
- arch/arm/cpu/arm920t/start.S,从87行开始改:
/* FCLK:HCLK:PCLK = 1:2:4 */
/* default FCLK is 120 MHz ! */
ldr r0, =CLKDIVN
mov r1, #3
str r1, [r0]
/*
* blog.csdn.net/funkunho 从这里开始为新添加的内容,设置时钟频率
*
* 根s3c2440数据手册得知,若HDIVN不为0,则需要将CPU总线模式设置为异步模式
* 原文如下:
* If HDIVN is not 0, the CPU bus mode has to be changed from the fast bus mode
* to the asynchronous.
* bus mode using following instructions(S3C2440 does not support synchronous bus mode).
* MMU_SetAsyncBusMode
* mrc p15,0,r0,c1,c0,0
* orr r0,r0,#R1_nF:OR:R1_iA
* mcr p15,0,r0,c1,c0,0
*/
mrc p15,0,r0,c1,c0,0
orr r0,r0,#0xc0000000
mcr p15,0,r0,c1,c0,0
ldr r0,=0x4c000004 //MPLLCON
ldr r1,=0x2a011 //(1<<0)|(1<<4)|(42<<12);
//FCLK = MPLL = 200MHz 设置不对会导致SDRAM不可用
str r1,[r0]
/* blog.csdn.net/funkunho */
3. 修改smdk2440.c
既然在start.S中已经进行时钟频率设置了,那在board_init_f中就没必要进行时钟频率设置了。在我的上一篇文章U-BOOT-2016.07移植 (第三篇) 代码重定位中就有分析到,board_init_f会调用函数数组init_sequence_f中存放的各个函数,其中board_early_init_f这个函数定义在smdk2440.c中,在里面进行时钟频率设置,所以我们需要修改这个函数中的内容,去掉时钟频率设置。
- board/samsung/smdk2440/smdk2440.c,将board_early_init_f函数修改如下:
int board_early_init_f(void)
{
struct s3c24x0_clock_power * const clk_power =
s3c24x0_get_base_clock_power();
struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();
/* blog.csdn.net/funkunho */
// /* to reduce PLL lock time, adjust the LOCKTIME register */
// writel(0xFFFFFF, &clk_power->locktime);
// /* configure MPLL */
// writel((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV,
// &clk_power->mpllcon);
// /* some delay between MPLL and UPLL */
// pll_delay(4000);
// /* configure UPLL */
// writel((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV,
// &clk_power->upllcon);
// /* some delay between MPLL and UPLL */
// pll_delay(8000);
/* blog.csdn.net/funkunho */
/* set up the I/O ports */
writel(0x007FFFFF, &gpio->gpacon);
writel(0x00044555, &gpio->gpbcon);
writel(0x000007FF, &gpio->gpbup);
writel(0xAAAAAAAA, &gpio->gpccon);
writel(0x0000FFFF, &gpio->gpcup);
writel(0xAAAAAAAA, &gpio->gpdcon);
writel(0x0000FFFF, &gpio->gpdup);
writel(0xAAAAAAAA, &gpio->gpecon);
writel(0x0000FFFF, &gpio->gpeup);
writel(0x000055AA, &gpio->gpfcon);
writel(0x000000FF, &gpio->gpfup);
writel(0xFF95FFBA, &gpio->gpgcon);
writel(0x0000FFFF, &gpio->gpgup);
writel(0x002AFAAA, &gpio->gphcon);
writel(0x000007FF, &gpio->gphup);
return 0;
}
4. 编译、烧写、启动单板
修改完上述代码后就可以将修改后的文件通过FTP工具拖到虚拟机linux上进行编译了,编译后在顶层目录会得到一个u-boot.bin,将其拖回windows,然后利用Jlink、openJTAG等烧写工具烧写到单板norflash上,然后以norflash启动单板,看串口1是否有打印出信息,有的话就算成功。