您的位置:首页 > 其它

uboot1.3.1移植到TQ2440笔记

2011-08-13 12:11 323 查看
1 uboot调试方法,下载UBOOT到SDRAM中,让其直接运行,调试之。
方法:TRY
leds.bin----按n进入TFTP下载模式,然后按7,输入sdram地址(无论是从norflash还是nandflash启动,sdram的起始地址均为0x30000000),然后输入要下载的程序名,下载完毕后,程序从0x30000000sdram的起始地址开始运行。
下载uboot-TRY

2 TQ2440硬件

CPU-S3C2440主频400MHz,最高533Hz
SDRAM—64M
NAND Flash-K9F2G08U0A,256M,Page Size : (2K + 64)Byte

Nor Flash-AM29LV160DB-90EC,2M
LCD?
NET CARD-DM90000

3 编译环境
顶层目录的Makefile文件
添加如下
tq2440_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920ttq2440 NULL s3c24x0

4 tq2440.h
在include/configs目录下建立一个配置文件tq2440.h,将smdk2410.h复制为tq2400.h,检查有关硬件位置配置是否正确?修改有关配置
先按2410的现有的配置作修改,后期根据需要再添加对其他硬件的支持。
锁相环PLL外部输入时钟
#define CONFIG_SYS_CLK_FREQ 12000000/*the TQ2440 has 12MHz input clock */

tq2440网卡型号为DM90000
相关配置-这种配置,一方面可以参照uboot源码中drivers/net中的DM9000驱动中需要的配置,另一方面要查看硬件资料,一般是硬件可以选择的功能,在配置文件中就要有相关的功能配置,作功能的选择。
#define CONFIG_DRIVER_DM9000 1
#define CONFIG_DM9000_BASE 0x20000300
#define DM9000_IO CONFIG_DM9000_BASE
#defineDM9000_DATA (CONFIG_DM9000_BASE + 4)
#define CONFIG_DM9000_USE_16BIT

BOOTPoptions引导程序,BOOTP或DHCP引导协议,可以从服务器获取自己的IP地址,服务器IP地址,以及启动镜像文件名等。
#define CONFIG_BOOTP_BOOTFILESIZE
#define CONFIG_BOOTP_BOOTPATH
#define CONFIG_BOOTP_GATEWAY
#define CONFIG_BOOTP_HOSTNAME

Command line configuration.命令,如何添加自己的命令?U_BOOT_CMD。
#include <config_cmd_default.h>

#define CONFIG_CMD_CACHE
#define CONFIG_CMD_DATE
#define CONFIG_CMD_ELF

kgdb serial port配置?CONFIG_CMD_KGDB什么用?
CFG_CLKS_IN_HZ?
CFG_LOAD_ADDR内核下载地址

PWM Timer CFG_HZ

配置用户栈,IRQ栈或FIQ栈的大小
LV800 flash-NANDFlash配置
配置大小,地址,多少sectors,擦除以及写超时时间

CFG_ENV相关的配置,环境变量是否在Flash中,大小。
是否需要配置#defineCFG_ENV_OFFSET 0x40000???

5将board目录下将smdk2410复制为tq2440目录,并将board/tq2440/tq2440.c改名为tq2440.c—后期还要修改这个文件??
修改board/tq2440/目录下的Makefile文件
COBJS := tq2440.o flash.o

6 修改第一阶段代码
cpu/arm920t/start.S文件(入口)
屏蔽如下两行有关LED的代码
bl coloured_LED_init
bl red_LED_on

修改屏蔽中断的部分将INTSUBMSK寄存器设为x07fff因为s3c2440有15个SUB中断

对时钟分频的选择暂时按默认?

cpu_init_crit-设置重要的寄存器,flushv4 I/D caches,disable MMUstuff and caches
它也会调用lowlevel_init,setupRAM timing。

中断部分暂时按默认,回头在配置使用中断,并定义自己的中断处理函数?

