您的位置:首页 > 其它

u-boot2012.04.01移植到mini2440

2015-11-06 13:13 393 查看
软件平台: Windows XP, Ubuntu

硬件平台: mini2440

软件: Source Insight、u-boot.2012.04.01 (官方下载源码)

一、uboot 启动分析

1.set the cpu to SVC32 mode(start.S)

2.turn off the watchdog

3.mask all IRQs by setting all bits in the INTMR

4.设置分频系数

5.cpu_init_crit

flush v4 I/D caches

disable MMU stuff and caches

lowlevel_init //setup RAM timing(lowlevel_init.S)

设置BWSCON

board_init_f //set sp, call board_init_f

init_sequence
(各种初始化)

...

board_early_init_f

...

serial_init

...

二、尝试

make smdk2410_config

make

成功生成的u-boot.bin并不能让mini2440启动

三、修改

1.修改根目录下boards.cfg在

smdk2410 arm arm920t - samsung s3c24x0

下添加一行

mini2440 arm arm920t
- samsung s3c24x0

2.make
mini2440_config

3.复制include\configs\smdk2410.h为include\configs\mini2440.h

4.cp board\samsung\smdk2410到board\samsung\mini2440

5.从start.S里可以看出,缺省认为60Mhz的HCLK来设置内存控制器,才设置系统时钟MPLL是有问题的。

因为没设置时钟时,是以晶振的频率运行的

注释掉(mini2440\smdk2410.c)int board_early_init_f(void)中的

#if
0

/*
configure MPLL */

writel((M_MDIV
<< 12) + (M_PDIV << 4) + M_SDIV,

&clk_power->mpllcon);

#endif

start.S修改分频设置

ldr
r0, =0x4C000014 /* FCLK提高到400Mhz,但HCLK不能超过133Mhz */

mov r1, #5 /*
FCLK:HCLK:PCLK = 1:4:8, HDIVN=10, PDIVN=1*/

str r1, [r0]

将MPLL的设置放到start.S

在分频后加上

/* 如果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

6.修改设置BWSCON的SMRDATA(lowlevel_init.S)

/*
BWSCON

[31]ST7:0 [27]ST6:0

[30]WS7:0 [26]WS6:0

[29:28]DW7:10 [25:24]DW6:10

only
bank6 and bank7 for sdram

[19]ST4:0

[18]WS4:1

[17:16]DW4:01

bank4 for DM9000

*/

.long
0x22050000 //BWSCON

/*
use the reset value */

.long
0x00000700 //BANKCON0

.long 0x00000700 //BANKCON1

.long 0x00000700 //BANKCON2

.long 0x00000700 //BANKCON3

.long 0x00000700 //BANKCON4

.long 0x00000700 //BANKCON5

/* MT [16:15] Determine
the memory type for bank6 and bank7

= 11 SDRAM

Trcd [3:2] RAS to
CAS delay, HCLK = 400Mhz/4 = 100Mhz

= 01 3 clocks (view
HY57V561620.pdf)

SCAN [1:0] Column
address number

= 01 9-bit (view
HY57V561620.pdf)

*/

.long 0x00018005 //BANKCON6

.long
0x00018005 //BANKCON7

/*

REFEN [23] SDRAM
Refresh Enable

= 1 Enable (self
or CBR/auto refresh)

TREFMD [22] SDRAM
Refresh Mode

= 0 CBR/Auto Refresh

Trp [21:20] SDRAM
RAS pre-charge Time

= 01 3 clocks (view
HY57V561620.pdf)

Tsrc [19:18] SDRAM
Semi Row cycle time, Trc=Tsrc+Trp => Tsrc=Trc-Trp => 9-3

= 10 6 clocks (view
HY57V561620.pdf)

Refresh Counter [10:0]
SDRAM refresh count value.

Refresh period =
(2^11-refresh_count+1)/HCLK

refresh_count = 64/8192
ms = 7.8125us

Rp = 2^11 + 1 - 135.75*7.8125
= 988 = 0x3dc

*/

.long
0x009803dc //REFRESH

/*
BURST_EN [7] ARM core burst operation enable.

= 1 Enable burst
operation

SCKE_EN [5] SDRAM
power down mode enable control by SCKE

= 1 SDRAM power down
mode enable

SCLK_EN [4]

= 1 SCLK is active
only during the access (recommended)

BK76MAP [2:0] BANK6/7
memory map

= 001 64MB/64MB

*/

.long
0x000000B1 //BANKSIZE

/*
CL [6:4] CAS latency

= 011 3 clocks

*/

.long
0x00000030 //MRSRB6

.long 0x00000030 //MRSRB7

再次make,并烧写u-boot.bin到nor
flash,启动后发现是乱码,应该是串口波特率问题,看看串口初始化



7.board.c (z:\u-boot-2012.04.01\arch\arm\lib\Board.c)

