项目开源地址:https://github.com/Mculover666/uboot-jz2440
在移植之前, 请首先确保对uboot的启动过程有所了解,参考:
board/厂家型号
之下)include/configs/目录下
)修改根目录下boards.cfg
文件,在其中按照规定的格式添加单板配置文件,格式如下:
Target ARCH CPU Board name Vendor SoC Options
//目标 CPU架构 CPU架构 单板名称 厂商名称 SOC信息 设置
至此,新单板的所有文件创建完成,编译测试:
make smdk2440_config
make
如果配置和编译通过,则证明新的单板文件没有问题,接下来按照uboot启动流程来修改代码。
上一小节中添加的单板配置文件include/configs/smdk2440.h
中包含了最顶层的一些宏定义配置,需要在修改过程中不断的进行修改。
在start_code中,依次检查需要修改的地方。
参考S3C2440-裸机篇-05 | S3C2440时钟体系详解(FCLK、PCLK、HCLK)。
#if defined(CONFIG_S3C2410)
/* 自己添加的S3C2440时钟分频系数配置 */
/* FCLK:HCLK:PCLK = =8:4:1 */
/* default FCLK is 400 MHz ! */
ldr r0, =CLKDIVN
mov r1, #5
str r1, [r0]
/* HDIVN不为0,设置CPU为异步模式(来源芯片手册)*/
mrc p15,0,r0,c1,c0,0
orr r0,r0,#0xc0000000 @#R1_nF:OR:R1_iA
mcr p15,0,r0,c1,c0,0
#endif
在单板配置文件中设置了栈顶指针sp:
所以无需修改,直接跳入到board_init_f函数执行即可。
在board_init_f函数中,board_early_init_f函数需要修改,修改时钟配置代码:
可以看到,通过修改M_MDIV、M_PDIV、M_SDIV的值来改变时钟配置,在该文件上面修改:
USB暂未用到,先不修改。
make distclean
make smdk2440_config
make
编译成功后,使用open-JTAG直接下载,将编译出的u-boot.bin文件下载到nor flash中,:
这种烧写方式太慢了,烧录一次需要3-5min,可以先将正常的uboot烧录到nor flash中,然后通过uboot的usb下载方式,将自己移植的uboot程序通过DNW工具发送给uboot,存放到内存中,这种方式下载速度非常快:
然后将内存中的程序烧录到nor flash中:
protect off all
erase 0 7ffff
cp.b 30000000 0 80000
//重启开发板
可以看到自己移植的uboot运行起来了,但是串口仍然有乱码,说明波特率设置有问题,后续进行修改:
烧写自己移植的程序之后,Nor Flash上原有的正常uboot已经被破坏,需要重新烧写!
在文件drivers/serial/serial_s3c24x0.c
中找到串口配置函数serial_init,进一步查找,同样在该文件中有serial_init_dev,该函数用来初始化串口设备,该函数末尾跳转到_serial_setbrg。
_serial_setbrg函数同样在该文件中调用get_PCLK函数来计算值,如下:
/* value is calculated so : (int)(PCLK/16./baudrate) -1 */
reg = get_PCLK() / (16 * gd->baudrate) - 1;
查看get_PCLK函数,跳转到文件arch/arm/cpu/arm920t/s3c24x0/speed.c
中,可以看到,该函数调用了get_HCLK:
/* return PCLK frequency */
ulong get_PCLK(void)
{
struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
return (readl(&clk_power->clkdivn) & 1) ? get_HCLK() / 2 : get_HCLK();
}
get_HCLK函数同样在该文件中,但是从源码可以看到,只有定义了宏CONFIG_S3C2440,该段代码才有效(整个文件还需要开启宏CONFIG_S3C24X0):
/* return HCLK frequency */
ulong get_HCLK(void)
{
struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
#ifdef CONFIG_S3C2440
switch (readl(&clk_power->clkdivn) & 0x6) {
default:
case 0:
return get_FCLK();
case 2:
return get_FCLK() / 2;
case 4:
return (readl(&clk_power->camdivn) & (1 << 9)) ?
get_FCLK() / 8 : get_FCLK() / 4;
case 6:
return (readl(&clk_power->camdivn) & (1 << 8)) ?
get_FCLK() / 6 : get_FCLK() / 3;
}
#else
return (readl(&clk_power->clkdivn) & 2) ? get_FCLK() / 2 : get_FCLK();
#endif
}
然后修改在start.S中配置时钟分频系数的代码:
编译之后发现nand文件有问题,这里暂且先不使用nand flash,在单板配置文件中屏蔽掉相关宏定义::
再次编译之后发现yaffs2文件系统有问题,这里暂且先不使用文件系统,在单板配置文件屏蔽掉相关宏定义:
再次编译,没有问题,下载到开发板的Nor Flash中,查看串口输出,可以正常打印,uboot初步移植成功:
接收更多精彩文章及资源推送,欢迎订阅我的微信公众号:『mculover666』。