uboot研读笔记 | 03 - 初步移植uboot 2012.04到JZ2440(修改时钟,配置串口)
Posted Neutionwei
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了uboot研读笔记 | 03 - 初步移植uboot 2012.04到JZ2440(修改时钟,配置串口)相关的知识,希望对你有一定的参考价值。
0. 教程完整目录
- 00 - 嵌入式Linux系统中Bootloader的作用和基本运行原理
- 01 - 下载uboot源码并使用VSCode远程查看源码、编译uboot(2012.04.01版本)
- 02 - 详细探索uboot启动过程(基于S3C2410处理器)
- 03 - 初步移植uboot 2012.04到JZ2440(修改时钟,配置串口)
- 04 - 移植uboot 2012.04到JZ2440(支持Nor Flash读写)
- 05 - 移植uboot 2012.04到JZ2440(支持Nand Flash读写)
- 06 - 移植uboot 2012.04到JZ2440(支持DM9000C网卡)
- 07 - 移植uboot 2012.04到JZ2440(裁剪uboot大小)
- 08 - 移植uboot 2012.04到JZ2440(设置mtd分区表)
- 09 - 移植uboot 2012.04到JZ2440(设置默认环境变量参数)
- 10 - 移植uboot 2012.04到JZ2440(烧写Linux内核、烧写yaffs2文件系统)
- 11 - 移植uboot 2012.04到JZ2440(移植完成,制作uboot补丁)
在移植之前, 请首先确保对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』。
以上是关于uboot研读笔记 | 03 - 初步移植uboot 2012.04到JZ2440(修改时钟,配置串口)的主要内容,如果未能解决你的问题,请参考以下文章
uboot研读笔记 | 04 - 移植uboot 2012.04到JZ2440(支持Nor Flash读写)
uboot研读笔记 | 13 - uboot编译构建Makefile分析研读(2016.03版本)
uboot研读笔记 | 14 - uboot启动流程分析(2016.03版本)
uboot研读笔记 | 01 - 下载uboot源码并使用VSCode远程查看源码编译uboot(2012.04.01版本)