serial_init(z:\u-boot-2012.04.01\drivers\serial\Serial_s3c24x0.c)

serial_init_dev

_serial_setbrg

get_PCLK(z:\u-boot-2012.04.01\arch\arm\cpu\arm920t\s3c24x0\Speed.c)

get_HCLK

发现没有定义CONFIG_S3C2440,它用2410的那套

那么在config中的mini2440.h中去掉#define
CONFIG_S3C2410改成#define CONFIG_S3C2440

make发现多个错误

s3c2410_nand.c:
In function 's3c2410_hwcontrol':

s3c2410_nand.c:57:
warning: implicit declaration of function 's3c2410_get_base_nand'

s3c2410_nand.c:57:
warning: initialization makes pointer from integer without a cast

s3c2410_nand.c:72: error:
dereferencing pointer to incomplete type

s3c2410_nand.c:72:
error: dereferencing pointer to incomplete type

s3c2410_nand.c:75:
error: dereferencing pointer to incomplete type

s3c2410_nand.c:75:
error: dereferencing pointer to incomplete type

s3c2410_nand.c:
In function 's3c2410_dev_ready':

s3c2410_nand.c:85:
warning: initialization makes pointer from integer without a cast

s3c2410_nand.c:87:
error: dereferencing pointer to incomplete type

s3c2410_nand.c:
In function 'board_nand_init':

s3c2410_nand.c:129:
warning: initialization makes pointer from integer without a cast

s3c2410_nand.c:150:
error: dereferencing pointer to incomplete type

s3c2410_nand.c:153:
error: dereferencing pointer to incomplete type

s3c2410_nand.c:154:
error: dereferencing pointer to incomplete type、

s3c2410_nand.c找错误,发现是因为更改了#define CONFIG_S3C2440后,s3c2410_nand未定义

暂且先让串口输出正常看看,去掉nand支持。

[root: u-boot-2012.04.01]# grep
"s3c2410_nand.o" * -nR

drivers/mtd/nand/Makefile:61:COBJS-$(CONFIG_NAND_S3C2410)
+= s3c2410_nand.o

drivers/mtd/nand/.depend.s3c2410_nand:1:s3c2410_nand.o:
s3c2410_nand.c \

drivers/mtd/nand/.depend:341:s3c2410_nand.o:
s3c2410_nand.c \

[root: u-boot-2012.04.01]# vi
drivers/mtd/nand/Makefile

找到

COBJS-$(CONFIG_NAND_S3C2410)
+= s3c2410_nand.o

现取消CONFIG_NAND_S3C2410的定义,在mini2440.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

则注释掉//#define CONFIG_CMD_NAND

再编译提示

fs/yaffs2/libyaffs2.o:
In function `yaffs_StartUp':

/home/profiles/u-boot-2012.04.01/fs/yaffs2/yaffscfg.c:210: undefined reference to `nand_info'

还是在mini2440.h中先注释掉

//#define CONFIG_YAFFS2

再次make,并烧写u-boot.bin到nor
flash,启动后发现Flash: *** failed ***,串口正常了,只是flash还有问题

8.为了去掉原u-boot复杂的重定位代码,现自己写重定位代码,将init.c添加到board/samsung/mini2440下。修改

board/samsung/mini2440/Makefile

改COBJS := smdk2410.o init.o

init.c内容如下

点击(此处)折叠或打开

#define NFCONF (*((volatile
unsigned long *)0x4E000000))

#define NFCONT (*((volatile
unsigned long *)0x4E000004))

#define NFCMMD (*((volatile
unsigned char *)0x4E000008)) //注意是char* 不是long*,与下面保持一致

#define NFADDR (*((volatile
unsigned char *)0x4E00000C))

#define NFDATA (*((volatile
unsigned char *)0x4E000010))

#define NFSTAT (*((volatile
unsigned char *)0x4E000020))

void nand_read_ll(unsigned int addr, unsigned char *buf, unsigned int len);

static int isNor()

{

volatile int *p = (volatile int *)0;

int val;

val = *p;

*p = 0xfdfdfdfd;

if(0xfdfdfdfd == *p) //可写,证明是在SRAM中运行,即是从NAND启动

{

*p = val;

return 0;

}

else //写NOR需要特定的命令时序

{

return 1;

}

}

void copy_to_sdram(unsigned char *src, unsigned char *dest, unsigned int len)

{

int i = 0;

/* 判断启动方式 */

if (isNor())

{

while(i < len)

{

dest[i] = src[i]; //直接读
NOR(view Figure 5-1. S3C2440A Memory Map after Reset)

i++;

}

}

else

{

nand_read_ll((unsigned int)src, dest, len);

}

}

void clear_bss(void)

{

extern int __bss_start, __bss_end__;

int *p = &__bss_start;

for(; p<=&__bss_end__; p++)

{

*p = 0;

}

}

void nand_init_ll(void)

