文档库

最新最全的文档下载
当前位置:文档库 > Jaguar.Yuan 的U-Boot之行——基于s3c2440的移植(免费分享)

Jaguar.Yuan 的U-Boot之行——基于s3c2440的移植(免费分享)

/*

* @hardware: mini s3c2440

* @author: Jaguar.Yuan

* @u-boot version: 2010.9

* @arm-linux-gcc -v: gcc version 4.3.3

*/

版本:2010.09移植时网上最新版本)

$ cd board/samsung/

$ cp smdk2410 s3c2440 -a

$ cd s3c2440/

0$ mv smdk2410.c s3c2440.c

$ gedit Makefile

修改:COBJS := s3c2440.o flash.o

$ cd ../../../include/configs/

$ cp smdk2410.h s3c2440.h

$ gedit ../../Makefile

修改约160行:CROSS_COMPILE ?= arm-linux-

在约2231行前添加:

s3c2440_config : unconfig

@$(MKCONFIG) $(@:_config=) arm arm920t s3c2440 samsung s3c24x0

切换到root模式进行编译版本是否可行:

yuan@EndSville_CShuai:~/u-boot-2010.09/include/configs$ su

密码:

# cd ../../(退到u-boot-2010.09目录下)

# make distclean

# make s3c2440_config

Configuring for s3c2440 board...

# make all

直到出现:arm-linux-objcopy --gap-fill=0xff -O binary u-boot u-boot.bin

root@EndSville_CShuai:/home/yuan/u-boot-2010.09#

只能说明一个问题.ok,编译成功了,版本可行,正式开始移植呗:

因为一般要修改nor flash里面的相对简单一点,直接把对应的芯片选对就OK了,但为了做到在Nand flash里就有难度一点,这里做主要是为了从nand flash里启动,接照系统启动的顺利进行修改。

首先修改/arch/arm/cpu/arm920t/start.S文件,这可是系统上电后正式加载的第一个文件

修改113行的内容,因为下面这两行是AT91RM9200DK的内容,S3C2440上面没必要用的东东,所以呢改为:

#if defined(CONFIG_AT91RM9200DK)

bl coloured_LED_init

bl red_LED_on

#endif

在148行添加:

#define CLK_CTL_BASE 0x4C000000

#define MDIV_405 0x7f << 12

#define PSDIV_405 0x21

#define MDIV_200 0xa1 << 12

#define PSDIV_200 0x31

在修改后的165行(下同,所指的行数均指在前面所说的修改行数后)

ldr r1, =0x3ff修改为ldr r1, =0x7ff

所改173行/* FCLK:HCLK:PCLK = 1:2:4 */这是默认的,而2440为1:4:8,所以要进行相应的修改:

173行的mov r1, #3修改为mov r1, #5

并在后面174行后面添加

mrc p15, 0, r1, c1, c0, 0

orr r1, r1, #0xc0000000

mcr p15, 0, r1, c1, c0, 0

mov r1, #CLK_CTL_BASE

mov r2, #MDIV_405

add r2, r2, #PSDIV_405

