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


    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'. ", 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 mode ");
    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,0
    " 
      33 +        "orr  r0,r0,#0xc0000000
    "
      34 +        "mcr  p15,0,r0,c1,c0,0
    " 
      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<(addr + len);)
     152 +    {
     153 +        //读命令
     154 +        nand_cmd(0x00);
     155 +        nand_is_ready();
     156 +        
     157 +        //发送地址
     158 +        nand_write_addr(i);
     159 +        nand_is_ready();
     160 +    
     161 +        //在次发出读命令
     162 +        nand_cmd(0x30);
     163 +        nand_is_ready();
     164 +        //读2K
     165 +        for(; j<2048; j++)
     166 +        {
     167 +            *buf = nand_read_char();
     168 +            buf++;
     169 +            i++;
     170 +        }
     171 +        j=0;
     172 +        nand_latency();
     173 +    }
     174 +    //取消选中
     175 +    nand_deselect_chip();
     176 +}
     177 +
     178 +static int boot_is_nor()
     179 +{
     180 +    //利用 NOR 不能写的特点判断
     181 +    volatile unsigned int *p = (volatile unsigned int *)0;
     182 +    unsigned int val;
     183 +    val = *p;
     184 +    *p = 0x12345678;
     185 +    if(0x12345678 == *p)
     186 +    {
     187 +        *p = val;
     188 +        return 0;
     189 +    }
     190 +    return 1;
     191 +}
     192 +
     193 +//片内4K 的程序要复制到链接SDRAM中去
     194 +void copy_code_to_sdram(unsigned char *src,unsigned char *dst,int len)
     195 +{
     196 +    int i = 0;
     197 +    if(boot_is_nor())
     198 +    {
     199 +        while(i < len)
     200 +        {
     201 +            dst[i] = src[i];
     202 +            i++;
     203 +        }
     204 +    }
     205 +    else
     206 +    {
     207 +        nand_read((int)src, dst, len);
     208 +    }
     209 +}
     210 +
     211 diff -urN u-boot-2016.03/arch/arm/cpu/arm920t/Makefile u-boot-2016.03ok/arch/arm/cpu/arm920t/Makefile
     212 --- u-boot-2016.03/arch/arm/cpu/arm920t/Makefile    2016-03-14 22:20:21.000000000 +0800
     213 +++ u-boot-2016.03ok/arch/arm/cpu/arm920t/Makefile    2016-05-17 06:48:31.767626866 +0800
     214 @@ -8,6 +8,7 @@
     215  extra-y    = start.o
     216  
     217  obj-y    += cpu.o
     218 +obj-y    += init.o
     219  obj-$(CONFIG_USE_IRQ)    += interrupts.o
     220  
     221  obj-$(CONFIG_EP93XX) += ep93xx/
     222 diff -urN u-boot-2016.03/arch/arm/cpu/arm920t/start.S u-boot-2016.03ok/arch/arm/cpu/arm920t/start.S
     223 --- u-boot-2016.03/arch/arm/cpu/arm920t/start.S    2016-03-14 22:20:21.000000000 +0800
     224 +++ u-boot-2016.03ok/arch/arm/cpu/arm920t/start.S    2016-05-17 06:48:31.782641369 +0800
     225 @@ -82,11 +82,50 @@
     226  
     227      /* FCLK:HCLK:PCLK = 1:2:4 */
     228      /* default FCLK is 120 MHz ! */
     229 -    ldr    r0, =CLKDIVN
     230 -    mov    r1, #3
     231 -    str    r1, [r0]
     232 +    //ldr    r0, =CLKDIVN
     233 +    //mov    r1, #3
     234 +     //str    r1, [r0]
     235 +
     236 +    /* 设置分频参数 */
     237 +    ldr r0, =CLKDIVN
     238 +    mov r1, #0x05;    /* FCLK:HCLK:PCLK=1:4:8 */
     239 +    str r1, [r0]
     240 +
     241 +    /* 如果HDIVN非0,CPU的总线模式应该从“fast bus mode”变为“asynchronous bus mode” */
     242 +    mrc    p15, 0, r1, c1, c0, 0        /* 读出控制寄存器 */ 
     243 +    orr    r1, r1, #0xc0000000            /* 设置为“asynchronous bus mode” */
     244 +    mcr    p15, 0, r1, c1, c0, 0        /* 写入控制寄存器 */
     245 +
     246 +    /* 配置时钟 */
     247 +    #define S3C2440_MPLL_400MHZ     ((0x5c<<12)|(0x01<<4)|(0x01))
     248 +    ldr r0, =0x4c000004
     249 +    ldr r1, =S3C2440_MPLL_400MHZ
     250 +    str r1, [r0]
     251 +
     252  #endif    /* CONFIG_S3C24X0 */
     253  
     254 +    /**
     255 +         * 调用 init.c 中的初始化
     256 +         * 因为已经初始化好内存 所以 sp 在 顶部 
     257 +         * 在 NOR 时不能用片内 4K
     258 +         */
     259 +        ldr sp, =4096
     260 +        bl init_sdram
     261 +        ldr sp, =0x34000000
     262 +        bl nand_init_ll
     263 +        /**
     264 +         * 从 0 地址开始复制 到 SDRAM 中
     265 +         * 在 smdk2440.h 中定义 #define CONFIG_SYS_TEXT_BASE
     266 +         * u-boot 的加载地址
     267 +         */
     268 +        mov r0,#0
     269 +        ldr r1, =CONFIG_SYS_TEXT_BASE
     270 +        ldr r2, =__bss_start
     271 +        sub r2, r2, r1
     272 +        bl copy_code_to_sdram
     273 +        bl clear_bss
     274 +        ldr pc, =_main
     275 +
     276      /*
     277       * we do sys-critical inits only at reboot,
     278       * not when booting from ram!
     279 @@ -95,8 +134,6 @@
     280      bl    cpu_init_crit
     281  #endif
     282  
     283 -    bl    _main
     284 -
     285  /*------------------------------------------------------------------------------*/
     286  
     287      .globl    c_runtime_cpu_setup
     288 diff -urN u-boot-2016.03/arch/arm/cpu/u-boot.lds u-boot-2016.03ok/arch/arm/cpu/u-boot.lds
     289 --- u-boot-2016.03/arch/arm/cpu/u-boot.lds    2016-03-14 22:20:21.000000000 +0800
     290 +++ u-boot-2016.03ok/arch/arm/cpu/u-boot.lds    2016-05-12 09:28:12.338040880 +0800
     291 @@ -32,7 +32,7 @@
     292       */
     293      /DISCARD/ : { *(.rel._secure*) }
     294  #endif
     295 -    . = 0x00000000;
     296 +    . = 0;
     297  
     298      . = ALIGN(4);
     299      .text :
     300 diff -urN u-boot-2016.03/arch/arm/Kconfig u-boot-2016.03ok/arch/arm/Kconfig
     301 --- u-boot-2016.03/arch/arm/Kconfig    2016-03-14 22:20:21.000000000 +0800
     302 +++ u-boot-2016.03ok/arch/arm/Kconfig    2016-05-09 08:48:52.118143749 +0800
     303 @@ -91,6 +91,10 @@
     304  config TARGET_SMDK2410
     305      bool "Support smdk2410"
     306      select CPU_ARM920T
     307 +    
     308 +config TARGET_SMDK2440
     309 +    bool "Support smdk2440"
     310 +    select CPU_ARM920T
     311  
     312  config TARGET_ASPENITE
     313      bool "Support aspenite"
     314 @@ -829,6 +833,7 @@
     315  source "board/phytec/pcm052/Kconfig"
     316  source "board/ppcag/bg0900/Kconfig"
     317  source "board/samsung/smdk2410/Kconfig"
     318 +source "board/samsung/smdk2440/Kconfig"
     319  source "board/sandisk/sansa_fuze_plus/Kconfig"
     320  source "board/schulercontrol/sc_sps_1/Kconfig"
     321  source "board/siemens/draco/Kconfig"
     322 diff -urN u-boot-2016.03/arch/arm/lib/crt0.S u-boot-2016.03ok/arch/arm/lib/crt0.S
     323 --- u-boot-2016.03/arch/arm/lib/crt0.S    2016-03-14 22:20:21.000000000 +0800
     324 +++ u-boot-2016.03ok/arch/arm/lib/crt0.S    2016-05-16 17:11:44.287690421 +0800
     325 @@ -99,7 +99,6 @@
     326   * relocate_code(addr_moni). Trick here is that we'll return
     327   * 'here' but relocated.
     328   */
     329 -
     330      ldr    sp, [r9, #GD_START_ADDR_SP]    /* sp = gd->start_addr_sp */
     331  #if defined(CONFIG_CPU_V7M)    /* v7M forbids using SP as BIC destination */
     332      mov    r3, sp
     333 @@ -130,14 +129,17 @@
     334  
     335      bl    c_runtime_cpu_setup    /* we still call old routine here */
     336  #endif
     337 +
     338 +
     339  #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_FRAMEWORK)
     340 -# ifdef CONFIG_SPL_BUILD
     341 +#ifdef CONFIG_SPL_BUILD
     342      /* Use a DRAM stack for the rest of SPL, if requested */
     343      bl    spl_relocate_stack_gd
     344      cmp    r0, #0
     345      movne    sp, r0
     346      movne    r9, r0
     347 -# endif
     348 +#endif
     349 +
     350      ldr    r0, =__bss_start    /* this is auto-relocated! */
     351  
     352  #ifdef CONFIG_USE_ARCH_MEMSET
     353 @@ -177,3 +179,4 @@
     354  #endif
     355  
     356  ENDPROC(_main)
     357 +
     358 diff -urN u-boot-2016.03/arch/arm/lib/relocate.S u-boot-2016.03ok/arch/arm/lib/relocate.S
     359 --- u-boot-2016.03/arch/arm/lib/relocate.S    2016-03-14 22:20:21.000000000 +0800
     360 +++ u-boot-2016.03ok/arch/arm/lib/relocate.S    2016-05-16 17:11:48.481661370 +0800
     361 @@ -26,6 +26,7 @@
     362  
     363  ENTRY(relocate_vectors)
     364  
     365 +
     366  #ifdef CONFIG_CPU_V7M
     367      /*
     368       * On ARMv7-M we only have to write the new vector address
     369 diff -urN u-boot-2016.03/board/samsung/smdk2440/Kconfig u-boot-2016.03ok/board/samsung/smdk2440/Kconfig
     370 --- u-boot-2016.03/board/samsung/smdk2440/Kconfig    1970-01-01 07:00:00.000000000 +0700
     371 +++ u-boot-2016.03ok/board/samsung/smdk2440/Kconfig    2016-05-18 15:00:45.794906725 +0800
     372 @@ -0,0 +1,15 @@
     373 +if TARGET_SMDK2440
     374 +
     375 +config SYS_BOARD
     376 +    default "smdk2440"
     377 +
     378 +config SYS_VENDOR
     379 +    default "samsung"
     380 +
     381 +config SYS_SOC
     382 +    default "s3c24x0"
     383 +
     384 +config SYS_CONFIG_NAME
     385 +    default "smdk2440"
     386 +
     387 +endif
     388 diff -urN u-boot-2016.03/board/samsung/smdk2440/lowlevel_init.S u-boot-2016.03ok/board/samsung/smdk2440/lowlevel_init.S
     389 --- u-boot-2016.03/board/samsung/smdk2440/lowlevel_init.S    1970-01-01 07:00:00.000000000 +0700
     390 +++ u-boot-2016.03ok/board/samsung/smdk2440/lowlevel_init.S    2016-05-18 15:00:45.654313065 +0800
     391 @@ -0,0 +1,147 @@
     392 +/*
     393 + * Memory Setup stuff - taken from blob memsetup.S
     394 + *
     395 + * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and
     396 + *                     Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl)
     397 + *
     398 + * Modified for the Samsung SMDK2410 by
     399 + * (C) Copyright 2002
     400 + * David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
     401 + *
     402 + * SPDX-License-Identifier:    GPL-2.0+
     403 + */
     404 +
     405 +
     406 +#include <config.h>
     407 +
     408 +/* some parameters for the board */
     409 +
     410 +/*
     411 + *
     412 + * Taken from linux/arch/arm/boot/compressed/head-s3c2410.S
     413 + *
     414 + * Copyright (C) 2002 Samsung Electronics SW.LEE  <hitchcar@sec.samsung.com>
     415 + *
     416 + */
     417 +
     418 +#define BWSCON    0x48000000
     419 +
     420 +/* BWSCON */
     421 +#define DW8            (0x0)
     422 +#define DW16            (0x1)
     423 +#define DW32            (0x2)
     424 +#define WAIT            (0x1<<2)
     425 +#define UBLB            (0x1<<3)
     426 +
     427 +#define B1_BWSCON        (DW32)
     428 +#define B2_BWSCON        (DW16)
     429 +#define B3_BWSCON        (DW16 + WAIT + UBLB)
     430 +#define B4_BWSCON        (DW16)
     431 +#define B5_BWSCON        (DW16)
     432 +#define B6_BWSCON        (DW32)
     433 +#define B7_BWSCON        (DW32)
     434 +
     435 +/* BANK0CON */
     436 +#define B0_Tacs            0x0    /*  0clk */
     437 +#define B0_Tcos            0x0    /*  0clk */
     438 +#define B0_Tacc            0x7    /* 14clk */
     439 +#define B0_Tcoh            0x0    /*  0clk */
     440 +#define B0_Tah            0x0    /*  0clk */
     441 +#define B0_Tacp            0x0
     442 +#define B0_PMC            0x0    /* normal */
     443 +
     444 +/* BANK1CON */
     445 +#define B1_Tacs            0x0    /*  0clk */
     446 +#define B1_Tcos            0x0    /*  0clk */
     447 +#define B1_Tacc            0x7    /* 14clk */
     448 +#define B1_Tcoh            0x0    /*  0clk */
     449 +#define B1_Tah            0x0    /*  0clk */
     450 +#define B1_Tacp            0x0
     451 +#define B1_PMC            0x0
     452 +
     453 +#define B2_Tacs            0x0
     454 +#define B2_Tcos            0x0
     455 +#define B2_Tacc            0x7
     456 +#define B2_Tcoh            0x0
     457 +#define B2_Tah            0x0
     458 +#define B2_Tacp            0x0
     459 +#define B2_PMC            0x0
     460 +
     461 +#define B3_Tacs            0x0    /*  0clk */
     462 +#define B3_Tcos            0x3    /*  4clk */
     463 +#define B3_Tacc            0x7    /* 14clk */
     464 +#define B3_Tcoh            0x1    /*  1clk */
     465 +#define B3_Tah            0x0    /*  0clk */
     466 +#define B3_Tacp            0x3     /*  6clk */
     467 +#define B3_PMC            0x0    /* normal */
     468 +
     469 +#define B4_Tacs            0x0    /*  0clk */
     470 +#define B4_Tcos            0x0    /*  0clk */
     471 +#define B4_Tacc            0x7    /* 14clk */
     472 +#define B4_Tcoh            0x0    /*  0clk */
     473 +#define B4_Tah            0x0    /*  0clk */
     474 +#define B4_Tacp            0x0
     475 +#define B4_PMC            0x0    /* normal */
     476 +
     477 +#define B5_Tacs            0x0    /*  0clk */
     478 +#define B5_Tcos            0x0    /*  0clk */
     479 +#define B5_Tacc            0x7    /* 14clk */
     480 +#define B5_Tcoh            0x0    /*  0clk */
     481 +#define B5_Tah            0x0    /*  0clk */
     482 +#define B5_Tacp            0x0
     483 +#define B5_PMC            0x0    /* normal */
     484 +
     485 +#define B6_MT            0x3    /* SDRAM */
     486 +#define B6_Trcd            0x1
     487 +#define B6_SCAN            0x1    /* 9bit */
     488 +
     489 +#define B7_MT            0x3    /* SDRAM */
     490 +#define B7_Trcd            0x1    /* 3clk */
     491 +#define B7_SCAN            0x1    /* 9bit */
     492 +
     493 +/* REFRESH parameter */
     494 +#define REFEN            0x1    /* Refresh enable */
     495 +#define TREFMD            0x0    /* CBR(CAS before RAS)/Auto refresh */
     496 +#define Trp            0x0    /* 2clk */
     497 +#define Trc            0x3    /* 7clk */
     498 +#define Tchr            0x2    /* 3clk */
     499 +#define REFCNT            1113    /* period=15.6us, HCLK=60Mhz, (2048+1-15.6*60) */
     500 +/**************************************/
     501 +
     502 +.globl lowlevel_init
     503 +lowlevel_init:
     504 +    /* memory control configuration */
     505 +    /* make r0 relative the current location so that it */
     506 +    /* reads SMRDATA out of FLASH rather than memory ! */
     507 +    ldr     r0, =SMRDATA
     508 +    ldr    r1, =CONFIG_SYS_TEXT_BASE
     509 +    sub    r0, r0, r1
     510 +    ldr    r1, =BWSCON    /* Bus Width Status Controller */
     511 +    add     r2, r0, #13*4
     512 +0:
     513 +    ldr     r3, [r0], #4
     514 +    str     r3, [r1], #4
     515 +    cmp     r2, r0
     516 +    bne     0b
     517 +
     518 +    /* everything is fine now */
     519 +    mov    pc, lr
     520 +
     521 +    .ltorg
     522 +/* the literal pools origin */
     523 +
     524 +SMRDATA:
     525 +    .long 0x22011110     //BWSCON
     526 +    .long 0x00000700     //BANKCON0
     527 +    .long 0x00000700     //BANKCON1
     528 +    .long 0x00000700     //BANKCON2
     529 +    .long 0x00000700     //BANKCON3  
     530 +    .long 0x00000740     //BANKCON4
     531 +    .long 0x00000700     //BANKCON5
     532 +    .long 0x00018005     //BANKCON6
     533 +    .long 0x00018005     //BANKCON7
     534 +    .long 0x008C04F4     // REFRESH
     535 +    .long 0x000000B1     //BANKSIZE
     536 +    .long 0x00000030     //MRSRB6
     537 +    .long 0x00000030     //MRSRB7
     538 +
     539 diff -urN u-boot-2016.03/board/samsung/smdk2440/MAINTAINERS u-boot-2016.03ok/board/samsung/smdk2440/MAINTAINERS
     540 --- u-boot-2016.03/board/samsung/smdk2440/MAINTAINERS    1970-01-01 07:00:00.000000000 +0700
     541 +++ u-boot-2016.03ok/board/samsung/smdk2440/MAINTAINERS    2016-05-18 15:00:45.729857753 +0800
     542 @@ -0,0 +1,6 @@
     543 +SMDK2440 BOARD
     544 +M:    David M眉ller <d.mueller@elsoft.ch>
     545 +S:    Maintained
     546 +F:    board/samsung/smdk2440/
     547 +F:    include/configs/smdk2440.h
     548 +F:    configs/smdk2440_defconfig
     549 diff -urN u-boot-2016.03/board/samsung/smdk2440/Makefile u-boot-2016.03ok/board/samsung/smdk2440/Makefile
     550 --- u-boot-2016.03/board/samsung/smdk2440/Makefile    1970-01-01 07:00:00.000000000 +0700
     551 +++ u-boot-2016.03ok/board/samsung/smdk2440/Makefile    2016-05-18 15:00:45.849850303 +0800
     552 @@ -0,0 +1,9 @@
     553 +#
     554 +# (C) Copyright 2000-2006
     555 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
     556 +#
     557 +# SPDX-License-Identifier:    GPL-2.0+
     558 +#
     559 +
     560 +obj-y    := smdk2440.o
     561 +obj-y    += lowlevel_init.o
     562 diff -urN u-boot-2016.03/board/samsung/smdk2440/smdk2440.c u-boot-2016.03ok/board/samsung/smdk2440/smdk2440.c
     563 --- u-boot-2016.03/board/samsung/smdk2440/smdk2440.c    1970-01-01 07:00:00.000000000 +0700
     564 +++ u-boot-2016.03ok/board/samsung/smdk2440/smdk2440.c    2016-05-18 15:00:45.625917593 +0800
     565 @@ -0,0 +1,142 @@
     566 +/*
     567 + * (C) Copyright 2002
     568 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
     569 + * Marius Groeger <mgroeger@sysgo.de>
     570 + *
     571 + * (C) Copyright 2002, 2010
     572 + * David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
     573 + *
     574 + * SPDX-License-Identifier:    GPL-2.0+
     575 + */
     576 +
     577 +#include <common.h>
     578 +#include <netdev.h>
     579 +#include <asm/io.h>
     580 +#include <asm/arch/s3c24x0_cpu.h>
     581 +
     582 +DECLARE_GLOBAL_DATA_PTR;
     583 +
     584 +#define FCLK_SPEED 1
     585 +
     586 +#if (FCLK_SPEED == 0)        /* Fout = 203MHz, Fin = 12MHz for Audio */
     587 +#define M_MDIV    0xC3
     588 +#define M_PDIV    0x4
     589 +#define M_SDIV    0x1
     590 +#elif (FCLK_SPEED == 1)        /* Fout = 202.8MHz */
     591 +#define M_MDIV    0xA1
     592 +#define M_PDIV    0x3
     593 +#define M_SDIV    0x1
     594 +#endif
     595 +
     596 +#define USB_CLOCK 1
     597 +
     598 +#if (USB_CLOCK == 0)
     599 +#define U_M_MDIV    0xA1
     600 +#define U_M_PDIV    0x3
     601 +#define U_M_SDIV    0x1
     602 +#elif (USB_CLOCK == 1)
     603 +#define U_M_MDIV    0x48
     604 +#define U_M_PDIV    0x3
     605 +#define U_M_SDIV    0x2
     606 +#endif
     607 +
     608 +static inline void pll_delay(unsigned long loops)
     609 +{
     610 +    __asm__ volatile ("1:
    "
     611 +      "subs %0, %1, #1
    "
     612 +      "bne 1b" : "=r" (loops) : "0" (loops));
     613 +}
     614 +
     615 +/*
     616 + * Miscellaneous platform dependent initialisations
     617 + */
     618 +
     619 +int board_early_init_f(void)
     620 +{
     621 +    struct s3c24x0_clock_power * const clk_power =
     622 +                    s3c24x0_get_base_clock_power();
     623 +    struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();
     624 +
     625 +    /* to reduce PLL lock time, adjust the LOCKTIME register */
     626 +    writel(0xFFFFFF, &clk_power->locktime);
     627 +
     628 +    /* configure MPLL */
     629 +    //writel((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV, &clk_power->mpllcon);
     630 +
     631 +    /* some delay between MPLL and UPLL */
     632 +    //pll_delay(4000);
     633 +
     634 +    /* configure UPLL */
     635 +    writel((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV,
     636 +           &clk_power->upllcon);
     637 +
     638 +    /* some delay between MPLL and UPLL */
     639 +    pll_delay(8000);
     640 +
     641 +    /* set up the I/O ports */
     642 +    writel(0x007FFFFF, &gpio->gpacon);
     643 +    writel(0x00044555, &gpio->gpbcon);
     644 +    writel(0x000007FF, &gpio->gpbup);
     645 +    writel(0xAAAAAAAA, &gpio->gpccon);
     646 +    writel(0x0000FFFF, &gpio->gpcup);
     647 +    writel(0xAAAAAAAA, &gpio->gpdcon);
     648 +    writel(0x0000FFFF, &gpio->gpdup);
     649 +    writel(0xAAAAAAAA, &gpio->gpecon);
     650 +    writel(0x0000FFFF, &gpio->gpeup);
     651 +    writel(0x000055AA, &gpio->gpfcon);
     652 +    writel(0x000000FF, &gpio->gpfup);
     653 +    writel(0xFF95FFBA, &gpio->gpgcon);
     654 +    writel(0x0000FFFF, &gpio->gpgup);
     655 +    writel(0x002AFAAA, &gpio->gphcon);
     656 +    writel(0x000007FF, &gpio->gphup);
     657 +
     658 +    return 0;
     659 +}
     660 +
     661 +int board_init(void)
     662 +{
     663 +    /* arch number of SMDK2410-Board */
     664 +    gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;
     665 +
     666 +    /* adress of boot parameters */
     667 +    gd->bd->bi_boot_params = 0x30000100;
     668 +
     669 +    icache_enable();
     670 +    dcache_enable();
     671 +
     672 +    return 0;
     673 +}
     674 +
     675 +int dram_init(void)
     676 +{
     677 +    /* dram_init must store complete ramsize in gd->ram_size */
     678 +    gd->ram_size = PHYS_SDRAM_1_SIZE;
     679 +    return 0;
     680 +}
     681 +
     682 +#ifdef CONFIG_CMD_NET
     683 +int board_eth_init(bd_t *bis)
     684 +{
     685 +    int rc = 0;
     686 +#ifdef CONFIG_CS8900
     687 +    rc = cs8900_initialize(0, CONFIG_CS8900_BASE);
     688 +#endif
     689 +
     690 +#ifdef CONFIG_DRIVER_DM9000
     691 +    rc = dm9000_initialize(bis);
     692 +#endif
     693 +    return rc;
     694 +}
     695 +#endif
     696 +
     697 +/*
     698 + * Hardcoded flash setup:
     699 + * Flash 0 is a non-CFI AMD AM29LV800BB flash.
     700 + */
     701 +ulong board_flash_get_legacy(ulong base, int banknum, flash_info_t *info)
     702 +{
     703 +    info->portwidth = FLASH_CFI_16BIT;
     704 +    info->chipwidth = FLASH_CFI_BY16;
     705 +    info->interface = FLASH_CFI_X16;
     706 +    return 1;
     707 +}
     708 diff -urN u-boot-2016.03/cmd/nand.c u-boot-2016.03ok/cmd/nand.c
     709 --- u-boot-2016.03/cmd/nand.c    2016-03-14 22:20:21.000000000 +0800
     710 +++ u-boot-2016.03ok/cmd/nand.c    2016-05-20 17:59:47.371697445 +0800
     711 @@ -619,6 +619,18 @@
     712                          maxsize, (u_char *)addr,
     713                          WITH_DROP_FFS | WITH_WR_VERIFY);
     714  #endif
     715 +#ifdef CONFIG_CMD_NAND_YAFFS
     716 +        } else if (!strcmp(s, ".yaffs")) {
     717 +            if (read) {
     718 +                printf("Unknown nand command suffix '%s'.
    ", s);
     719 +                return 1;
     720 +            }
     721 +            ret = nand_write_skip_bad(nand, off, &rwsize, NULL,
     722 +                        maxsize, (u_char *)addr,
     723 +                        WITH_YAFFS_OOB);
     724 +#endif
     725 +
     726 +
     727          } else if (!strcmp(s, ".oob")) {
     728              /* out-of-band data */
     729              mtd_oob_ops_t ops = {
     730 diff -urN u-boot-2016.03/common/board_r.c u-boot-2016.03ok/common/board_r.c
     731 --- u-boot-2016.03/common/board_r.c    2016-03-14 22:20:21.000000000 +0800
     732 +++ u-boot-2016.03ok/common/board_r.c    2016-05-19 12:47:22.083443762 +0800
     733 @@ -737,6 +737,7 @@
     734      sandbox_main_loop_init();
     735  #endif
     736      /* main_loop() can return to retry autoboot, if so just run it again */
     737 +    run_command("mtdparts default", 0);
     738      for (;;)
     739          main_loop();
     740      return 0;
     741 diff -urN u-boot-2016.03/configs/smdk2440_defconfig u-boot-2016.03ok/configs/smdk2440_defconfig
     742 --- u-boot-2016.03/configs/smdk2440_defconfig    1970-01-01 07:00:00.000000000 +0700
     743 +++ u-boot-2016.03ok/configs/smdk2440_defconfig    2016-05-09 07:56:48.822806092 +0800
     744 @@ -0,0 +1,4 @@
     745 +CONFIG_ARM=y
     746 +CONFIG_TARGET_SMDK2440=y
     747 +CONFIG_SYS_PROMPT="SMDK2440 # "
     748 +# CONFIG_CMD_SETEXPR is not set
     749 diff -urN u-boot-2016.03/drivers/mtd/cfi_flash.c u-boot-2016.03ok/drivers/mtd/cfi_flash.c
     750 --- u-boot-2016.03/drivers/mtd/cfi_flash.c    2016-03-14 22:20:21.000000000 +0800
     751 +++ u-boot-2016.03ok/drivers/mtd/cfi_flash.c    2016-05-17 15:30:45.155765043 +0800
     752 @@ -16,7 +16,6 @@
     753  
     754  /* The DEBUG define must be before common to enable debugging */
     755  /* #define DEBUG    */
     756 -
     757  #include <common.h>
     758  #include <console.h>
     759  #include <dm.h>
     760 diff -urN u-boot-2016.03/drivers/mtd/jedec_flash.c u-boot-2016.03ok/drivers/mtd/jedec_flash.c
     761 --- u-boot-2016.03/drivers/mtd/jedec_flash.c    2016-03-14 22:20:21.000000000 +0800
     762 +++ u-boot-2016.03ok/drivers/mtd/jedec_flash.c    2016-05-17 15:30:45.174882256 +0800
     763 @@ -401,6 +401,24 @@
     764          }
     765      },
     766  #endif
     767 +    {
     768 +        .mfr_id        = (u16)MX_MANUFACT,
     769 +        .dev_id        = AM29LV160DB,
     770 +        .name        = "MX 29LV160DB",
     771 +        .uaddr        = {
     772 +            [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
     773 +        },
     774 +        .DevSize    = SIZE_2MiB,
     775 +        .CmdSet        = CFI_CMDSET_AMD_LEGACY,
     776 +        .NumEraseRegions= 4,
     777 +        .regions    = {
     778 +            ERASEINFO(16*1024, 1),
     779 +            ERASEINFO(8*1024,  2),
     780 +            ERASEINFO(32*1024, 1),
     781 +            ERASEINFO(64*1024, 31),
     782 +        }
     783 +    },
     784 +
     785  };
     786  
     787  static inline void fill_info(flash_info_t *info, const struct amd_flash_info *jedec_entry, ulong base)
     788 diff -urN u-boot-2016.03/drivers/mtd/nand/Makefile u-boot-2016.03ok/drivers/mtd/nand/Makefile
     789 --- u-boot-2016.03/drivers/mtd/nand/Makefile    2016-03-14 22:20:21.000000000 +0800
     790 +++ u-boot-2016.03ok/drivers/mtd/nand/Makefile    2016-05-17 16:43:22.449544201 +0800
     791 @@ -63,6 +63,7 @@
     792  obj-$(CONFIG_NAND_NDFC) += ndfc.o
     793  obj-$(CONFIG_NAND_PXA3XX) += pxa3xx_nand.o
     794  obj-$(CONFIG_NAND_S3C2410) += s3c2410_nand.o
     795 +obj-$(CONFIG_NAND_S3C2440) += s3c2440_nand.o
     796  obj-$(CONFIG_NAND_SPEAR) += spr_nand.o
     797  obj-$(CONFIG_TEGRA_NAND) += tegra_nand.o
     798  obj-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o
     799 diff -urN u-boot-2016.03/drivers/mtd/nand/nand_util.c u-boot-2016.03ok/drivers/mtd/nand/nand_util.c
     800 --- u-boot-2016.03/drivers/mtd/nand/nand_util.c    2016-03-14 22:20:21.000000000 +0800
     801 +++ u-boot-2016.03ok/drivers/mtd/nand/nand_util.c    2016-05-20 18:45:19.582988542 +0800
     802 @@ -580,6 +580,21 @@
     803  
     804      if (actual)
     805          *actual = 0;
     806 +#ifdef CONFIG_CMD_NAND_YAFFS
     807 +        if (flags & WITH_YAFFS_OOB) {
     808 +            if (flags & ~WITH_YAFFS_OOB)
     809 +                return -EINVAL;
     810 +    
     811 +            int pages;
     812 +            pages = nand->erasesize / nand->writesize;
     813 +            blocksize = (pages * nand->oobsize) + nand->erasesize;
     814 +            if (*length % (nand->writesize + nand->oobsize)) {
     815 +                printf("Attempt to write incomplete page"
     816 +                    " in yaffs mode
    ");
     817 +                return -EINVAL;
     818 +            }
     819 +        } else
     820 +#endif
     821  
     822      blocksize = nand->erasesize;
     823  
     824 @@ -649,6 +664,36 @@
     825              write_size = left_to_write;
     826          else
     827              write_size = blocksize - block_offset;
     828 +#ifdef CONFIG_CMD_NAND_YAFFS
     829 +        if (flags & WITH_YAFFS_OOB) {
     830 +            int page, pages;
     831 +            size_t pagesize = nand->writesize;
     832 +            size_t pagesize_oob = pagesize + nand->oobsize;
     833 +            struct mtd_oob_ops ops;
     834 +
     835 +            ops.len = pagesize;
     836 +            ops.ooblen = nand->oobsize;
     837 +            ops.mode = MTD_OPS_RAW;
     838 +            ops.ooboffs = 0;
     839 +
     840 +            pages = write_size / pagesize_oob;
     841 +            for (page = 0; page < pages; page++) {
     842 +                WATCHDOG_RESET();
     843 +
     844 +                ops.datbuf = p_buffer;
     845 +                ops.oobbuf = ops.datbuf + pagesize;
     846 +
     847 +                rval = mtd_write_oob(nand, offset, &ops);
     848 +                if (rval != 0)
     849 +                    break;
     850 +
     851 +                offset += pagesize;
     852 +                p_buffer += pagesize_oob;
     853 +            }
     854 +        }
     855 +        else
     856 +        {
     857 +#endif
     858  
     859          truncated_write_size = write_size;
     860  #ifdef CONFIG_CMD_NAND_TRIMFFS
     861 @@ -666,7 +711,8 @@
     862  
     863          offset += write_size;
     864          p_buffer += write_size;
     865 -
     866 +          }
     867 +        
     868          if (rval != 0) {
     869              printf("NAND write to offset %llx failed %d
    ",
     870                  offset, rval);
     871 diff -urN u-boot-2016.03/drivers/mtd/nand/s3c2440_nand.c u-boot-2016.03ok/drivers/mtd/nand/s3c2440_nand.c
     872 --- u-boot-2016.03/drivers/mtd/nand/s3c2440_nand.c    1970-01-01 07:00:00.000000000 +0700
     873 +++ u-boot-2016.03ok/drivers/mtd/nand/s3c2440_nand.c    2016-05-20 17:45:21.900454122 +0800
     874 @@ -0,0 +1,185 @@
     875 +/*
     876 + * (C) Copyright 2006 OpenMoko, Inc.
     877 + * Author: Harald Welte <laforge@openmoko.org>
     878 + *
     879 + * SPDX-License-Identifier:    GPL-2.0+
     880 + */
     881 +
     882 +//#define DEBUG
     883 +#include <common.h>
     884 +
     885 +#include <nand.h>
     886 +#include <asm/arch/s3c24x0_cpu.h>
     887 +#include <asm/io.h>
     888 +
     889 +#define S3C2440_NFCONF_EN          (1<<15)
     890 +#define S3C2440_NFCONF_512BYTE     (1<<14)
     891 +#define S3C2440_NFCONF_4STEP       (1<<13)
     892 +#define S3C2440_NFCONF_INITECC     (1<<12)
     893 +#define S3C2440_NFCONF_nFCE        (1<<1)
     894 +#define S3C2440_NFCONF_TACLS(x)    ((x)<<12)
     895 +#define S3C2440_NFCONF_TWRPH0(x)   ((x)<<8)
     896 +#define S3C2440_NFCONF_TWRPH1(x)   ((x)<<4)
     897 +
     898 +#define S3C2440_ADDR_NALE 8
     899 +#define S3C2440_ADDR_NCLE 0xc
     900 +
     901 +#ifdef CONFIG_NAND_SPL
     902 +
     903 +/* in the early stage of NAND flash booting, printf() is not available */
     904 +#define printf(fmt, args...)
     905 +
     906 +static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
     907 +{
     908 +    int i;
     909 +    struct nand_chip *this = mtd->priv;
     910 +
     911 +    for (i = 0; i < len; i++)
     912 +        buf[i] = readb(this->IO_ADDR_R);
     913 +}
     914 +#endif
     915 +
     916 +static void s3c24x0_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
     917 +{
     918 +    struct nand_chip *chip = mtd->priv;
     919 +    struct s3c24x0_nand *nand = s3c24x0_get_base_nand();
     920 +
     921 +    debug("hwcontrol(): 0x%02x 0x%02x
    ", cmd, ctrl);
     922 +    
     923 +    if (ctrl & NAND_CLE)
     924 +        nand->nfcmd = cmd;
     925 +    if (ctrl & NAND_ALE)
     926 +        nand->nfaddr = cmd;
     927 +
     928 +}
     929 +
     930 +static void s3c2440_nand_select(struct mtd_info *mtd, int chipnr)
     931 +{
     932 +    struct s3c24x0_nand *nand = s3c24x0_get_base_nand();
     933 +
     934 +    switch (chipnr) {
     935 +    case -1: /* 取消选中 */
     936 +        nand->nfcont |= (1<<1);
     937 +        break;
     938 +    case 0:  /* 选中 */
     939 +        nand->nfcont &= ~(1<<1);
     940 +        break;
     941 +
     942 +    default:
     943 +        BUG();
     944 +    }
     945 +}
     946 +
     947 +
     948 +static int s3c24x0_dev_ready(struct mtd_info *mtd)
     949 +{
     950 +    struct s3c24x0_nand *nand = s3c24x0_get_base_nand();
     951 +    debug("dev_ready
    ");
     952 +    return readl(&nand->nfstat) & 0x01;
     953 +}
     954 +
     955 +#ifdef CONFIG_S3C2440_NAND_HWECC
     956 +void s3c24x0_nand_enable_hwecc(struct mtd_info *mtd, int mode)
     957 +{
     958 +    struct s3c24x0_nand *nand = s3c24x0_get_base_nand();
     959 +    debug("s3c24x0_nand_enable_hwecc(%p, %d)
    ", mtd, mode);
     960 +    writel(readl(&nand->nfconf) | S3C2440_NFCONF_INITECC, &nand->nfconf);
     961 +}
     962 +
     963 +static int s3c24x0_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
     964 +                      u_char *ecc_code)
     965 +{
     966 +    struct s3c24x0_nand *nand = s3c24x0_get_base_nand();
     967 +    ecc_code[0] = readb(&nand->nfecc);
     968 +    ecc_code[1] = readb(&nand->nfecc + 1);
     969 +    ecc_code[2] = readb(&nand->nfecc + 2);
     970 +    debug("s3c24x0_nand_calculate_hwecc(%p,): 0x%02x 0x%02x 0x%02x
    ",
     971 +          mtd , ecc_code[0], ecc_code[1], ecc_code[2]);
     972 +
     973 +    return 0;
     974 +}
     975 +
     976 +static int s3c24x0_nand_correct_data(struct mtd_info *mtd, u_char *dat,
     977 +                     u_char *read_ecc, u_char *calc_ecc)
     978 +{
     979 +    if (read_ecc[0] == calc_ecc[0] &&
     980 +        read_ecc[1] == calc_ecc[1] &&
     981 +        read_ecc[2] == calc_ecc[2])
     982 +        return 0;
     983 +
     984 +    printf("s3c24x0_nand_correct_data: not implemented
    ");
     985 +    return -1;
     986 +}
     987 +#endif
     988 +
     989 +int board_nand_init(struct nand_chip *nand)
     990 +{
     991 +    u_int32_t cfg;
     992 +    u_int8_t tacls, twrph0, twrph1;
     993 +    struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
     994 +    struct s3c24x0_nand *nand_reg = s3c24x0_get_base_nand();
     995 +
     996 +    debug("board_nand_init()
    ");
     997 +
     998 +    writel(readl(&clk_power->clkcon) | (1 << 4), &clk_power->clkcon);
     999 +
    1000 +    /* initialize hardware */
    1001 +#if defined(CONFIG_S3C24XX_CUSTOM_NAND_TIMING)
    1002 +    tacls  = CONFIG_S3C24XX_TACLS;
    1003 +    twrph0 = CONFIG_S3C24XX_TWRPH0;
    1004 +    twrph1 =  CONFIG_S3C24XX_TWRPH1;
    1005 +#else
    1006 +    tacls = 4;
    1007 +    twrph0 = 8;
    1008 +    twrph1 = 8;
    1009 +#endif
    1010 +    //cfg = S3C2440_NFCONF_EN;
    1011 +    cfg = S3C2440_NFCONF_TACLS(tacls - 1);
    1012 +    cfg |= S3C2440_NFCONF_TWRPH0(twrph0 - 1);
    1013 +    cfg |= S3C2440_NFCONF_TWRPH1(twrph1 - 1);
    1014 +    writel(cfg, &nand_reg->nfconf);
    1015 +
    1016 +    /* initialize nand_chip data structure */
    1017 +    nand->IO_ADDR_R = (void *)&nand_reg->nfdata;
    1018 +    nand->IO_ADDR_W = (void *)&nand_reg->nfdata;
    1019 +
    1020 +    /* read_buf and write_buf are default */
    1021 +    /* read_byte and write_byte are default */
    1022 +#ifdef CONFIG_NAND_SPL
    1023 +    nand->read_buf = nand_read_buf;
    1024 +#endif
    1025 +
    1026 +    /* hwcontrol always must be implemented */
    1027 +    nand->cmd_ctrl = s3c24x0_hwcontrol;
    1028 +
    1029 +    nand->dev_ready = s3c24x0_dev_ready;
    1030 +
    1031 +#ifdef CONFIG_S3C2440_NAND_HWECC
    1032 +    nand->ecc.hwctl = s3c24x0_nand_enable_hwecc;
    1033 +    nand->ecc.calculate = s3c24x0_nand_calculate_ecc;
    1034 +    nand->ecc.correct = s3c24x0_nand_correct_data;
    1035 +    nand->ecc.mode = NAND_ECC_HW;
    1036 +    nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE;
    1037 +    nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;
    1038 +    nand->ecc.strength = 1;
    1039 +#else
    1040 +    nand->ecc.mode = NAND_ECC_SOFT;
    1041 +#endif
    1042 +
    1043 +#ifdef CONFIG_S3C2440_NAND_BBT
    1044 +    nand->bbt_options |= NAND_BBT_USE_FLASH;
    1045 +#endif
    1046 +
    1047 +    /* 4 ECC
    1048 +     * 1 CE 先不选中,用的时候在选中
    1049 +     * 0 启动 flash controller
    1050 +     */
    1051 +    writel(1<<4 | 1<<1 | 1, &nand_reg->nfcont);
    1052 +    nand->select_chip = s3c2440_nand_select;
    1053 +
    1054 +
    1055 +    debug("end of nand_init
    ");
    1056 +
    1057 +    return 0;
    1058 +}
    1059 +
    1060 diff -urN u-boot-2016.03/include/configs/smdk2410.h u-boot-2016.03ok/include/configs/smdk2410.h
    1061 --- u-boot-2016.03/include/configs/smdk2410.h    2016-03-14 22:20:21.000000000 +0800
    1062 +++ u-boot-2016.03ok/include/configs/smdk2410.h    2016-05-12 08:31:46.907513241 +0800
    1063 @@ -18,10 +18,10 @@
    1064   * (easy to change)
    1065   */
    1066  #define CONFIG_S3C24X0        /* This is a SAMSUNG S3C24x0-type SoC */
    1067 -#define CONFIG_S3C2410        /* specifically a SAMSUNG S3C2410 SoC */
    1068 +#define CONFIG_S3C2440
    1069  #define CONFIG_SMDK2410        /* on a SAMSUNG SMDK2410 Board */
    1070  
    1071 -#define CONFIG_SYS_TEXT_BASE    0x0
    1072 +#define CONFIG_SYS_TEXT_BASE    0x33f00000
    1073  
    1074  
    1075  #define CONFIG_SYS_ARM_CACHE_WRITETHROUGH
    1076 @@ -49,16 +49,16 @@
    1077  /************************************************************
    1078   * USB support (currently only works with D-cache off)
    1079   ************************************************************/
    1080 -#define CONFIG_USB_OHCI
    1081 -#define CONFIG_USB_OHCI_S3C24XX
    1082 -#define CONFIG_USB_KEYBOARD
    1083 -#define CONFIG_USB_STORAGE
    1084 -#define CONFIG_DOS_PARTITION
    1085 +/*#define CONFIG_USB_OHCI */
    1086 +/*#define CONFIG_USB_OHCI_S3C24XX */
    1087 +/*#define CONFIG_USB_KEYBOARD */
    1088 +/*#define CONFIG_USB_STORAGE */
    1089 +/*#define CONFIG_DOS_PARTITION */
    1090  
    1091  /************************************************************
    1092   * RTC
    1093   ************************************************************/
    1094 -#define CONFIG_RTC_S3C24X0
    1095 +/*#define CONFIG_RTC_S3C24X0*/
    1096  
    1097  
    1098  #define CONFIG_BAUDRATE        115200
    1099 @@ -66,22 +66,22 @@
    1100  /*
    1101   * BOOTP options
    1102   */
    1103 -#define CONFIG_BOOTP_BOOTFILESIZE
    1104 -#define CONFIG_BOOTP_BOOTPATH
    1105 -#define CONFIG_BOOTP_GATEWAY
    1106 -#define CONFIG_BOOTP_HOSTNAME
    1107 +/*#define CONFIG_BOOTP_BOOTFILESIZE*/
    1108 +/*#define CONFIG_BOOTP_BOOTPATH*/
    1109 +/*#define CONFIG_BOOTP_GATEWAY*/
    1110 +/*#define CONFIG_BOOTP_HOSTNAME*/
    1111  
    1112  /*
    1113   * Command line configuration.
    1114   */
    1115 -#define CONFIG_CMD_BSP
    1116 +/*#define CONFIG_CMD_BSP*/
    1117  #define CONFIG_CMD_CACHE
    1118 -#define CONFIG_CMD_DATE
    1119 -#define CONFIG_CMD_DHCP
    1120 +/*#define CONFIG_CMD_DATE*/
    1121 +/*#define CONFIG_CMD_DHCP*/
    1122  #define CONFIG_CMD_NAND
    1123  #define CONFIG_CMD_PING
    1124 -#define CONFIG_CMD_REGINFO
    1125 -#define CONFIG_CMD_USB
    1126 +/*#define CONFIG_CMD_REGINFO*/
    1127 +/*#define CONFIG_CMD_USB*/
    1128  
    1129  #define CONFIG_SYS_HUSH_PARSER
    1130  #define CONFIG_CMDLINE_EDITING
    1131 @@ -93,8 +93,8 @@
    1132  #define CONFIG_ZERO_BOOTDELAY_CHECK
    1133  
    1134  #define CONFIG_NETMASK        255.255.255.0
    1135 -#define CONFIG_IPADDR        10.0.0.110
    1136 -#define CONFIG_SERVERIP        10.0.0.1
    1137 +#define CONFIG_IPADDR        192.168.1.88
    1138 +#define CONFIG_SERVERIP        192.168.1.1
    1139  
    1140  #if defined(CONFIG_CMD_KGDB)
    1141  #define CONFIG_KGDB_BAUDRATE    115200    /* speed to run kgdb serial port */
    1142 @@ -167,24 +167,27 @@
    1143   * NAND configuration
    1144   */
    1145  #ifdef CONFIG_CMD_NAND
    1146 -#define CONFIG_NAND_S3C2410
    1147 -#define CONFIG_SYS_S3C2410_NAND_HWECC
    1148  #define CONFIG_SYS_MAX_NAND_DEVICE    1
    1149  #define CONFIG_SYS_NAND_BASE        0x4E000000
    1150 +#define CONFIG_NAND_S3C2440
    1151 +#define CONFIG_S3C24XX_CUSTOM_NAND_TIMING
    1152 +#define CONFIG_S3C24XX_TACLS        1
    1153 +#define CONFIG_S3C24XX_TWRPH0        2
    1154 +#define CONFIG_S3C24XX_TWRPH1        1
    1155  #endif
    1156  
    1157  /*
    1158   * File system
    1159   */
    1160 -#define CONFIG_CMD_FAT
    1161 -#define CONFIG_CMD_EXT2
    1162 -#define CONFIG_CMD_UBI
    1163 -#define CONFIG_CMD_UBIFS
    1164 +/*#define CONFIG_CMD_FAT*/
    1165 +/*#define CONFIG_CMD_EXT2*/
    1166 +/*#define CONFIG_CMD_UBI*/
    1167 +/*#define CONFIG_CMD_UBIFS*/
    1168  #define CONFIG_CMD_MTDPARTS
    1169  #define CONFIG_MTD_DEVICE
    1170  #define CONFIG_MTD_PARTITIONS
    1171  #define CONFIG_YAFFS2
    1172 -#define CONFIG_RBTREE
    1173 +/*#define CONFIG_RBTREE*/
    1174  
    1175  /* additions for new relocation code, must be added to all boards */
    1176  #define CONFIG_SYS_SDRAM_BASE    PHYS_SDRAM_1
    1177 diff -urN u-boot-2016.03/include/configs/smdk2440.h u-boot-2016.03ok/include/configs/smdk2440.h
    1178 --- u-boot-2016.03/include/configs/smdk2440.h    1970-01-01 07:00:00.000000000 +0700
    1179 +++ u-boot-2016.03ok/include/configs/smdk2440.h    2016-05-20 17:44:46.556075095 +0800
    1180 @@ -0,0 +1,171 @@
    1181 +/*
    1182 + * (C) Copyright 2002
    1183 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
    1184 + * Marius Groeger <mgroeger@sysgo.de>
    1185 + * Gary Jennejohn <garyj@denx.de>
    1186 + * David Mueller <d.mueller@elsoft.ch>
    1187 + *
    1188 + * Configuation settings for the SAMSUNG SMDK2440 board.
    1189 + *
    1190 + * SPDX-License-Identifier:    GPL-2.0+
    1191 + */
    1192 +
    1193 +#ifndef __CONFIG_H
    1194 +#define __CONFIG_H
    1195 +
    1196 +/*
    1197 + * High Level Configuration Options
    1198 + * (easy to change)
    1199 + */
    1200 +#define CONFIG_S3C24X0        /* This is a SAMSUNG S3C24x0-type SoC */
    1201 +#define CONFIG_S3C2440        /* specifically a SAMSUNG S3C2440 SoC */
    1202 +#define CONFIG_SMDK2440        /* on a SAMSUNG SMDK2440 Board */
    1203 +
    1204 +#define CONFIG_SYS_TEXT_BASE    0x30a00000/*0x33f00000*/
    1205 +
    1206 +
    1207 +#define CONFIG_SYS_ARM_CACHE_WRITETHROUGH
    1208 +
    1209 +/* input clock of PLL (the SMDK2440 has 12MHz input clock) */
    1210 +#define CONFIG_SYS_CLK_FREQ    12000000
    1211 +
    1212 +#define CONFIG_CMDLINE_TAG    /* enable passing of ATAGs */
    1213 +#define CONFIG_SETUP_MEMORY_TAGS
    1214 +#define CONFIG_INITRD_TAG
    1215 +
    1216 +/* 放在NAND FLASH 中 大小 128K 开始地址  */
    1217 +#define CONFIG_ENV_IS_IN_NAND
    1218 +#define CONFIG_SYS_ENV_SECT_SIZE    (128 << 10)
    1219 +#define CONFIG_ENV_OFFSET            (256<<10)
    1220 +#define CONFIG_ENV_SIZE    CONFIG_SYS_ENV_SECT_SIZE
    1221 +
    1222 +
    1223 +/* 添加兼容 yaffs2 烧写支持 */
    1224 +#define CONFIG_CMD_NAND_YAFFS
    1225 +#define CONFIG_CMD_MTDPARTS    /* Enable MTD parts commands */
    1226 +#define CONFIG_MTD_DEVICE    /* needed for mtdparts commands */
    1227 +#define MTDIDS_DEFAULT            "nand0=nand"
    1228 +#define MTDPARTS_DEFAULT        "mtdparts=nand:256k(bootloader),"
    1229 +                                "128k(params),"
    1230 +                                "2m(kernel),-(root)"
    1231 +
    1232 +#define CONFIG_BOOTARGS "noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0"
    1233 +#define CONFIG_BOOTCOMMAND "nand read.jffs2 0x30007FC0 kernel; bootm 0x30007FC0"
    1234 +
    1235 +/*
    1236 + * Hardware drivers
    1237 + */
    1238 +#define CONFIG_DRIVER_DM9000
    1239 +#define CONFIG_DM9000_BASE 0x20000000
    1240 +#define DM9000_IO        CONFIG_DM9000_BASE
    1241 +#define DM9000_DATA        (CONFIG_DM9000_BASE+4)
    1242 +#define CONFIG_NETMASK        255.255.255.0
    1243 +#define CONFIG_IPADDR        192.168.1.123
    1244 +#define CONFIG_SERVERIP        192.168.1.100
    1245 +#define CONFIG_ETHADDR "00:50:56:C0:00:08"
    1246 +
    1247 +/*
    1248 + * select serial console configuration
    1249 + */
    1250 +#define CONFIG_S3C24X0_SERIAL
    1251 +#define CONFIG_SERIAL1        1    /* we use SERIAL 1 on SMDK2440 */
    1252 +
    1253 +
    1254 +
    1255 +#define CONFIG_BAUDRATE        115200
    1256 +
    1257 +
    1258 +#define CONFIG_CMD_PING
    1259 +
    1260 +/* autoboot */
    1261 +#define CONFIG_BOOTDELAY    5
    1262 +#define CONFIG_BOOT_RETRY_TIME    -1
    1263 +#define CONFIG_RESET_TO_RETRY
    1264 +#define CONFIG_ZERO_BOOTDELAY_CHECK
    1265 +
    1266 +
    1267 +#if defined(CONFIG_CMD_KGDB)
    1268 +#define CONFIG_KGDB_BAUDRATE    115200    /* speed to run kgdb serial port */
    1269 +#endif
    1270 +
    1271 +/*
    1272 + * Miscellaneous configurable options
    1273 + */
    1274 +#define CONFIG_SYS_LONGHELP        /* undef to save memory */
    1275 +#define CONFIG_SYS_CBSIZE    256
    1276 +/* Print Buffer Size */
    1277 +#define CONFIG_SYS_PBSIZE    (CONFIG_SYS_CBSIZE + 
    1278 +                sizeof(CONFIG_SYS_PROMPT)+16)
    1279 +#define CONFIG_SYS_MAXARGS    16
    1280 +#define CONFIG_SYS_BARGSIZE    CONFIG_SYS_CBSIZE
    1281 +
    1282 +#define CONFIG_DISPLAY_CPUINFO                /* Display cpu info */
    1283 +
    1284 +#define CONFIG_SYS_MEMTEST_START    0x30000000    /* memtest works on */
    1285 +#define CONFIG_SYS_MEMTEST_END        0x33F00000    /* 63 MB in DRAM */
    1286 +
    1287 +#define CONFIG_SYS_LOAD_ADDR        0x30800000
    1288 +
    1289 +/* support additional compression methods */
    1290 +#define CONFIG_BZIP2
    1291 +#define CONFIG_LZO
    1292 +#define CONFIG_LZMA
    1293 +
    1294 +/*-----------------------------------------------------------------------
    1295 + * Physical Memory Map
    1296 + */
    1297 +#define CONFIG_NR_DRAM_BANKS    1          /* we have 1 bank of DRAM */
    1298 +#define PHYS_SDRAM_1        0x30000000 /* SDRAM Bank #1 */
    1299 +#define PHYS_SDRAM_1_SIZE    0x04000000 /* 64 MB */
    1300 +
    1301 +#define PHYS_FLASH_1        0x00000000 /* Flash Bank #0 */
    1302 +
    1303 +#define CONFIG_SYS_FLASH_BASE    PHYS_FLASH_1
    1304 +
    1305 +/*-----------------------------------------------------------------------
    1306 + * FLASH and environment organization
    1307 + */
    1308 +
    1309 +#define CONFIG_SYS_FLASH_CFI
    1310 +#define CONFIG_FLASH_CFI_DRIVER
    1311 +#define CONFIG_FLASH_CFI_LEGACY
    1312 +#define CONFIG_SYS_FLASH_LEGACY_512Kx16
    1313 +#define CONFIG_FLASH_SHOW_PROGRESS    45
    1314 +
    1315 +#define CONFIG_SYS_MAX_FLASH_BANKS    1
    1316 +#define CONFIG_SYS_FLASH_BANKS_LIST     { CONFIG_SYS_FLASH_BASE }
    1317 +#define CONFIG_SYS_MAX_FLASH_SECT    (35)
    1318 +
    1319 +
    1320 +/*
    1321 + * Size of malloc() pool
    1322 + * BZIP2 / LZO / LZMA need a lot of RAM
    1323 + */
    1324 +#define CONFIG_SYS_MALLOC_LEN    (4 * 1024 * 1024)
    1325 +
    1326 +#define CONFIG_SYS_MONITOR_LEN    (448 * 1024)
    1327 +#define CONFIG_SYS_MONITOR_BASE    CONFIG_SYS_FLASH_BASE
    1328 +
    1329 +#define CONFIG_CMD_NAND
    1330 +/*
    1331 + * NAND configuration
    1332 + */
    1333 +#ifdef CONFIG_CMD_NAND
    1334 +#define CONFIG_NAND_S3C2440
    1335 +#define CONFIG_SYS_MAX_NAND_DEVICE    1
    1336 +#define CONFIG_SYS_NAND_BASE        0x4E000000
    1337 +#define CONFIG_S3C24XX_CUSTOM_NAND_TIMING 
    1338 +#define CONFIG_S3C24XX_TACLS  1
    1339 +#define CONFIG_S3C24XX_TWRPH0 2
    1340 +#define CONFIG_S3C24XX_TWRPH1 1
    1341 +
    1342 +#endif
    1343 +
    1344 +/* additions for new relocation code, must be added to all boards */
    1345 +#define CONFIG_SYS_SDRAM_BASE    PHYS_SDRAM_1
    1346 +#define CONFIG_SYS_INIT_SP_ADDR    (CONFIG_SYS_SDRAM_BASE + 0x1000 - 
    1347 +                GENERATED_GBL_DATA_SIZE)
    1348 +
    1349 +#define CONFIG_BOARD_EARLY_INIT_F
    1350 +
    1351 +#endif /* __CONFIG_H */
    1352 diff -urN u-boot-2016.03/include/env_default.h u-boot-2016.03ok/include/env_default.h
    1353 --- u-boot-2016.03/include/env_default.h    2016-03-14 22:20:21.000000000 +0800
    1354 +++ u-boot-2016.03ok/include/env_default.h    2016-05-18 20:31:50.860466037 +0800
    1355 @@ -22,6 +22,10 @@
    1356  #else
    1357  const uchar default_environment[] = {
    1358  #endif
    1359 +#ifdef    CONFIG_ETHADDR    
    1360 +    "ethaddr=" CONFIG_ETHADDR ""
    1361 +#endif
    1362 +
    1363  #ifdef    CONFIG_ENV_CALLBACK_LIST_DEFAULT
    1364      ENV_CALLBACK_VAR "=" CONFIG_ENV_CALLBACK_LIST_DEFAULT ""
    1365  #endif
    1366 diff -urN u-boot-2016.03/include/nand.h u-boot-2016.03ok/include/nand.h
    1367 --- u-boot-2016.03/include/nand.h    2016-03-14 22:20:21.000000000 +0800
    1368 +++ u-boot-2016.03ok/include/nand.h    2016-05-20 17:44:57.399450808 +0800
    1369 @@ -99,6 +99,8 @@
    1370  int nand_read_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
    1371                 size_t *actual, loff_t lim, u_char *buffer);
    1372  
    1373 +#define WITH_YAFFS_OOB    (1 << 0) /* whether write with yaffs format. This flag                  * is a 'mode' meaning it cannot be mixed with                  * other flags */
    1374 +
    1375  #define WITH_DROP_FFS    (1 << 0) /* drop trailing all-0xff pages */
    1376  #define WITH_WR_VERIFY    (1 << 1) /* verify data was written correctly */
    1377  
    1378 diff -urN u-boot-2016.03/Makefile u-boot-2016.03ok/Makefile
    1379 --- u-boot-2016.03/Makefile    2016-03-14 22:20:21.000000000 +0800
    1380 +++ u-boot-2016.03ok/Makefile    2016-05-09 08:38:00.046292963 +0800
    1381 @@ -7,7 +7,8 @@
    1382  SUBLEVEL =
    1383  EXTRAVERSION =
    1384  NAME =
    1385 -
    1386 +ARCH=arm
    1387 +CROSS_COMPILE=arm-linux-
    1388  # *DOCUMENTATION*
    1389  # To see a list of typical targets execute "make help"
    1390  # More info can be located in ./README
    1391 Binary files u-boot-2016.03/.swp and u-boot-2016.03ok/.swp differ




  • 相关阅读:
    中小企业需要企业邮箱吗?中小性公司选什么邮箱性价比高?
    主流电子邮箱有哪些?你的邮箱选对了吗?
    外贸邮箱选择什么企业邮箱更安全?
    企业邮箱适用于哪些行业?公司邮箱都用什么?
    如何注册公司收费邮箱?注册公司邮箱有哪些优势?
    convert_cyr_string — 将字符由一种 Cyrillic 字符转换成另一种
    chunk_split — 将字符串分割成小块
    addslashes — 使用反斜线引用字符串
    addcslashes — 以 C 语言风格使用反斜线转义字符串中的字符
    extract — 从数组中将变量导入到当前的符号表
  • 原文地址:https://www.cnblogs.com/ningci/p/5513452.html
Copyright © 2020-2023  润新知