{

/* NFCONF

TACLS [13:12] CLE & ALE
duration setting value (0~3)

= 0 Duration = HCLK x TACLSHCLK x TACLS (view K9F1208.pdf)

TWRPH0 [10:8] TWRPH0 duration setting value (0~7)

Duration = HCLK x ( TWRPH0 + 1 ) = 25ns (view
K9F1208.pdf) 1/135.75 = 7ns

= 3 TWRPH0 >= 25 / 7 - 1 = 2.57

TWRPH1 [6:4] TWRPH1 duration setting value (0~7)

Duration = HCLK x ( TWRPH1 + 1 ) = 10ns (view
K9F1208.pdf)

= 1 TWRPH1 >= 10 / 7 - 1 = 0.42

*/

#define TACLS 0

#define TWRPH0 3

#define TWRPH1 1

NFCONF = (TACLS<<12) | (TWRPH0<<8) | (TWRPH1<<4);

/* NFCONT

InitECC [4] Initialize ECC decoder/encoder(Write-only)

= 1 Initialize ECC decoder/encoder

Reg_nCE [1] NAND Flash Memory nFCE signal control

= 1 Force nFCE to high (Disable chip select)

MODE [0] NAND flash controller operating mode

= 1 NAND flash controller enable

*/

NFCONT = (1<<4) | (0<<1) | (1<<0);

}

static void nand_select(void)

{

NFCONT &= ~(1<<1);

}

static void nand_deselect(void)

{

NFCONT |= (1<<1);

}

static void nand_cmd(unsigned char cmd)

{

volatile int i;

NFCMMD = cmd;

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

}

static void nand_addr(unsigned int addr)

{

/* Address(5Cycle)

Col Add.1,2 & Row Add.1,2,3

*/

int col = addr % 2048;

int row = addr / 2048;

volatile int i;

NFADDR = col & 0xff;

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

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

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

NFADDR = row & 0xff;

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

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

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

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

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

}

static void nand_wait(void)

{

while(!(NFSTAT&1));

}

void nand_read_ll(unsigned int addr, unsigned char *dest, unsigned int len)

{

int col = addr % 2048, i = 0;

nand_select();

while(i < len)

{

/* view K9K8G08U0A.pdf */

nand_cmd(0x00);

nand_addr(addr);

nand_cmd(0x30);

nand_wait();

for(; col<2048 && i<len; col++)

{

dest[i] = NFDATA;

i++;

addr++;

}

col = 0;

}

nand_deselect();

}

修改start.S

#ifndef
CONFIG_SKIP_LOWLEVEL_INIT

bl cpu_init_crit

#endif

ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)

bic sp, sp, #7 /* 8-byte
alignment for ABI compliance */

bl
nand_init_ll

mov
r0, #0

//ldr r1, =_start

ldr r1, _TEXT_BASE //CONFIG_SYS_TEXT_BASE
= 0x33f00000

ldr r2, _bss_start_ofs

bl
copy_to_sdram //copy_to_sdram(r0, r1, r2)

bl clear_bss

ldr
pc, =call_board_init_f //远跳转

/*
Set stackpointer in internal RAM to call board_init_f */

call_board_init_f:

ldr
r0,=0x00000000

bl board_init_f

修改mini2440.h中#define CONFIG_SYS_TEXT_BASE
0x33f80000

自己写了重定位,就去掉它写的重定位函数

注释掉掉board.c中board_init_f中//relocate_code(addr_sp,
id, addr);

删掉start.S中下面不需要的代码

点击(此处)折叠或打开

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

/*

* void relocate_code (addr_sp, gd, addr_moni)

*

* This "function" does not return, instead
it continues in RAM

* after relocating the monitor code.

*

*/

.globl relocate_code

relocate_code:

mov r4, r0 /* save addr_sp */

mov r5, r1 /* save addr of gd */

mov r6, r2 /* save addr of destination */

/* Set up the stack */

stack_setup:

mov sp, r4

adr r0, _start

cmp r0, r6

beq clear_bss /* skip relocation */

mov r1, r6 /* r1 <- scratch for copy_loop */

ldr r3, _bss_start_ofs

add r2, r0, r3 /* r2 <- source
end address */

copy_loop:

ldmia {r9-r10} /* copy from source address [r0] */

stmia {r9-r10} /* copy to target address [r1] */

cmp r0, r2 /* until source end address [r2] */

blo copy_loop

#ifndef CONFIG_SPL_BUILD

/*

* fix .rel.dyn relocations

*/

ldr r0, _TEXT_BASE /* r0 <- Text
base */

sub r9, r6, r0 /* r9 <- relocation
offset */

ldr r10, _dynsym_start_ofs /* r10 <- sym
table ofs */

add r10, r10, r0 /* r10 <- sym
table in FLASH */

ldr r2, _rel_dyn_start_ofs /* r2 <- rel
dyn start ofs */

