U-boot

移植了半个月,一个国庆假期都被我用掉了,终于把u-boot移植到了我的TQ2440,做了一些记录贴出来吧!
 
环境:Windows XP + 虚拟机Fedora14
交叉编译器:arm-linux-gcc-4.3.2(EABI)
u-boot版本:u-boot-2010-06.tar.bz2
开发板资源: TQ2440
Nor Flash 2M
NAND Flash 256M
SDRAM 64M
DM9000
为了查看源码:在XP 下装了Source Insight便于源码的追踪,很多问题稍微看看源码就知道怎么运用
了。
难点:NAND FLASH的移植,引导问题
主要是依据smdk2410移植TQ2440,两者CPU的主要差别在时钟和Nand Flash控制器上,同时2440
额外增加了一些控制器。因此在时钟中和Nand Flash控制部分需要着重注意。同样Nand Flash的控制
部分是移植的关键问题之一。
我写这个主要是本着学习的态度去做,对ARM更加的了解,同时明白各个开发过程的分析,熟悉嵌
入式Linux的技术细节。
其中可能存在很多的借鉴(抄袭),但是毕竟是自己做过了,就会有收获的。
开始我的u-boot之旅吧。
第一阶段主要是实现板级创建和时钟的配置
1、首先,解压缩源码
[root@Gong-Computer u-boot-2010.06]# tar -jxvf /mnt/hgfs/Linux/u-boot-2010.06.tar.bz2 -C /opt
查看README中的基本信息,对源码有所了解,这个我建议大家看看,其中很多的问题从中找到答案。
[ root@Gong-Computer u-boot-2010.06]# vi README
创建自己的板子SMDK2440
1.1、在根目录下打开Makefile文件,添加编译器:
[root@Gong-Computer u-boot-2010.06]#vi Makefile
查找CROSS_COMPILE,然后补齐如下
#/*修改编译器,设定为arm-linux-,编译器应该是arm-linux-gcc,
#这里只是arm-linux-具体的原因请参看根目录下的config.mk文件,就会发现gcc
#在config.mk文件中自动补齐,所以只需要arm-linux-*/
# set default to nothing for native builds
ifeq ($(HOSTARCH),$(ARCH))
CROSS_COMPILE = arm-linux-
endif
1.2在board/samsung下创建smdk2440,复制smdk2410目录下的代码到smdk2440中,修改相应的代码。
[root@Gong-Computer u-boot-2010.06]# cd board/samsung/
[root@Gong-Computer samsung]# mkdir smdk2440
[root@Gong-Computer samsung]# cp -fr smdk2410/* smdk2440/
[root@Gong-Computer samsung]# cd smdk2440/
[root@Gong-Computer smdk2440]# mv smdk2410.c smdk2440.c
[root@Gong-Computer smdk2440]# vi Makefile
修改目标文件
#COBJS := smdk2410.o flash.o
COBJS := smdk2440.o flash.o
SOBJS := lowlevel_init.o
1.3、添加库文件
[root@Gong-Computer smdk2440]# cd ../../
[root@Gong-Computer board]# cd ../
[root@Gong-Computer u-boot-2010.06]# cp include/configs/smdk2410.h include/configs/smdk2440.h
1.4、添加编译目标板的编译项
[root@Gong-Computer u-boot-2010.06]# vi Makefile
smdk2410_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 samsung s3c24x0
smdk2440_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t smdk2440 samsung s3c24x0
然后保存。
*说明:
arm :CPU 的架构(ARCH)
arm920t:CPU 的类型
mini2440 :对应在board 目录下建立新的开发板项目的目录
samsung:新开发板项目目录的上级目录,如直接在board 下建立新的开发板项目的目录,则这里就为
NULL
s3c24x0:CPU 型号
*注意:编译选项格式的第二行要用Tab 键开始,否则编译会出错
1、5编译自己的板子
[root@Gong-Computer u-boot-2010.06]# make smdk2440_config
Configuring for smdk2440 board...
[root@Gong-Computer u-boot-2010.06]# make
.....
t-2010.06/arch/arm/lib/eabi_compat.o -L /usr/local/arm/4.3.2/bin/../lib/gcc/arm-none-linuxgnueabi/
4.3.2/armv4t -lgcc -Map u-boot.map -o u-boot
arm-linux-objcopy -O srec u-boot u-boot.srec
arm-linux-objcopy --gap-fill=0xff -O binary u-boot u-boot.bin

说明自己的板子以及配置好了。接下来就是配置板子相关的信息。




(2)

修改时钟和中断设置,关闭看门狗,修改源码添加支持CONFIG_3C2440.
u-boot第一阶段的移植,主要是CPU时钟配置以及Nor Flash 和nand Flash的代码的移植,创建一
个好的堆栈环境为实现第二阶段的C语言创造条件,难点在Nand Flash的移植问题,硬件不一样,方
法也存在差异。
首先分析第一阶段的入口地址,查看lds链接文本,找到源文件的入口
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
//上面是规定输出的数据格式
OUTPUT_ARCH(arm)
//架构体系
ENTRY(_start)
//开始点
SECTIONS
{
. = 0x00000000; //从0x00000000处开始
. = ALIGN(4);// 对齐方式,四个字节
.text :
{
//在代码段存储的形式说明了代码的入口
//因此 arch/arm/cpu/arm920t/start.o对应的源文件就是入口代码
arch/arm/cpu/arm920t/start.o (.text)
*(.text) //其他的代码暂时不需要严格的顺序,因此不用分配存储顺序
}
...
}
对应的其他段都有各自的意义,参看lds详解,了解其中的意义。
找到入口文件arch/arm/cpu/arm920t/start.S,分析其中的基本流程,进行修改
首先看两个头文件
#include <common.h> //关于错误处理等一些通用的操作
#include <config.h> //自动生成,不能修改,主要包含相关的头文件库
 
.globl _start
40 _start: b start_code //定义了入口,开始就是一个跳转命令
//下面定义了一个基本的异常中断处理过程,其中这些异常中断服务程序都是有固定的地址的,具体
查看数据手册。
41 ldr pc, _undefined_instruction
42 ldr pc, _software_interrupt
43 ldr pc, _prefetch_abort
44 ldr pc, _data_abort
45 ldr pc, _not_used
46 ldr pc, _irq
47 ldr pc, _fiq
48
49 _undefined_instruction: .word undefined_instruction
50 _software_interrupt: .word software_interrupt
51 _prefetch_abort: .word prefetch_abort
52 _data_abort: .word data_abort
53 _not_used: .word not_used
54 _irq: .word irq
55 _fiq: .word fiq
注意这段代码中的一个定义方式:
label .word number ;也就是在label这个标记处放一个字宽度的数值number
73 _TEXT_BASE:
74 .word TEXT_BASE
75
76 .globl _armboot_start
77 _armboot_start:
78 .word _start
79
80 /*
81 * These are defined in the board-specific linker script.
82 */
83 .globl _bss_start
84 _bss_start:
85 .word __bss_start
86
87 .globl _bss_end
88 _bss_end:
89 .word _end
90
91 #ifdef CONFIG_USE_IRQ
92 /* IRQ stack memory (calculated at run-time) */
93 .globl IRQ_STACK_START
94 IRQ_STACK_START:
 
95 .word 0x0badc0de
96
97 /* IRQ stack memory (calculated at run-time) */
98 .globl FIQ_STACK_START
99 FIQ_STACK_START:
100 .word 0x0badc0de
101 #endif
这些主要是分配一些段,也是和上面的相同的定义方式,注意其中的 TEXT_BASE,它是一个数,查
看board/samsung/smdk2440/config.mk
[root@Gong-Computer u-boot-2010.06]# vi board/samsung/smdk2440/config.mk
# SMDK2410 has 1 bank of 64 MB DRAM
# 3000'0000 to 3400'0000
# Linux-Kernel is expected to be at 3000'8000, entry 3000'8000
# optionally with a ramdisk at 3080'0000
# we load ourself to 33F8'0000
# download area is 3300'0000
TEXT_BASE = 0x33F80000
接下来就是真正的开始阶段:
start_code:
/*首先进入了管理员模式*/
mrs r0, cpsr
bic r0, r0, #0x1f
orr r0, r0, #0xd3
msr cpsr, r0
由于TQ2440中没有LED部分的实现,因此关闭LED
/*关闭AT91的LED初始化*/
/* bl coloured_LED_init*/
/* bl red_LED_on*/
接下来就是关闭关门狗和中断以及配置CPU时钟,S3C2410于S3C2440的中断系统差不多,但是
S3C2440的子中断屏蔽寄存器要多一些,因此中断方便的设置存在差异,需要修改代码。
#ifdef CONFIG_S3C24X0
/* turn off the watchdog */
//S3C24x0的寄存器
# if defined(CONFIG_S3C2400)
# define pWTCON 0x15300000
# define INTMSK 0x14400008 /* Interupt-Controller base addresses */
# define CLKDIVN 0x14800014 /* clock divisor register */
#else 由于S3C2440于S3C2410的寄存器地址相同,因此不需要重新添加,复用代码即可
# define pWTCON 0x53000000
# define INTMSK 0x4A000008 /* Interupt-Controller base addresses */
 
