s3c2440 移值u-boot-2016.03 第6篇 支持mtd yaffs 烧写

发布时间:2023-09-01  

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);

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>