lowleve_init.S
配置存储器控制器原理
需配置内容:支持大字节序,小字节序;每个BANK的地址空间128M,总共1GB;可编程控制的总线位宽(8/16/32),不过BANK0只能为(16/32);总共8个BANK,BANK0-BANK5可以支持ROM,SRAM等,BANK6-BANK7除可以支持ROM,SRAM外,还支持SDRAM;BANK0-BANK6共7个BANK的起始地址是固定的;BANK7的起始地址可编程选择;BANK6,BANK7的地址空间大小时可编程控制的;
每个BANK的访问周期均可编程控制;
可通过外部的“wait“信号延长总线的访问周期;
在外接SDRAM时,支持自刷新和省电模式。

BWSCON寄存器决定每个BANK数据总线宽度,WAIT状态,是否使用UB/LB
BANKCON0-BANKCON5控制外界设备的访问时序

BANKCON6-BANKCON7设置外接是SRAM还是SDRAM,RASto CAS delay,列地址位数。(它与SDRAM的型号有关,查看数据手册)

设置刷新寄存器REFRESH-特别时刷新周期,与SDRAM时钟频率(HCLK
)和SDRAM刷新周期(可在SDRAM芯片手册上查找)有关。默认情况下HCLK为多少?配置了比例后HCLK是多少?

BANKSIZE寄存器,配置ARM核是否支持突发传输,是否使用SCKE信号令SDRAM进入省电模式,设置BANK6/7的大小。

SDRAM模式设置寄存器MRSRBx,设置SDRAM时序的一个时间参数。

7修改第二阶段代码

移植lib_arm/board.c代码

7-1首先对init_sequence的各个初始化函数进行移植
7-1-1cpu_init
不需要处理,它只是在用户配置使用中断的情况下,设置IRQ和FIQ中断栈。
7-1-2board_init
它的主要作用设置时钟,I/O等,在board/tq2440/tq2440.c目录下定义需要重点关注。
I/O--gpio->GPACON= 0x007FFFFF;
设置所有端口为输入
gpio->GPBCON = 0x00055555;GPB0-GPB9为输出,GPB10为输入。
gpio->GPBUP = 0x000007FF;并且都使能上拉功
gpio->GPCCON = 0xAAAAAAAA;每个引脚都配置为10,具体查看手册
gpio->GPCUP = 0x0000FFFF;
使能上拉
gpio->GPDCON = 0xAAAAAAAA;
同上
gpio->GPDUP = 0x0000FFFF;
gpio->GPECON = 0xAAAAAAAA;
同上
gpio->GPEUP = 0x0000FFFF;
gpio->GPFCON = 0x000055AA;GPF7-GPF4为输出,GPF3-GPF0为EINT[3]-EINT[0]
gpio->GPFUP = 0x000000FF;
使能上拉
gpio->GPGCON = 0xFF94FFBA;
gpio->GPGUP = 0x0000FFEF;
gpio->GPGDAT = gpio->GPGDAT &((~(1<<4)) | (1<<4)) ;
gpio->GPHCON = 0x002AFAAA;
gpio->GPHUP = 0x000007FF;
gpio->GPJCON = 0x02aaaaaa;
gpio->GPJUP = 0x00001fff;

修改s3c24x0.h中的#ifdefCONFIG_S3C2410改为#ifdefined(CONFIG_S3C2410) ||
defined(CONFIG_S3C2440),否则GPACON等会找不到定义。

配置时钟----对于S3C2440要修改结构体,因为它多一个寄存器CAMDIVN。
将FCLK设为400MHz,分频比FCLK:HCLK:PCLK=1:4:8。还将UPLL设为48MHz,即UCLK为48MHz,以在内核中支持USB控制器。
#define S3C2440_MPLL_400MHZ ((0x5c<<12)| (0x01<<4) | (0x01)))

#define S3C2440_UPLL_400MHZ ((0x38<<12)| (0x02<<4) | (0x02)))