# define INTSUBMSK 0x4A00001C
# define CLKDIVN 0x4C000014 /* clock divisor register */
// 关闭看门狗的代码
ldr r0, =pWTCON
mov r1, #0x0
str r1, [r0]
//进行中断屏蔽,关闭了中断控制器中的中断
mov r1, #0xffffffff
ldr r0, =INTMSK
str r1, [r0]
//子中断屏蔽寄存器的设置,需要修改
# if defined(CONFIG_S3C2410)
ldr r1, =0x3ff
ldr r0, =INTSUBMSK
str r1, [r0]
# endif
//添加S3C2440的子中断屏蔽寄存器控制,具体的值参看手册
# if defined(CONFIG_S3C2440)
ldr r1, =0x7ff
ldr r0, =INTSUBMSK
str r1, [r0]
# endif
接下来是时钟频率的控制,S3C2440于S3C2410的时钟频率存在较大的差异需要重新配置
/ *添加对S3C2440CPU和USB时钟控制的设置*/
/*将时间频率设置为1:4:8*/
/*12.0000MHz 405.00 MHz 127(0x7f) 2 1*/
/*具体的值参考数据手册的255页PLL VALUE SELECTION TABLE*
#if defined(CONFIG_S3C2440)
#define MPLLCON 0x4c000004 /*添加主频率设置寄存器*/
#define UPLLCON 0x4c000008 /*添加USB时钟频率设置寄存器*/
/*设置主时钟频率为405MHZ,1:4:8*/
ldr r0,=CLKDIVN
mov r1,#5
str r1,[r0]
ldr r0,=MPLLCON
ldr r1,=0x7F021
str r1,[r0]
 
/*设置USB的时钟大小为48MHZ*/
ldr r0=UPLLCON
ldr r1,=0x38022
str r1,[r0]
#else
/*下面是其他CPU的时钟控制*/
/* FCLK:HCLK:PCLK = 1:2:4 */
/* default FCLK is 120 MHz ! */
ldr r0, =CLKDIVN
mov r1, #3
str r1, [r0]
#endif
#endif /* CONFIG_S3C24X0 *//*以上是结束时钟控制部分*/
这边是实现了CPU 时钟的控制,板级的速度和频率也要作相应的修改,才能适应下一阶段的运行,
CPU的时钟设置完成以后需要对板级的时钟和速度进行修改,因此设置新的板级的时钟,具体的修
改为如下两个部分.
[root@Gong-Computer u-boot-2010.06]# vi board/samsung/smdk2440/smdk2440.c
/*#define FCLK_SPEED 1*/
#define FCLK_SPEED 2
#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 0xA1
#define M_PDIV 0x3
#define M_SDIV 0x1
/*具体参看书册*/
#elif FCLK_SPEED==2 /* Fout = 405 MHZ*/
#define M_MDIV 0x7f
#define M_PDIV 0x2
#define M_SDIV 0x1
#endif
/*#define USB_CLOCK 1*/
#define USB_CLOCK 2
#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
#define U_M_SDIV 0x2
/*具体参卡手册*/
#elif USB_CLOCK==2 /*Uout = 48MHZ*/
#define U_M_MDIV 0x38
#define U_M_PDIV 0x2
#define U_M_SDIV 0x2
#endif
[root@Gong-Computer u-boot-2010.06]# vi arch/arm/cpu/arm920t/s3c24x0/speed.c
/*主时钟的修改FCLK*/
static ulong get_PLLCLK(int pllreg)
.......
m = ((r & 0xFF000) >> 12) + 8;
p = ((r & 0x003F0) >> 4) + 2;
s = r & 0x3;
#if defined(CONFIG_S3C2440)/*设置对应的速度*/
/*参考S3C2440 芯片手册上254页的公式:PLL=(2 * m * Fin)/(p * 2s)*/
if(pllreg==MPLL)
return ((CONFIG_SYS_CLK_FREQ*m*2)/(p<<s));
#endif
/*这个是S3C2410的时钟设置*/
return (CONFIG_SYS_CLK_FREQ * m) / (p << s);
/*HCLK的修改*/
ulong get_HCLK(void)/*这个HCLK肯定也要修改,因为主频律变化了*/
{
struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();/*获得寄存器的值*/
#if defined(CONFIG_S3C2440)
/*为了使得更加具有通用性,采取判断的方式,本来可以直接返回get_FCLK/4,但是通用性下降*/
/*因为CLKDIVN的23位是关于HCLK的设置,参看手册258页*/
if(clk_power->CLKDIVN&0x06)
{
if(clk_power->CLKDIVN&0x06 == 2)
return (get_FCLK()/2);
if ((clk_power->CLKDIVN & 0x6)==6)
return((clk_power->CAMDIVN & 0x100) ? get_FCLK()/6 :get_FCLK()/3);
if ((clk_power->CLKDIVN & 0x6)==4)
return((clk_power->CAMDIVN & 0x200) ? get_FCLK()/8 :get_FCLK()/4);
}
else
return(get_FCLK());
#else/*S3C2410的时钟设置*/
return (readl(&clk_power->CLKDIVN) & 2) ? get_FCLK() / 2 : get_FCLK();
#endif
}
PCLK的时钟不需要修改。
修改部分源码,添加对CONFIG_S3C2440的支持:
这个时候编译我们都是借用了S3C2410的寄存器, 还没有添加S3C2440的选项,因此修改存在
CONFIG_S3C2410的区域。 这时候最好借助Source Insight跟踪存在CONFIG_S3C2410的区域,并根
据实际情况对其进行修改,存在较大差别的区域进行补充,但是不要改变结构体名字,只能改变其内
容。
首先是: s3c24x0.h中关于CPU外设的寄存器存在较大的差异
80 u32 INTOFFSET;
81 /*S3C2440于S3C2410的差别主要是在子屏蔽寄存器中的配置,寄存器位置相同*/
82 #if defined(CONFIG_S3C2410)||defined(CONFIG_S3C2440)
83 u32 SUBSRCPND;
84 u32 INTSUBMSK;
85 #endif
/*S3C2440与S3C2410的DMA相同*/
93 #if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
94 u32 DISRCC;
95 #endif
96 u32 DIDST;
97 #if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
98 u32 DIDSTC;
99 #endif
#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
109 u32 res[7];
110 #endif
u32 CLKDIVN;
128 /*查看手册,这是不同的地方,在时钟的配置区域得到体现*/
129 #if defined(CONFIG_S3C2440)
130 u32 CAMDIVN;
150 /*修改地方*/
151 #if defined(CONFIG_S3C2410)||de fined(CONFIG_S3C2440)
152 u32 LCDINTPND;
153 u32 LCDSRCPND;
154 u32 LCDINTMSK;
155 #endif
156 #ifdef(CONFIG_S3C2410)
157 u32 LPCSEL;
158 #endif
159 /*查看手册,这只是差别,其实可以不修改*/
160 #ifdef(CONFIG_S3C2440)
161 u32 TCONSEL;
162 #endif
165 #if defined(CONFIG_S3C2410)
166 /* NAND FLASH (see S3C2410 manual chapter 6) */
167 struct s3c2410_nand {
168 u32 NFCONF;
169 u32 NFCMD;
170 u32 NFADDR;
171 u32 NFDATA;
172 u32 NFSTAT;
173 u32 NFECC;
174 };
175 #endif
176 /*该寄存器的差别较大,具体的差别跟踪源码,进行修改*/
177 #if defined(CONFIG_S3C2440)
178 /* NAND FLASH (see S3C2440 manual chapter 6) */
179 struct s3c2410_nand { //不要改变结构体的名字,只是改变其内容
180 u32 NFCONF;
181 u32 NFCONT;
182 u32 NFCMD;
183 u32 NFADDR;
184 u32 NFDATA;
185 u32 NFMECCD0;
186 u32 NFMECCD1;
187 u32 NFSECCD;
188 u32 NFSTAT;
189 u32 NFESTAT0;
190 u32 NFESTAT1;
191 u32 NFMECC0;
192 u32 NFMECC1;
193 u32 NFSECC;
194 u32 NFSBLK;
195 u32 NFEBLK
196 };
197 #endif
436 #if defined(CONFIG_S3C2410)|| defined(CONFIG_S3C2440)
。。。。。。。。
486 #ifdef(CONFIG_S3C2440)
487 u32 res9;
488 u32 DSC0;
489 u32 DSC1;
 
490 u32 MSLCON;
491 u32 GPJCON;
492 u32 GPJDAT;
493 u32 GPJUP;
494 u32 res10;
495 #endif
其次 :[root@Gong-Computer u-boot-2010.06]# vi arch/arm/include/asm/arch-s3c24x0/s3c24x0_cpu.h
#elif defined (CONFIG_S3C2410 )|| defined(CONFIG_S3C2440)
#include <asm/arch/s3c2410.h>
然后是:
[root@Gong-Computer u-boot-2010.06]# vi drivers/i2c/s3c24x0_i2c.c查找在defined (CONFIG_S3C2410)后面添加||defined(CONFIG_S3C2440)即可。
/*添加新的选项,S3C2440*/
60 #if defined(CONFIG_S3C2410)|| defined(CONFIG_S3C2440)
61 return (readl(&gpio->GPEDAT) & 0x8000) >> 15;
62 #endif
79 #if defined(CONFIG_S3C2410)|| defined(CONFIG_S3C2440)
80 writel((readl(&gpio->GPEDAT) & ~0x4000) | (x & 1) << 14, &gpio->GPEDAT);
81 #endif
131 #if defined(CONFIG_S3C2410)|| defined(CONFIG_S3C2440)
132 ulong old_gpecon = readl(&gpio->GPECON);
133 #endif
140 #if defined(CONFIG_S3C2410)|| defined(CONFIG_S3C2440)
141 /* set I2CSDA and I2CSCL (GPE15, GPE14) to GPIO
166 #if defined(CONFIG_S3C2410)|| defined(CONFIG_S3C2440)
167 writel(old_gpecon, &gpio->GPECON);
最后是 :[root@Gong-Computer u-boot-2010.06]# vi common/serial.c
71 #elif defined(CONFIG_S3C2410)|| defined(CONFIG_S3C2440)
72 #if defined(CONFIG_SERIAL1)
160#if defined(CONFIG_S3C2410)|| defined(CONFIG_S3C2440)
161 serial_register(&s3c24xx_serial0_device);
162 serial_register(&s3c24xx_serial1_device);
163 serial_register(&s3c24xx_serial2_device);
[ root@Gong-Computer u-boot-2010.06]# vi arch/arm/cpu/arm920t/start.S
/*为了调试方便需要将cpu初始化部分注释掉,在后面阶段还是会打开,现在只是调试*/
207 /*
208 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
209 bl cpu_init_crit
210 #endif
211 */

修改板级相关的头文件:

[root@Gong-Computer u-boot-2010.06]# vi include/configs/smdk2440.h

//#define CONFIG_S3C2410   1

//#define CONFIG_SMDK2410  1

添加

#define CONFIG_S3C244   1

#define CONFIG_SMDK244  1

这样可以分类讨论。因为前面已经添加了CONFIG_S3C2440相关的代码,因此不会出很多的错误。
[root@Gong-Computer u-boot-2010.06]# make -d
采用调试的方式进行编译,但是出现了一些错误,是在 timer.c 中出现 error "tbclk not configured",不
知道怎么办只能查看源码了,查看源码发现是因为屏蔽掉了smdk2440.h中的#define
CONFIG_SMDK2410,根据错误原因我在源码中添加:
[root@Gong-Computer u-boot-2010.06]# vi arch/arm/cpu/arm920t/s3c24x0/timer
.c
176 ulong get_tbclk(void)
177 {
178 ulong tbclk;
179
180 #if defined(CONFIG_SMDK2400) || defined(CONFIG_TRAB)
181 tbclk = timer_load_val * 100;
182 #elif defined(CONFIG_SBC2410X) || \
183 defined(CONFIG_SMDK2410) || \
184 defined(CONFIG_SMDK2440) || \ //添加项
185 defined(CONFIG_VCMA9)
186 tbclk = CONFIG_SYS_HZ;
187 #else
188 # error "tbclk not configured"
189 #endif
190
191 return tbclk;
192 }
修改完成以后,重新编译调试;
[root@Gong-Computer u-boot-2010.06]# make -d
.....
Invoking recipe from Makefile:426 to update target `System.map'.
Putting child 0x9ea4ce0 (System.map) PID 29959 on the chain.
Live child 0x9ea4ce0 (System.map) PID 29959
Reaping winning child 0x9ea4ce0 PID 29959
Removing child 0x9ea4ce0 PID 29959 from chain.
Successfully remade target file `System.map'.
Finished prerequisites of target file `all'.
Must remake target `all'.
Successfully remade target file `all'.
这说明修改完成了,并没有错误了。这样可以很实现调试了。
第一次调试的过程中我将时钟配置部分的代码写反了,导致总是出现data abort错误,
EmbedSky> tftp 0x30000000 u-boot_debug.bin
dm9000 i/o: 0x20000300, id: 0x90000a46
MAC: 0a:1b:2c:3d:4e:5f
TFTP from server 192.168.10.154; our IP address is 192.168.10.122
Filename 'u-boot_debug.bin'.
Load address: 0x30000000

Loading: T #######
done
Bytes transferred = 101152 (18b20 hex)
EmbedSky> go 0x30000000
## Starting application at 0x30000000 ...
data abort
pc : [<300000a0>] lr : [<33d0d5f8>]
sp : 33cbdb74 ip : ffffffff fp : 33cbdde1
r10: 33cbdce1 r9 : 00000000 r8 : 33cbffdc
r7 : 33cbdde1 r6 : 00000002 r5 : 33cbdc94 r4 : 30000000
r3 : 00000002 r2 : 50000000 r1 : 0007f021 r0 : 4c000004
Flags: nZCv IRQs off FIQs off Mode SVC_32
Resetting CPU ...
仔细检查发现是在MPLLCON配置过程中对寄存器赋值的代码出错了,写成了
str r0,[r1]
改写成
str r1,[r0]
就实现了时钟部分最基础的移植,采用TQ2440原来的u-boot通过TFTP上传镜像到SDRAM,即可
实现下面的结果。
##### Boot for Nor Flash Main Menu #####
##### EmbedSky USB download mode #####
........
EmbedSky> tftpboot 0x30000000 u-boot_debug.bin
dm9000 i/o: 0x20000300, id: 0x90000a46
MAC: 0a:1b:2c:3d:4e:5f
TFTP from server 192.168.10.154; our IP address is 192.168.10.122
Filename 'u-boot_debug.bin'.
Load address: 0x30000000
Loading: T #######
done
Bytes transferred = 101152 (18b20 hex)
EmbedSky> go 0x30000000
## Starting application at 0x30000000 ...
U-Boot 2010.06 (Oct 06 2011 - 15:21:00)
DRAM: 64 MiB
Flash: 512 KiB
*** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
Net: CS8900-0
SMDK2410 #
这说明DRAM部分已经没有问题了。





(3)

Nor Flash的移植,以及提示符的修改。
1、首先将提示符由原来的SMDK2410修改为 u-boot@SMDK2440:
[root@Gong-Computer u-boot-2010.06]# vi include/configs/smdk2440.h
119 //#define CONFIG_SYS_PROMPT "SMDK2410 # " /* Monitor Command Prompt */
120 #define CONFIG_SYS_PROMPT "
u-boot@SMDK2440 # " /* Monitor Command
Prompt(提示符)*/
然后修改Nor Flash的代码。
2、通 常,在嵌入式bootloader 中,有两种方式来引导启动内核:从Nor Flash 启动和从 Nand Flash 启动。
u-boot 中默认是从Nor Flash 启动的。
EN29LV160A特性:
Flexible Sector Architecture:
- One 16-Kbyte, two 8-Kbyte, one 32-Kbyte,
and thirty-one 64-Kbyte sectors (byte mode)
- One 8-Kword, two 4-Kword, one 16-Kword
and thirty-one 32-Kword sectors (word mode
)
EN29LV160A是16位的Nor Flash,一 共存在35个页,前4页的数据较小,而后面的31页数据均为
64k字节,第一页数据为16K字节,第二、三页8K字节,第四段为32K字节.存在两种工作模式根据。
The signal set on the BYTE# Pin controls whether the device data I/O pins DQ15-DQ0 operate in the byte or
word configuration. When the Byte# Pin is set at logic ‘1’, then the device is in word configuration, DQ15-
DQ0 are active and are controlled by CE# and OE#. On the other hand, if the Byte# Pin is set at logic ‘0’,
then the device is in byte configuration, and only data I/O pins DQ0-DQ7 are active and controlled by CE#
and OE#. The data I/O pins DQ8- DQ14 are tri-stated, and the DQ15 pin is used as an input for the LSB (A-1
) address function.
A bit cannot be programmed from a “0” back to a “1”. Only erase operations can convert a “0” to a “1”.
说明了BYTE决定了FLASH的模式,TQ2440的BYTE接了高电平,因此采用了Word模式。
TQ2440的ADDR1-ADDR20接到了Flash的A0-A19,另外两个A20和A21是没有作用的,这与
Flash封装相同但是大小不同存在很大的关系。 Nor Flash的片选端接在了TQ2440的nGCS0上,说明
了Nor Flash映射到内存映射的第0块区域,(阅读S3C2440A的第5章)
由于SMDK2410板子中支持AMD_LV400和AMD_LV800,因此需要添加关于EN29LV160A的支持,
2.1、屏蔽掉AMD_LV400和AMD_LV800,然后添加新的支持项CONFIG_EON_29LV160AB 1 。
/*新添加的芯片EON_29LV160AB*/
[root@Gong-Computer u-boot-2010.06]# vi include/configs/smdk2440.h
168 #define CONFIG_EON_29LV160AB 1
169
170 #define CONFIG_SYS_MAX_FLASH_BANKS 1 /* max number of memory banks */
171
 
/*屏蔽两种芯片的信息*/
174 #ifdef CONFIG_AMD_LV800
175 #define PHYS_FLASH_SIZE 0x00100000 /* 1MB */
176 #define CONFIG_SYS_MAX_FLASH_SECT (19) /* max number of sectors on one chip */
177 #define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x0F0000) /* addr of
environment */
178 #endif
179 #ifdef CONFIG_AMD_LV400
180 #define PHYS_FLASH_SIZE 0x00080000 /* 512KB */
181 #define CONFIG_SYS_MAX_FLASH_SECT (11) /* max number of sectors on one chip */
182 #define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x070000) /* addr of
environment */
183 #endif
186 /*添加新芯片的信息*/
187 #ifdef CONFIG_EON_29LV160AB
188 #define PHYS_FLASH_SIZE 0x200000 /*存储器的实际大小*/
189 #define CONFIG_SYS_MAX_FLASH_SECT (35) /*芯片的页数,也就是扇区数,35个,芯
片资料中有*/
190 #define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x80000)
191 /*环境变量的存储地址,0x80000,215K字,环境变量的首地址是在0x80000处*/
192 #endif
2.2、为flash添加ID号,这个ID 号是一个固定的值,由于是采用了bottom boot block ,从低地址到
高地址增长的形式。 可知ID 号是2249。添加ID号的函数为
[root@Gong-Computer u-boot-2010.06]# vi include/flash.h
182 /*添加两种不同扇区方式的ID标号,标号在手册中可以找到*/
183 #define EON_ID_LV160AB_T 0x22C422C4 /* LV160AB ID (16 M, top boot sector) */
184 /*top boot sect 是第一个分区在最高位,bottom boot sect 是第一个分区在最低位*/
185 #define EON_ID_LV160AB_B 0x22492249 /* LV160AB ID (16 M, bottom boot sect) */
2.3、同时查找EON公司的代号,便于后面添加信息。
173 /* Manufacturers inside bank 1 have ids like 0x01xx01xx */
174 #define EON_MANUFACT 0x011C011C /* EON manuf. ID in D23..D16, D7..D0 */ /
2.4、 定义分区大小,同时实现操作,显示厂商信息
[root@Gong-Computer u-boot-2010.06]# vi board/samsung/smdk2440/flash.c
修改主分区的大小
 
32 //#define MAIN_SECT_SIZE 0x10000 /* 64 KB */
33 /*这个分区的大小是按着模式来分的,
34 *当按着字模式时,分区大小就是32K Word
35 *当按着字节模式时,分区的大小就是64K Byte
36 *TQ2440时按着字模式工作的,因此分区大小为32K
37 */
38 #define MAIN_SECT_SIZE 0x8000 /* 32 K Word */
39
40 flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
理解两个宏定义:
58 #define MEM_FLASH_ADDR1 (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE +
(0x00000555 << 1)))
59 #define MEM_FLASH_ADDR2 (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE +
(0x000002AA << 1)))
这两句的理解是于硬件相关的,其中的 CONFIG_SYS_FLASH_BASE 是指Flash对应的基地址,
同时后面的两个数是由芯片本身决定的,不同的芯片其参数不一样,需要查看芯片手册。 Flash操作
过程中都是在一定的时间周期内在一定的地址写上特定的数据实现不同的操作的。在EN29LV1602
的芯片手册中规定了在两个不同的模式下的各种操作:
在字模式下: 在两个周期下分别对地址0x555和0x2AA写上相应的数据即可实现相应的操作。
在字节模式下:在两个周期下分别对地址0xAAA和0x555分别写上不同的数据实现相应的操作。
这两组地址都是对Flash芯片而言的绝对地址,但是对于CPU而言是一个相对地址,是相对于Flash
的基地址而言的,因此需要加上CONFIG_SYS_FLASH_BASE

由于TQ2440的ADDR1接在了EON29LV1602的A0上,因此每一次写相应的地址都需要左移1位,
才能正确的访问实际需要访问的地址,如果是ADDR0接在A0上,则不需要实现该操作,同时是按
着字模式进行控制,因此得到了相应的数据,如上所示。由于Flash就是处于第0块上,因此基地址
就是0x00000000.
修改ulong flash_init (void)
73 ulong flash_init (void)//初始化flash
.........
88 /*添加芯片的厂家信息*/
89 #elif defined(CONFIG_EON_29LV160AB)
90 (EON_MANUFACT & FLASH_VENDMASK) |/*添加厂商*/
91 (EON_ID_LV160AB_B & FLASH_TYPEMASK);/*添加芯片的ID号*/
修改每一次访问的大小,这个需要根据芯片进行实际的修改,EON_29LV1602的参数参看手册。
 
103 if (j <= 3) {
104 /* 1st one is 8 KB ,第一分区的大小是8K字*/
105 if (j == 0) {
106 flash_info[i].start[j] =
107 flashbase + 0;
108 }
109
110 /* 2nd and 3rd are both 4 KB ,第二第三分区的大小是4K 字*/
111 if ((j == 1) || (j == 2)) {
112 /*0x2000就是第一分区的8K,0x1000就是4K*/
113 flash_info[i].start[j] =
114 /* flashbase + 0x4000 + (j -
115 1) *
116 0x2000;*/
117 flashbase + 0x2000 + (j -
118 1)*
119 0x1000;
120 }
121
122 /* 4th 16 KB ,第四个分区的大小为16K*/
123 if (j == 3) {
124 flash_info[i].start[j] =
125 /* flashbase + 0x8000;*/
126 flashbase + 0x4000;
127 }
128 } else {/*其他的分区为32K*/
129 flash_info[i].start[j] =
130 flashbase + (j - 3) * MAIN_SECT_SIZE;
131 }
修改void flash_print_info (flash_info_t * info) //打印信息
150 void flash_print_info (flash_info_t * info) //打印信息
.....
case (AMD_MANUFACT & FLASH_VENDMASK):
156 printf ("AMD: ");
157 break;
158 /*添加答应厂商的信息*/
159 case (EON_MANUFACT & FLASH_VENDMASK):
160 printf("EON: ") ;
161 break;
171 case (AMD_ID_LV800B & FLASH_TYPEMASK):
172 printf ("1x Amd29LV800BB (8Mbit)\n");
173 break;
174 /*添加ID信息*/
175 case (EON_ID_LV160AB_B & FLASH_TYPEMASK):
176 printf ("1x EON_29LV160AB (16Mbit)\n");
177 break;
修改int flash_erase (flash_info_t * info, int s_first, int s_last)
203 int flash_erase (flash_info_t * info, int s_first, int s_last)
..........
218 /*厂商检测,需要确保正确操作*/
219 if ((info->flash_id & FLASH_VENDMASK) !=
220 /* (AMD_MANUFACT & FLASH_VENDMASK)) {*/
221 (EON_MANUFACT & FLASH_VENDMASK)) {
222 return ERR_UNKNOWN_FLASH_VENDOR;
223 }
编译的过程中可能会出错,检查自己修改过的代码应该就能找到原因了。
编译调试:make distclean
make clean
make smdk2440_config
make -d
Invoking recipe from Makefile:426 to update target `System.map'.
Putting child 0x8adb688 (System.map) PID 9015 on the chain.
Live child 0x8adb688 (System.map) PID 9015
Reaping winning child 0x8adb688 PID 9015
Removing child 0x8adb688 PID 9015 from chain.
Successfully remade target file `System.map'.
Finished prerequisites of target file `all'.
Must remake target `all'.
Successfully remade target file `all'.
编译成功
调试,将debug的u-boot通过tftp加载到内存中,然后通过go 命令测试是否成功。
EmbedSky> tftpboot 0x30000000 u-boot_debug_nor.bin
dm9000 i/o: 0x20000300, id: 0x90000a46
MAC: 0a:1b:2c:3d:4e:5f
TFTP from server 192.168.10.154; our IP address is 192.168.10.122
Filename 'u-boot_debug_nor.bin'.
Load address: 0x30000000
Loading: T #######
done
Bytes transferred = 101252 (18b84 hex)
EmbedSky> go 0x30000000
## Starting application at 0x30000000 ...
U-Boot 2010.06 (Oct 06 2011 - 21:00:13)
Flash: 2 MiB
In: serial
Out: serial
Err: serial
Net: CS8900-0
u-boot@SMDK2440 #
以上说明修改的Nor Flash成功。
u-boot@SMDK2440 # printenv
bootdelay=3
baudrate=115200
ipaddr=10.0.0.110
serverip=10.0.0.1
netmask=255.255.255.0
ethact=CS8900-0
stdin=serial
stdout=serial
stderr=serial
Environment size: 143/65532 bytes
u-boot@SMDK2440 # saveenv
Saving Environment to Flash...
Un-Protected 2 sectors
Erasing Flash...Erasing sector 19 ... ok.
Erasing sector 20 ... ok.
Erased 2 sectors
Writing to Flash... done
Protected 2 sectors
u-boot@SMDK2440 #
命令测试成功。



