全部博文(218)
分类: 嵌入式
2011-11-04 14:31:04
u-boot-2011.09在ST2410上的移植之启用CS8900网卡功能
接上篇,启用CS8900网卡功能,实现tftp下载(红色部分为我添加的,蓝色为修改的)
u-boot本身有cs8900网卡驱动程序,所以需要修改的地方不多。由于数据通过总线传送,所以要注意地址空间的配置和总线的配置。
1)、首先修改include/configs/st2410.h文件
57 #define CONFIG_NET_MULTI
58 #define CONFIG_CS8900 /* 前文注释,这里再把它打开we have a CS8900 on-board */
59 #define CONFIG_CS8900_BASE 0x19000300
60 #define CONFIG_CS8900_BUS16 /* the Linux driver does accesses as shorts */
确定网卡的基地址,我的开发板CS8900接在nGCS3上,而且是A24引脚为高时使能CS8900A的IO模式,同这里配置的一样,所以代码不用修改。
117 #define CONFIG_ETHADDR 08:00:3e:26:0a:5b //by add
118 #define CONFIG_NETMASK 255.255.255.0
119 #define CONFIG_IPADDR 192.168.1.200
120 #define CONFIG_SERVERIP 192.168.1.91
CONFIG_IPADDR 宏是你开发板的IP地址。tftp client
CONFIG_SERVERIP 宏是你安装tftp server的系统的IP
2) BWSCON寄存器的设置,BANKCON3寄存器的设置,这里不用修改,列出的目的是对不同网卡时要在这里修改,由于网卡占用的是nGCS3之上地址,所以需要设置/board/st2410/lowlevel.S文件中相应寄存器的值:
#define B3_BWSCON (DW16 + WAIT + UBLB)
#define B3_Tacs 0x0 /* 0clk */
#define B3_Tcos 0x3 /* 4clk */
#define B3_Tacc 0x7 /* 14clk */
#define B3_Tcoh 0x1 /* 1clk */
#define B3_Tah 0x0 /* 0clk */
#define B3_Tacp 0x3 /* 6clk */
#define B3_PMC 0x0 /* normal */
3) 设置完毕后可以重新编译。
ST2410 # tftp 0x32000000 u-boot.bin
TFTP from server 192.168.1.91; our IP address is 192.168.1.200
Filename 'u-boot.bin'.
Load address: 0x32000000
Loading: #################################################################
############################
done
Bytes transferred = 474216 (73c68 hex)
ST2410 # go 0x32000000
## Starting application at 0x32000000 ...??
U-Boot 2011.09 (Oct 28 2011 - 07:27:57)
U-Boot code: 32000000 -> 3206B500 BSS: -> 320AEBE4
monitor len: 000AEBE4
ramsize: 04000000
TLB table at: 33ff0000
Top of RAM usable for U-Boot at: 33ff0000
Reserving 698k for U-Boot at: 33f41000
Reserving 4160k for malloc() at: 33b31000
Reserving 24 Bytes for Board Info at: 33b30fe8
Reserving 120 Bytes for Global Data at: 33b30f70
New Stack Pointer is: 33b30f60
RAM Configuration:
Bank #0: 30000000 64 MiB
relocation Offset is: 01f41000
WARNING: Caches not enabled
monitor flash len: 00073C68
dram_bank_mmu_setup: bank: 0
Now running in RAM - U-Boot at: 33f41000
NAND: board_nand_init()
end of nand_init
hwcontrol(): 0xff 0x83
hwcontrol(): 0xffffffff 0x81
raise: Signal # 8 caught
raise: Signal # 8 caught
dev_ready
hwcontrol(): 0x90 0x83
hwcontrol(): 0x00 0x85
hwcontrol(): 0xffffffff 0x81
raise: Signal # 8 caught
raise: Signal # 8 caught
dev_ready
hwcontrol(): 0x90 0x83
hwcontrol(): 0x00 0x85
hwcontrol(): 0xffffffff 0x81
raise: Signal # 8 caught
raise: Signal # 8 caught
dev_ready
hwcontrol(): 0xffffffff 0x80
64 MiB
*** Warning - bad CRC, using default environment
Destroy Hash Table: 33fae068 table = (null)
Create Hash Table: N=79
INSERT: table 33fae068, filled 1/79 rv 33b32438 ==> name="bootdelay" value="5"
INSERT: table 33fae068, filled 2/79 rv 33b32378 ==> name="baudrate" value="115200"
INSERT: table 33fae068, filled 3/79 rv 33b32474 ==> name="ethaddr" value="08:00:3e:26:0a:5b"
INSERT: table 33fae068, filled 4/79 rv 33b32348 ==> name="ipaddr" value="192.168.1.200"
INSERT: table 33fae068, filled 5/79 rv 33b32450 ==> name="serverip" value="192.168.1.91"
INSERT: table 33fae068, filled 6/79 rv 33b325dc ==> name="netmask" value="255.255.255.0"
INSERT: free(data = 33b322a0)
INSERT: done
In: serial
Out: serial
Err: serial
Net: raise: Signal # 8 caught
CS8900-0
### main_loop entered: bootdelay=5
### main_loop: bootcmd="
ST2410 #
去掉“raise: Signal # 8 caught”
http://blog.csdn.net/zhaocj/article/details/6667758
在开发板上电后,会出现“raise: Signal # 8 caught”。这虽然不影响系统的正常运行,但也是一个不小的bug,也许会影响以后u-boot-2011.06的移植,因此我们有必要把这个bug去除掉。
其实把这个bug去掉也很简单,就是把time.c(在arch/arm/cpu/arm920t/s3c24x0/目录下)这个文件中的四个全局变量用gd这个数据结构中的4个相关成员代替就可以了,具体的就是:
timer_load_val用gd->timer_rate_hz替代;
timer_clk用gd->tbl替代;
timestamp用gd->timer_reset_value替代;
lastdec用gd->lastinc替代。
下面我们就列出time.c这个文件具体需要修改的地方:
去掉第38行和第39行关于timer_load_val和timer_clk这两个变量的声明,并加上下面代码:
38:DECLARE_GLOBAL_DATA_PTR;
去掉第49行和第50行关于timestamp和lastdec这两个变量的声明;
去掉第60行至第68行语句(if (timer_load_val == 0)的判断内容),改为:
60:gd->timer_rate_hz = get_PCLK() /(2*16*100);
61:gd->tbl = get_PCLK() / (2 * 16);
剩下需要修改的内容就是具体的变量替换,其中每条语句前面的行号为源文件的行号:
70 gd->lastinc = gd->timer_rate_hz;//lastdec = timer_load_val;
71:writel(gd->timer_rate_hz,&timers->tcntb4);
78:gd->timer_reset_value = 0;
97 tmo *= (timer_load_val * 100);
108 return tmr / (gd->tbl / CONFIG_SYS_HZ);//return tmr / (timer_clk / CONFIG_SYS_HZ);
119 tmo *= (gd->timer_rate_hz * 100);//tmo *= (timer_load_val * 100);
122 tmo = usec * (gd->timer_rate_hz * 100);//tmo = usec * (timer_load_val * 100);
142 if (gd->lastinc >= now) {//if (lastdec >= now) {
144 gd->timer_reset_value += gd->lastinc - now;//timestamp += lastdec - now;
147 gd->timer_reset_value += gd->lastinc + gd->timer_rate_hz - now;//timestamp += lastdec + timer_load_val - now;
149 gd->lastinc = now;//lastdec = now;
150
151 return gd->timer_reset_value;//return timestamp;
163 tbclk = gd->timer_rate_hz * 100;//tbclk = timer_load_val * 100;
通过上述的修改,我们再上电启动后,就不会再有raise: Signal # 8 caught了。
4) tftp测试:
CONFIG_DRIVER_CS8900的定义使得cs8900.c可以被编译(当然还得定义CFG_CMD_NET才行),因为 cs8900.c中在函数定义的前面就有编译条件判断:#ifdef CONFIG_DRIVER_CS8900 如果这个选项没有定义,整个cs8900.c就不会被编译了。
而常数参量CS8900_BASE则用在cs8900.h头文件中定义各个功能寄存器的地址。u-boot的CS8900工作在IO模式下,只要给定IO寄存器在内存中映射的基地址,其余代码就与平台无关了。
u-boot的命令也是通过目标板的配置头文件来配置的,比如要添加ping命令,就必须添加CFG_CMD_NET和CFG_CMD_PING才行。不然common/cmd_net.c就不会被编译了。
从这里我可以这么认为,u-boot工程可配置性和移植性可以分为两层:
一是由makefile来实现,配置工程要包含的文件和文件夹上,用什么编译器。
二是由目标板的配置头文件来实现源码级的可配置性,通用性。主要使用的是#ifdef #else #endif 之类来实现的。
注意:一定要将引导代码烧写到flash中引导,直接在内存调试阶段不能初始化网卡。
二)网络测试及tftp下载
在CentOS 6.0 下安装配置tftp服务 过程如下:
1. 挂载CDROM
[root@localhost mnt]# ls /dev/cdrom
/dev/cdrom
[root@localhost mnt]# mount /dev/cdrom /mnt/cdrom/
2. 安装xinetd
[root@localhost cdrom]# cd CentOS/
[root@localhost CentOS]# ls *inet*
xinetd-2.3.14-10.el5.i386.rpm
[root@localhost CentOS]# rpm -ivh xinetd-2.3.14-10.el5.i386.rpm
3. 安装tftp
[root@localhost CentOS]# ls *ftp*
ftp-0.17-35.el5.i386.rpm tftp-0.42-3.1.el5.centos.i386.rpm
gftp-2.0.18-3.2.2.i386.rpm tftp-server-0.42-3.1.el5.centos.i386.rpm
lftp-3.5.1-2.fc6.i386.rpm vsftpd-2.0.5-12.el5.i386.rpm
[root@localhost CentOS]# rpm -ivh tftp-server-0.42-3.1.el5.centos.i386.rpm
[root@localhost CentOS]# rpm -ivh tftp-0.42-3.1.el5.centos.i386.rpm
4. 安装完成,查看一下
[root@localhost CentOS]# rpm -qa|grep tftp
tftp-server-0.42-3.1.el5.centos
tftp-0.42-3.1.el5.centos
5. 修改配置文件
[root@localhost CentOS]# vim /etc/xinetd.d/tftp
# default: off
# description: The tftp server serves files using the trivial file transfer \
# protocol. The tftp protocol is often used to boot diskless \
# workstations, download configuration files to network-aware printers, \
# and to start the installation process for some operating systems.
service tftp
{
socket_type = dgram
protocol = udp
wait = yes
user = root
server = /usr/sbin/in.tftpd
server_args = -s /tftpboot
disable = no
per_source = 11
cps = 100 2
flags = IPv4
}
6. 重启xinetd,并配置tftp开机启动
[root@localhost CentOS]# service xinetd restart
[root@localhost CentOS]# setup
修改权限:
[root@localhost /]# chmod 777 /tftpboot/
重启:
[root@localhost ~]# service xinetd restart
7.测试
[root@localhost ~]# cd /tftpboot/
[root@localhost tftpboot]# ls
a.txt ramdisk_sjx_0.7.3.gz
[root@localhost tftpboot]# vim a.txt
[root@localhost tftpboot]# cd
[root@localhost ~]# tftp 192.168.1.91
tftp> get a.txt
tftp> q
[root@localhost ~]# ls
a.txt install.log remove20090915 work
[root@localhost ~]# more a.txt
aaaaaaaaaaaaaa
成功!
ST2410 # ping 192.168.1.91
host 192.168.1.91 is alive
然后使用lokkit命令关闭防火墙,sellinux
ST2410 # tftp 0x30008000 u-boot.bin
TFTP from server 192.168.1.91; our IP address is 192.168.1.200
Filename 'u-boot.bin'.
Load address: 0x30008000
Loading: ##########################
done
Bytes transferred = 132096 (20400 hex)
测试成功,然后将board/configs/st2410.h里的宏CONFIG_SKIP_LOWLEVEL_INIT去掉和board/st2410/config.mk的TEXT_BASE修改为0x33f80000,下载到nor flash既可。下一篇中我们还用调试的方法来调试支持Nand Flash的读写操作。
三、支持norflash读写操作
三、改代码:
1. NOR FLASH的初始化函数为flash_init
2. 新版u-boot-2011.09中的flash_init在drivers/mtd/cfi_flash.c定义(老版本的还在board/smdk2410/flash.c中有定义board/smdk2410/flash.c的代码,它只支持AMD_LV400和AMD_LV800两种芯片)看drivers/mtd/Makefile的代码,发现它要配置CONFIG_FLASH_CFI_DRIVER才会被编译
COBJS-$(CONFIG_FLASH_CFI_DRIVER) += cfi_flash.o
分析flash_detect_legacy,发现如下代码,只能继续深入了解flash_init :
if (!flash_detect_legacy(cfi_flash_bank_addr(i), i))// 使用旧方法来识别
flash_get_size(cfi_flash_bank_addr(i), i);// 如果旧方法不成功,则使用新方法
并且CONFIG_FLASH_CFI_LEGACY未定义:
#ifdef CONFIG_FLASH_CFI_LEGACY
static void flash_read_jedec_ids (flash_info_t * info)
{
。。。。。。。。。。。。。。。。。。。。。。。
}
static int flash_detect_legacy(phys_addr_t base, int banknum)
{
。。。。。。。。。。。。。。。。。。。
}
#else
static inline int flash_detect_legacy(phys_addr_t base, int banknum)
{
return 0; /* use CFI */
}
#endif
可知:现在的u-boot使用新方法来识别FLASH。
3. 决定使用drivers/mtd/cfi_flash.c的代码:
在include/configs/smdk2410.h里:
#define CONFIG_SYS_FLASH_CFI
#define CONFIG_FLASH_CFI_DRIVER
#define CONFIG_FLASH_CFI_LEGACY
然后重新make
ST2410 # go 0x32000000
## Starting application at 0x32000000 ...??
U-Boot 2011.09 (Nov 07 2011 - 09:33:10)
U-Boot code: 32000000 -> 3206F4F4 BSS: -> 320B3524
monitor len: 000B3524
ramsize: 04000000
TLB table at: 33ff0000
Top of RAM usable for U-Boot at: 33ff0000
Reserving 717k for U-Boot at: 33f3c000
Reserving 4160k for malloc() at: 33b2c000
Reserving 24 Bytes for Board Info at: 33b2bfe8
Reserving 120 Bytes for Global Data at: 33b2bf70
New Stack Pointer is: 33b2bf60
RAM Configuration:
Bank #0: 30000000 64 MiB
relocation Offset is: 01f3c000
WARNING: Caches not enabled
monitor flash len: 0007830C
dram_bank_mmu_setup: bank: 0
Now running in RAM - U-Boot at: 33f3c000
Flash: fwc addr (null) cmd f0 00f0 16bit x 16 bit
fwc addr 0000aaaa cmd aa 00aa 16bit x 16 bit
fwc addr 00005554 cmd 55 0055 16bit x 16 bit
fwc addr 0000aaaa cmd 90 0090 16bit x 16 bit
fwc addr (null) cmd f0 00f0 16bit x 16 bit
JEDEC PROBE: ID f0 ea00 0
fwc addr (null) cmd ff 00ff 16bit x 16 bit
fwc addr (null) cmd 90 0090 16bit x 16 bit
fwc addr (null) cmd ff 00ff 16bit x 16 bit
JEDEC PROBE: ID 90 ea00 0
*** failed ***
### ERROR ### Please RESET the board ###
没有识别出NOR FLASH
可知,确定flash_read_jedec_ids读出了FLASH的ID:JEDEC PROBE: ID f0 ea00 0
分析jedec_flash_match:根据读出的厂家ID、设备ID,在jedec_table数组里找到对应项。
UBOOT未识别出NOR FLASH的原因:jedec_table里没有SST39VF1601的信息
drivers/mtd/jedec_flash.c
11. 在jedec_table数组里加入SST39VF1601的信息:
#ifdef CONFIG_SYS_FLASH_LEGACY_SST39VF1601
{
.mfr_id = 0xf0,
.dev_id = 0xea00,
.name = "SST39VF1601",
.uaddr = {
[0] = MTD_UADDR_0x5555_0x2AAA, /* x8 */
[1] = MTD_UADDR_0x5555_0x2AAA /* x16 */
},
.DevSize = SIZE_2MiB,
.CmdSet = P_ID_AMD_STD,
.NumEraseRegions= 2,
.regions = {
ERASEINFO(0x1000,256),
ERASEINFO(0x1000,256)
}
},
#endif
再在include/configs/st2410.h中添加下面宏定义
#define CONFIG_SYS_FLASH_LEGACY_SST39VF1601
编译、烧写、重启,输出信息为:
U-Boot 1.3.4 (May 13 2011 - 15:56:13)
DRAM: 64 MB
fwc addr 00000000 cmd f0 00f0 16bit x 16 bit
fwc addr 0000aaaa cmd aa 00aa 16bit x 16 bit
fwc addr 00005554 cmd 55 0055 16bit x 16 bit
fwc addr 0000aaaa cmd 90 0090 16bit x 16 bit
fwc addr 00000000 cmd f0 00f0 16bit x 16 bit
JEDEC PROBE: ID bf 234b 0
ERROR: too many flash sectors
ERROR: too many flash sectors
Flash: 2 MB
In: serial
Out: serial
Err: serial
在源码里搜"ERROR: too many flash sectors",可得:
if (sect_cnt >= CFG_MAX_FLASH_SECT) {
printf("ERROR: too many flash sectors\n");
break;
}
在include/configs/smdk2410.h里修改CFG_MAX_FLASH_SECT的值,取个比较大的,比如1024
重新编译即可
使用"save"命令时,出现很多调试信息,所以要关闭打印信息:
在drivers/mtd/cfi_flash.c的第1行去掉以下语句:
#define DEBUG 1
背景知识:
1. 使用u-boot的命令熟悉NOR FLASH的操作
1.1 读ID
mw.w AAAA AA
mw.w 5554 55
mw.w AAAA 90
md.l 0
退出读ID的状态:
mw.w 0 f0
1.2 往NOR FLASH地址为0x70000的地方写入0x1234 (操作过程中可以用 md.l 70000 查看结果)
a. 先擦除
mw.w AAAA AA
mw.w 5554 55
mw.w AAAA 80
mw.w AAAA AA
mw.w 5554 55
mw.w 70000 30
b. 再写
mw.w AAAA AA
mw.w 5554 55
mw.w AAAA A0
mw.w 70000 1234
7.
在driver/mtd/Makefile
从u-boot 1.1.6中拷贝flash.c
cp ../u-boot-1.1.6/board/st2410/flash.c board/samsung/st2410/
然后修改board/samsung/st2410/Makefile
COBJS:= st2410.o
修改为
COBJS:= st2410.o flash.o
修改u-boot以支持SST39VF1601:
一、下载源码,编译
make distclean
make smdk2410_config
make
make distclean
make smdk2410_config
make
出现错误:
make: arm-linux-gcc: Command not found
原因:
1. 确实没有这个命令
2. 有这个命令,但是PATH没有设这个命令所在的目录
修改Makefile, 把arm-linux-改为arm-linux-gnu-
二、烧写u-boot.bin,启动结果为:
Flash: 512K
*** Warning - bad CRC, using default environment
执行: save 提示出错
原因:UBOOT不支持SST39VF1601
三、改代码:
1. NOR FLASH的初始化函数为flash_init
2. flash_init在两个地方定义:board/smdk2410/flash.c
drivers/mtd/cfi_flash.c
看board/smdk2410/flash.c的代码,发现它只支持AMD_LV400和AMD_LV800两种芯片
看drivers/mtd/cfi_flash.c的代码,发现它被"#ifdef CFG_FLASH_CFI_DRIVER"包含起来
3. 决定使用drivers/mtd/cfi_flash.c的代码:
在include/configs/smdk2410.h里:
#define CFG_FLASH_CFI_DRIVER 1
然后重新make
出错:
arm-linux-gnu-gcc -g -Os -fno-strict-aliasing -fno-common -ffixed-r8 -msoft-float -malignment-traps -D__KERNEL__ -DTEXT_BASE=0x33F80000 -I/home/farsight/wei/u-boot/u-boot-1.3.4/include -fno-builtin -ffreestanding -nostdinc -isystem /opt/crosstool/gcc-3.4.5-glibc-2.3.6/arm-linux-gnu/lib/gcc/arm-linux-gnu/3.4.5/include -pipe -DCONFIG_ARM -D__ARM__ -march=armv4 -mapcs-32 -Wall -Wstrict-prototypes -c -o cfi_flash.o cfi_flash.c
cfi_flash.c: In function `flash_map':
cfi_flash.c:286: error: structure has no member named `portwidth'
4. 找到出错的结构体的定义:
typedef struct {
ulong size; /* total bank size in bytes */
ushort sector_count; /* number of erase units */
ulong flash_id; /* combined device & manufacturer code */
ulong start[CFG_MAX_FLASH_SECT]; /* physical sector start addresses */
uchar protect[CFG_MAX_FLASH_SECT]; /* sector protection status */
#ifdef CFG_FLASH_CFI
uchar portwidth; /* the width of the port */
uchar chipwidth; /* the width of the chip */
ushort buffer_size; /* # of bytes in write buffer */
ulong erase_blk_tout; /* maximum block erase timeout */
ulong write_tout; /* maximum write timeout */
ulong buffer_write_tout; /* maximum buffer write timeout */
ushort vendor; /* the primary vendor id */
ushort cmd_reset; /* vendor specific reset command */
ushort interface; /* used for x8/x16 adjustments */
ushort legacy_unlock; /* support Intel legacy (un)locking */
uchar manufacturer_id; /* manufacturer id */
ushort device_id; /* device id */
ushort device_id2; /* extended device id */
ushort ext_addr; /* extended query table address */
ushort cfi_version; /* cfi version */
ushort cfi_offset; /* offset for cfi query */
ulong addr_unlock1; /* unlock address 1 for AMD flash roms */
ulong addr_unlock2; /* unlock address 2 for AMD flash roms */
const char *name; /* human-readable name */
#endif
可知原因为:CFG_FLASH_CFI未定义
于是:
在include/configs/smdk2410.h里:
#define CFG_FLASH_CFI_DRIVER 1
#define CFG_FLASH_CFI 1
再make
5. 再次出错:
arm-linux-gnu-gcc -g -Os -fno-strict-aliasing -fno-common -ffixed-r8 -msoft-float -malignment-traps -D__KERNEL__ -DTEXT_BASE=0x33F80000 -I/home/farsight/wei/u-boot/u-boot-1.3.4/include -fno-builtin -ffreestanding -nostdinc -isystem /opt/crosstool/gcc-3.4.5-glibc-2.3.6/arm-linux-gnu/lib/gcc/arm-linux-gnu/3.4.5/include -pipe -DCONFIG_ARM -D__ARM__ -march=armv4 -mapcs-32 -Wall -Wstrict-prototypes -c -o cfi_flash.o cfi_flash.c
cfi_flash.c: In function `flash_init':
cfi_flash.c:1985: error: `CFG_MONITOR_BASE' undeclared (first use in this function)
CFG_MONITOR_BASE 是要保护的FLASH的起始地址,这只是u-boot里提供的软件保护机制,避免使用u-boot的命令
误擦除FLASH上的u-boot
可以如下试验:
md.l 0
erase 0 fff
md.l 0
protect off all
erase 0 fff
md.l 0
于是:
在include/configs/smdk2410.h里:
#define CFG_FLASH_CFI_DRIVER 1
#define CFG_FLASH_CFI 1
#define CFG_MONITOR_BASE 0
6. 没有出错,把u-boot.bin重烧、启动:
U-Boot 1.3.4 (May 13 2011 - 14:59:37)
DRAM: 64 MB
## Unknown FLASH on Bank 1 - Size = 0x00000000 = 0 MB
Flash: 0 kB
没有识别出NOR FLASH
只能继续深入了解flash_init :
if (!flash_detect_legacy (BANK_BASE(i), i)) // 使用旧方法来识别
flash_get_size (BANK_BASE(i), i); // 如果旧方法不成功,则使用新方法
7. 分析flash_detect_legacy,发现如下代码,并且CONFIG_FLASH_CFI_LEGACY未定义:
#ifdef CONFIG_FLASH_CFI_LEGACY
static inline int flash_detect_legacy(ulong base, int banknum)
{
........
}
#else
static inline int flash_detect_legacy(ulong base, int banknum)
{
return 0; /* use CFI */
}
#endif
可知:现在的u-boot使用新方法来识别FLASH。
8. 尝试通过修改新方法来识别FLASH
flash_init
flash_get_size
flash_detect_cfi
__flash_detect_cfi
CFI(common flash interface):
flash的信息(工作电压、时间参数、容量、可擦除块)保存在FLASH内部;
平时是不可见的;
可以发出特定的命令来读出这些信息
从芯片手册上,这些命令为:
5555H AAH
2AAAH 55H
5555H 98H
从u-boot的代码上看,命令为(发现没有"解锁"):
flash_write_cmd (info, 0, flash_offset_cfi[cfi_offset], FLASH_CMD_CFI);
所以:SST39VF1601不是百分百遵循CFI规范,我们退回"旧的方法"
9. 分析旧的方法:flash_detect_legacy
要使用flash_detect_legacy, 先在include/configs/smdk2410.h里面:
#define CONFIG_FLASH_CFI_LEGACY 1
#define CFG_FLASH_CFI_DRIVER 1
#define CFG_FLASH_CFI 1
#define CFG_MONITOR_BASE 0
执行make, 出错:
drivers/mtd/libmtd.a(cfi_flash.o)(.text+0x1878): In function `flash_init':
/home/farsight/wei/u-boot/u-boot-1.3.4/drivers/mtd/cfi_flash.c:1544: undefined reference to `board_flash_get_legacy'
修改board/smdk2410/flash.c,去掉所有的代码,改为:
#include
#include
ulong board_flash_get_legacy(ulong base, int banknum, flash_info_t *info)
{
info->portwidth = FLASH_CFI_16BIT;
info->chipwidth = FLASH_CFI_16BIT;
info->interface = FLASH_CFI_X8X16;
return 1;
}
然后make、烧写、启动:
U-Boot 1.3.4 (May 13 2011 - 15:56:13)
DRAM: 64 MB
Flash: 0 kB
In: serial
Out: serial
Err: serial
SMDK2410 #
SMDK2410 #
10. 深入分析flash_detect_legacy:
flash_detect_legacy
board_flash_get_legacy board/samsung/smdk2410/smdk2410.c
flash_read_jedec_ids 1639
jedec_flash_match
为方便观察,把调试信息打开:
在drivers/mtd/cfi_flash.c的第1行加入:
#define DEBUG 1
重新编译、运行uboot,输出信息如下:
U-Boot 1.3.4 (May 13 2011 - 15:56:13)
DRAM: 64 MB
fwc addr 00000000 cmd f0 00f0 16bit x 16 bit
fwc addr 0000aaaa cmd aa 00aa 16bit x 16 bit
fwc addr 00005554 cmd 55 0055 16bit x 16 bit
fwc addr 0000aaaa cmd 90 0090 16bit x 16 bit
fwc addr 00000000 cmd f0 00f0 16bit x 16 bit
JEDEC PROBE: ID bf 234b 0
fwc addr 00000000 cmd ff 00ff 16bit x 16 bit
fwc addr 00000000 cmd 90 0090 16bit x 16 bit
fwc addr 00000000 cmd ff 00ff 16bit x 16 bit
JEDEC PROBE: ID 12 0 0
Flash: 0 kB
In: serial
Out: serial
Err: serial
可知,确定flash_read_jedec_ids读出了FLASH的ID:JEDEC PROBE: ID bf 234b 0
分析jedec_flash_match:根据读出的厂家ID、设备ID,在jedec_table数组里找到对应项。
UBOOT未识别出NOR FLASH的原因:jedec_table里没有SST39VF1601的信息
drivers/mtd/jedec_flash.c
11. 在jedec_table数组里加入SST39VF1601的信息:
{
.mfr_id = 0xbf,
.dev_id = 0x234b,
.name = "SST39VF1601",
.uaddr = {
[0] = MTD_UADDR_0x5555_0x2AAA, /* x8 */
[1] = MTD_UADDR_0x5555_0x2AAA /* x16 */
},
.DevSize = SIZE_2MiB,
.CmdSet = P_ID_AMD_STD,
.NumEraseRegions= 2,
.regions = {
ERASEINFO(0x1000,256),
ERASEINFO(0x1000,256)
}
}
编译、烧写、重启,输出信息为:
U-Boot 1.3.4 (May 13 2011 - 15:56:13)
DRAM: 64 MB
fwc addr 00000000 cmd f0 00f0 16bit x 16 bit
fwc addr 0000aaaa cmd aa 00aa 16bit x 16 bit
fwc addr 00005554 cmd 55 0055 16bit x 16 bit
fwc addr 0000aaaa cmd 90 0090 16bit x 16 bit
fwc addr 00000000 cmd f0 00f0 16bit x 16 bit
JEDEC PROBE: ID bf 234b 0
ERROR: too many flash sectors
ERROR: too many flash sectors
Flash: 2 MB
In: serial
Out: serial
Err: serial
在源码里搜"ERROR: too many flash sectors",可得:
if (sect_cnt >= CFG_MAX_FLASH_SECT) {
printf("ERROR: too many flash sectors\n");
break;
}
在include/configs/smdk2410.h里修改CFG_MAX_FLASH_SECT的值,取个比较大的,比如1024
重新编译即可
使用"save"命令时,出现很多调试信息,所以要关闭打印信息:
在drivers/mtd/cfi_flash.c的第1行去掉以下语句:
#define DEBUG 1
背景知识:
1. 使用u-boot的命令熟悉NOR FLASH的操作
1.1 读ID
mw.w AAAA AA
mw.w 5554 55
mw.w AAAA 90
md.l 0
退出读ID的状态:
mw.w 0 f0
1.2 往NOR FLASH地址为0x70000的地方写入0x1234 (操作过程中可以用 md.l 70000 查看结果)
a. 先擦除
mw.w AAAA AA
mw.w 5554 55
mw.w AAAA 80
mw.w AAAA AA
mw.w 5554 55
mw.w 70000 30
b. 再写
mw.w AAAA AA
mw.w 5554 55
mw.w AAAA A0
mw.w 70000 1234
2. CFI(common flash interface):
flash的信息(工作电压、时间参数、容量、可擦除块)保存在FLASH内部;
平时是不可见的;
可以发出特定的命令来读出这些信息
从芯片手册上,这些命令为:
5555H AAH
2AAAH 55H
5555H 98H
四、支持nandflash启动及读写操作