#define S3C2440_CLKDIV 0x05/*FCLK:HCLK:PCLK=1:4:8,UCLK=UPLL*/
相应的也需要修改get_PLLCLK(由MPLLCON配置值以及外部输入时钟频率计算MPLL或FCLK的频率值),get_HCLK,get_PCLK。
原理:
MPLLCON寄存器,用于设置FCLK于Fin的倍数
位[19:12]的值称为MDIV,位[9:4]的值称为PDIV,位[1:0]的值称为SDIV。
FCLK与Fin的关系如下:
MPLL(FCLK)=(2*m*Fin)/(p*2^s)
其中:m=MDIV+8,p=PDIV+2, s=SDIV
Fin一般为12MHz,上电时,PLL没启动,FCLK即等于外部输入时钟,称为Fin,若要提高系统时钟,需要软件来启用PLL。
s3c2440由两个寄存器CAMDIVN和CLKDIVN。

#include <s3c2410.h>改为#include<s3c2440.h>-目录include/建立s3c2440.h,可由s3c2410.h复制过来,然后作相应的修改。
并在s3c24x0.h中加入相关定义
s3c24x0.h中定义了这一系列各种设备对应寄存器的结构体如Memorycontroller,USBHOST,INTERRUPT等。
s3c2440.h一方面定义各种结构体的基地址,并给出返回结构体对象的方法。如下:
static inline S3C24X0_MEMCTL * constS3C24X0_GetBase_MEMCTL(void)

{
return (S3C24X0_MEMCTL *const)S3C24X0_MEMCTL_BASE;
}
另一方面定义特有的一些特性如串口个数,SPI通道个数,HWECC,ISR,PENDINGBIT。

这个时候make一下工程,修改出错的地方,所有出错的地方都应该是因为要加上defined(CONFIG_S3C2440)的缘故,或者defined(CONFIG_TQ2440)。
#if defined(CONFIG_S3C2400)
#include <s3c2400.h>
#elif defined(CONFIG_S3C2410)
#include <s3c2410.h>
#elif defined(CONFIG_S3C2440)
#include <s3c2440.h>
#endif

7-1-3interrupt_init-cpu/arm920t/s3c2440/interrupts.c
pwm定时器4,提供一些延时一定时间的办法?具体实现以后查看。

env_init
环境变量CFG_ENV_IS_IN_FLASH

init_baudrate初始化波特率
................................................................................................................................................................

8 nand flash下载支持

8-1配置include/configs/tq2440.h,使用新的nandflash代码,驱动代码在drivers/mtd/nand/目录下。
/* nand flash */
#define CONFIG_CMD_NAND 1
#define CFG_NAND_BASE 0
#define CFG_MAX_NAND_DEVICE 1

8-2在include/s3c24x0.h文件中增加S3C240_NAND数据结构;
在include/s3c2440.h文件中定义S3C2440_GetBase_NAND函数,并#defineS3C2440_NAND_BASE
0x4E000000

8-3
建立cpu/arm920t/s3c24x0/nand_flash.c文件,文件主要作用是针对S3C2440实现NAND Flash最底层访问函数,并进行一些硬件的设置(比如时序,使能NANDFlash控制器等)。新的驱动代码只是提供了对NANDFlash的封装,只要向上提供底层初始化函数board_nand_init来设置好平台/开发板相关的初始化,提供接口即可。

修改cpu/arm920t/s3c24x0/Makefile文件:
COBJS = i2c.o interrupts.o serial.ospeed.o \
usb.o usb_ohci.o nand_flash.o

编译,此时U-BOOT应该可以擦除,读写NANDFlash了。

9 nand flash启动支持
nandflash前4k代码会自动拷贝到steppingstone内运行,因此要让在前4k代码中确保将u-boot代码拷贝到sdram中,然后跳转到sdram继续运行u-boot。把拷贝nandflash的代码放到第一阶段实现。

