先给自己打个广告,本人的微信公众号正式上线了,搜索:张笑生的地盘,主要关注嵌入式软件开发,股票基金定投,足球等等,希望大家多多关注,有问题可以直接留言给我,一定尽心尽力回答大家的问题,二维码如下:
a. 阅读代码,一般地,都是从start.S开始阅读代码
b. 发现不足,uboot先以60MHz的时钟来计算参数设置内存控制器,但是MPLL还未设置
c. 修改 smdk2440.c 中的 board_early_init_f 函数部分,不在这个函数中设置PLL时钟以及MPLL时钟,将下面语句注释掉
/* 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);
d. 在start.S中设置PLL时钟以及MPLL时钟
(1) 利用韦老师的uboot烧写我们编译的uboot,命令 usb 1 30000000,然后利用dnw烧写
(2) 去掉flash的写保护 protect off all
(3) 擦除 erase 0 7FFFF
(4) 将文件烧写到nor flash命令 cp.b 30000000 0 80000
(5) 将uboot反汇编生成 uboot.dis 文件
OpenJTAG单步调试
因为我们烧写的是我们未做任何修改,直接编译生成的uboot,烧写完成之后,肯定没有任何输出
那么此时我们应该如何调试
连接OpenJTAG的线
打开OpenJTAG
点击connect,然后点击telnet
在弹出的命令窗口中,输入如下命令
a. halt
b. mdw 0
c. bp 0x98 4 hw //在0x98地址位置处打上一个硬件断点,这个地址是uboot.dis反汇编文件中
//cpu_init_crit函数地址
d. 让cpu开始运行 step 0 step resume
(6) 修改Start.S文件,关于时钟PLL和MPLL的配置,以及内存的配置,参照 G:\100ask\第1期和第2期衔接视频\32th_my_bootloader\2th 中的start.s来配置
将时钟设置部分代码改为如下
/* FCLK:HCLK:PCLK = 1:2:4 */
/* default FCLK is 120 MHz ! */
ldr r0, =0x4c000014
// mov r1, #0x03; // FCLK:HCLK:PCLK=1:2:4, HDIVN=1,PDIVN=1
mov r1, #0x05; // FCLK:HCLK:PCLK=1:4:8
str r1, [r0]
/* 如果HDIVN非0,CPU的总线模式应该从“fast bus mode”变为“asynchronous bus mode” */
mrc p15, 0, r1, c1, c0, 0 /* 读出控制寄存器 */
orr r1, r1, #0xc0000000 /* 设置为“asynchronous bus mode” */
mcr p15, 0, r1, c1, c0, 0 /* 写入控制寄存器 */
#define S3C2440_MPLL_400MHZ ((0x5c<<12)|(0x01<<4)|(0x01))
/* MPLLCON = S3C2440_MPLL_200MHZ */
ldr r0, =0x4c000004
ldr r1, =S3C2440_MPLL_400MHZ
str r1, [r0]
/* 启动ICACHE */
mrc p15, 0, r0, c1, c0, 0 @ read control reg
orr r0, r0, #(1<<12)
mcr p15, 0, r0, c1, c0, 0 @ write it back
内存的设置,修改lowlevel_init.S,改为如下
SMRDATA:
.long 0x22011110 //BWSCON
.long 0x00000700 //BANKCON0
.long 0x00000700 //BANKCON1
.long 0x00000700 //BANKCON2
.long 0x00000700 //BANKCON3
.long 0x00000740 //BANKCON4
.long 0x00000700 //BANKCON5
.long 0x00018005 //BANKCON6
.long 0x00018005 //BANKCON7
.long 0x008C04F4 // REFRESH
.long 0x000000B1 //BANKSIZE
.long 0x00000030 //MRSRB6
.long 0x00000030 //MRSRB7
e. 重新编译 make distclean,然后make
f. 烧写新编译的uboot,重启开发板,发现有打印,但是打印乱码,说明我们修改的代码发生了作用,可能是串口波特率问题
g. 查看出口设置部分,发现arch/arm/cpu/arm920t/s3c24x0/speed.c文件中的get_HCLK函数中没有定义CONFIG_S3C2440这个宏,所以配置还是2410的配置。
static ulong get_PLLCLK(int pllreg)
{
struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
ulong r, m, p, s;
if (pllreg == MPLL)
r = readl(&clk_power->mpllcon);
else if (pllreg == UPLL)
r = readl(&clk_power->upllcon);
else
hang();
m = ((r & 0xFF000) >> 12) + 8;
p = ((r & 0x003F0) >> 4) + 2;
s = r & 0x3;
#if defined(CONFIG_S3C2440)
if (pllreg == MPLL)
return 2 * m * (CONFIG_SYS_CLK_FREQ / (p << s));
#endif
return (CONFIG_SYS_CLK_FREQ * m) / (p << s);
}
处理措施: include/configs/smdk2440.h : 增加 CONFIG_S3C2440 宏定义.分析哪个文件有没有编译进去,就去看该文件所在目录下的Makefile
//#define CONFIG_S3C2410 /* specifically a SAMSUNG S3C2410 SoC */
#define CONFIG_S3C2440 /* specifically a SAMSUNG S3C2440 SoC */
h. 修改之后,重新编译,发现编译错误,s3c2410_nand 报错,我们可以先不支持nand操作,修改makefile,先不支持编译s3c2410_nand
解决办法 include/configs/smdk2440.h : 注释CONFIG_CMD_NAND 宏定义
#define CONFIG_CMD_ELF
//#define CONFIG_CMD_NAND
#define CONFIG_CMD_PING
i. 在注释掉上面的宏定义时,继续make还是会出错,提示yaffscfg.c:210: undefined reference to `nand_info’,我们找到这个c文件,发现里面用到了nand定义,但是因为我们上面注释掉了,导致定义出错
解决办法 include/configs/smdk2440.h : 注释掉 CONFIG_YAFFS2 宏定义
#if 0
#define CONFIG_CMD_FAT
#define CONFIG_CMD_EXT2
#define CONFIG_CMD_UBI
#define CONFIG_CMD_UBIFS
#define CONFIG_CMD_MTDPARTS
#define CONFIG_MTD_DEVICE
#define CONFIG_MTD_PARTITIONS
#define CONFIG_YAFFS2
#define CONFIG_RBTREE
#endif
j. make distclean 然后再 make ,编译成功
k. 烧写新编译好的uboot,重启开发板,发现有正确打印输出,代码修改正确