ddd
全部博文(22)
分类: 嵌入式
2010-04-25 13:55:51
移植U-Boot-2009.08到友善之臂mini2440(三)
3.1 在board/mini2440/目录下加入NAND Flash读取函数(start.S中需要的nand_read_ll函数)文件nand_read.c,新建nand_read.c,这里的开发板使用的是128MB ,大页的读写。下面是nand_read.c文件的内容。(注意和小页的NandFlash的不同)
board/mini2440/nand_read.c
#include
#include
#define __REGb(x) (*(volatile unsigned char *)(x))
#define __REGw(x) (*(volatile unsigned short *)(x))
#define __REGi(x) (*(volatile unsigned int *)(x))
#define NF_BASE 0x4e000000
#if defined(CONFIG_S
#define NFCONF __REGi(NF_BASE + 0x0)
#define NFCMD __REGb(NF_BASE + 0x4)
#define NFADDR __REGb(NF_BASE + 0x8)
#define NFDATA __REGb(NF_BASE + 0xc)
#define NFSTAT __REGb(NF_BASE + 0x10)
#define NFSTAT_BUSY 1
#define nand_select() (NFCONF &= ~0x800)
#define nand_deselect() (NFCONF |= 0x800)
#define nand_clear_RnB() do {} while (0)
#elif defined(CONFIG_S
#define NFCONF __REGi(NF_BASE + 0x0)
#define NFCONT __REGi(NF_BASE + 0x4)
#define NFCMD __REGb(NF_BASE + 0x8)
#define NFADDR __REGb(NF_BASE + 0xc)
#define NFDATA __REGb(NF_BASE + 0x10)
#define NFDATA16 __REGw(NF_BASE + 0x10)
#define NFSTAT __REGb(NF_BASE + 0x20)
#define NFSTAT_BUSY (1 << 2)
#define nand_select() (NFCONT &= ~(1 << 1))
#define nand_deselect() (NFCONT |= (1 << 1))
#define nand_clear_RnB() (NFSTAT |= NFSTAT_BUSY)
#endif
static inline void nand_wait(void)
{
int i;
while (!(NFSTAT & NFSTAT_BUSY))
for (i=0; i<10; i++);
}
#if defined(CONFIG_S
#define NAND_PAGE_SIZE 512
#define BAD_BLOCK_OFFSET 517
#define NAND_BLOCK_MASK (NAND_PAGE_SIZE - 1)
#define NAND_BLOCK_SIZE 0x4000
#else
#define NAND_5_ADDR_CYCLE
#define NAND_PAGE_SIZE 2048
#define BAD_BLOCK_OFFSET NAND_PAGE_SIZE
#define NAND_BLOCK_MASK (NAND_PAGE_SIZE - 1)
#define NAND_BLOCK_SIZE (NAND_PAGE_SIZE * 64)
#endif
#if defined(CONFIG_S
#error "S
#endif
static int is_bad_block(unsigned long i)
{
unsigned char data;
unsigned long page_num;
nand_clear_RnB();
#if (NAND_PAGE_SIZE == 512)
NFCMD = NAND_CMD_READOOB;
NFADDR = BAD_BLOCK_OFFSET & 0xf;
NFADDR = (i >> 9) & 0xff;
NFADDR = (i >> 17) & 0xff;
NFADDR = (i >> 25) & 0xff;
#elif (NAND_PAGE_SIZE == 2048)
page_num = i >> 11;
NFCMD = NAND_CMD_READ0;
NFADDR = BAD_BLOCK_OFFSET & 0xff;
NFADDR = (BAD_BLOCK_OFFSET >> 8) & 0xff;
NFADDR = page_num & 0xff;
NFADDR = (page_num >> 8) & 0xff;
NFADDR = (page_num >> 16) & 0xff;
NFCMD = NAND_CMD_READSTART;
#endif
nand_wait();
data = (NFDATA & 0xff);
if (data != 0xff)
return 1;
return 0;
}
static int nand_read_page_ll(unsigned char *buf, unsigned long addr)
{
unsigned short *ptr16 = (unsigned short *)buf;
unsigned int i, page_num;
nand_clear_RnB();
NFCMD = NAND_CMD_READ0;
#if (NAND_PAGE_SIZE == 512)
NFADDR = addr & 0xff;
NFADDR = (addr >> 9) & 0xff;
NFADDR = (addr >> 17) & 0xff;
NFADDR = (addr >> 25) & 0xff;
#elif (NAND_PAGE_SIZE == 2048)
page_num = addr >> 11;
NFADDR = 0;
NFADDR = 0;
NFADDR = page_num & 0xff;
NFADDR = (page_num >> 8) & 0xff;
NFADDR = (page_num >> 16) & 0xff;
NFCMD = NAND_CMD_READSTART;
#else
#error "unsupported nand page size"
#endif
nand_wait();
for (i = 0; i < NAND_PAGE_SIZE; i++)
{
*buf = (NFDATA & 0xff);
buf++;
}
return NAND_PAGE_SIZE;
}
int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)
{
int i, j;
if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK))
{
return -1;
}
nand_select();
nand_clear_RnB();
for (i=0; i<10; i++);
for (i=start_addr; i < (start_addr + size);)
{
j = nand_read_page_ll(buf, i);
i += j;
buf += j;
}
nand_deselect();
return 0;
}
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
3.2修改board/mini2440/Makefile文件,28行,将nand_read.c编译进u-boot:
OBJS := mini2440.o nand_read.o flash.o
3.3修改board/mini2440/lowlevel_init.S文件
(1)修改 REFRESH 的刷新周期:
/* REFRESH parameter */
#define REFEN 0x1 /* Refresh enable */
#define TREFMD 0x0 /* CBR(CAS before RAS)/Auto refresh */
//#define Trp 0x0 /* 2clk */
#define Trc 0x3 /* 7clk */
#define Tchr 0x2 /* 3clk */
//#define REFCNT 0x0459
# if defined(CONFIG_S
#define Trp 0x2 /* 4clk */
#define REFCNT 1012
#else
#define Trp 0x0 /* 2clk */
#define REFCNT 0x0459
#endif
3.4 在/board/mini2440/mini2440.c 中对GPIO和PLL的配置进行修改
(1)添加网络头文件的支持
#include
#include 3c2410.h>
#include
#include
#include
(2)修改GPIO和PLL的配置
#if FCLK_SPEED==0 /* Fout = 203MHz, Fin = 12MHz for Audio */
#define M_MDIV 0xC3
#define M_PDIV 0x4
#define M_SDIV 0x1
#elif FCLK_SPEED==1 /* Fout = 202.8MHz */
//#define M_MDIV 0x
//define M_PDIV 0x4
//#define M_SDIV 0x0
//xujun
#if defined(CONFIG_S
/* Fout = 405MHz */
#define M_MDIV 0x
#define M_PDIV 0x2
#define M_SDIV 0x1
#endif
#endif
#if USB_CLOCK==0
#define U_M_MDIV 0xA1
#define U_M_PDIV 0x3
#define U_M_SDIV 0x1
#elif USB_CLOCK==1
//#define U_M_MDIV 0x48
//#define U_M_PDIV 0x3
//xujun
#if defined(CONFIG_S
#define U_M_MDIV 0x38
#define U_M_PDIV 0x2
#endif
#define U_M_SDIV 0x2
#endif
(3)为连接LED和蜂鸣器的GPIO修改配置寄存器:
/* set up the I/O ports */
gpio->GPACON = 0x007FFFFF;
#if defined(CONFIG_MINI2440)
gpio->GPBCON = 0x00055555;
#else
gpio->GPBCON = 0x00044556;
#endif
gpio->GPBUP = 0x000007FF;
。。。。。。
(4)为引导linux 内核,修改开发板的类型代码
/* arch number of SMDK2410-Board */
//gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;
#if defined(CONFIG_S
/* arch number ofMINI2440-Board */
gd->bd->bi_arch_number = MACH_TYPE_MINI2440 ;
#endif
(5)为使int board_init (void)设置完成后,LED1和LED2同时亮起,在int board_init (void)的最后添加:
/* adress of boot parameters */
gd->bd->bi_boot_params = 0x30000100
icache_enable();
dcache_enable();
# if defined(CONFIG_MINI2440_LED)
gpio->GPBDAT = 0x181;
#endif
return 0;
}
(6) 添加对dm9000的初始化函数
#ifdef CONFIG_DRIVER_DM9000
int board_eth_init(bd_t *bis)
{
return dm9000_initialize(bis);
}
#endif
(7)
删除自带的nandflash的初始化函数
#if 0
#if defined(CONFIG_CMD_NAND)
extern ulong nand_probe(ulong physadr);
static inline void NF_Reset(void)
{
int i;
………………
#ifdef DEBUG
printf("NAND flash probing at 0x%.8lX\n", (ulong)nand);
#endif
printf ("%4lu MB\n", nand_probe((ulong)nand) >> 20);
}
#endif
#endif
3.5
修改 lib_arm/board.c文件
(1)
添加头文件支持
#include
#include
#include 3c2410.h>
(2)添加LED功能,指示进度
#if 0
/************************************************************************
* Coloured LED functionality
************************************************************************
* May be supplied by boards if desired
*/
void inline __coloured_LED_init (void) {}
……………………
void inline blue_LED_off(void)__attribute__((weak, alias("__blue_LED_off")));
#endif
static int display_banner (void)
{
#if defined(CONFIG_MINI2440_LED)
S
gpio->GPBDAT = 0x101;
#endif
………
if defined(CONFIG_RESET_PHY_R)
debug ("Reset Ethernet PHY\n");
reset_phy();
#endif
#endif
#if defined(CONFIG_MINI2440_LED)
S
#endif
# if defined(CONFIG_MINI2440_LED)
gpio->GPBDAT = 0x0;
#endif
printf("\n**********************************************************");
printf("\n\thello! this U-BOOT is modified by XUJUN, at
printf("\t-USTB--xujun--beijing--mini2440-uboot-\n");
printf("\t QQ is 306141829\n");
printf("\t-LOVE ARM Linux and U-BOOT-\n");
printf("**********************************************************\n");
/* main_loop() can return to retry autoboot, if so just run it again. */
for (;;) {
main_loop ();