9-1测试从nor flash还是从nandflash启动
无论是从NORFlash还是从NAND Flash启动,地址0处为指令"b
Reset",机器码为0xEA00000B,对于从NAND Flash启动的情况,其开始4KB的代码会复制到CPU内部4K内存中,对于从NOR
Flash启动的情况,NORFlash的开始地址即为0。对于NOR Flash,必须通过一定的命令序列才能写数据,所以可以根据这点差别来分辨是从NAND
Flash还是NORFlash启动:向地址0写入一个数据,然后读出来,如果没有改变的话就是NORFlash,也就是说数据没有写进去。

9-2拷贝代码与flash读写的代码单独在一个c文件boot_init.c中,放在board/tq2440目录下。
在start.S中调用拷贝程序。实现代码如下:

#ifndef CONFIG_SKIP_RELOCATE_UBOOT
relocate: /* relocate U-Boot to RAM */
adr r0, _start /* r0 <- currentposition of code */
ldr r1, _TEXT_BASE /* test if we runfrom flash or RAM */

cmp r0, r1 /*don't reloc during debug */
beq clear_bss

ldr r2, _armboot_start
ldr r3, _bss_start
sub r2, r3, r2 /* r2 <- size ofarmboot */
#if 1
bl CopyCode2Ram /* r0: source, r1:dest, r2: size */
#else
add r2, r0, r2 /* r2 <- source endaddress */

copy_loop:
ldmia r0!, {r3-r10} /* copy fromsource address [r0] */

stmia r1!, {r3-r10} /* copy to target address [r1] */

cmp r0, r2 /* until source endaddreee [r2] */
ble copy_loop
#endif
#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
9-3修改board/tq2440目录下的Makefile文件:
COBJS := tq2440.o flash.o boot_init.o
修改连接脚本确保boot_init.o代码在前4KB(boot/tq2440/u-boot.lds),如下:

OUTPUT_FORMAT("elf32-littlearm","elf32-littlearm", "elf32-littlearm")

/*OUTPUT_FORMAT("elf32-arm","elf32-arm", "elf32-arm")*/

OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;

. = ALIGN(4);
.text :
{
cpu/arm920t/start.o (.text)
board/tq2440/boot_init.o (.text)
board/tq2440/lowlevel_init.o (.text)
*(.text)
}

. = ALIGN(4);
.rodata : { *(.rodata) }

. = ALIGN(4);
.data : { *(.data) }

. = ALIGN(4);
.got : { *(.got) }

. = .;
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;

. = ALIGN(4);
__bss_start = .;
.bss : { *(.bss) }
_end = .;
}
................................................................................................................................................................

10调试

10-1下载uboot到SDRAM调试,注意下载地址为0x33f80000,因为TEXT_BASE=
0x33F80000,下载完成后,程序会直接跳到0x33f80000开始执行

10-2网络功能还不行ethaddr=00:00:00:00:00:00
需要设置网络,setenvipaddr,setenv ethaddr, setenv serverip, saveen命令设置网络。
这时候已经可以用tftpboot命令下载程序到内存SDRAM中,然后用go命令可以跳到下载程序的起始地址,运行下载的程序。

10-3需要完善从nandflash启动u-boot以及支持将程序直接下载到nandflash中的功能。

10-4调试nand flash功能



从图中可以看出nandflash初始化正常,大小为256MiB。
但是用nanderase命令擦除flash时,却会出现无论那个地址都是badblock的情况?需要找出是什么原因?
调试根据打印信息可以发现每次读取oob中的值不一致why?而且不是0xFF
nand_dev_id=0xda
oobblock=2048
nand flash的信息是正确的包括块大小,页大小,oob大小,ID等。
问题困扰了好久,最后终于发现原来是一个变量应该赋值时需要加上取地址符号。还好出了这个问题把mtd设备层的实现跟了个遍,基本理解了其实现原理,以及运行过程。
最后运行结果如下:



10-5测试从nandflash启动的功能,运行正常。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: