uboot研读笔记 | 03 - 初步移植uboot 2012.04到JZ2440(修改时钟,配置串口)

在移植之前, 请首先确保对uboot的启动过程有所了解,参考:

1.新建单板

  • ① 新建单板目录,复制已有相似的目录即可(在board/厂家型号之下)

  • ② 新建单板配置文件,复制相似即可(在include/configs/目录下

  • ③添加单板配置文件

修改根目录下boards.cfg文件,在其中按照规定的格式添加单板配置文件,格式如下:

Target ARCH CPU Board name  Vendor SoC Options

//目标	CPU架构 CPU架构 单板名称 厂商名称 SOC信息 设置

搜索smdk2410,仿照24120的添加一行2440的:

至此,新单板的所有文件创建完成,编译测试:

make smdk2440_config
make

如果配置和编译通过,则证明新的单板文件没有问题,接下来按照uboot启动流程来修改代码。

2. 单板配置文件

上一小节中添加的单板配置文件include/configs/smdk2440.h中包含了最顶层的一些宏定义配置,需要在修改过程中不断的进行修改。

  • 一定不要先直接修改最顶层的宏定义!
  • 一定不要先直接修改最顶层的宏定义!
  • 一定不要先直接修改最顶层的宏定义!

3. 初步修改配置

在start_code中,依次检查需要修改的地方。

参考S3C2440-裸机篇-05 | S3C2440时钟体系详解(FCLK、PCLK、HCLK)

3.1. 修改时钟分频系数

#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 

3.2. 调用lowlevel_init函数设置内存控制器

内存控制器中关于SDRAM的配置修改如下:

在地址配置中去掉了tchr的选项,s3c2440中没有:

3.3. 修改board_init_f函数

在单板配置文件中设置了栈顶指针sp:

所以无需修改,直接跳入到board_init_f函数执行即可。

在board_init_f函数中,board_early_init_f函数需要修改,修改时钟配置代码:

可以看到,通过修改M_MDIV、M_PDIV、M_SDIV的值来改变时钟配置,在该文件上面修改:

USB暂未用到,先不修改。

3.4. 编译测试

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已经被破坏,需要重新烧写!

4. 修改串口设置

在文件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
}

5. 开启CONFIG_S3C2440宏定义

在配置文件中开启这个宏定义:

然后修改在start.S中配置时钟分频系数的代码:

编译之后发现nand文件有问题,这里暂且先不使用nand flash,在单板配置文件中屏蔽掉相关宏定义::

再次编译之后发现yaffs2文件系统有问题,这里暂且先不使用文件系统,在单板配置文件屏蔽掉相关宏定义:

再次编译,没有问题,下载到开发板的Nor Flash中,查看串口输出,可以正常打印,uboot初步移植成功:

接收更多精彩文章及资源推送,欢迎订阅我的微信公众号:『mculover666』

发布了227 篇原创文章 · 获赞 590 · 访问量 26万+

猜你喜欢

转载自blog.csdn.net/Mculover666/article/details/104484787
今日推荐