add r2, r2, r0 /* r2 <- rel
dyn start in FLASH */

ldr r3, _rel_dyn_end_ofs /* r3 <- rel
dyn end ofs */

add r3, r3, r0 /* r3 <- rel
dyn end in FLASH */

fixloop:

ldr r0, [r2] /* r0 <- location
to fix up, IN */

add r0, r0, r9 /* r0 <- location
to fix up in RAM */

ldr r1, [r2, #4]

and r7, r1, #0xff

cmp r7, #23 /* relative fixup? */

beq fixrel

cmp r7, #2 /* absolute fixup? */

beq fixabs

/* ignore unknown type of fixup */

b fixnext

fixabs:

/* absolute fix: set location to (offset) symbol
value */

mov r1, r1, LSR #4 /* r1 <- symbol
index in .dynsym */

add r1, r10, r1 /* r1 <- address of symbol in table */

ldr r1, [r1, #4]
/* r1 <- symbol value */

add r1, r1, r9 /* r1 <- relocated
sym addr */

b fixnext

fixrel:

/* relative fix: increase location by offset */

ldr r1, [r0]

add r1, r1, r9

fixnext:

str r1, [r0]

add r2, r2, #8 /* each
rel.dyn entry is 8 bytes */

cmp r2, r3

blo fixloop

#endif

clear_bss:

#ifndef CONFIG_SPL_BUILD

ldr r0, _bss_start_ofs

ldr r1, _bss_end_ofs

mov r4, r6 /* reloc addr */

add r0, r0, r4

add r1, r1, r4

mov r2, #0x00000000 /* clear */

clbss_l:str r2, [r0]
/* clear loop... */

add r0, r0, #4

cmp r0, r1

bne clbss_l

bl coloured_LED_init

bl red_led_on

#endif

因为第二阶段函数board_init_f需要

修改函数定义

unsigned int board_init_f (ulong);(common.h)

unsigned int board_init_f(ulong bootflag) (arch/arm/lib/board.c)

函数体最后加上

return
(unsigned int)id;

返回后给start.S的第二阶段代码用

在start.S

ldr r0,=0x00000000

bl board_init_f

后加上

//board_init_f的返回值在r0里面,刚好把id传给board_init_r

ldr r1, _TEXT_BASE

bl board_init_r

vi
arch/arm/config.mk

注释掉

#LDFLAGS_u-boot
+= -pie

修改

arch/arm/cpu/u-boot.lds添加 board/samsung/mini2440/libmini2440.o
(.text)

.text :

{

__image_copy_start = .;

CPUDIR/start.o (.text)

board/samsung/mini2440/libmini2440.o
(.text)

*(.text)

}

修改board.c

//addr -= gd->mon_len;

//addr &= ~(4096
- 1);

addr
= CONFIG_SYS_TEXT_BASE;

make后烧写发现



9.在SI中搜索"Flash:“

(z:\u-boot-2012.04.01\arch\arm\lib\Board.c)

#if !defined(CONFIG_SYS_NO_FLASH)

puts("Flash: ");

继续看

if (flash_size > 0) {

...

}else {

puts(failed);
//输出*** failed ***

hang();
//挂起

}

void hang(void)

{

puts("###
ERROR ### Please RESET the board ###\n");

for
(;;); //死循环

}

注释掉//hang();

再次make,并烧写u-boot.bin到nor
flash,发现uboot是启动起来了不过flash和nand都不识别



10.定义#define DEBUG (z:\u-boot-2012.04.01\include\configs\Mini2440.h)

方便调试



11.找nor的识别问题

从图中JEDEC
PROBE: ID 1 2249 0和代码(z:\u-boot-2012.04.01\drivers\mtd\Cfi_flash.c)

debug("JEDEC
PROBE: ID %x %x %x\n",

info->manufacturer_id,

info->device_id,

info->device_id2);

可以看出manufacturer_id是1,device_id是2249,device_id2是0

flash_init (z:\u-boot-2012.04.01\drivers\mtd\Cfi_flash.c)

flash_detect_legacy

//
match jedec ids against table. If a match is found, fill flash_info entry

jedec_flash_match
(z:\u-boot-2012.04.01\drivers\mtd\Jedec_flash.c)

if
((jedec_table[i].mfr_id & mask) == (info->manufacturer_id
& mask) &&

(jedec_table[i].dev_id
& mask) == (info->device_id & mask)) {

fill_info(info, &jedec_table[i], base);

ret = 1;

break;

}

可以看到manufacturer_id、device_id都要和jedec_table中的信息匹配。

添加mini2440用的nor
flash信息(需要查看芯片手册Am29LV160DB.pdf)

{

.mfr_id = 1,

.dev_id = 0x2249,

.name
= "Am29LV160DB",

.uaddr = {

[1] = MTD_UADDR_0x0555_0x02AA /* x16 */

},

.DevSize = SIZE_2MiB,

.CmdSet = CFI_CMDSET_AMD_LEGACY,

.NumEraseRegions = 4,

.regions = {

ERASEINFO(0x04000, 1),

ERASEINFO(0x02000,
2),

ERASEINFO(0x08000,
1),

ERASEINFO(0x10000, 31),

}

},



取消DEBUG定义(看之前的DEBUG信息足以),再次编译烧写

12.提示Flash: ERROR: too many flash sectors

搜索发现#define CONFIG_SYS_MAX_FLASH_SECT
(19) //(z:\u-boot-2012.04.01\include\configs\Mini2440.h)

修改大一点#define CONFIG_SYS_MAX_FLASH_SECT
(128)

make烧写,Flash:2 MiB.



13.修改栈指针

start.S中加上

.globl base_sp

base_sp:

.long 0

start_code:

.....

ldr
r1, _TEXT_BASE

ldr
sp, base_sp

bl
board_init_r

在board.c的board_init_f加上

extern
ulong base_sp;

...

memcpy(id, (void *)gd, sizeof(gd_t));

base_sp
= addr_sp;

//relocate_code(addr_sp,
id, addr);

14.加上nand的支持

在mini2440.h中取消注释

#define CONFIG_CMD_NAND

make出错,拷贝drivers/mtd/nand/s3c2410_nand.c复制为s3c2440_nand.c

修改mini2440.h

#ifdef CONFIG_CMD_NAND

#ifdef
CONFIG_S3C2410

#define CONFIG_NAND_S3C2410

#define CONFIG_SYS_S3C2410_NAND_HWECC

#else

#define
CONFIG_NAND_S3C2440

#define CONFIG_SYS_S3C2440_NAND_HWECC

#endif

#define CONFIG_SYS_MAX_NAND_DEVICE 1

#define CONFIG_SYS_NAND_BASE 0x4E000000

#endif

修改drivers/mtd/nand/Makefile

加上

COBJS-$(CONFIG_NAND_S3C2410)
+= s3c2410_nand.o

COBJS-$(CONFIG_NAND_S3C2440) += s3c2440_nand.o

修改s3c2440_nand.c中的s3c2410_nand为s3c2440_nand(除了宏)

包括s3c2440_dev_ready、s3c2440_hwcontrol、s3c2440_get_base_nand

从nand_init开始看

nand_init_chip

board_nand_init

...

tacls
= 4;

twrph0
= 8;

twrph1
= 8;

#endif

cfg = S3C2410_NFCONF_EN;

cfg |= S3C2410_NFCONF_TACLS(tacls
- 1);

cfg |= S3C2410_NFCONF_TWRPH0(twrph0
- 1);

cfg |= S3C2410_NFCONF_TWRPH1(twrph1
- 1);

writel(cfg, &nand_reg->nfconf);

/*
NFCONF

TACLS [13:12]
CLE & ALE duration setting value (0~3)

= 0
Duration = HCLK x TACLSHCLK x TACLS (view K9F1208.pdf)

TWRPH0 [10:8]
TWRPH0 duration setting value (0~7)

Duration
= HCLK x ( TWRPH0 + 1 ) = 25ns (view K9F1208.pdf) 1/135.75 = 7ns

= 3
TWRPH0 >= 25 / 7 - 1 = 2.57

TWRPH1 [6:4]
TWRPH1 duration setting value (0~7)

Duration
= HCLK x ( TWRPH1 + 1 ) = 10ns (view K9F1208.pdf)

= 1 TWRPH1
>= 10 / 7 - 1 = 0.42

*/

cfg = ((tacls-1)<<12) | ((tacls-1)<<8)
| ((tacls-1)<<4);

writel(cfg, &nand_reg->nfconf);

/*
NFCONT

InitECC
[4] Initialize ECC decoder/encoder(Write-only)

= 1 Initialize
ECC decoder/encoder

Reg_nCE
[1] NAND Flash Memory nFCE signal control

= 1 Force
nFCE to high (Disable chip select)

MODE [0]
NAND flash controller operating mode

= 1 NAND
flash controller enable

*/

writel((1<<4) | (0<<1) | (1<<0),
&nand_reg->nfcont);

...

nand->select_chip
= NULL;

//修改为nand->select_chip
= s3c2440_select_nand;

自己写

static void s3c2440_select_nand(struct
mtd_info *mtd, int chipnr)

{

struct
s3c2440_nand *nand = s3c2440_get_base_nand();

switch (chipnr) {

case -1: //-1 for deselect

nand->nfcont
|= 1<<1;

break;

case
0: //0 for select

nand->nfcont
&= ~(1<<1);

break;

default:

BUG();

}

}

nand->cmd_ctrl
= s3c2440_hwcontrol;

//修改s3c2410_hwcontrol,根据ctrl判断是发命令还是地址

static void s3c2410_hwcontrol(struct mtd_info *mtd, int dat, unsigned int ctrl)

{

struct s3c2440_nand *nand = s3c2440_get_base_nand();

debug("hwcontrol(): 0x%02x 0x%02x\n", dat, ctrl);

if (ctrl & NAND_CLE)

{

writeb(dat,
&nand->nfcmd);

}

else if (ctrl & NAND_ALE)

{

writeb(dat,
&nand->nfaddr);

}

}

...

nand_scan

nand_scan_ident

nand_set_defaults

if
(chip->cmdfunc == NULL)

chip->cmdfunc = nand_command; //static
void nand_command(struct mtd_info *mtd, unsigned int command, int column, int page_addr)

if
(!chip->select_chip)

chip->select_chip = nand_select_chip;

nand_get_flash_type

chip->select_chip(mtd,
0);

chip->cmdfunc(mtd,
NAND_CMD_READID, 0x00, -1);

<=>nand_command

chip->cmd_ctrl(mtd, readcmd, ctrl);

<=>s3c2410_hwcontrol;

nand_register

add_mtd_device

make后nand可以正常使用了

15.mini2440用dm9000网卡,搜索drivers/net/Makefile 可以发现

COBJS-$(CONFIG_DRIVER_DM9000)
+= dm9000x.o

由mini2440.h中的宏CONFIG_DRIVER_DM9000控制,并且从上面结果可以看到,需要去掉cs8900的宏.

#if 0

#define CONFIG_CS8900
/* we have a CS8900 on-board */

#define CONFIG_CS8900_BASE
0x19000300

#define CONFIG_CS8900_BUS16
/* the Linux driver does accesses as shorts */

#else

#define
CONFIG_DRIVER_DM9000

#endif

make看看结果

dm9000x.c:
In function 'dm9000_outblk_8bit':

dm9000x.c:156:
error: 'DM9000_DATA' undeclared (first use in this function)

dm9000x.c:156:
error: (Each undeclared identifier is reported only once

dm9000x.c:156:
error: for each function it appears in.)

dm9000x.c:
In function 'dm9000_outblk_16bit':

dm9000x.c:165:
error: 'DM9000_DATA' undeclared (first use in this function)

dm9000x.c:
In function 'dm9000_outblk_32bit':

dm9000x.c:173:
error: 'DM9000_DATA' undeclared (first use in this function)

dm9000x.c:
In function 'dm9000_inblk_8bit':

dm9000x.c:180:
error: 'DM9000_DATA' undeclared (first use in this function)

dm9000x.c:
In function 'dm9000_inblk_16bit':

dm9000x.c:189:
error: 'DM9000_DATA' undeclared (first use in this function)

dm9000x.c:
In function 'dm9000_inblk_32bit':

dm9000x.c:197:
error: 'DM9000_DATA' undeclared (first use in this function)

dm9000x.c:
In function 'dm9000_rx_status_32bit':

dm9000x.c:204:
error: 'DM9000_IO' undeclared (first use in this function)

dm9000x.c:206:
error: 'DM9000_DATA' undeclared (first use in this function)

dm9000x.c:
In function 'dm9000_rx_status_16bit':

dm9000x.c:213:
error: 'DM9000_IO' undeclared (first use in this function)

dm9000x.c:215:
error: 'DM9000_DATA' undeclared (first use in this function)

dm9000x.c:
In function 'dm9000_rx_status_8bit':

dm9000x.c:221:
error: 'DM9000_IO' undeclared (first use in this function)

dm9000x.c:224:
error: 'DM9000_DATA' undeclared (first use in this function)

dm9000x.c:
In function 'dm9000_probe':

dm9000x.c:243:
error: 'CONFIG_DM9000_BASE' undeclared (first use in this function)

dm9000x.c:
In function 'dm9000_send':

dm9000x.c:420:
error: 'DM9000_IO' undeclared (first use in this function)

dm9000x.c:
In function 'dm9000_rx':

dm9000x.c:484:
error: 'DM9000_DATA' undeclared (first use in this function)

dm9000x.c:
In function 'DM9000_ior':

dm9000x.c:574:
error: 'DM9000_IO' undeclared (first use in this function)

dm9000x.c:575:
error: 'DM9000_DATA' undeclared (first use in this function)

dm9000x.c:
In function 'DM9000_iow':

dm9000x.c:584:
error: 'DM9000_IO' undeclared (first use in this function)

dm9000x.c:585:
error: 'DM9000_DATA' undeclared (first use in this function)

make[1]:
*** [dm9000x.o] Error 1

make[1]:
Leaving directory `/home/profiles/u-boot-2012.04.01/drivers/net'

make:
*** [drivers/net/libnet.o] Error 2

报错

grep
"DM9000_DATA" * -nR参考其他开发板

include/configs/M5253DEMO.h:95:#
define DM9000_DATA (CONFIG_DM9000_BASE + 4)

定义了

#
define CONFIG_DM9000_BASE (CONFIG_SYS_CS1_BASE | 0x300)

#
define DM9000_IO CONFIG_DM9000_BASE

#
define DM9000_DATA (CONFIG_DM9000_BASE + 4)

则在mini2440.h上加上这些宏,并把值参照原理图芯片手册,DM9000接片选4即bank4,由2440手册知0x20000000是bank4的基址修改过来为:

#define
CONFIG_DM9000_BASE 0x20000000

#define
DM9000_IO CONFIG_DM9000_BASE

#define
DM9000_DATA (CONFIG_DM9000_BASE + 4) //LADDR2开始接到DM9000上

内存控制器初始化已经在lowlevel.S中设置过为

SMRDATA:

.long 0x22050000 //BWSCON

make烧写从nor启动,发现Net:
No ethernet found.



16.在source insight中搜索“No
ethernet found.”找出原因

eth_initialize (board.c)

board_eth_init (mini2440/smdk2410.c)

cs8900_initialize此处不合适,添加DM9000的函数

#ifdef
CONFIG_CS8900

rc = cs8900_initialize(0, CONFIG_CS8900_BASE);

#endif

#ifdef
CONFIG_DRIVER_DM9000

rc
= dm9000_initialize(bis);

#endif

再次make烧写来试验网络功能

set
ipaddr 169.254.252.201 (连上网线同自己要ping的机器在一个网段)

set
serverip 169.254.252.200

set
gatewayip 255.255.0.0 (同自己要ping的机器一致)

set
ethaddr 08:00:27:71:89:bb

ping
169.254.252.200 通了



自行测试下tftp的下载功能。

tftp
30000000 uImage

发面bootm
30000000后不能启动linux,在解压后停住了。应该是开发板型号没修改

修改board_init(board.c)中

gd->bd->bi_arch_number
= MACH_TYPE_SMDK2410;为

gd->bd->bi_arch_number
= MACH_TYPE_MINI2440;

再次tftp下载后bootm就启动了

17.环境变量

开发板烧写u-boot后,发现***
Warning - bad CRC, using default environment

SI搜索一下。

set_default_env

default_environment

#ifdef CONFIG_BOOTARGS

"bootargs=" CONFIG_BOOTARGS
"\0"

#ifdef CONFIG_BOOTCOMMAND

"bootcmd=" CONFIG_BOOTCOMMAND
"\0"

在mini2440.h中加上

#define CONFIG_BOOTARGS
"console=ttySAC0 root=/dev/mtdblock3"

#define
CONFIG_BOOTCOMMAND "nand read 30000000 0x60000 0x500000;bootm 30000000"

修改

#define
CONFIG_NETMASK 255.255.0.0

#define CONFIG_IPADDR
169.254.252.201

#define CONFIG_SERVERIP
169.254.252.200

加上

#define CONFIG_ETHADDR
08:00:27:71:89:bb

18.裁剪

在mini2440.h找不需要的宏

#if 0

#define
CONFIG_USB_OHCI

#define
CONFIG_USB_KEYBOARD

#define
CONFIG_USB_STORAGE

#define
CONFIG_DOS_PARTITION

#endif

//#define
CONFIG_RTC_S3C24X0

#if
0

#define
CONFIG_BOOTP_BOOTFILESIZE

#define
CONFIG_BOOTP_BOOTPATH

#define
CONFIG_BOOTP_GATEWAY

#define
CONFIG_BOOTP_HOSTNAME

#endif

//#define
CONFIG_CMD_USB

//#define
CONFIG_CMD_DATE

//#define
CONFIG_CMD_DHCP

#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

裁剪后make发现

u-boot.bin的大小为204344B小了很多

19.环境变量默认存在nor,为了让u-boot里面的saveenv命令将环境变量保存到nand,且不能破坏内核,需要修改保存的位置。

在SI中搜索"saveenv",找到env_nand.c文件,到Makefile中找寻它所依赖的宏.

vi
common/Makefile,发现它依赖于CONFIG_ENV_IS_IN_NAND

(mini2440.h)修改

#if 0

#define CONFIG_ENV_ADDR
(CONFIG_SYS_FLASH_BASE + 0x070000)

#define CONFIG_ENV_IS_IN_FLASH

#define CONFIG_ENV_SIZE
0x10000

/* allow to overwrite
serial and ethaddr */

#define CONFIG_ENV_OVERWRITE

#endif

添加

#define CONFIG_ENV_IS_IN_NAND

在env_nand.c中找到宏CONFIG_ENV_OFFSET,这个制定存在nand的哪个地址

需要看看原内核的分区。

在我使用的2.6.32.2源代码中发现

static struct mtd_partition friendly_arm_default_nand_part[]
= {

[0]
= {

.name
= "supervivi",

.size
= 0x00040000,

.offset
= 0,

},

[1]
= {

.name
= "param",

.offset
= 0x00040000,

.size
= 0x00020000,

},

[2]
= {

.name
= "Kernel",

.offset
= 0x00060000,

.size
= 0x00500000,

},

[3]
= {

.name
= "root",

.offset
= 0x00560000,

.size
= 1024 * 1024 * 1024, //

},

[4]
= {

.name
= "nand",

.offset
= 0x00000000,

.size
= 1024 * 1024 * 1024, //

}

};

(或者启动内核后发现)



参数存在0x40000开始的0x20000大小处

则加定义(mini2440.h)

#define CONFIG_ENV_OFFSET
0x40000

#define CONFIG_ENV_SIZE
0x20000

#define CONFIG_ENV_RANGE
CONFIG_ENV_SIZE //擦除单位

make后烧写nor

此时还有***
Warning - bad CRC, using default environment

在u-boot里执行save命令重启就行了

u-boot倒计时5秒如果没有执行的话,就会执行我们设置的

#define CONFIG_BOOTCOMMAND "nand
read 30000000 0x60000 0x500000;bootm 30000000"

即从nand flash 0x60000的地方读0x500000的数据(整个内核)到内存0x30000000的地方,然后从0x30000000启动内核。

于是我们必须先将uImage烧写到0x60000的地方:

先下载tftp
30000000 uImage

nand
erase 60000 500000

nand
write 30000000 60000 500000 //这样60000的地方就有了可启动的内核

下次重启开发板,5秒延时之后将自动读内核并加载运行

20.代替繁琐的数字

在board.c的board_init_r中加上

run_command("mtdparts
default", 0); //必须让uboot执行这条命令

/*
main_loop() can return to retry autoboot, if so just run it again. */

for (;;) {

main_loop();

}

在mini2440中定义宏

#define
CONFIG_CMD_MTDPARTS

参照其它开发板再添加上

#define
CONFIG_MTD_DEVICE

#define MTDIDS_DEFAULT "nand0=mini2440-0"

#define MTDPARTS_DEFAULT
"mtdparts=mini2440-0:256k(u-boot)," \

"128k(params)," \

"5m(kernel),"
\

"-(rootfs)"
\ //-余下的所有给rootfs

make后提示发现drivers\mtd\mtdcore.c中的get_mtd_device_nm未定义。

则可以直接去drivers\mtd\Makefile中查看哪个宏决定是否编译成mtdcore.o

或者grep
"mtdcore.o" * -nR发现是CONFIG_MTD_DEVICE控制的

将宏添加到mini2440.h

#define CONFIG_MTD_DEVICE

再次make并烧写

在uboot执行命令mtdparts



现在可以尝试用名字代替数字的分区表示,如

tftp
30000000 uImage

nand
erase.part kernel

nand
write 30000000 kernel

此版对于yaffs的一个小bug

drivers/mtd/nand/nand_util.c (nand_write_skip_bad)中

改为

ops.len = pagesize;

ops.ooblen = nand->oobsize;

ops.mode = MTD_OOB_RAW;

ops.ooboffs = 0;

pages = write_size / pagesize_oob;

for (page = 0; page < pages; page++) {

WATCHDOG_RESET();

ops.datbuf = p_buffer;

ops.oobbuf = ops.datbuf + pagesize;

rval = nand->write_oob(nand, offset, &ops);

if (rval)

break;

offset += pagesize;

p_buffer += pagesize_oob;

}

if (!need_skip && !(flags & WITH_DROP_FFS))
{

改为

if
(!need_skip && !(flags & WITH_DROP_FFS) && !(flags & WITH_YAFFS_OOB)) {

之前的内核都是用nfs文件系统。

如果想用jffs2或者yaffs应该执行下列命令

烧写JFFS2

tftp 30000000 fs.jffs2

nand erase.part rootfs

nand write.jffs2 30000000 0x00260000 5b89a8

set bootargs console=ttySAC0 root=/dev/mtdblock3 rootfstype=jffs2

烧写YAFFS(需要先在mini2440中重新#define CONFIG_CMD_NAND_YAFFS再编译)

tftp 30000000 fs.yaffs2

nand erase.part rootfs

nand write.yaffs 30000000 260000 889bc0 //文件大小

用uboot更新自身

tftp 30000000 u-boot_new.bin; protect off all; erase 0 3ffff; cp.b 30000000 0 40000

移植完后制作补丁

mv u-boot-2012.04.01 u-boot-2012.04.01_ok

tar xjf u-boot-2012.04.01.tar.bz2

diff -urN u-boot-2012.04.01 u-boot-2012.04.01_ok > u-boot-2012.04.01.patch

打补丁

cd u-boot-2012.04.01

patch -p1 < ../u-boot-2012.04.01.patch //因为现在所在u-boot-2012.04.01目录,-p1
数字表示忽略第一个斜杠



u-boot-2012-patch@2440.rar


编译新uboot

make mini2440_config

make
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: