1, 解决启动时的错误
Warning - bad CRC, using default environment
搜索发现 在 /tools/env/fw_env.c 中
/* 放在NAND FLASH 中 大小 128K 开始地址 */
#define CONFIG_ENV_IS_IN_NAND
#define CONFIG_SYS_ENV_SECT_SIZE (128 << 10)
#define CONFIG_ENV_OFFSET (256<<10)
#define CONFIG_ENV_SIZE CONFIG_SYS_ENV_SECT_SIZE
2, 添加 MTD
#define CONFIG_CMD_MTDPARTS /* Enable MTD parts commands */
#define CONFIG_MTD_DEVICE /* needed for mtdparts commands */
#define MTDIDS_DEFAULT "nand0=nand"
#define MTDPARTS_DEFAULT "mtdparts=nand:256k(uboot),"
"128k(env),"
"2m(kernel),-(fs)"
在 /common/board_r.c
man_loop 中添加
run_command("mtdparts default", 0);
擦除 nand flash
nand erase.part uboot
nand write 0x30000000 uboot
3, 下载试验
nfs 0x30000000 192.168.1.10:/nfs/fs.yaffs2
nand erase.part fs
nand write.yaffs 0x30000000 0x00260000 0x8607c0 (文件大小)
set bootargs noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0
boot 启动
写入出错
Unknown nand command suffix '.yaffs2'
4, 支持 yaffs2
在 smdk2440.h 发现有个,配置后 #define CONFIG_YAFFS2
编译后,大了很多,有 335K ,菜单多了几个功能
yls - yaffs ls
ymkdir - YAFFS mkdir
ymount - mount yaffs
ymv - YAFFS mv
yrd - read file from yaffs
yrdm - read file to memory from yaffs
yrm - YAFFS rm
yrmdir - YAFFS rmdir
ytrace - show/set yaffs trace mask
yumount - unmount yaffs
ywr - write file to yaffs
ywrm - write file from memory to yaffs
试着挂载,失败,文档也没有找到,导致 u-boot 也非常大,换一种方法。
之前可以使用 #define CONFIG_CMD_NAND_YAFFS
对比了 u-boot 2013 2014 2015 都有这个功能, 但从 2015-10 移除了
参考u-boot 2015修改代码添加支持
/* 添加兼容 yaffs2 烧写支持 */
/include/configs/smdk2440.h
#define CONFIG_CMD_NAND_YAFFS
/cmd/nand.c
在543line:
if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) {
里面添加 622line:
#ifdef CONFIG_CMD_NAND_YAFFS
} else if (!strcmp(s, ".yaffs")) {
if (read) {
printf("Unknown nand command suffix '%s'.n", s);
return 1;
}
ret = nand_write_skip_bad(nand, off, &rwsize, NULL,
maxsize, (u_char *)addr,
WITH_YAFFS_OOB);
#endif
/include/nand.h 101line: 添加
#define WITH_YAFFS_OOB (1 << 0) /* whether write with yaffs format. This flag * is a 'mode' meaning it cannot be mixed with * other flags */
/drivers/mtd/nand/nand_util.c 583line:
#ifdef CONFIG_CMD_NAND_YAFFS
if (flags & WITH_YAFFS_OOB) {
if (flags & ~WITH_YAFFS_OOB)
return -EINVAL;
int pages;
pages = nand->erasesize / nand->writesize;
blocksize = (pages * nand->oobsize) + nand->erasesize;
if (*length % (nand->writesize + nand->oobsize)) {
printf("Attempt to write incomplete page"
" in yaffs moden");
return -EINVAL;
}
} else
#endif
666line:
#ifdef CONFIG_CMD_NAND_YAFFS
if (flags & WITH_YAFFS_OOB) {
int page, pages;
size_t pagesize = nand->writesize;
size_t pagesize_oob = pagesize + nand->oobsize;
struct mtd_oob_ops ops;
ops.len = pagesize;
ops.ooblen = nand->oobsize;
ops.mode = MTD_OPS_AUTO_OOB;
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 = mtd_write_oob(nand, offset, &ops);
if (rval != 0)
break;
offset += pagesize;
p_buffer += pagesize_oob;
}
}
else
#endif
{
这里要包含下面的部分。 最后 u-boot 改完后,会有大补丁。大家可以下载比较。
..............
}
编译后,252K
重新烧写出错
NAND write to offset 2a1000 failed -22 0 bytes written: ERROR
ops.mode = MTD_OPS_RAW; 这里也要改。
最终 完成了, 可以烧写 yaffs2 , 也能使用 NAND FLASH NOR FLASH ,网卡, u-boot 差不多结束了。
2016.03.u-boot 补丁
1 diff -urN u-boot-2016.03/arch/arm/cpu/arm920t/init.c u-boot-2016.03ok/arch/arm/cpu/arm920t/init.c
2 --- u-boot-2016.03/arch/arm/cpu/arm920t/init.c 1970-01-01 07:00:00.000000000 +0700
3 +++ u-boot-2016.03ok/arch/arm/cpu/arm920t/init.c 2016-05-19 05:34:00.645377559 +0800
4 @@ -0,0 +1,206 @@
5 +/* NAND FLASH控制器 */
6 +#define NFCONF (*((volatile unsigned long *)0x4E000000))
7 +#define NFCONT (*((volatile unsigned long *)0x4E000004))
8 +#define NFCMMD (*((volatile unsigned char *)0x4E000008))
9 +#define NFADDR (*((volatile unsigned char *)0x4E00000C))
10 +#define NFDATA (*((volatile unsigned char *)0x4E000010))
11 +#define NFSTAT (*((volatile unsigned char *)0x4E000020))
12 +
13 +/* CLK */
14 +#define CLKDIVN (*(volatile unsigned long *)0x4C000014)
15 +#define MPLLCON (*(volatile unsigned long *)0x4C000004)
16 +
17 +/* SDRAM */
18 +#define BWSCON (*(volatile unsigned long *)0x48000000)
19 +#define BANKCON4 (*(volatile unsigned long *)0x48000014)
20 +#define BANKCON6 (*(volatile unsigned long *)0x4800001c)
21 +#define REFRESH (*(volatile unsigned long *)0x48000024)
22 +#define BANKSIZE (*(volatile unsigned long *)0x48000028)
23 +#define MRSRB6 (*(volatile unsigned long *)0x4800002c)
24 +
25 +void init_clock(void)
26 +{
27 + //Mpll = 400M
28 + MPLLCON = (0x5c<<12) | (1<<4) | 1;
29 + //FCLK 400M HCLK 100M PCLK 50M
30 + CLKDIVN = 2<<1 | 1<<0;
31 + __asm__(
32 + "mrc p15,0,r0,c1,c0,0n"
33 + "orr r0,r0,#0xc0000000n"
34 + "mcr p15,0,r0,c1,c0,0n"
35 + );
36 +}
37 +
38 +void init_sdram(void)
39 +{
40 + #if 0
41 + BWSCON = 1<<25;
42 + BANKCON6 = 1<<16 | 1<<15 | 1;
43 + REFRESH = (1<<23) + 1268;
44 + BANKSIZE = 1<<7 | 1<<4 | 1;
45 + MRSRB6 = 0x30;
46 + #else
47 + BWSCON = 1<<25 | 1<<16;
48 + BANKCON4 = 0x00000740;
49 + BANKCON6 = 1<<16 | 1<<15 | 1;
50 + REFRESH = (1<<23) + 1268;
51 + BANKSIZE = 1<<7 | 1<<4 | 1;
52 + MRSRB6 = 0x30;
53 + #endif
54 +}
55 +
56 +void clear_bss(void)
57 +{
58 + extern int __bss_start, __bss_end;
59 + int *p = &__bss_start;
60 +
61 + for (; p < &__bss_end; p++)
62 + {
63 + *p = 0;
64 + }
65 +}
66 +
67 +static void nand_latency(void)
68 +{
69 + int i=100;
70 + while(i--);
71 +}
72 +
73 +static void nand_is_ready(void)
74 +{
75 + //bit 0 : 1 不忙了
76 + while(! (NFSTAT & 1));
77 +}
78 +
79 +static void nand_write_addr(unsigned int addr)
80 +{
81 + int col, page;
82 + col = addr % 2048;
83 + page = addr / 2048;
84 +
85 + NFADDR = col & 0xff; /* Column Address A0~A7 */
86 + nand_latency();
87 + NFADDR = (col >> 8) & 0x0f; /* Column Address A8~A11 */
88 + nand_latency();
89 + NFADDR = page & 0xff; /* Row Address A12~A19 */
90 + nand_latency();
91 + NFADDR = (page >> 8) & 0xff; /* Row Address A20~A27 */
92 + nand_latency();
93 + NFADDR = (page >> 16) & 0x03; /* Row Address A28~A29 */
94 + nand_latency();
95 +}
96 +
97 +static unsigned char nand_read_char(void)
98 +{
99 + //只保留8个bit
100 + return NFDATA & 0xff;
101 +}
102 +
103 +static void nand_cmd(unsigned char cmd)
104 +{
105 + NFCMMD = cmd;
106 + nand_latency();
107 +}
108 +
109 +static void nand_select_chip(void)
110 +{
111 + //1bit : 0 选中
112 + NFCONT &= ~(1<<1);
113 +}
114 +
115 +static void nand_deselect_chip(void)
116 +{
117 + //1bit : 1 选中
118 + NFCONT |= (1<<1);
119 +}
120 +
121 +static void nand_reset(void)
122 +{
123 + nand_select_chip();
124 + nand_cmd(0xff);
125 + nand_deselect_chip();
126 +}
127 +
128 +void nand_init_ll(void)
129 +{
130 + //TACLS 3.3v 时 12ns
131 + #define TACLS 0
132 + //12ns
133 + #define TWRPH0 1
134 + //5ns
135 + #define TWRPH1 0
136 + NFCONF = TACLS<<12 | TWRPH0<<8 | TWRPH1<<4;
137 + /* 4 ECC
138 + * 1 CE 先不选中,用的时候在选中
139 + * 0 启动 flash controller
140 + */
141 + NFCONT = 1<<4 | 1<<1 | 1;
142 + nand_reset();
143 +}
144 +
145 +static void nand_read(unsigned int addr, unsigned char *buf, int len)
146 +{
147 + //选中
148 + nand_select_chip();
149 + //j 地址可能不是从0对齐开始读的
150 + unsigned int i = addr,j = addr % 2048;
151 + for(; i 152 + {
153 + //读命令
154 + nand_cmd(0x00);