str r2, [r1, #0x04]

接下来感觉是能不能启动的重点,从nand flash启动的,首先就得先在193行后添加:

/***** CHECK_CODE_POSITION **********/

adr r0, _start /* r0 <- current position of code */

ldr r1, _TEXT_BASE /* test if we run from flash or RAM */

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

beq stack_setup

/****** CHECK_CODE_POSITION *********/

/******* CHECK_BOOT_FLASH *********/

ldr r1, =( (4<<28)|(3<<4)|(3<<2) ) /* address of Internal SRAM 0x4000003C*/

mov r0, #0 /* r0 = 0 */

str r0, [r1]

mov r1, #0x3c /* address of men 0x0000003C*/

ldr r0, [r1]

cmp r0, #0

bne relocate

/* recovery */

ldr r0, =(0xdeadbeef)

ldr r1, =( (4<<28)|(3<<4)|(3<<2) )

str r0, [r1]

/******** CHECK_BOOT_FLASH **********/

#define LENGTH_UBOOT 0x60000

#define NAND_CTL_BASE 0x4E000000

#define oNFCONF 0x00

#define oNFCONT 0x04

#define oNFCMD 0x08

#define oNFSTAT 0x20

@ reset NAND

mov r1, #NAND_CTL_BASE

ldr r2, =( (7<<12)|(7<<8)|(7<<4)|(0<<0) )

str r2, [r1, #oNFCONF]

ldr r2, [r1, #oNFCONF]

ldr r2, =( (1<<4)|(0<<1)|(1<<0) ) @ Active low CE Control str r2, [r1, #oNFCONT]

ldr r2, [r1, #oNFCONT]

ldr r2, =(0x6) @ RnB Clear

str r2, [r1, #oNFSTAT]

ldr r2, [r1, #oNFSTAT]

mov r2, #0xff @ RESET command

strb r2, [r1, #oNFCMD]

mov r3, #0 @ wait

nand1:

add r3, r3, #0x1

cmp r3, #0xa

blt nand1

nand2:

ldr r2, [r1, #oNFSTAT] @ wait ready

tst r2, #0x4

beq nand2

ldr r2, [r1, #oNFCONT]

orr r2, r2, #0x2 @ Flash Memory Chip Disable

str r2, [r1, #oNFCONT]

@ get read to call C functions (for nand_read())

ldr sp, DW_STACK_START @ setup stack pointer

mov fp, #0 @ no previous frame, so fp=0

@ copy U-Boot to RAM

ldr r0, =TEXT_BASE

mov r1, #0x0

mov r2, #LENGTH_UBOOT

bl nand_read_ll

tst r0, #0x0

beq ok_nand_read

bad_nand_read:

loop2:

b loop2 @ infinite loop

ok_nand_read:

@ verify

mov r0, #0

ldr r1, =TEXT_BASE

mov r2, #0x400 @ 4 bytes * 1024 = 4K-bytes

go_next:

ldr r3, [r0], #4

ldr r4, [r1], #4

teq r3, r4

bne notmatch

subs r2, r2, #4

beq stack_setup

bne go_next

notmatch:

loop3:

b loop3

这里主要是进行nand flash的检查,可还不是真正的启用了。在322行ldr pc, _start_armboot

#if defined(CONFIG_S3C2440_LED)

#define GPIO_CTL_BASE 0x56000000

#define oGPIO_B 0x10

#define oGPIO_CON 0x0

#define oGPIO_DAT 0x4

#define oGPIO_UP 0x8

mov r1, #GPIO_CTL_BASE

add r1, r1, #oGPIO_B

ldr r2, =0x295551

str r2, [r1, #oGPIO_CON]

mov r2, #0xff

str r2, [r1, #oGPIO_UP]

ldr r2, =0x1c1

str r2, [r1, #oGPIO_DAT]

#endif

到这里就是第一阶段已经成功了,由gpio口中B口控制的LED第一个灯上亮

在352上_start_armboot: .word start_armboot

#define STACK_BASE 0x33f00000

#define STACK_SIZE 0x10000

.align 2

DW_STACK_START: .word STACK_BASE+STACK_SIZE-4

这里是对齐方式,在内存的对齐方式

现在start.S修改的内容算是修改完了,可以关掉,以后也什么要修改到这个加载的文件的地方了。

按理说,启动过程是start.S结束后会进入第二阶段,从352行的start_armboot函数调用,进入到arch/arm/lib/board.c文件的start_armboot函数。

但是呢,因为start.S在启动是进行了相关初始化,调用了/board/samsung/s3c2440/lowlevel_init.S文件进行初始化,所以在修改board.c之前修改lowlevel_init.s文件

修改54行上的,

#define B1_BWSCON (DW32)

修改为:#define B1_BWSCON (DW16)

修改123行为#define Trp 0x2(时钟周期)

修改126行为#define REFCNT 1012

修改165行 .word 0x32为 .word 0xb2

这个文件修改的内容也就这点,ok,可以关闭

第一阶段的内容启动到这里算是完成了,不过现在还不能编译,因为修改的东西还没有加载呢,因为在第一阶段会调用NAND初始化相关函数,而现在还没修改,所以想急着看成果的朋友,只有再等等了,精彩马上出现。

所以,现在可谓说是已经做好前奏了,进入第二阶段的内容了,就是所谓的arch/arm/lib/board.c文件

在80行前添加

#ifdef CONFIG_DRIVER_DM9000

extern void dm9000_get_enetaddr (uchar * addr);

#endif

因为在后面会加入dm9000的驱动,突然发现一个很进步的现象,与2009.8的版本相比,

2010.9版本中已经把cs8900没添加了,但rtl8019还留着。

修改140行display_banner函数中添加一点花哨的东西,就是为了好看,没其它的目的。

在刚开始的地方加入:

#if defined(CONFIG_S3C2440_LED)

S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();

gpio->GPBDAT = 0x100;

#endif

printf ("\n\n");

printf("*******************************************************************

******\n");

printf("*******************************************************************

*****\n");

printf("****

****\n");

printf("**** Welcome To Embedded World ****\n");

printf("****

****\n");

printf("**** Designed By: Jaguar.Yuan ****\n");

printf("**** Date : 2010-10-16

****\n");

printf("**** Address :SWUST-CS(East6E-105)

****\n");

printf("*******************************************************************

*****\n");

printf("*******************************************************************

*****\n");

printf ("%s\n", version_string);//这里少了两个换行符,也只是为了方便看而已

然后在291行void start_armboot (void)

#if defined(CONFIG_S3C2440_LED)

S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();

gpio->GPBDAT = 0x0;

#endif

因为用了gpio等相关函数,所以要引入头文件:

#include

与以前的版本不同,以前的版本引入的文件为#include

然后这个文件算是搞定了,也可以关闭了。

因为在前面添加了nand flash的读写,就是在start.S文件中引入了nand_read_ll的调

用,但是系统中还没有这个函数,所以在board/samsung/s3c2440/下面新建一个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

#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

#define nand_select() (NFCONT &= ~(1 << 1))

#define nand_deselect() (NFCONT |= (1 << 1))

#define nand_clear_RnB() (NFSTAT |= (1 << 2))

static inline void nand_wait(void)

{

int i;

while (!(NFSTAT & NFSTAT_BUSY))

for (i=0; i<10; i++);

}

struct boot_nand_t {

int page_size;

int block_size;

int bad_block_offset;

// unsigned long size;

};

static int is_bad_block(struct boot_nand_t * nand, unsigned long i)

{

unsigned char data;

unsigned long page_num;

nand_clear_RnB();

if (nand->page_size == 512) {

NFCMD = NAND_CMD_READOOB; /* 0x50 */

NFADDR = nand->bad_block_offset & 0xf;

NFADDR = (i >> 9) & 0xff;

NFADDR = (i >> 17) & 0xff;

NFADDR = (i >> 25) & 0xff;

} else if (nand->page_size == 2048) {

page_num = i >> 11; /* addr / 2048 */

NFCMD = NAND_CMD_READ0;

NFADDR = nand->bad_block_offset & 0xff;

NFADDR = (nand->bad_block_offset >> 8) & 0xff;

NFADDR = page_num & 0xff;

NFADDR = (page_num >> 8) & 0xff;

NFADDR = (page_num >> 16) & 0xff;

NFCMD = NAND_CMD_READSTART;

} else {

return -1;

}

nand_wait();

data = (NFDATA & 0xff);

if (data != 0xff)

return 1;

return 0;

}

static int nand_read_page_ll(struct boot_nand_t * nand, 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) {

/* Write Address */

NFADDR = addr & 0xff;

NFADDR = (addr >> 9) & 0xff;

NFADDR = (addr >> 17) & 0xff;

NFADDR = (addr >> 25) & 0xff;

} else if (nand->page_size == 2048) {

page_num = addr >> 11; /* addr / 2048 */

/* Write Address */

NFADDR = 0;

NFADDR = 0;

NFADDR = page_num & 0xff;

NFADDR = (page_num >> 8) & 0xff;

NFADDR = (page_num >> 16) & 0xff;

NFCMD = NAND_CMD_READSTART;

} else {

return -1;

}

nand_wait();

for (i = 0; i < (nand->page_size>>1); i++) {

*ptr16 = NFDATA16;

ptr16++;

}

return nand->page_size;

}

static unsigned short nand_read_id()

{

unsigned short res = 0;

NFCMD = NAND_CMD_READID;

NFADDR = 0;

res = NFDATA;

res = (res << 8) | NFDATA;

return res;

}

extern unsigned int dynpart_size[];

/* low level nand read function */

int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size) {

int i, j;

unsigned short nand_id;

struct boot_nand_t nand;

/* chip Enable */

nand_select();

nand_clear_RnB();

for (i = 0; i < 10; i++)

;

nand_id = nand_read_id();

if (0) { /* dirty little hack to detect if nand id is misread */ unsigned short * nid = (unsigned short *)0x31fffff0;

*nid = nand_id;

}

if (nand_id == 0xec76 || /* Samsung K91208 */

nand_id == 0xad76 ) { /*Hynix HY27US08121A*/

nand.page_size = 512;

nand.block_size = 16 * 1024;

nand.bad_block_offset = 5;

// nand.size = 0x4000000;

} else if (nand_id == 0xecf1 || /* Samsung K9F1G08U0B */

nand_id == 0xecda || /* Samsung K9F2G08U0B */

nand_id == 0xecd3 ) { /* Samsung K9K8G08 */

nand.page_size = 2048;

nand.block_size = 128 * 1024;

nand.bad_block_offset = nand.page_size;

// nand.size = 0x8000000;

} else {

return -1; // hang

}

if ((start_addr & (nand.block_size-1)) || (size & ((nand.block_size-1)))) return -1; /* invalid alignment */

for (i=start_addr; i < (start_addr + size);) {

if (i & (nand.block_size-1)== 0) {

if (is_bad_block(&nand, i) ||

is_bad_block(&nand, i + nand.page_size)) {

/* Bad block */

i += nand.block_size;

size += nand.block_size;

continue;

}

}

j = nand_read_page_ll(&nand, buf, i);

i += j;

buf += j;

}

/* chip Disable */

nand_deselect();

return 0;

}

因为添加了文件,所以要把这个东西加入Makefile才能编译,修改

/board/samsung/s3c2440/Makefile文件,把前面提到的那行再修改呗:

第28行:COBJS := s3c2440.o flash.o nand_read.o

其实,到这里就可以再#make all 一下了,虽然现在的东西还不能下载到板子上用,但如果能make通过,至少也能说明你前面没有出错,如果产生error了,那不好意思,看看是什么问题呗。

然后就进入board/samsung/s3c2440/s3c2440.c,修改第40行

#elif FCLK_SPEED==1 /* Fout = 202.8MHz */

#define M_MDIV 0x7f

#define M_PDIV 0x2

#define M_SDIV 0x1

#endif

第52行

#elif USB_CLOCK==1

#define U_M_MDIV 0x48

#define U_M_PDIV 0x3

#define U_M_SDIV 0x2

#endif

第91行以下的内容修改为:

gpio->GPACON = 0x007FFFFF;

gpio->GPBCON = 0x00295551;

gpio->GPBUP = 0x000007FF;

gpio->GPCCON = 0xAAAAA6AA;

gpio->GPCDAT &= ~(1<<5);

gpio->GPCUP = 0xFFFFFFFF;

gpio->GPDCON = 0xAAAAAAAA;

gpio->GPDUP = 0xFFFFFFFF;

gpio->GPECON = 0xAAAAAAAA;

gpio->GPEUP = 0x0000FFFF;

gpio->GPFCON = 0x000055AA;

gpio->GPFUP = 0x000000FF;

gpio->GPGCON = 0xFF95FF3A;

gpio->GPGUP = 0x0000FFFF;

gpio->GPHCON = 0x0016FAAA;

gpio->GPHUP = 0x000007FF;

gpio->EXTINT0=0x22222222;

gpio->EXTINT1=0x22222222;

gpio->EXTINT2=0x22222222;

当然接下来这个

gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;

这行是系统的机器码,在以后加载内核的时候,所修改的必须与这里的相同才能启动系统,这里调用的 MACH_TYPE_SMDK2410定义在include/asm/mach-types.h中的195行,在2010.9的版本中定义为182,而在以前的2009.8的版本中定义为192,这里可以根据自己

的情况修改,也可以不修改以后在移植内核的时候修改内核的一样(这里我不作修改,以后我会在内核移植中再作说明)。

好了,有点说远了,回到主题,继续刚才的s3c2440.c文件,在119行添加:

#if defined(CONFIG_S3C2440_LED)

gpio->GPBDAT = 0x00000181;

#endif

当然,这里你也可以不须要针对CONFIG_S3C2440_LED的内容,我加的目的,只是为了保证启动时看到LED灯依次这起来,能感觉到进度,如果在某一个地方卡死了,能从LED上看出是在第一阶段还是第二阶段启动失败的。

在文件最后的int board_eth_init(bd_t *bis)

#ifdef CONFIG_DRIVER_DM9000

rc = dm9000_initialize(bis);

#endif

因为实验板上的是dm9000的网卡,已经没有什么rtl8019,cs8900的网卡了。

Ok ,这个文件算是搞定了,

接下来修改/include/configs/s3c2440.h,这个文件才是重点,因为大家都知道头文件的作用,如果没有头文件,你下面的C文件写得再好,也没用。

前面一直说到的LED进度显示,这里就要定义了在40行添加:

#define CONFIG_SMDK2440_LED 1

接下来是59行左右,大家一看就明白了,因为没有cs8900的网卡,所以这一块也没必要用了。修改为:

#define CONFIG_NET_MULTI

#define CONFIG_DRIVER_DM9000 1

#define CONFIG_DM9000_BASE 0x20000300

#define DM9000_IO CONFIG_DM9000_BASE

#define DM9000_DATA (CONFIG_DM9000_BASE + 4)

#define CONFIG_DM9000_USE_16BIT

#define CONFIG_DM9000_NO_SROM 1

#undef CONFIG_DM9000_DEBUG

不过前面那行一定要留着,#define CONFIG_NET_MULTI,没这行,哼哼,会付出代价滴....试试就知道了.....

添加必要的命令,如果没有命令参数,某些部分是不能编译的,而后果是即使你从板子上启动了,不能用命令可也是一件悲哀的事呀,和没有启动有什么区别呢?

有95行左右,修改后的命令如下:

#define CONFIG_CMD_CACHE

#define CONFIG_CMD_DATE

#define CONFIG_CMD_ELF

#define CONFIG_CMD_NET

#define CONFIG_CMD_PING

#define CONFIG_CMD_DHCP

#define CONFIG_CMD_ASKENV

#define CONFIG_CMD_NAND

#define CONFIG_CMD_REGINFO

#define CONFIG_CMD_FAT

因为网卡已经起来了,所以在108行左右就可以根据自己的实验环境修改了

#define CONFIG_ETHADDR 08:00:3e:26:0a:5b

#define CONFIG_NETMASK 255.255.255.0

#define CONFIG_IPADDR 192.168.1.56

#define CONFIG_SERVERIP 192.168.1.101

第一个是MAC地址,第二个是掩码,第三个是我开发板IP,第四个是我的电脑(我把它以后做成主机),其它的现在还没有修改,以后把电脑上弄好了再来,免得在启动的时候报错,看着就不爽。

然后在125行:这里也不是一定要修改的,我只是让启动后看到自己的东西,感觉更有成就感而已,呵呵,当然也不是必须要修改:

#define CONFIG_SYS_PROMPT "[J.Yuan@u-Boot]#"

然后是164行以后:

/*-----------------------------------------------------------------------

* FLASH and environment organization

*/

这下面的内容已经改得差不多认不是出哪些是官方的了,哎....

把完整的代码放在下面,只要实现的就是NAND FLASH的定义,以及相关寄存器的定义

#define CONFIG_SST_VF1601 1 /* uncomment this if you have a Am29LV160DB flash */

#define CONFIG_SYS_MAX_FLASH_BANKS 1 /* max number of memory banks */

/* timeout values are in ticks */

#define CONFIG_SYS_FLASH_ERASE_TOUT (5*CONFIG_SYS_HZ) /* Timeout for Flash Erase */

#define CONFIG_SYS_FLASH_WRITE_TOUT (5*CONFIG_SYS_HZ) /* Timeout for Flash Write */

/********I2C Driver Config******/

#define CONFIG_CMD_EEPROM

#define CONFIG_CMD_I2C

#define CONFIG_DRIVER_S3C24X0_I2C 1 /* we use the buildin I2C controller */ #define CONFIG_HARD_I2C 1 /* I2C with hardware support */

#define CONFIG_SYS_I2C_SPEED 100000 /* I2C speed and slave address */ #define CONFIG_SYS_I2C_SLAVE 0x7F

#define CONFIG_SYS_I2C_EEPROM_ADDR 0x50 /* EEPROM at24c08 */ #define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 1 /* Bytes of address */ /* mask of address bits that overflow into the "EEPROM chip address" */

#define CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW 0x07

#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS 4 /* The Catalyst CAT24WC08 has */ /********I2C Driver Config******/

#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 10 /* and takes up to 10 msec */

#define CONFIG_SYS_EEPROM_PAGE_WRITE_ENABLE

#define CONFIG_ENV_IS_IN_NAND 1

#define CONFIG_ENV_OFFSET 0X60000

#define CONFIG_ENV_SIZE 0x20000 /* Total Size of Environment Sector */

/* == LENGTH_UBOOT*/

#ifdef CONFIG_SST_VF1601

#define PHYS_FLASH_SIZE 0x00200000 /* 2MB */

#define CONFIG_SYS_MAX_FLASH_SECT (32) /* max number of sectors on one chip */

#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + CONFIG_ENV_OFFSET) /* addr of environment */

#endif

/*-----------------------------------------------------------------------

* NAND flash settings

*/

#if defined(CONFIG_CMD_NAND)

#define CONFIG_NAND_S3C2410

#define CONFIG_SYS_NAND_BASE 0x4E000000

#define CONFIG_SYS_MAX_NAND_DEVICE 1 /* Max number of NAND devices */ #define SECTORSIZE 512

#define SECTORSIZE_2K 2048

#define NAND_SECTOR_SIZE SECTORSIZE

#define NAND_SECTOR_SIZE_2K SECTORSIZE_2K

#define NAND_BLOCK_MASK 511

#define NAND_BLOCK_MASK_2K 2047

#define NAND_MAX_CHIPS 1

#define CONFIG_MTD_NAND_VERIFY_WRITE

#define CONFIG_SYS_64BIT_VSPRINTF /* needed for nand_util.c */

#endif /* CONFIG_CMD_NAND */

#endif /* __CONFIG_H */

这个文件先修改这些内容,因为以后加载什么启动项呀,什么驱动的,都会在这里修改,这里只是实现初初步的,所以先修改到这里,以后修改的时候再说呗。上面提到I2C的那一段代码,在这里添不添加随你吧。

然后进入arch/arm/include/asm/arch-s3c24x0/s3c24x0.h文件,而在2009.8的版本中,

这个文件的位置是在include/s3c24x0.h中

修改118行,struct s3c24x0_clock_power结构体中最后一行添加:

u32 CAMDIVN;

修改155行,struct s3c2410_nand结构体中修改为:

u32 NFCONF;

u32 NFCONT;

u32 NFCMD;

u32 NFADDR;

u32 NFDATA;

u32 NFMECCD0;

u32 NFMECCD1;

u32 NFSECCD;

u32 NFSTAT;

u32 NFESTAT0;

u32 NFESTAT1;

u32 NFMECC0;

u32 NFMECC1;

u32 NFSECC;

u32 NFSBLK;

u32 NFEBLK;

这个文件修改也就这点内容,最后修改arch/cpu/arm920t/s3c24x0/speed.c文件,这个文件是时钟相关的,如果没有的话,呵呵,串口是看不到东东滴,而且这里面一直有一个所谓的BUG,如果不修改,后果是很严重滴..........

修改函数static ulong get_PLLCLK(int pllreg)

if (pllreg == MPLL)

return ((CONFIG_SYS_CLK_FREQ * m * 2) /(p << s));

else if (pllreg == UPLL)

return (CONFIG_SYS_CLK_FREQ * m) / (p << s);

修改函数ulong get_HCLK(void)

{

struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();

if (readl(&clk_power->CLKDIVN) & 0x6) {

if ((readl(&clk_power->CLKDIVN) & 0x6)==2)

return(get_FCLK()/2);

if ((readl(&clk_power->CLKDIVN) & 0x6)==6)

return((readl(&clk_power->CAMDIVN) & 0x100) ? get_FCLK()/6 : get_FCLK()/3);

if ((readl(&clk_power->CLKDIVN) & 0x6)==4)

return((readl(&clk_power->CAMDIVN) & 0x200) ? get_FCLK()/8 : get_FCLK()/4);

return(get_FCLK());

}

else

return(get_FCLK());

}

然后还有一个地方了,修改arch/arm/cpu/arm/arm920t/u-boot.lds文件,在43上行添加启动顺序,如果没有修改,虽然能编译通过,但在实验板上是运行不起来滴,因为启动时调用执行的顺序出不正确,那能正常运行吗?闲话少说,直接上相关代码。

{

arch/arm/cpu/arm920t/start.o (.text)

board/samsung/s3c2440/lowlevel_init.o (.text)

board/samsung/s3c2440/nand_read.o (.text)

*(.text)

}

其实添加的就是lowlevel_init.o和nand_read.o两个文件,必须的初始化的时候,在内存的前4kb空间中,所以呢,没有就不能正常运行了。

Ok,到这里为此,可以执行接下来这几条命令:

#make distclean

#make s3c2440_config

#make all

然后把生成的u-boot.bin下载到开发板的nand flash分区中,上电,看看终端显示什么了呢?

Jaguar.Yuan 的U-Boot之行——基于s3c2440的移植(免费分享)

不过修改到这里,里面还有一个bug忘了,如果不修改的话,虽然能启动,但nand分区不能正常读,修改如下:

修改drivers/mtd/nand/s3c2410_nand.c文件

在文件开始的寄存器的定义,修改如下:

#define NF_BASE 0x4e000000

#define S3C2410_NFCONT_EN (1<<0)

#define S3C2410_NFCONT_INITECC (1<<4)

#define S3C2410_NFCONT_nFCE (1<<1)

#define S3C2410_NFCONT_MAINECCLOCK (1<<5)

#define S3C2410_NFCONF_TACLS(x) ((x)<<12)

#define S3C2410_NFCONF_TWRPH0(x) ((x)<<8)

#define S3C2410_NFCONF_TWRPH1(x) ((x)<<4)

#define S3C2410_ADDR_NALE 0x08

#define S3C2410_ADDR_NCLE 0x0c

ulong IO_ADDR_W = NF_BASE;

修改57行和73行,把这两行内容注释掉

// struct nand_chip *chip = mtd->priv;

// chip->IO_ADDR_W = (void *)IO_ADDR_W;

修改63行:

IO_ADDR_W = (ulong)nand;

去掉前面的声明,因为已经在前面声明过了,

修改第81行为:

writeb(cmd, (void *)IO_ADDR_W);

修改125行board_nand_init函数中,对硬件初始化的值为

twrph0 = 4;

twrph1 = 2;

tacls = 0;

cfg = 0;

同时在147行后添加

cfg = (0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(0<<6)|(0<<5)|(1<<4)|(0<<1)|(1<<0);

writel(cfg, &nand_reg->NFCONT);

有两次写控制寄存器的过程

ok了,现在可以重新make 一下,下载到开发板上,可以正常执行了。不知道是不是可以看到如下的界面了呢?

Jaguar.Yuan 的U-Boot之行——基于s3c2440的移植(免费分享)

不过不知道大家有没有发现,我明明在s3c2440.h中添加了#define PHYS_FLASH_SIZE 0x00200000 /* 2MB */,但显示的还是flash 512kb,这明显是不正确的。所以还得修改

board/samsung/s3c2440/flash.c,

第40行修改为:

#define CMD_ERASE_CONFIRM 0x00000050

第45行修改为:

#define MEM_FLASH_ADDR2 (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x00002AAA << 1)))

在ulong flash_init (void)

#elif defined(CONFIG_SST_VF1601)

(SST_MANUFACT & FLASH_VENDMASK) |

(SST_ID_xF1601 & FLASH_TYPEMASK);

修改为:void flash_print_info (flash_info_t * info)

case (SST_MANUFACT & FLASH_VENDMASK):

printf ("SST: ");

break;

在153行后添加

case (SST_ID_xF1601 & FLASH_TYPEMASK):

printf ("1x SST39VF1601 (2MB)\n");

break;

修改flash_erase函数中,198行

if ((info->flash_id & FLASH_VENDMASK) !=

(SST_MANUFACT & FLASH_VENDMASK)) {

return ERR_UNKNOWN_FLASH_VENDOR;

}

现在呢,重新make一下,然后下载进去,现在的的参数是不是改变了呢,

Jaguar.Yuan 的U-Boot之行——基于s3c2440的移植(免费分享)

ok....

基本的工作完成,至于USB、SD卡驱动将在后面进一步完善,有兴趣的敬请关注.....