移植u-boot-2012.04.01到jz2440开发板
来源:互联网 发布:关于java 编辑:程序博客网 时间:2024/06/10 12:44
今天我给大家分享一下如何移植一个纯净的uboot到jz2440开发大版,通过记录学习分享,与大家一起进步!!!
1.首先我们在uboot官网下载u-boot-2012.04.01.tar.bz2,建立source insight工程。将下载好的uboot通过FTP服务器传送到虚拟机中的linux系统下。
解压uboot:
tar xjf u-boot-2012.04.01.tar.bz2
cd u-boot-2012.04.01
make smdk2410_config
make
将得到的u-boot.bin文件下载到开发板(下载方式不唯一),连接至串口,发现没有输出。所以我们下载的uboot不支持我们的jz2440开发板,我们接下来应该通过修改uboot源码使它支持我们的开发板。
2.分析u-boot: 得知大概的启动过程如下:
-初始化硬件:关看门狗、设置时钟、设置SDRAM、初始化NAND FLASH
-如果bootloader较大,要把它重定位到SDRAM
-把内核从NAND FLASH 读到 SDRAM
-设置“设置要传给内核的参数”
-跳转要执行的内核
3.修改U-BOOT代码
3.1 建一个单板
cd board/samsung/
cp smdk2410 smdk2440 -rf
cd ../../include/configs/
cp smdk2410.h smdk2440.h
修改boards.cfg:
仿照:
smdk2410 arm arm920t - samsung s3c24x0
添加:
smdk2440 arm arm920t - samsung s3c24x0
重新编译烧写看结果:串口还是没有输出.
阅读代码发现不足:UBOOT里先以60MHZ的时钟计算参数来设置内存控制器,但是MPLL还未设置
处理措施:把MPLL的设置放到start.S里,取消board_early_init_f里对MPLL的设置
操作如下:
在uboot中的start.s中170行有代码如下:
/* FCLK:HCLK:PCLK = 1:2:4 */ /* default FCLK is 120 MHz ! */ ldr r0, =CLKDIVN mov r1, #3 str r1, [r0]
这是设置时钟的,我们将这一部分删掉,然后换成如下代码:
/* 2. 设置时钟 */ 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: .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28)) .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC)) .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC)) .word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC)) .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC)) .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC)) .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC)) .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN)) .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)) .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT) .word 0x32 .word 0x30 .word 0x30
将其删掉改为:
.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
重新编译烧写看看什么情况:编译烧写成功,启动串口,输出打印乱码如下(至少有打印了,说明我们已经成功了第一步,哈哈哈):
3.1下面解决串口打印乱码问题:
查看串口波特率的设置,在arch\arm\lib中有函数board_init_f,其中有一个结构体init_sequence:
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { if ((*init_fnc_ptr)() != 0) { hang ();
跳转到这个结构体:
init_fnc_t *init_sequence[] = {#if defined(CONFIG_ARCH_CPU_INIT) arch_cpu_init, /* basic arch cpu dependent setup */#endif#if defined(CONFIG_BOARD_EARLY_INIT_F) board_early_init_f,#endif#ifdef CONFIG_OF_CONTROL fdtdec_check_fdt,#endif timer_init, /* initialize timer */#ifdef CONFIG_FSL_ESDHC get_clocks,#endif env_init, /* initialize environment */ init_baudrate, /* initialze baudrate settings */ serial_init, /* serial communications setup */ console_init_f, /* stage 1 init of console */ display_banner, /* say that we are here */#if defined(CONFIG_DISPLAY_CPUINFO) print_cpuinfo, /* display cpu info (and speed) */#endif#if defined(CONFIG_DISPLAY_BOARDINFO) checkboard, /* display board info */#endif#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C) init_func_i2c,#endif dram_init, /* configure available RAM banks */ NULL,};
里面是各种初始化,找到串口初始化:serial_init,跳转到这里:
int serial_init(void){ return serial_init_dev(UART_NR);}#endif
然后跳转到这里:serial_init_dev
/* Initialise the serial port. The settings are always 8 data bits, no parity, * 1 stop bit, no start bits. */static int serial_init_dev(const int dev_index){ struct s3c24x0_uart *uart = s3c24x0_get_base_uart(dev_index);#ifdef CONFIG_HWFLOW hwflow = 0; /* turned off by default */#endif /* FIFO enable, Tx/Rx FIFO clear */ writel(0x07, &uart->ufcon); writel(0x0, &uart->umcon); /* Normal,No parity,1 stop,8 bit */ writel(0x3, &uart->ulcon); /* * tx=level,rx=edge,disable timeout int.,enable rx error int., * normal,interrupt or polling */ writel(0x245, &uart->ucon);#ifdef CONFIG_HWFLOW writel(0x1, &uart->umcon); /* rts up */#endif /* FIXME: This is sooooooooooooooooooo ugly */#if defined(CONFIG_ARCH_GTA02_v1) || defined(CONFIG_ARCH_GTA02_v2) /* we need auto hw flow control on the gsm and gps port */ if (dev_index == 0 || dev_index == 1) writel(0x10, &uart->umcon);#endif _serial_setbrg(dev_index); return (0);}
然后跳转到这里:_serial_setbrg
void _serial_setbrg(const int dev_index)
{
struct s3c24x0_uart *uart = s3c24x0_get_base_uart(dev_index);
unsigned int reg = 0;
int i;
/* value is calculated so : (int)(PCLK/16./baudrate) -1 */reg = get_PCLK() / (16 * gd->baudrate) - 1;writel(reg, &uart->ubrdiv);for (i = 0; i < 100; i++) /* Delay */ ;
}
跳转到:get_PCLK
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
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; }
我们会发现#ifdef CONFIG_S3C2440 这一句是黑色的,说明没有定义这个CONFIG_S3C2440,
处理措施:
在include/configs/smdk2440.h: 去掉CONFIG_S3C2410 ,换成CONFIG_S3C2440
#define CONFIG_S3C2440
定义好这个之后,重新编译,发现编译有错误如下:
错误显示有大量关于nand的错误,猜想原因应该是此uboot暂时不支持该单板,我决定先把nand去掉,先看看串口是否可以正常打印出不是乱码的消息,之后再加入nand的支持,要一步一步来嘛!我们把关于nand的编译选项去掉,查看/drivers/mtd/nand/Makefile,找到只一句:
COBJS-$(CONFIG_NAND_S3C2410) += s3c2410_nand.o
说明编译s3c2410_nand.c以来的定义是:CONFIG_NAND_S3C2410,在源码中搜索CONFIG_NAND_S3C2410,在smdk2440.h中找到:
#ifdef CONFIG_CMD_NAND#define CONFIG_NAND_S3C2410#define CONFIG_SYS_S3C2410_NAND_HWECC#define CONFIG_SYS_MAX_NAND_DEVICE 1#define CONFIG_SYS_NAND_BASE 0x4E000000#endif
说明定义了CONFIG_CMD_NAND则CONFIG_NAND_S3C2410就被定义,我们只需要让CONFIG_CMD_NAND不被定义即可,搜索到如下:
#define CONFIG_CMD_NAND
将其改为:
//#define CONFIG_CMD_NAND
重新编译,没有出现错误,烧写测试串口输出为:
哈哈哈!!!!,串口终于输出而且不是乱码了,我们已经走出了第一步,接下来就是让它支持nand flash了,也不是容易的事情啊,已经写了这么多了,就放到下一篇 博客中吧!!!
想跟我一起交流学的加我
qq:1126137994
二维码:
微信:liu1126137994
二维码:
备注:交流学习哦
另外我这里有大量的学习资料,以及现成的项目的经验总结,欢迎叨扰!!!
- 移植u-boot-2012.04.01到jz2440开发板
- 移植u-boot-2012.04.01到jz2440开发板之修改代码支持NAND启动
- 编译JZ2440开发板的u-boot
- 14.4 移植U-Boot到开发板
- 移植u-boot到mini2440开发板。
- u-boot120401移植到JZ2440
- u-boot-2012.04.01移植到TQ2440
- 移植u-boot-2012.04.01到s3c2440
- u-boot在jz2440上移植
- u-boot-2012.04.01移植到TQ2440(一):建立自己的开发板
- u-boot2012.04移植到jz2440 -- ->正常显示u-boot启动信息
- U-Boot的移植之(三)实战篇:移植U-Boot到XSBASE270开发板
- U-Boot的移植之(三)实战篇:移植U-Boot到XSBASE270开发板
- U-Boot的移植之(三)实战篇:移植U-Boot到XSBASE270开发板
- u-boot-2012.04.01移植(s3c2440 开发板)
- U-boot移植到新的开发板1
- 移植u-boot-2012到mini2440开发板的笔记
- 移植u-boot-2010.09到Tiny6410开发板
- UnityShader初级篇——凹凸映射
- hdoj 1005 Number Sequence
- 编程学习理论(一)
- 自定义控件:实现加减功能
- 织梦文章页评论框不显示的解决方法
- 移植u-boot-2012.04.01到jz2440开发板
- 波纹扩散特效(仿支付宝咻一咻功能)
- 贪婪的送礼者vijos
- leetcode 438. Find All Anagrams in a String 一个简单的移动窗口问题
- 局部变量和全局变量
- 37. Sudoku Solver
- 一个SoapExcept异常的处理以及.NET平台下WebService应用的一点注意事项
- 新标准大学英语综合教程2(第二版)unit1答案截图
- wannfly 挑战赛5 A