(4)


Nand Flash 中的复制可能存在一些差别,但是基本思想仍然相同实现代码的搬迁。
Nand Flash 相比Nor Flash各自有自己的优势,同时也有自己的劣势,S3C2440支持两种Flash的引导
方式。其中S3C2440提供了NADN FLASH的控制器,但是该控制器于S3C2410的存在较大的差别,
因此需要重写代码,同 时TQ2440的Nand Flash是K9F2G08UXA是一个256M的Flash。由于uboot
属于最底层的程序, 所以需要对芯片资料有所认识,最好熟悉芯片基本的操作和特性
K9F2G08UXA 是一个具有128K页,2048块,每一块64页,每一页具有(2K+64)byte,2K是主区,
64是信息区域, 每一块是(128K+4K)byte的空间。所有的操作都是通过一个8位的IO实现。对每
一页的访问通过列地址进行访问,2K空间一共需要11个位宽,因此列访问需要两次,第一次前8位,
第二次前4位,后4位为0。行地址和列地址是分开访问的。页访问通过行地址实现, 一共128K,则
需要17位位宽,这样8位IO口需要三次才能访问完全,前两次的8位,后一次的1位
,其他位都必
须为0。因此K9F2G08UXA 的地址是5次地址方式。这才导致了5个周期输入。实质上存储空间不
止256M。具体的操作的方式是通过一些命令实现的,因此需要熟悉命令,才能实现控制。
U-boot中Nand Flash的实现主要是u-boot将自身从nand Flash中搬移到内存中去,然后才能执行,这
个过程需要我们采用汇编代码实现。
/*建议在修改下一项的过程中最好在修改前编译一次,确保没有错误再修改这样才能知道是那一阶段
出了问题,便于修改*/
具体的操作如下:
1、添加Nand Flash操作的寄存器
2、屏蔽从Nor Flash复制的代码
/*屏蔽掉从Nor Flash启动的方式*/
#if 0
#ifndef CONFIG_SKIP_RELOCATE_UBOOT
....
#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
#endif
3、添加从Nand Flash引导的代码
#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
#endif
/*添加从Nand Flash 引导的代码*/
#ifdef CONFIG_S3C2440_NAND_BOOT /*增加条件编译*/
mov r1,#NAND_CTL_BASE
/*两种参数均可以*/
/* ldr r2,=(0<<12)|(3<<8)|(0<<4)|(3<<2)|(1<<1)*/
ldr r2,=( (7<<12)|(7<<8)|(7<<4)|(0<<0) )
/*设置寄存器NFCONF,具体的值查看手册*/
str r2,[r1,#oNFCONF]
/*将NFCONF的值加载到r2*/
ldr r2,[r1,#oNFCONF]
/*两种参数均可以*/
/* ldr r2,=(1<<4)|(1<<1)|(1<<0)*/
ldr r2, =( (1<<4)|(0<<1)|(1<<0) ) @ Active low CE Control
/*设置寄存器NFCONT*/
str r2,[r1,#oNFCONT]
ldr r2,[r1,#oNFCONT]
/*如果采用上面注释起来的代码,下面的三句代码也需要注释起来*/
ldr r2,=(0x06) //清除RnB
str r2,[r1,#oNFSTAT]
//加载寄存器中的内容
ldr r2,[r1,#oNFSTAT]
mov r2,#0xff /*复位的命令*/
/*存储一个字节到r1+oNFCMD*/
strb r2,[r1,#oNFCMD]
mov r3,#0 /*等待*/
nand1:/*实际上就是一个循环,相当于等待操作*/
add r3,r3,#0x1
cmp r2,#0xa
blt nand1
nand2:
ldr r2,[r1,#oNFSTAT] /*读Nand Flash的控制器的状态寄存器*/
tst r2,#0x4 /*检查是否准备完毕*/
beq nand2
ldr r2,[r1,#oNFCONT]
/*参看手册*/
orr r2,r2,#0x02 /*取消片选*/
str r2,[r1,#oNFCONT]
/*为C代码准备堆栈空间*/
ldr sp,DW_STACK_START
mov fp,#0
/*复制代码到SDRAM中*/
ldr r0,=TEXT_BASE /*复制到ARM中的真实地址*/
mov r1,#0x0 /*代码在Nand Flash的起始地址*/
mov r2,#0x30000 /*u-boot的长度*/
bl nand_read_ll /*调用C代码读Nand Flash*/
tst r0,#0x0 /*根据返回值是否是0,如果是0,则正确操作*/
beq ok_nand_read
bad_nand_read:
loop2:
b loop2 /*无穷的循环,出错误*/
/*在Nand Flash模式下,S3C2440内部的4KRAM被映射到0x0地址处,上电以后CPU自动复制
Nand Flash的4K代码到该地址
处*/
/*比较搬移到TEXT_BASE地址处的数据和内部存储器RAM的前4K数据,如果完全相同,则
表示搬移成功*/
ok_nand_read:
mov r0,#0 /*访问地址内部的RAM:0x00000000*/
ldr r1,=TEXT_BASE /*访问地址SDRAM:TEXT_BASE处的数据*/
mov r2,#0x400 /*CPU自动搬移的4K代码用来比较,4k = 1024 * 4 byte*/
go_next:
ldr r3,[r0],#4 /*将r0的内容复制r3,然后r0指向的地址变为原来的r0 = r0 +4*/
ldr r4,[r1],#4 /*将r1的内容复制给r4,然后改变r1指向的地址r1 = r1 +4,因为每一次加载
都是4个字节*/
teq r3,r4
bne notmatch /*如果内容步相符,则指出不符合*/
/*如果数据符合,则将r2自减,当等于0时说明比较操作完成,每次减去4,是因为每次操作的数
据都是4字节*/
subs r2,r2,#4
beq stack_setup /*说明4K代码比较完成*/
bne go_next /*说明还没有比较完成*/
notmatch:
loop3:
b loop3 /*无限循环,出错*/
#endif /*CONFIG_S3C2440_NAND_BOOT*/
定义DW_STACK_START
_start_armboot: .word start_armboot
/*添加对DW_STACK_START的定义*/
.align 2
DW_STACK_START: .word STACK_BASE+STACK_SIZE-4
开启之前关闭的cpu_init_crit
#if 1
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_crit
#endif
#endif
在板子相关的文件夹中添加nand_read_ll的操作函数nand_read.c
[ root@Gong-Computer u-boot-2010.06]# gedit board/samsung/smdk2440/nand_read.c
#include <config.h>
#define BUSY 1
#define NF_BASE 0x4E000000
#define __REGb(x) (*(volatile unsigned char *)(x))
#define __REGi(x) (*(volatile unsigned int *)(x))
/*通过偏移量得到状态寄存器基地址*/
#define NFCONF __REGi(NF_BASE + 0x0 )
#define NFCONT __REGi(NF_BASE + 0x4 )
#define NFCMD __REGb(NF_BASE + 0x8 )
#define NFDATA __REGb(NF_BASE + 0x10)
#define NFSTAT __REGb(NF_BASE + 0x20)
#define NAND_CHIP_ENABLE (NFCONT &= ~(1<<1)) /*Nand 片选使能*/
#define NAND_CHIP_DISABLE (NFCONT |= (1<<1)) /*取消Nand 片选*/
#define NAND_CLEAR_RB (NFSTAT |= BUSY)
#define NAND_DETECT_RB { while(!(NFSTAT & BUSY));}
#define NAND_SECTOR_SIZE 2048
#define NAND_BLOCK_MASK (NAND_SECTOR_SIZE - 1)
/*TQ2440 NAND FLASH的5周期地址写方式 */
static void s3c2440_write_addr_lp(unsigned int addr)
{
int i;
volatile unsigned char *p = (volatile unsigned char *)&NFADDR;
int col, page;
col = addr & NAND_BLOCK_MASK;
page = addr / NAND_SECTOR_SIZE;
*p = col & 0xff; /* Column Address A0~A7 */
for(i=0; i<10; i++);
*p = (col >> 8) & 0x0f; /* Column Address A8~A11 */
for(i=0; i<10; i++);
*p = page & 0xff; /* Row Address A12~A19 */
for(i=0; i<10; i++);
*p = (page >> 8) & 0xff; /* Row Address A20~A27 */
for(i=0; i<10; i++);
*p = (page >> 16) & 0x01; /* Row Address A28~A29 */
for(i=0; i<10; i++);
}
/* low level nand read function */
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_CHIP_ENABLE; /*选中Nand 片选*/
for(i = start_addr; i < (start_addr + size);)
{
/*发出READ0 指令*/
/*NAND_CLEAR_RB*/
NFCMD = 0; //查看手册可知
s3c2440_write_addr_lp(i);
/*2k page*/
NFCMD = 0x30; //查看手册可知
NAND_DETECT_RB;
for(j=0; j < NAND_SECTOR_SIZE; j++, i++)
{
*buf = NFDATA;
buf++;
}
}
NAND_CHIP_DISABLE; /*取消片选信号*/
return 0;
}
将刚加入的函数添加到板级相关的Makefile中,这样就能是它得到编译
[root@Gong-Computer u-boot-2010.06]# vi board/samsung/smdk2440/Makefile
COBJS := smdk2440.o flash.o nand_read.o
SOBJS := lowlevel_init.o
还有一个比较重要的修改就是我们必须取保cpu_init_crit在NAND_FLASH相关的操作之前进行,因
此需要确保lowlevel_init.o 的内容在nand_read.o之前,因此需要修改链接文本文件u-boot.lds,将
lowlevel_init.o 直接写在nand_read.o前面。
[root@Gong-Computer u-boot-2010.06]# vi arch/arm/cpu/arm920t/u-boot.lds
. = ALIGN(4);
.text :
{
arch/arm/cpu/arm920t/start.o (.text)
board/samsung/smdk2440/lowlevel_init.o (.text)
board/samsung/smdk2440/nand_read.o (.text)
*(.text)
}
然后编译调试下载:
[root@Gong-Computer u-boot-2010.06]# make -d
本来打算 调试,但是发现在nor flash模式下不能调试,每次都直接死机,所以下载到nand flash中
调试模式的编译结果:
......
Must remake target `System.map'.
Invoking recipe from Makefile:426 to update target `System.map'.
Putting child 0x9817dc0 (System.map) PID 27892 on the chain.
Live child 0x9817dc0 (System.map) PID 27892
Reaping winning child 0x9817dc0 PID 27892
Removing child 0x9817dc0 PID 27892 from chain.
Successfully remade target file `System.map'.
Finished prerequisites of target file `all'.
Must remake target `all'.
利用天嵌的u-boot下载。然后切换到NADN_FLASH模式下得到下面的结果:
##### Boot for Nor Flash Main Menu #####
##### EmbedSky TFTP download mode #####
[1] Download u-boot.bin to Nand Flash
[2] Download Eboot (eboot.nb0) to Nand Flash
[3] Download Linux Kernel (zImage.bin) to Nand Flash
[4] Download stepldr.nb1 to Nand Flash
[5] Set TFTP parameters(PC IP,TQ2440 IP,Mask IP...)
[6] Download YAFFS image (root.bin) to Nand Flash
[7] Download Program (uCOS-II or TQ2440_Test) to SDRAM and Run it
[8] Boot the system
[9] Format the Nand Flash
[0] Set the boot parameters
[a] Download User Program (eg: uCOS-II or TQ2440_Test)
[b] Download LOGO Picture (.bin) to Nand Flash
[l] Set LCD Parameters
[o] Download u-boot to Nor Flash
[p] Test network (TQ2440 Ping PC's IP)
[r] Reboot u-boot
[t] Test Linux Image (zImage)
[q] Return main Menu
Enter your selection: 1
dm9000 i/o: 0x20000300, id: 0x90000a46
MAC: 0a:1b:2c:3d:4e:5f
TFTP from server 192.168.10.154; our IP address is 192.168.10.122
Filename 'u-boot.bin'.
Load address: 0x30000000
Loading: T #######
done
Bytes transferred = 101628 (18cfc hex)
NAND erase: device 0 offset 0x0, size 0x40000
Erasing at 0x20000 -- 100% complete.
OK
NAND write: device 0 offset 0x0, size 0x18cfc
Writing data at 0x18800 -- 100% complete.
101628 bytes written: OK
切换到NAND FLASH模式下:
U-Boot 2010.06 (Oct 07 2011 - 21:09:41)
DRAM: 64 MiB
Flash: 2 MiB
*** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
Net: CS8900-0
u-boot@SMDK2440 # nand info
Unknown command 'nand' - try 'help'
u-boot@SMDK2440 #
nand info不支持,说明关于NAND FLASH的命令还没有添加,这是对NAND Flash移植的第二部分。
第二阶段的移 植主要是C语言的移植,入口函数是 start_armboot 函数,其中它调用了board.c这个板
级密切相关的函数。其中的代码就有关于nand Flash 的宏等。
查找函数board.c
[root@Gong-Computer u-boot-2010.06]# find -name board.c
./arch/i386/lib/board.c
./arch/mips/lib/board.c
./arch/microblaze/lib/board.c
./arch/avr32/lib/board.c
./arch/arm/cpu/arm_cortexa8/omap3/board.c
./arch/arm/lib/board.c
./arch/blackfin/lib/board.c
./arch/sh/lib/board.c
./arch/sparc/lib/board.c
./arch/nios2/lib/board.c
./arch/powerpc/lib/board.c
./arch/m68k/lib/board.c
[root@Gong-Computer u-boot-2010.06]# vi arch/arm/lib/board.
board.c board.o
[root@Gong-Computer u-boot-2010.06]# vi arch/arm/lib/board.c
....
#if defined(CONFIG_CMD_NAND)
puts ("NAND: ");
nand_init(); /* go init the NAND */
#endif
因此可知需要添加相应的宏 CONFIG_CMD_NAND,具体的后面会执行
添加nand flash操作的相关函数。
[root@Gong-Computer u-boot-2010.06]# gedit drivers/mtd/nand/s3c2440_nand.c
#include <common.h>
#if 0
#define DEBUGN printf
#else
#define DEBUGN(x, args ...) {}
#endif
#include <nand.h>
#include <asm/arch/s3c24x0_cpu.h>
#include <asm/io.h>
#define __REGb(x) (*(volatile unsigned char *)(x))
#define __REGi(x) (*(volatile unsigned int *)(x))
#define NF_BASE 0x4e000000 /*Nand 配置寄存器基地址*/
#define NFCONF __REGi(NF_BASE + 0x0) /*偏移后还是得到配置寄存器基地址*/
#define NFCONT __REGi(NF_BASE + 0x4) /*偏移后得到Nand 控制寄存器基地址*/
#define NFCMD __REGb(NF_BASE + 0x8) //偏移后得到Nand 指令寄存器基地址
#define NFADDR __REGb(NF_BASE + 0xc) //偏移后得到Nand 地址寄存器基地址
#define NFDATA __REGb(NF_BASE + 0x10) //偏移后得到Nand 数据寄存器基地址
#define NFMECCD0 __REGi(NF_BASE + 0x14) //偏移后得到Nand 主数据区域ECC0 寄存器基地址
#define NFMECCD1 __REGi(NF_BASE + 0x18) //偏移后得到Nand 主数据区域ECC1 寄存器基地址
#define NFSECCD __REGi(NF_BASE + 0x1C) //偏移后得到Nand 空闲区域ECC 寄存器基地址
#define NFSTAT __REGb(NF_BASE + 0x20) //偏移后得到Nand 状态寄存器基地址
#define NFSTAT0 __REGi(NF_BASE + 0x24) //偏移后得到Nand ECC0 状态寄存器基地址
#define NFSTAT1 __REGi(NF_BASE + 0x28) //偏移后得到Nand ECC1 状态寄存器基地址
#define NFMECC0 __REGi(NF_BASE + 0x2C) //偏移后得到Nand 主数据区域ECC0 状态寄存器基地址
#define NFMECC1 __REGi(NF_BASE + 0x30) //偏移后得到Nand 主数据区域ECC1 状态寄存器基地址
#define NFSECC __REGi(NF_BASE + 0x34) //偏移后得到Nand 空闲区域ECC 状态寄存器基地址
#define NFSBLK __REGi(NF_BASE + 0x38) //偏移后得到Nand 块开始地址
#define NFEBLK __REGi(NF_BASE + 0x3c) //偏移后得到Nand 块结束地址
#define S3C2440_NFCONT_nCE (1<<1)
#define S3C2440_ADDR_NALE 0x0c
#define S3C2440_ADDR_NCLE 0x08
ulong IO_ADDR_W = NF_BASE;
static void s3c2440_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
{
struct nand_chip *chip = mtd->priv;
DEBUGN("hwcontrol(): 0x%02x 0x%02x/n", cmd, ctrl);
if (ctrl & NAND_CTRL_CHANGE) {
IO_ADDR_W = NF_BASE;
if (!(ctrl & NAND_CLE))
//要写的是地址
IO_ADDR_W |= S3C2440_ADDR_NALE;
if (!(ctrl & NAND_ALE))
//要写的是命令
IO_ADDR_W |= S3C2440_ADDR_NCLE;
if (ctrl & NAND_NCE)
NFCONT &= ~S3C2440_NFCONT_nCE; //使能nand flash
else
NFCONT |= S3C2440_NFCONT_nCE; //禁止nand flash
}
if (cmd != NAND_CMD_NONE)
writeb(cmd,(void *)IO_ADDR_W);
}
static int s3c2440_dev_ready(struct mtd_info *mtd)
{
DEBUGN("dev_ready/n");
return (NFSTAT & 0x01);
}
int board_nand_init(struct nand_chip *nand)
{
u_int32_t cfg;
u_int8_t tacls, twrph0, twrph1;
struct s3c24x0_clock_power * const clk_power =s3c24x0_get_base_clock_power();
DEBUGN("board_nand_init()/n");
clk_power->CLKCON |= (1 << 4);
twrph0 = 3; twrph1 = 0; tacls = 0;
cfg = (tacls<<12)|(twrph0<<8)|(twrph1<<4)|(3<<2)|(1<<1)|(0<<0);
NFCONF = cfg;
//cfg = (1<<6)|(1<<4)|(0<<1)|(1<<0);
cfg = (1<<4)|(0<<1)|(1<<0);
NFCONT = cfg;
/* initialize nand_chip data structure */
nand->IO_ADDR_R = nand->IO_ADDR_W = (void *)0x4e000010;
/* read_buf and write_buf are default */
/* read_byte and write_byte are default */
/* hwcontrol always must be implemented */
nand->cmd_ctrl = s3c2440_hwcontrol;
nand->dev_ready = s3c2440_dev_ready;
nand->ecc.mode = NAND_ECC_SOFT;
return 0;
}
将加入的函数添加到可编译的范围里。
[root@Gong-Computer u-boot-2010.06]# vi drivers/mtd/nand/Makefile
/*将新添加的函数加入到编译范围之内*/
COBJS-y += s3c2440_nand.o
COBJS-$(CONFIG_NAND_S3C2440) += s3c2440_nand.o
添加默认命令:
[root@Gong-Computer u-boot-2010.06]# vi include/config_cmd_default.h
26 #define CONFIG_CMD_ITEST /* Integer (and string) test */
27
28 #define CONFIG_CMD_NAND /* NAND 相关的操作*/
29
30 #ifndef CONFIG_SYS_NO_FLASH
42 #define CONFIG_CMD_SAVEENV /* saveenv */
/*新添加的命令*/
43 #define CONFIG_CMD_EDITENV /* editenv */
44 #define CONFIG_CMD_ASKENV /* askenv */
当然在smdk2440.h中也可以添加nand flash的操作,但是CONFIG_CMD_NAND需要定义在较前的位
置,至少在CONFIG_CMD_SAVEENV的前面
。原因不知道,不然会出错误。同时需要定义成这样:
#define CONFIG_CMD_NAND 1,其实本质上都是相同的。
在smdk2440.h中添加保存环境变量的相关参数
[root@Gong-Computer u-boot-2010.06]# vi include/configs/smdk2440.h
209 #if defined(CONFIG_CMD_NAND)
210 /*添加将环境变量保存到FLASH的宏定义*/
211 #define CONFIG_ENV_IS_IN_NAND 1 /*指明将环境变量保存在Nand Flash中*/
212 #define CONFIG_ENV_OFFSET 0x40000 /*将环境变量保存到nand 中的0x40000 位置*/
213 #define CONFIG_ENV_SIZE 0x20000 /* Total Size of Environment Sector*/
214
215 /*这里的参数大小是根据实际芯片的扇区大小确定的,由于NAND FLASH中的u-boot占用了
前256K
216 *这需要根据实际的情况来分配大小。希望引起注意,不要前后考虑不一致。
217 */
218 /*将环境变量保存到NAND FLASH中,因此需要注释掉这两行*/
219 #else
220 #define CONFIG_ENV_IS_IN_FLASH 1
221 #define CONFIG_ENV_SIZE 0x10000 /* Total Size of Environment Sector */
222 #endif
然后编译:
[root@Gong-Computer u-boot-2010.06]# make
make -C drivers/mtd/nand/
make[1]: Entering directory `/opt/u-boot-2010.06/drivers/mtd/nand'
Makefile:35: *** missing separator. Stop.
make[1]: Leaving directory `/opt/u-boot-2010.06/drivers/mtd/nand'
make: *** [drivers/mtd/nand/libnand.a] Error 2
这个错误说明是Makefile存在问题,而且在35行,发现原来是注释的符号错了,修改为
#/*将新添加的函数加入到编译范围之内*/
 
[root@Gong-Computer u-boot-2010.06]# make -d
........
-Wall -Wstrict-prototypes -fno-stack-protector \
-o nand.o nand.c -c
Putting child 0x93cc850 (nand.o) PID 18851 on the chain.
Live child 0x93cc850 (nand.o) PID 18851
nand.c:34: error: 'CONFIG_SYS_MAX_NAND_DEVICE' undeclared here (not in a function)
nand.c:37: error: 'CONFIG_SYS_NAND_BASE' undeclared here (not in a function)
Reaping losing child 0x93cc850 PID 18851
make[1]: *** [nand.o] Error 1
Removing child 0x93cc850 PID 18851 from chain.
make[1]: Leaving directory `/opt/u-boot-2010.06/drivers/mtd/nand'
Reaping losing child 0x98c6d58 PID 18690
make: *** [drivers/mtd/nand/libnand.a] Error 2
Removing child 0x98c6d58 PID 18690 from chain.
重新编译发现还是存在问题,这说明刚才的修改存在问题,而且问题比较严重,不知道怎么去修改,
需要查看Nand_flash相关的代码,这时候采用Source Insight实现代码的跟踪是比较有优势的。虽然
提示出来了,但是还是不是很清楚,通过查看源码同时比较其他外设更加丰富的实验板发现在板级的
头文件中smdk2440.h中需要添加上面缺少的两个宏。这两个值的具体值是什么还是需要查看源码,
或者对比以下其他开发板中的具体值,特别是 CONFIG_SYS_NAND_BASE的值需要参考修改
添加宏如下:
236 #define CONFIG_SYS_MAX_NAND_DEVICE 1 /*芯片的个数*/
237 #define CONFIG_SYS_NAND_BASE 0x4E000000 /*是指控制器在内存中的基地址*/
重新编译和测试:
[root@Gong-Computer u-boot-2010.06]# make -d
Invoking recipe from Makefile:426 to update target `System.map'.
Putting child 0x99070f0 (System.map) PID 27598 on the chain.
Live child 0x99070f0 (System.map) PID 27598
Reaping winning child 0x99070f0 PID 27598
Removing child 0x99070f0 PID 27598 from chain.
Successfully remade target file `System.map'.
Finished prerequisites of target file `all'.
Must remake target `all'.
Successfully remade target file `all'.
下载到开发板的NAND FLASH,然后切换到NAND FLASH模式下。
##### Boot for Nor Flash Main Menu #####
##### EmbedSky TFTP download mode #####
[1] Download u-boot.bin to Nand Flash
[2] Download Eboot (eboot.nb0) to Nand Flash
[3] Download Linux Kernel (zImage.bin) to Nand Flash
[4] Download stepldr.nb1 to Nand Flash
[5] Set TFTP parameters(PC IP,TQ2440 IP,Mask IP...)
[7] Download Program (uCOS-II or TQ2440_Test) to SDRAM and Run it
[8] Boot the system
[9] Format the Nand Flash
[0] Set the boot parameters
[a] Download User Program (eg: uCOS-II or TQ2440_Test)
[b] Download LOGO Picture (.bin) to Nand Flash
[l] Set LCD Parameters
[o] Download u-boot to Nor Flash
[p] Test network (TQ2440 Ping PC's IP)
[r] Reboot u-boot
[t] Test Linux Image (zImage)
[q] Return main Menu
Enter your selection: 1
dm9000 i/o: 0x20000300, id: 0x90000a46
MAC: 0a:1b:2c:3d:4e:5f
TFTP from server 192.168.10.154; our IP address is 192.168.10.122
Filename 'u-boot.bin'.
Load address: 0x30000000
Loading: T ##########
done
Bytes transferred = 140064 (22320 hex)
NAND erase: device 0 offset 0x0, size 0x40000
Erasing at 0x20000 -- 100% complete.
OK
NAND write: device 0 offset 0x0, size 0x22320
Writing data at 0x22000 -- 100% complete.
140064 bytes written: OK
U-Boot 2010.06 (Oct 08 2011 - 10:44:25)
DRAM: 64 MiB
Flash: 2 MiB
NAND: 256 MiB
In: serial
Out: serial
Err: serial
Net: CS8900-0
Hit any key to stop autoboot: 0
Unknown command 'boot_zImage' - try 'help'
u-boot@SMDK2440 # nand info /*NAND 参数正确*/
Device 0: NAND 256MiB 3,3V 8-bit, sector size 128 KiB
u-boot@SMDK2440 # saveenv
Saving Environment to NAND... /*保存在可NAND*/
Erasing Nand...
Erasing at 0x40000 -- 100% complete.
Writing to Nand... done
u-boot@SMDK2440 #
以上说明Nand FLASH移植成功。
但是还是存在一个问题就是我们的Nor Flash将不会作为启动项,我们注释掉了nor Flash搬移的过程。
如果只是作为引导这个时候已经可以了,可以直接跳转到网络的移植方面。 但是毕竟TQ 提供了双
动,关于双启动的方法我暂时还在实验阶段,需要正在调试过程中。
双启动的原理网上的大牛Tekkaman 已经作出了解释,自己参看分析。
简单来说就是首先判断内存控制器的OM[1:0]的值判断在nand Flash模式还是在nor Flash中,具体的
判断方法就是读BWSCON [2:1]位。基本的框架如下所示,具体实现分析代码。
# define BWSCON 0x48000000
ldr r0,=BWSCON
ldr r0,[r0]
and r0,r0,#6
cmp r0, #0
bne relocate
///
//nand_boot
//Nand 搬移代码

relocate:
//nor_boot
//Nor 搬移代码

接测NAND FLASH中坏块的方法:
Samsung makes sure that either the 1st or 2nd page of every initial invalid block has non-FFh data at the
column address of 2048



(5)



网络的移植,由于TQ2440的网卡是DM9000,而SMDK2410的网卡是CS8900,因此需要移植,
DM9000的一些代码在net文件夹中已经存在,只需要对照CS8900进行移植。
首先板级屏蔽掉CS8900的宏,添加DM9000相关的宏
57 /*
58 * Hardware drivers
59 */
60 /*屏蔽CS8900的宏定义*/
61 #if 0
62 #define CONFIG_NET_MULTI
63 #define CONFIG_CS8900 /* we have a CS8900 on-board */
64 #define CONFIG_CS8900_BASE 0x19000300
65 #define CONFIG_CS8900_BUS16 /* the Linux driver does accesses as sho rts */
66 #endif
68 /*添加DM9000的宏定义*/
69 #define CONFIG_DRIVER_DM9000 1
70 #define CONFIG_NET_MULTI 1
71 #define CONFIG_DM9000_NO_SROM 1
72 #define CONFIG_DM9000_BASE 0x20000300 /*网卡片选地址*/
73 #define DM9000_IO CONFIG_DM9000_BASE
74 #define DM9000_DATA (CONFIG_DM9000_BASE + 4) /*网卡数据地址*/
102 /*添加ping命令*/
103 #define CONFIG_CMD_PING
104 /*添加网卡支持命令*/
105 #define CONFIG_CMD_NET
106 /*添加NFS命令*/
107 #define CONFIG_CMD_NFS
121 /*恢复被注销的网卡MAC地址*/
122 #define CONFIG_ETHADDR 08:00:3e:26:0a:5b
123
124 /*子网掩码*/
125 #define CONFIG_NETMASK 255.255.255.0
126 /*添加TQ2440的IP地址*/
127 #define CONFIG_IPADDR 192.168.10.122
128 /*添加主机IP地址*/
129 #define CONFIG_SERVERIP 192.168.10.154
 
对了还需要添加初始化代码
/*添加DM9000的初始化代码*/
vi board/samsung/smdk2440/smdk2440.c中,查找CS8900相关的即可实现
编译下载测试:
##### Boot for Nor Flash Main Menu #####
##### EmbedSky TFTP download mode #####
[1] Download u-boot.bin to Nand Flash
[2] Download Eboot (eboot.nb0) to Nand Flash
[3] Download Linux Kernel (zImage.bin) to Nand Flash
[4] Download stepldr.nb1 to Nand Flash
[5] Set TFTP parameters(PC IP,TQ2440 IP,Mask IP...)
[6] Download YAFFS image (root.bin) to Nand Flash
[7] Download Program (uCOS-II or TQ2440_Test) to SDRAM and Run it
[8] Boot the system
[9] Format the Nand Flash
[0] Set the boot parameters
[a] Download User Program (eg: uCOS-II or TQ2440_Test)
[b] Download LOGO Picture (.bin) to Nand Flash
 
[o] Download u-boot to Nor Flash
[p] Test network (TQ2440 Ping PC's IP)
[r] Reboot u-boot
[t] Test Linux Image (zImage)
[q] Return main Menu
Enter your selection: 1
dm9000 i/o: 0x20000300, id: 0x90000a46
MAC: 0a:1b:2c:3d:4e:5f
TFTP from server 192.168.10.154; our IP address is 192.168.10.122
Filename 'u-boot.bin'.
Load address: 0x30000000
Loading: T ##########
done
Bytes transferred = 142244 (22ba4 hex)
NAND erase: device 0 offset 0x0, size 0x40000
Erasing at 0x20000 -- 100% complete.
OK
NAND write: device 0 offset 0x0, size 0x22ba4
Writing data at 0x22800 -- 100% complete.
142244 bytes written: OK
Enter your selection:
U-Boot 2010.06 (Oct 08 2011 - 19:17:17)
DRAM: 64 MiB
Flash: 2 MiB
NAND: 256 MiB
In: serial
Out: serial
Err: serial
Net: dm9000 /*DM9000移植成功*/
Hit any key to stop autoboot: 0
Unknown command 'boot_zImage' - try 'help'
u-boot@SMDK2440 # tftpboot 0x30000000 u-boot.bin
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 0a:1b:2c:3d:4e:5f
could not establish link
Using dm9000 device
TFTP from server 192.168.10.154; our IP address is 192.168.10.122 /*TFTP成功*/
Filename 'u-boot.bin'.
Load address: 0x30000000
Loading: ##########
done
Bytes transferred = 142244 (22ba4 hex)
u-boot@SMDK2440 # go 0x30000000
## Starting application at 0x30000000 ...
u-boot@SMDK2440 # nfs 0x30000000 192.168.10.154:/opt/filesystem/zImage.bin /*NFS支持*/
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 0a:1b:2c:3d:4e:5f
could not establish link
Using dm9000 device
File transfer via NFS from server 192.168.10.154; our IP address is 192.168.10.2
Filename '/opt/filesystem/zImage.bin'.
Load address: 0x30000000
Loading: *
done
u-boot@SMDK2440 # go 0x30000000
## Starting application at 0x30000000 ...
U-Boot 2010.06 (Oct 08 2011 - 19:17:17)
DRAM: 64 MiB
Flash: 2 MiB
NAND: 256 MiB
In: serial
Out: serial
Err: serial
Net: dm9000
Hit any key to stop autoboot: 0
u-boot@SMDK2440 #
结合网上的论述,建议将一些代码屏蔽掉,避免出更多的问题,主要是一些错误标示和延迟时间相关
的东西。首先,现在虽然成功了,但是还存在一些问题就是启动网络的服务非常的慢,需要等较长的
时间,同时结合别人的经验,我也照着做了修改。
1、修改网卡的DM9000的驱动bug
/*屏蔽掉网卡报coudle not estable link 的错误*/
[root@Gong-Computer u-boot-2010.06]# vi drivers/net/dm9000x.c
static int dm9000_init(struct eth_device *dev, bd_t *bd)
......
#if 0
i = 0;
while (!(phy_read(1) & 0x20)) { /* autonegation complete bit */
udelay(1000);
i++;
if (i == 10000) {
printf("could not establish link\n");
return 0;
}
}
#endif
2屏蔽掉dm9000_halt 函数中的内容
[root@Gong-Computer u-boot-2010.06]# vi drivers/net/dm9000x.c
static void dm9000_halt(struct eth_device *netdev)
{
/*屏蔽内容,但不能屏蔽函数*/
#if 0
DM9000_DBG("%s\n", __func__);
/* RESET devie */
phy_write(0, 0x8000); /* PHY RESET */
DM9000_iow(DM9000_GPR, 0x01); /* Power-Down PHY */
DM9000_iow(DM9000_IMR, 0x80); /* Disable all interrupt */
DM9000_iow(DM9000_RCR, 0x00); /* Disable RX */
#endif
}
编译下载,下载可以采用之前移植的nand flash和网络进行烧写了,而不用再使用TQ2440提供的uboot
命令了。具体操作如下:
U-Boot 2010.06 (Oct 09 2011 - 14:42:27)
DRAM: 64 MiB
Flash: 2 MiB
NAND: 256 MiB
In: serial
Out: serial
Err: serial
Net: dm9000
Hit any key to stop autoboot: 0
Unknown command 'boot_zImage' - try 'help'
u-boot@SMDK2440 # tftp 0x30000000 u-boot_netbug.bin
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 0a:1b:2c:3d:4e:5f
could not establish link
Using dm9000 device
TFTP from server 192.168.10.154; our IP address is 192.168.10.122
Filename 'u-boot_netbug.bin'.
Load address: 0x30000000
Loading: ##########
done
Bytes transferred = 144512 (23480 hex)
u-boot@SMDK2440 # nand erase 0x0 0x40000
NAND erase: device 0 offset 0x0, size 0x40000
Erasing at 0x20000 -- 100% complete.
OK
u-boot@SMDK2440 # nand write 0x30000000 0x0 0x40000
NAND write: device 0 offset 0x0, size 0x40000
262144 bytes written: OK
u-boot@SMDK2440 #
Nand Flash的写入一定是先擦除再写入,这是Flash的特点。
重启以后得到如下的效果:
U-Boot 2010.06 (Oct 09 2011 - 19:45:11)
DRAM: 64 MiB
Flash: 2 MiB
NAND: 256 MiB
In: serial
Out: serial
Err: serial
Net: dm9000
Hit any key to stop autoboot: 0
Unknown command 'boot_zImage' - try 'help'
u-boot@SMDK2440 #
测试网络命令:
u-boot@SMDK2440 # ping 192.168.10.154
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 0a:1b:2c:3d:4e:5f
operating at unknown: 0 mode
Using dm9000 device
host 192.168.10.154 is alive
u-boot@SMDK2440 # tftp 0x30000000 uImage.img
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 0a:1b:2c:3d:4e:5f
operating at unknown: 0 mode
Using dm9000 device
TFTP from server 192.168.10.154; our IP address is 192.168.10.122
Filename 'uImage.img'.
Load address: 0x30000000
Loading: #################################################################
#################################################################
##################################
done
Bytes transferred = 2400432 (24a0b0 hex)
这个时候的速度相比之前要快很多。
但是出现了新的问题,NFS不能实现了,具体参看下面的问题。
u-boot@SMDK2440 # nfs 0x30000000 192.168.10.154:/opt/filesystem
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 0a:1b:2c:3d:4e:5f
operating at unknown: 0 mode
Using dm9000 device
File transfer via NFS from server 192.168.10.154; our IP address is 192.168.10.122
Filename '/opt/filesystem'.
Load address: 0x30000000
Loading: T *** ERROR: Cannot mount
T T T T T T T T T T T T T T T T T T T T T T T T T T T T T
Retry count exceeded; starting again
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 0a:1b:2c:3d:4e:5f
operating at unknown: 0 mode
Using dm9000 device
File transfer via NFS from server 192.168.10.154; our IP address is 192.168.10.122
Filename '/opt/filesystem'.
Load address: 0x30000000
Loading: *** ERROR: Cannot mount
T T T T T T T T T T T T T T T T T T T T T T T T T T T T T
根据网上的说法我又修改了net/nfs.c
[root@Gong-Computer u-boot-2010.06]# vi net/nfs.c
nfs_umountall_reply (uchar *pkt, unsigned len)
{
struct rpc_t rpc_pkt;
debug("%s\n", __func__);
memcpy ((unsigned char *)&rpc_pkt, pkt, len);
/*我修改过*/
// if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
if ((ntohl(rpc_pkt.u.reply.id)+1) != rpc_id)
return -1;
if (rpc_pkt.u.reply.rstatus ||
rpc_pkt.u.reply.verifier ||
rpc_pkt.u.reply.astatus) {
return -1;
}
fs_mounted = 0;
memset (dirfh, 0, sizeof(dirfh));
return 0;
}
u-boot@SMDK2440 # tftp 0x30000000 u-boot_nfs.bin
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 0a:1b:2c:3d:4e:5f
operating at unknown: 0 mode
Using dm9000 device
TFTP from server 192.168.10.154; our IP address is 192.168.10.122
Filename 'u-boot_nfs.bin'.
Load address: 0x30000000
Loading: ##########
done
Bytes transferred = 144520 (23488 hex)
u-boot@SMDK2440 # nand erase 0x0 0x40000
NAND erase: device 0 offset 0x0, size 0x40000
Erasing at 0x20000 -- 100% complete.
OK
u-boot@SMDK2440 # nand write 0x30000000 0x0 0x40000
NAND write: device 0 offset 0x0, size 0x40000
262144 bytes written: OK
u-boot@SMDK2440 #
U-Boot 2010.06 (Oct 09 2011 - 20:10:13)
DRAM: 64 MiB
Flash: 2 MiB
NAND: 256 MiB
In: serial
Out: serial
Err: serial
Net: dm9000
Hit any key to stop autoboot: 0
Unknown command 'boot_zImage' - try 'help'
u-boot@SMDK2440 # nfs 0x30000000 192.168.10.154:/opt/filesystem/u-boot.bin
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 0a:1b:2c:3d:4e:5f
operating at unknown: 0 mode
Using dm9000 device
File transfer via NFS from server 192.168.10.154; our IP address is 192.168.10.122
Filename '/opt/filesystem/u-boot.bin'.
Load address: 0x30000000
Loading: T #############################*** ERROR: Cannot umount
我将刚才改过的地方再改了回来,竟然发现能够加载了,可能是因为我的文件数据太大(>64M),
导致RAM区不能正常的接受,因此不能加载成功,但是小的数据能够实现文件的加载,如下图所示。
u-boot@SMDK2440 # nfs 0x30000000 192.168.10.154:/opt/filesystem/u-boot.bin
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 0a:1b:2c:3d:4e:5f
operating at unknown: 0 mode
Using dm9000 device
File transfer via NFS from server 192.168.10.154; our IP address is 192.168.10.122
Filename '/opt/filesystem/u-boot.bin'.
Load address: 0x30000000
Loading: #############################
done
Bytes transferred = 144520 (23488 hex)
实质上此时已经可以用于linux操作系统的移植,接下来我们进行移植。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值