레이블이 IF-NAND인 게시물을 표시합니다. 모든 게시물 표시
레이블이 IF-NAND인 게시물을 표시합니다. 모든 게시물 표시

12/19/2016

DM8148의 NAND 와 UBIFS 문제 (Power-Cut)

1. Background 

DM8148 Board를 고객에게 Board를 제작해주고, 1년 동안 잘동작이 되었지만, 1년이 지난후 갑자기 문제가 발생이 되어
아래와 같이 원인분석을 하기 시작하였다. 고객은 갑자기 그렇다고 하는데, 일단 사용보드 2개가 동일한 증상을 보여 문제사항을 분석하기로 하였다.


1.1 문제사항

Booting 할때마다 아래와 같이 Kernel에서 Mount할때 UBIFS의 Recovery Mode를 진입을하여,
이를 매번실패한 후 Booting이 되지 않고 에러 발생.

  • UBIFS 문제점 
UBI: attaching mtd4 to ubi0
UBI: physical eraseblock size:   131072 bytes (128 KiB)
UBI: logical eraseblock size:    126976 bytes
UBI: smallest flash I/O unit:    2048
UBI: sub-page size:              512
UBI: VID header offset:          2048 (aligned 2048)
UBI: data offset:                4096
UBI: max. sequence number:       240
UBI: attached mtd4 to ubi0
UBI: MTD device name:            "File System"
UBI: MTD device size:            505 MiB
UBI: number of good PEBs:        4040
UBI: number of bad PEBs:         2                        // bad block marking 잘 동작 
UBI: number of corrupted PEBs:   0
UBI: max. allowed volumes:       128
UBI: wear-leveling threshold:    4096
UBI: number of internal volumes: 1
UBI: number of user volumes:     1
UBI: available PEBs:             0
UBI: total number of reserved PEBs: 4040
UBI: number of PEBs reserved for bad PEB handling: 40
UBI: max/mean erase counter: 2/0
UBI: image sequence number:  214330113
UBI: background thread "ubi_bgt0d" started, PID 38
....
UBIFS: recovery needed
UBIFS error (pid 1): replay_log_leb: log error detected while replaying the log at LEB 3:0
List of all partitions:
1f00             128 mtdblock0  (driver?)
1f01            2304 mtdblock1  (driver?)
1f02             128 mtdblock2  (driver?)
1f03            4352 mtdblock3  (driver?)
1f04          517376 mtdblock4  (driver?)
No filesystem could mount root, tried:  ubifs
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
Backtrace: 
[] (dump_backtrace+0x0/0x110) from [] (dump_stack+0x18/0x1c)
 r7:d6412000 r6:c006d928 r5:c002c4c4 r4:c0472b90
[] (dump_stack+0x0/0x1c) from [] (panic+0x60/0x17c)
[] (panic+0x0/0x17c) from [] (mount_block_root+0x1e0/0x220)
 r3:00000000 r2:00000020 r1:d643bf78 r0:c03cce1c
[] (mount_block_root+0x0/0x220) from [] (prepare_namespace+0x94/0x1d4)
[] (prepare_namespace+0x0/0x1d4) from [] (kernel_init+0x114/0x154)
 r5:c00086b0 r4:c0472340
[] (kernel_init+0x0/0x154) from [] (do_exit+0x0/0x5e4)
 r5:c00086b0 r4:00000000


2. UBOOT에서 기본 TEST 및 문제진단


uboot에서 기본적으로 tftp를 이용하여, kernel 및 filesystem을 download 후 이를 다시 NAND에 write 한 후 NAND Boot를 하면 한번은 제대로 동작이 된다.

처음과 같이 전원단에 갑자기 On/Off를 하면 상위와 동일한 증상이 발생한다.

2.1 UBOOT에서 Bad Block TEST

상위 테스트로 일단 Kernel Image와 Filesystem Image에는 문제가 없다고 판단이 되었다.

SLC Type의 NAND 이지만 Bad Block문제라고 생각이 되어 이를 UBOOT에서 Bad Block을 직접 설정하고 해결하려고 했다. (BBT설정 )

  • NAND의 bad block 검출방법
RAM의 Image와 NAND Image를 비교하여 틀린 곳을 발견  
  
U-Boot#  tftp 0x81000000 file_system.img
Bytes transferred = 140771328 (8640000 hex)  

U-Boot#  nand read 0xA0000000 0x6c0000 0x8640000
// 35192832 = 140771328/4 bytes 

U-Boot#  cmp 0x81000000 0xA0000000 35192832
word at 0x8100000c (0x00000000) != word at 0xa000000c (0x01000000)
Total of 3 words were the same 

  // 0x8100000c - 0x81000000 = 0xc + 0x6c0000 
  // 0xa000000c - 0xA0000000 = 0xc + 0x6c0000



  • NAND에  Bad block를 Marking
아래와 같이 문제가되는 Block을 Bad Block이라고 직접 Marking 을 한다 
  
U-Boot#  nand markbad 0x6c000C
U-Boot#  nand bad 
006c0000

// Nand bad block maring 2nd Test 

U-Boot#  nand read 0xA0000000 0x6c0000 0x8640000
U-Boot#  cmp 0x81000000 0xA0000000 35192832

word at 0x897423c4 (0xff7fffff) != word at 0xa87423c4 (0xffffffff)
Total of 35457265 words were the same

  // 0x897423c4 - 0x81000000 = 0x087423C4 + 0x006c0000 = 0x08E023C4 --> read size를 초과했다. 
  // 위 로그를 보면 나의 count 보다 초과 했다. 다른 곳 위치가 filesystem의 범위를 벗어났다. 

위와 같이 진행을 하여 Bad Block을 Marking을 여러번 한 후 TEST를 했으나, 결과는 동일하게 나타났으며, 그 원인을 Bad Block이 아닌 다른문제로 보기로 하였다.
( 물론 Uboot Loader와 Kernel 사이의 Bad block Table의 호환성도 확인해야한다)


2.2 UBIFS 설정변경 

원래 문제를 다시 분석을 해보면, 초반 한번은 제대로 Booting이 된다 , 그리고, 그 다음 Power on/off를 하면 이 문제가 다시 발생을 하는데, 이때 NAND에 무슨 문제가
발생한다고 생각해서 아래와 같이 Kernel의 Argument를 변경하였다.

현재 kernel argument이며, 현재 mtd4에 page size 2048로 설정되어있으며 rw이기때문에 이를 ro로 변경
 
set bootargs "console=ttyO0,115200n8 earlyprintk noinitrd rootwait=1 rw ubi.mtd=4,2048 rootfstype=ubifs root=ubi0:rootfs notifyk.vpssm3_sva=0xBF900000 mem=364M@0x80000000 mem=320M@0x9FC00000 mem=1023M@0xC0000000 vmalloc=500M ip=none vram=50M ti814xfb.vram=0:24M,1:16M,2:6M"

  • read only 변경후 해결 (임시방편)
read only로 하면 , 즉 ro , 변경하면 동작은 위 문제는 해결이 되었다. 
 
set bootargs "console=ttyO0,115200n8 earlyprintk noinitrd rootwait=1 ro ubi.mtd=4,2048 rootfstype=ubifs root=ubi0:rootfs notifyk.vpssm3_sva=0xBF900000 mem=364M@0x80000000 mem=320M@0x9FC00000 mem=1023M@0xC0000000 vmalloc=500M ip=none vram=50M ti814xfb.vram=0:24M,1:16M,2:6M"

  • UBIFS mount 및 kernel argument 
   http://processors.wiki.ti.com/index.php/UBIFS_Support

ro로 하면 문제는 해결이 되지만, UBIFS라는 것이 RW를 사용하기위해서 사용하는것이 목적일텐데, 이것은 해결이 아니고, 임시방편이라고 생각이 들어
다음과 같이 근본적인 원인을 더 분석하기로하였다.

2.3 UBIFS의 문제사항 파악 

UBIFS에서 왜 Recovery를 하는 지 정확한 원인을 알기 위해서 찾던도중 The unstable bits issue라는 것이있다는 것을 알게되었다.
원인은 잦은 Power Cut때문에 위와 같은 문제발생이 된다고 하는데, 예를들면 CPU는 NAND에게 CMD 주고 NAND가 이를 처리하는 도중
지속적으로 전원이 나가면 이런 문제가 발생이 된다고 한다.
현재 우리 보드가 Reset 버튼을 찾기 어려워서 자주 Power를 뽑게되어 있어, 이런문제가 발생한것 같다. (본인도, Reset보다는 Power on/off를 함)


현재 회로도를 보면, PMIC와 DM8148은 연결이 되어있고, PMIC는 SMPS가 지원이 되기때문에, Switch용으로 Capacitor 사용하지만, 현재 이부분과 연관이 있을 것 같다. (추측)
전원이 나가면, SOC에게는 CMD를 주는 여러번의 기회를 주지만, NAND에서 이를 처리할 시간이 없어서 발생하는 문제이니, HW적으로도
이부분은 문제일것이라고 생각이 들면 이부분은 더 살펴보아야 할 것 같다.

시간이 더 허락이 된다면, 추후 회로도와 관련사항을 더 봐야할 것 같다.

  • The unstable bits issue
   http://www.linux-mtd.infradead.org/doc/ubifs.html#L_unstable_bits

  • UBIFS 관련내용 
   http://www.linux-mtd.infradead.org/doc/ubifs.html

  UBIFS의 구조 및 동작원리
  https://bootlin.com/pub/conferences/2016/elce/brezillon-ubi-mlc/ubi-mlc.pdf

  • 구글링을 해서 나와 유사한 문제를 찾았다. 
   http://forum.doozan.com/read.php?2,907,919

 
3. 결론 


3.1 NAND Power-Cut의 문제사항


Power-cut이라는 것이 전원공급을 갑자기 중단하는 방법을 말한다.

  • Unstable bits issue란? 
이용어는 NAND가 write or erase 하는 도중  power-cut 으로 발생되는 불안정한 BIT오류를 말한다.

처음 튼튼한 SLC (robust SLC) 인 경우와 NOR Type에는 나온적이 아직은 없다고 하지만,
현재의 SLC와 MLC에 공통적으로 나오는 현상이라고 한다.
이 문제는 아직 해결이 되지 않았으며, 어느 flash건 나올 수 있다. (UBIFS에서도 해결이 안됨)

잦은 power-cut으로 인하여 NAND 안에는 unstable bits가 존재하며, 이 bit들이 증가하여,
ECC가 이를 보정 못했을 경우 문제가 확산이 되는 경우 발생한다.

UBIFS 경우 이 문제가 발생이되면 ECC Error가 발생이되고 recovery mode 들어가 복구를 시도 하지만 복구가 제대로 안되는 경우가 발생이 한다.
이 때 File system은 오류가 생기고 에러가 발생이된다.
인터넷 글을 읽어보면, 이것은 불안전한 bit이기 때문에 제대로 read가 될 경우도 있다.
그래서 제대로 동작이 될 경우도 있지만, 문제가 지속되는 경우도 발생한다.

결론은 항상 unstable bits는 NAND안에 존재하지만 이는 power-cut에 의해 발생이 되며,
그리고 기본적으로 ECC 알고리즘이 이를 복구를 해주지만, 이 unstalbe bit 가 증가하면 
이를 복구를 못해주어 문제가 발생한다.

* unstable bits : power cut으로 발생으로 되며, NAND안에서 존재하게된다.
* ECC (Error-correcting code) (1bit/4bit ECC)
* bit-flip: 외부의 요인으로 bit가 변경되는 현상, (heat or power cut or low voltage)

unstalbe bits란?
  http://www.linux-mtd.infradead.org/doc/ubifs.html#L_unstable_bits

  • Power Cut Off Interval 비교 (아래 논문참고)
Power Cut off interval은 아래의 논문을 보면,CPU에서 Command 가 NAND에 실행되는 시간부터 Power를 off하는 시간의 간격이다.
이에 따라 간단히 에러율을 볼수가 있는데,  (논문내용을 함부로 가져올수가 없어서)
간단히 정리해본다.

4.1 Program and power failure (논문)
SLC마다 다르지만, 대체적으로  Power cut off는 100ms기반으로 에러율이 많이 틀려지는 것 같다.

4.2 Erase and power failure (논문)
확실히 Erase Command가 실행시간이 오래걸리며, 생각을 해봐도, Block 단위로 할테니,
시간이 많이 걸리는 것 같다.
그래서, 위와 다르게 SLC type 마다 너무 다 다르다.

이는 개별 NAND datasheet에서 Command 실행시간을 확인을 해봐야 할 것같다.


  • 관련논문 
  https://cseweb.ucsd.edu/~swanson/papers/DAC2011PowerCut.pdf


  • Software 해결방안 (unstable bits)
UBIFS 사용할 경우 recovery mode로 인하여 잘못 복구되어서 문제가 확산이 된다.
하지만, yaffs의 구조가 어떻게 작동이 되는지는 정확히 모르겠지만, 이 부분에 있어서
UBIFS보다 낫다고 한다.
Yaffs로 변경이 되어다고 해서 완전히 해결이 되는 문제는 아니지만 발생빈도가 줄어드는것같다.

  위 내용은 아래 참조 (HW내용도 기술됨)
  http://yaffs.net/lurker/message/20140710.203207.b2255691.it.html


  • Hardware 해결방안 (unstable bits)
NAND의 Power 관련인 VCC에 Decoupling Capacitor 달아주는 거나 이에 관련된 부분을 검토하는 것이다.
그리고 가능하다면 회로도가 넓이 및 다른 것도 고려해야 하는 것 같다.

물론 근본적 원인은  power-cut이 될 경우 NAND Controller인 SOC는 먼저 종료가 되는 것 이지만,
Power-Cut 동안 이미 받은 NAND가 Command를 받아 처리하는 것을 완료될때까지 잠시지연시키는 것이 HW 최대 해결방안이다.





  • 상위회로도 아래와 동일
  https://e2e.ti.com/support/arm/sitara_arm/f/791/t/358906

  • NAND or DDR HW 설계시 알아야할 기본내용 
  bypass (decoupling) capacitor 관련내용
  http://magicom9.tistory.com/78

12/07/2016

Uboot Nand Command 와 설정확인

1. Uboot env 설정 확인 및 설정 

TI-Davinci Series를 다시 사용할줄을 몰랐으며, 이 오래된 모델을 대학원 교육용으로 팔기위해서 간단히 설정정리하고자 한다.

  • Board Information (RAM Info)
U-Boot# bdinfo
arch_number = 0x00000BBC
env_t       = 0x00000000
boot_params = 0x80000100
DRAM bank   = 0x00000000
-> start    = 0x80000000
-> size     = 0x40000000
DRAM bank   = 0x00000001
-> start    = 0xC0000000
-> size     = 0x40000000
ethaddr     = d0:ff:50:af:35:52
ip_addr     = 192.168.1.78
baudrate    = 115200 bps

  • NAND info 
U-Boot# nand info
Device 0: nand0, sector size 128 KiB

  • Uboot default env info
U-Boot# pri
bootdelay=3
baudrate=115200
autoload=yes
verify=yes
bootfile=uImage
ramdisk_file=ramdisk.gz
loadaddr=0x81000000
script_addr=0x80900000
loadbootscript=fatload mmc 0 ${script_addr} boot.scr
bootscript= echo Running bootscript from MMC/SD to set the ENV...; source ${script_addr}
ethaddr=d0:ff:50:af:35:52
ethact=cpsw
ipaddr=192.168.219.201
serverip=192.168.219.112
bootcmd=nand read 0x81000000 0x00280000 0x300000;bootm 0x81000000
bootargs=console=ttyO0,115200n8 earlyprintk noinitrd rootwait=1 rw ubi.mtd=4,2048 rootfstype=ubifs root=ubi0:rootfs notifyk.vpssm3_sva=0xBF900000 mem=364M@0x80000000 mem=320M@0x9FC00000 mem=1023M@0xC0000000 vmalloc=500M ip=none vram=50M ti814xfb.vram=0:24M,1:16M,2:6M

DM368 IPNC :>pri
bootdelay=4
baudrate=115200
bootfile="uImage"
setboot=setenv bootargs $(bootargs)
broadcast=192.168.0.255
gateway=192.168.0.1
ethaddr=00:0C:0C:A0:04:22
verify=no
filesize=2100000
fileaddr=82000000
netmask=255.255.255.0
ipaddr=192.168.0.207
serverip=192.168.0.210
bootcmd=nboot 0x80700000 0 0x500000;bootm 0x80700000
bootargs=mem=48M console=ttyS1,115200n8 noinitrd ip=192.168.1.168:192.168.1.210:192.168.1.1:255.255.255.0:::off rw ubi.mtd=3,2048 rootfstype=ubifs root=ubi0:rootfs cmemk.phys_start=0x83000000 cmemk.phys_end=0x88000000 cmemk.phys_start_1=0x00001000 cmemk.phys_end_1=0x00008000 cmemk.pools_1=1x28672 cmemk.allowOverlap=1 cmemk.useHeapIfPoolUnavailable=1 nohz=off highres=off clocksource=acpi_pm lpj=1077248 eth=00:0C:0C:A0:04:22
stdin=serial
stdout=serial
stderr=serial
ver=U-Boot 1.3.4 (Jun  5 2013 - 12:45:48) DM368-IPNC-5.1.0

Environment size: 843/131068 bytes


CPSW관련
  http://processors.wiki.ti.com/index.php/AM335x_CPSW_(Ethernet)_Driver's_Guide

  • Uboot Config 
U-BOOT는 환경설정은 Device의 의존적인 환경변수존재하며, Uboot도 Kernel Config처럼 Config를 설정하여 추가하고 싶을 설정,
즉 Command를 추가가능하다. 또한 Config 설정에서 각각의 프롬프트 이름을 비롯하여 default env 설정부분을 Uboot Source에서 직접 변경가능하다.

아래는 기본적인 테스트이며, 최종으로 본인의 default env 설정확정되면, Uboot Source에서 default env 관련 부분을 수정하도록 하자.

1.1. Uboot 에서 Kernel 부팅시 문제사항 정리 

  • U-BOOT에서 uncompressing 한 후 바로 멈춤경우
Bytes transferred = 2720236 (2981ec hex)
## Booting kernel from Legacy Image at 81000000 ...
   Image Name:   Linux-2.6.37
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    2720172 Bytes = 2.6 MiB
   Load Address: 80008000
   Entry Point:  80008000
   Verifying Checksum ... OK
   Loading Kernel Image ... OK
OK

Starting kernel ...

Uncompressing Linux... done, booting the kernel.  


  • 기본Boot 문제해결방법 (이외방법은 아래 사이트 참조)
Serial 설정 문제확인
bootargs 설정문제 해결하기위해서 uboot에 rootwait를 추가.

printenv bootargs
bootargs=console=ttyS2,115200n8 root=/dev/mmcblk0p2 rw rootwait

세부사항은 kernel argument 참조
  https://linux-sunxi.org/Kernel_arguments

  • 일반적인 Boot 문제사항들 (아래사이트 확인) 
일반적으로 boot 시 발생하는 문제사항 정리
  http://processors.wiki.ti.com/index.php/Kernel_-_Common_Problems_Booting_Linux
bootmem 에러나서 관련내용
  http://jake.dothome.co.kr/bootmem/

  • U-BOOT NAND 문제사항
   jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at
   https://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/716/t/244611
   http://naito.tistory.com/entry/jffs2scaneraseblock-Magic-bitmask-0x1985-not-found-at-0x0000fcac-0x0b45-instead

  • NXP에서 제공하고 U-Boot Quick Reference
IMX6을 하면서 읽게되었지만, 역시 문서가 쉽고 이해하기가 쉬운거 같다
  http://www.nxp.com/files/32bit/doc/quick_ref_guide/MEDIA5200UBPG/MEDIA5200UBPG.pdf


1.2. Uboot 기본환경변수로 테스트  

Uboot가 booting 한 후 Uboot의 bootdelay 설정시간이후에 Uboot의 bootcmd는 자동실행되어 Uboot의 bootargs를 kernel에 전달하여 Kernel Boot를 진행한다.


  • DM368 설정 (bootcmd)
DM368 IPNC :> setenv verify no                                  // CRC에러 
DM368 IPNC :> setenv bootcmd 'nboot 0x80700000 0 0x500000;bootm 0x80700000'

  • DM8147 설정(bootargs)
아래와 같이 ${} 본인이 원하는 환경변수 별도로 이용하여 각 설정을 변경

U-Boot# setenv bootargs_ubifsrw "console=ttyO0,115200n8 earlyprintk noinitrd rootwait=1 rw ubi.mtd=4,2048 rootfstype=ubifs root=ubi0:rootfs notifyk.vpssm3_sva=0xBF900000 mem=364M@0x80000000 mem=320M@0x9FC00000 mem=1023M@0xC0000000 vmalloc=500M ip=none vram=50M ti814xfb.vram=0:24M,1:16M,2:6M"
U-Boot# setenv bootargs_ubifsro "console=ttyO0,115200n8 earlyprintk noinitrd rootwait=1 ro ubi.mtd=4,2048 rootfstype=ubifs root=ubi0:rootfs notifyk.vpssm3_sva=0xBF900000 mem=364M@0x80000000 mem=320M@0x9FC00000 mem=1023M@0xC0000000 vmalloc=500M ip=none vram=50M ti814xfb.vram=0:24M,1:16M,2:6M"
U-Boot# setenv bootargs "${bootargs_ubifsro}" 
U-Boot# setenv bootargs "${bootargs_ubifsro} ${serverip}"  

bootcmd 인 경우 좀 특별한데 명령어들을 자동으로 실행해주는 환경변수이므로 보다 주의해서 작성하자.
Uboot는 기본적인 Shell 처럼 간단한 Uboot Script도 작성가능하므로 이를 최대이용
  1. 기본적으로 다른 환경변수는 표시는다음과 같이 한다.    ${ name }
  2. Command 구분자 ';' 세미콜론을 사용한다. 
  3. bootcmd에는 run 명령어로 다른 환경변수를 실행가능하다. 
  4. bootcmd에는 기본명령어인 setenv 비롯하여 uboot command가 실행가능
  5. 이외 외부 script 및 if 문도 사용가능        

* 주의사항  setenv or set 할 경우 "" or '' 권하며, 하지 않아도 설정은 되지만 간혹 제대로 설정이 되지 스페이스문제로 설정이 안되는 경우가 발생한다. 

1.3. Uboot Network/Video 기본설정 

bootargs 설정을 NFS로 변경하기 위해서 아래와 같이 각각 변경을 해주고 최후에 bootargs의 root를 network로 설정

NFS설정을 위해 아래와 같이 Uboot에 Network 기본설정 아래와 같이 해준다.
  • Network 환경설정 및 확인 
U-Boot# set serverip 192.168.1.100
U-Boot# set ipaddr 192.168.1.39
U-Boot# set gatewayip 192.168.1.1
U-Boot# set netmask 255.255.255.0
U-Boot# set hostname "jhlee-VirtualBox"
U-Boot# set nfspath "/home/jhlee/dm8148/targetfs"

DM368 IPNC :> setenv ethaddr 00:0C:0C:A0:04:22
DM368 IPNC :> setenv ipaddr 192.168.1.20
DM368 IPNC :> setenv gateway 192.168.1.1
DM368 IPNC :> setenv serverip 192.168.1.100
DM368 IPNC :> setenv netmask 255.255.255.0


  • Host에서 Hostname 확인 
 jhlee@jhlee-VirtualBox:~/dm8148$ hostname
jhlee-VirtualBox


* 주의사항 
  1. set은 setenv와 동일 (가끔씩 set이 동작이 안될때는 setenv로 변경)
  2. hostname 가급적 server이름을 설정해야겠지만, 아무거나 설정해도 무방하다.
  3. nfs mount test는 server에서 반드시 TEST 해보자. 

  • DM814x Video 설정 (2G M설정)
  1. mem =xxx : linux memory 설정
  2. vpssm3

set videoset "notifyk.vpssm3_sva=0xBF900000 mem=364M@0x80000000 mem=320M@0x9FC00000 mem=1023M@0xC0000000 vmalloc=500M vram=50M ti814xfb.vram=0:24M,1:16M,2:6M"

  1. 기본설정확인 (Start 0x80000000  : Size : 512M or 1024M or 2048M) 
  2. 현재 2GM사용하지만, 512M와 1024M 만 지원 (1024 Memory Map 선택)
  3. 0xC0000000 이후 부터 Linux로 모두 할당 
  4. Memory를 연속적으로 설정하지 않았기때문에, 이부분 설정을 따로 해야할 것 같다.
설정시 아래의 Memory Map을 반드시 참조.
  http://processors.wiki.ti.com/index.php/EZSDK_Memory_Map
  http://lxr.linux.no/linux/mm/Kconfig


1.4 Uboot의 bootargs 와 bootcmd 

  • UBIFS 와 NFS Boot Mode (bootargs의 분할)
현재 UBIFS를 RW모드와 RO모드 두개 설정하며, NFS도 일반모드 설정과 뒤에 다시 MEM 설정하기에 이를 지운다.


  • bootargs를 여러개 옵션으로 분할
U-Boot# set bootarg_consol "console=ttyO0,115200n8"
U-Boot# set bootarg_debug  "earlyprintk rootwait=1"
U-Boot# set bootarg_etc    "noinitrd"  
U-Boot# set bootarg_ubifsro  "ro ubi.mtd=4,2048 rootfstype=ubifs root=ubi0:rootfs"
U-Boot# set bootarg_ubifsrw "rw ubi.mtd=4,2048 rootfstype=ubifs root=ubi0:rootfs"
U-Boot# set bootarg_nfs "rw root=/dev/nfs nfsroot=${serverip}:${nfspath},nolock"
U-Boot# set bootarg_net "ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:eth0:off"
U-Boot# set bootarg_netnone "ip=none" 

  • bootargs를 조합하여 설정진행 
setnenv bootargs를 상위 변수들을 조합하여 재설정

U-Boot# setenv args_nfs 'setenv bootargs ${bootarg_consol} ${bootarg_debug} ${bootarg_etc}  ${bootarg_nfs} ${bootarg_net} ${videoset}'
U-Boot# setenv args_ubiro 'setenv bootargs ${bootarg_consol} ${bootarg_debug} ${bootarg_etc}  ${bootarg_ubifsro} ${bootarg_netnone} ${videoset}'
U-Boot# setenv args_ubirw 'setenv bootargs ${bootarg_consol} ${bootarg_debug} ${bootarg_etc}  ${bootarg_ubifsrw} ${bootarg_netnone} ${videoset}'

  • bootargs를 UBIFS로 직접설정
DM368 IPNC :> setenv bootargs mem=48M console=ttyS1,115200n8 noinitrd ip=192.168.1.168:192.168.1.210:192.168.1.1:255.255.255.0:::off rw ubi.mtd=3,2048 rootfstype=ubifs root=ubi0:rootfs cmemk.phys_start=0x83000000 cmemk.phys_end=0x88000000 cmemk.phys_start_1=0x00001000 cmemk.phys_end_1=0x00008000 cmemk.pools_1=1x28672 cmemk.allowOverlap=1 cmemk.useHeapIfPoolUnavailable=1 nohz=off highres=off clocksource=acpi_pm lpj=1077248 eth=00:0C:0C:A0:04:22

  • bootargs를 NFS로 직접설정
  1. nfsrootdebug: nfs debug 가능
  2. rootdelay=4: filesystem mount 시점을 조절가능
  3. earlyprintk: KERNEL 의 CONFIG_EARLY_PRINTK=y 설정후 가능
  4. quiet: 에러 이외의 메세지를 보고 싶지 않다면 사용

DM368 IPNC :> setenv bootargs 'console=ttyS1,115200n8 rw mem=48M root=/dev/nfs nfsrootdebug rootdelay=4 nfsroot=192.168.1.100:/home/jhlee/dm368/mt5/Source/ipnc_rdk/target/filesys_dm368,nolock mem=48M cmemk.phys_start="0x83000000" cmemk.phys_end="0x88000000" cmemk.phys_start_1="0x00001000" cmemk.phys_end_1="0x00008000" cmemk.pools_1="1x28672" cmemk.allowOverlap=1 eth=00:0C:0C:A0:04:22 ip=192.168.1.168 nohz=off highres=off clocksource=acpi_pm lpj=1077248 earlyprintk'

NFS Boot Mode
  https://www.kernel.org/doc/Documentation/filesystems/nfs/nfsroot.txt
Kernel Argument (bootargs)
  https://www.kernel.org/doc/Documentation/kernel-parameters.txt

  • bootcmd의 분할과 bootargs 설정 
  1. dhcp : dhcp client로 동작 tftp로 uImage가져온다.
  2. autoload: dhcp에서 자동으로 tftp로 uImage 가져오는 작업을 막는다.
  3. loadaddr: tftp 할 경우 loadaddr주소
  4. tftp or tftpboot: tftp로 data를 가져온다.

아래와 같이 다양한 bootcmd를 지원가능하도록  분할하여 쉽게 구성하도록하자

U-Boot# set autoload no
U-Boot# set loadaddr 0x81000000

U-Boot# set bootcmd_nfs1 'dhcp;run args_nfs; tftp uImage-dm814x-evm.bin;bootm'
U-Boot# set bootcmd_nfs2 'dhcp;run args_nfs; tftp 0x81000000 uImage;bootm'
U-Boot# set bootcmd_nfs3 "dhcp;run args_nfs; tftpboot uImage-dm814x-evm.bin;bootm"

U-Boot# set bootcmd_nfs  'run args_nfs; tftp uImage;bootm'
U-Boot# set bootcmd_ubi  "run args_ubirw;nand read 0x81000000 0x00280000 0x300000;bootm 0x81000000"
U-Boot# set bootcmd_ubi_me  'run args_ubirw; tftp uImage;bootm'

  •  bootcmd의 NFS/UBI_ME/UBI 설정
U-Boot# set bootcmd "run bootcmd_nfs"
U-Boot# set bootcmd "run bootcmd_ubi_me"
U-Boot# set bootcmd "run bootcmd_ubi"

  • U-BOOT의 환경변수 설명 (반드시 확인)
  http://www.denx.de/wiki/DULG/UBootEnvVariables
  http://www.denx.de/wiki/view/DULG/UBootEnvVariables

  • U-BOOT NFS 환경설정 
  http://processors.wiki.ti.com/index.php/DM814x_AM387x_PSP_U-Boot#Environment_Settings_for_NFS_Filesystem
  http://www.denx.de/wiki/publish/DULG/to-delete/LinuxNfsRoot.html


2. Board 의 정보파악 후 검증

  • Memory info 
Memory Start Address 와 Memory Size를 bdinfo로 파악하자.
이 정보가 잘못되었다면, datasheet를 이용하여 파악하자. (Memory Map)

  • NAND info 
Nand의 Memory Map 주소와 각 영역의 Size를 파악하자.
제대로 동작한다면, Kernel에서 mtd에서 알려준다.

 
NAND device: Manufacturer ID: 0x2c, Chip ID: 0xcc (Micron )
Creating 5 MTD partitions on "omap2-nand.0":
0x000000000000-0x000000020000 : "U-Boot-min"
0x000000020000-0x000000260000 : "U-Boot"
0x000000260000-0x000000280000 : "U-Boot Env"
0x000000280000-0x0000006c0000 : "Kernel"
0x0000006c0000-0x000020000000 : "File System"

Kernel command line: console=ttyO0,115200n8 earlyprintk noinitrd rootwait=1 rw ubi.mtd=4,2048 rootfstype=ubifs root=ubi0:rootfs notifyk.vpssm3_sva=0xBF900000 mem=364M@0x80000000 mem=320M@0x9FC00000 mem=1023M@0xC0000000 vmalloc=500M ip=none vram=50M ti814xfb.vram=0:24M,1:16M,2:6M

nand page size : 2048


  • 기본검증방법 
Memory Size를 정확히 파악한 후 Image의 size를 생각하여, 두 Memory 주소를 얻는다.
본인은 1G Memory이며, 0x8000 0000 : DDR START ADDR
                                0x4000 0000 : 1 G

0x81000000  부터 U-BOOT Application을 사용가능하다고, U-BOOT msg에서 파악.
0xA0000000  Size : 0x20000000 : 256M

위의 nand address를 파악해서 이제 검증시작하자.

  https://processors.wiki.ti.com/index.php/Booting_Linux_kernel_using_U-Boot

2.1 Uboot의 Memory TEST

Uboot에서 사용해보니, 너무느리며, 비효율적이다. 만약 시간이 많다면, 사용하고, 시간이 없다면, tftpboot kernel을 이용하여 DRAM을 검증하자.
그리고, NFS System도 같이 이용한다면 더욱 좋을 것 같다.

  • Uboot의 memory test 
U-Boot#  mtest 0x81000000 
U-Boot#  mtest 0x81000000  0x82000000


2.2 Uboot의 NAND TEST

NAND의 Test의 목적은 bad block문제로 인하여 nand boot가 제대로 안되는 것인지 파악하고, NAND의 read/write가 제대로 동작이 되는지를 확인하는 것이다.
일단 nand info를 통해 nand 기본정보를 파악하고, bad block이 scrub 이 되었는지  확인해보자.

nand bad를 해보면 bad block 정보를 읽어 표시해준다.
nand createbbt 명령어가 없을 경우 최근 version uboot는 이 명령어가 사라져 버리고 자동으로 scan해서 만들어 버리는 것 같다.
Uboot version마다 다를수 있으므로, 주의하자

2.3 NAND Image 기본검증

일단 tftpboot를 통해서 kernel의 Image 검증한 후 각각의 NAND Read/Write를 하여 문제없는지 확인하자.

  • TFTPBOOT TEST
DM368 IPNC :> tftpboot 0x80007FC0 dm368ipnc/uImage_ipnc_dm368
DM368 IPNC :> bootm 0x80007FC0;

  • How To update KERNEL & Filesystem
DM368 IPNC :> tftpboot 0x80700000 dm368ipnc/uImage_ipnc_dm368
DM368 IPNC :> tftpboot 0x82000000 dm368ipnc/ipnc_dm368_ubifs

DM368 IPNC :> nand erase 0x500000 0x400000               // NAND ERASE 4MB  
DM368 IPNC :> nand write 0x80700000 0x500000 0x400000    // KERNEL WRITE 4MB

DM368 IPNC :> nand erase 0x900000 0x2800000              //NAND ERASE 4MB
DM368 IPNC :> nand write 0x82000000 0x900000 0x2800000   //FS  WRITE 40MB


  • NAND Image 검증
DM368 IPNC :> tftpboot 0x80700000 dm368ipnc/uImage_ipnc_dm368
DM368 IPNC :> nand read 0x82000000 0x500000 0x400000   // KERNEL READ 4MB
DM368 IPNC :> cmp 0x80700000 0x82000000  0x38a420      // check tftpboot 

상위와 동일함
U-Boot#  tftp 0x81000000 uImage
Bytes transferred = 2215324 (21cd9c hex) 

U-Boot#  nand read 0xA0000000 0x280000 0x21cd9c 

// 553831 = 2215324/4 bytes 

U-Boot#  cmp   0x81000000 0xA0000000 553831
U-Boot#  cmp.l 0x81000000 0xA0000000 553831
 
word at 0x8121cd9c (0x605f9029) != word at 0x8221cd9c (0xffffffff)
Total of 553831 words were the same 

2/16/2015

NAND BBM(Bad Block Management)

1. NAND의 Block의 상태 

  • NAND Block의 상태종류 
  1. 1st block : Chip Vendor는 1st Block은 Bad Block이 되지 않게 유지해줌  
  2. Factory-Default bad blocks:  Chip Vendor는 Block 의 1st or 2nd Page의 OOB 정보표시 
  3. Worn-out bad blocks : NAND 를 Erase or Write할 경우 BAD Block이 발생한 경우  
  4. Good blocks : 현재 좋은 상태의 Block 

  • Factory-Default Bad Block
    공장 초기에 제공해주는 Bad Block 정보이며, Chip Vendor 마다
    다를 수 있으므로 Datasheet를 참고 해야한다.

     - Samsung 인경우,
         각 Block의  1st or 2nd page의 6th OOB의 값이 0xFF 아닐 경우, BAD
   
이 정보는 Large page or Small page, bus width 에 따라 달라질 수 있다.
(Chip vendor 정보 반드시 참고)  
아래 link에 macronix를 정보를 소개.
이 정보를 BBI ( Bad block indication ) 라고도 호칭하기도 한다.


  • 1st Block
Chip Vendor마다 다르겠지만, 보통 ECC도 필요가 없으며, Nand 회사에서 보증하는 Block으로
약 1000 write 까지보증한다고 한다, 이부분도 각각의 Datasheet를 참고를 해야겠다.
하지만, 보통 1st Block에서 문제생기는 일은 거의 없기에 구지 자세히 알필요까지는 없을 것 같다.

  • Worn-out bad blocks 
보통 Write 제한이 있기에, 이를 초과 했을 경우, bad block이 발생. or
사용도중 Program or Erase 도중 fail 이나서 STATUS를 읽어서 ERROR 읽어 경우도
Bad block으로 처리한다.

1.2 NAND의 Bad Block 숙지사항 

UBOOT기준으로 설명을 하면, 이전 Version에는 아래의 사이트 처럼 U-Boot 에서
Bad Block을 만들어주는 Command가 존재했지만, 최신 Version으로 가면 없어진다.

NAND처리는 지속적으로 변화고 있으며,  본인의 BSP 를 비롯하여, U-BOOT, Kernel의
MTD관련부분을 어느정도 정확하게 알아야 동작원리를 알아야 겠다.

기본적인 BBT(Bad Block Table) 원리와 BBM(Bad Block Management) 부분을 정확하게
알아야 나중에 에러가 발생을 하여도 문제진단이 빠를 것 같다.

  • U-BOOT의 NAND관련 Command (오래된 Version) 
  http://wiki.openmoko.org/wiki/NAND_bad_blocks



  • U-BOOT의 NAND관련 Command 

  https://www.denx.de/wiki/DULG/UBootCmdGroupNand


1.3 BSP의 NAND의 구성 


  • AM35x-OMAP35x 관련 내용 
TI의 AM35x와 OMAP3관련 NAND 설정 및 이에 관련내용들이며, UBOOT에서 nanecc 라는 ECC설정가능명령도 존재한다.

  http://processors.wiki.ti.com/index.php/AM35x-OMAP35x-PSP_04.02.00.07_UserGuide



  • i.M28과 BBT와 BBI설명 
아래 문서를 읽어보면,  I.MX28 NAND 구성은 재미있는 것 같다.
2K page 64 OOB 구성을 512+16 매번 쪼깨서 사용하며, 이것은 정말 신선하게 느껴졌다.
매번 느끼는 것이지만, Bad block 의 관리와 NAND관리는 MPU와도 밀접한 것 같다.


  Freescale-i.MX28-MCIMX281AVM4B-Learning Centre MCU-Application Notes-Freescale.Application_Notes_5.pdf

  https://www.element14.com/community/docs/DOC-31589/l/freescale-application-note-for-nand-flash-bad-block-management-for-linux-bsp





2. Linux의 NAND BBM(Bad Block Management) 


2.1 Bad Block Table 생성 

Bad Block Table은 2bit 정보로 각 Block을 관리하며, 보통은 BBT은 2개의 Block을 사용을 하며, 하나는 Back-up용으로 생각하면 된다.

MPU-Nand Driver에서  static struct nand_bbt_descr을 선언하여 사용.
기본적 Last 2 Block or 1st Block을 사용하며, 아래와 같은 가지고 사용을 한다.

Nand에서 사용하는 BBT 
 * The table uses 2 bits per block
 * 11b:     block is good
 * 00b:     block is factory marked bad
 * 01b, 10b:    block is marked bad due to wear

Memory에서 사용하는 임시 BBT
 * The memory bad block table uses the following scheme:
 * 00b:     block is good
 * 01b:     block is marked bad due to wear
 * 10b:     block is reserved (to protect the bbt area)
 * 11b:     block is factory marked bad


Bad block table
  http://www.linux-mtd.infradead.org/tech/mtdnand/x144.html

  • BBT의 생성되는 Flowchart
초기에 U-Boot에서 한번 하며, 아래와 같이 공장 초기 값을 이용하여 만든다.
Factory-Default  bad block 정보이용하여  Bad block Table에 만드는 방법
현재 Linux BBT 역시 이와 같은 방식으로 동작하지만, 옵션에 따라 미세하게 다르게 동작.


http://bbs.ednchina.com/FORUM_POST_17_89328_0.HTM
  http://www.macronix.com/Lists/ApplicationNote/Attachments/729/AN0278V1%20-%20BB%20information%20introduction.pdf
  https://www.micron.com/resource-details/8e059ff2-fb4f-4e05-974c-e205226d2318


3. U-BOOT 와 Kernel BBT 분석 

Uboot 와 Kernel은 NAND를 사용시에는 BBT를 사용하며, 이에 관련된 부분을 알아보자. 

  • U-BOOT
U-BOOT NAND Bad Block Table 관련부분

 $ vi ./drivers/mtd/nand/davinci_nand.c

void davinci_nand_init(struct nand_chip *nand)
{
        nand->chip_delay  = 0;
#ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
        nand->bbt_options         |= NAND_BBT_USE_FLASH;
#endif
#ifdef CONFIG_SYS_NAND_NO_SUBPAGE_WRITE
        nand->options     |= NAND_NO_SUBPAGE_WRITE;
#endif
#ifdef CONFIG_SYS_NAND_HW_ECC
        nand->ecc.mode = NAND_ECC_HW;
        nand->ecc.size = 512;
        nand->ecc.bytes = 3;
        nand->ecc.strength = 1;
        nand->ecc.calculate = nand_davinci_calculate_ecc;
        nand->ecc.correct  = nand_davinci_correct_data;
        nand->ecc.hwctl  = nand_davinci_enable_hwecc;
#else
        nand->ecc.mode = NAND_ECC_SOFT;
#endif /* CONFIG_SYS_NAND_HW_ECC */
#ifdef CONFIG_SYS_NAND_4BIT_HW_ECC_OOBFIRST
        nand->ecc.mode = NAND_ECC_HW_OOB_FIRST;
        nand->ecc.size = 512;
        nand->ecc.bytes = 10;
        nand->ecc.strength = 4;
        nand->ecc.calculate = nand_davinci_4bit_calculate_ecc;
        nand->ecc.correct = nand_davinci_4bit_correct_data;
        nand->ecc.hwctl = nand_davinci_4bit_enable_hwecc;
        nand->ecc.layout = &nand_davinci_4bit_layout_oobfirst;
#endif

$ vi ./drivers/mtd/nand/nand_bbt.c
nand_default_bbt
    -> 1.bbt_main_descr,bbt_mirror_descr  //NAND_BBT_USE_FLASH 때문에 default BBT옵션설정 
    -> 2.nand_scan_bbt 
           -> check_create
                 -> create_bbt
                      ->  scan_block_full or scan_block_fast

$ vi ./include/linux/mtd/bbm.h  // BBT 관련옵션 확인 


  • bbt_md(bbt_mirror_descr) or bbt_td(bbt_main_descr) 설정분석 
  1. NAND_BBT_LASTBLOCK :  NAND 마지막 Block BBT 존재여부 확인 
  2. NAND_BBT_CREATE      :  NAND BBT가 없다면 생성  
  3. NAND_BBT_WRITE       :  NAND BBT에 WRITE 가능   
  4. NAND_BBT_2BIT          :  각 Bblock 당 정보를 2bit식 할당 
  5. NAND_BBT_VERSION   :   BBT Version 정보 표시  
  6. NAND_BBT_PERCHIP    :   NAND Chip 마다 BBT 생성 


$ vi ./drivers/mtd/nand/nand_bbt.c

/* Generic flash bbt descriptors */
static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' };
static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' };

static struct nand_bbt_descr bbt_main_descr = {
        .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
                | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,

        .offs = 8,  //offset of the pattern in the oob area of the page
        .len = 4,   //length of the pattern
        .veroffs = 12,  //offset of the bbt version counter in the oob are of the page
        .maxblocks = NAND_BBT_SCAN_MAXBLOCKS, //maximum number of blocks to search for a bbt
        .pattern = bbt_pattern      //pattern to identify bad block table or factory marked
};

static struct nand_bbt_descr bbt_mirror_descr = {
        .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
                | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
        .offs = 8,
        .len = 4,
        .veroffs = 12,
        .maxblocks = NAND_BBT_SCAN_MAXBLOCKS,
        .pattern = mirror_pattern
};

static struct nand_bbt_descr bbt_main_no_oob_descr = {
        .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
                | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP
                | NAND_BBT_NO_OOB,
        .len = 4,
        .veroffs = 4,
        .maxblocks = NAND_BBT_SCAN_MAXBLOCKS,
        .pattern = bbt_pattern
};

static struct nand_bbt_descr bbt_mirror_no_oob_descr = {
        .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
                | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP
                | NAND_BBT_NO_OOB,
        .len = 4,
        .veroffs = 4,
        .maxblocks = NAND_BBT_SCAN_MAXBLOCKS,
        .pattern = mirror_pattern
};


  • Kernel Source

  http://lxr.free-electrons.com/source/drivers/mtd/nand/Makefile

  nand-objs := nand_base.o nand_bbt.o nand_timings.o

  http://lxr.free-electrons.com/source/drivers/mtd/nand/nand_bbt.c

  • drivers/mtd/nand/nand_bbt.c

           nand_scan_bbt
Search
-> check_create
                     -> mark_bbt_region
->nand_update_bbt

               * check_create
                        read_abs_bbt
                                   read_bbt


  http://lxr.free-electrons.com/source/drivers/mtd/nand/nand_base.c
  • drivers/mtd/nand/nand_base.c

        /* Fill in remaining MTD driver data */
         mtd->type = nand_is_slc(chip) ? MTD_NANDFLASH : MTD_MLCNANDFLASH;
         mtd->flags = (chip->options & NAND_ROM) ? MTD_CAP_ROM :
                                                 MTD_CAP_NANDFLASH;
         mtd->_erase = nand_erase;
         mtd->_point = NULL;
         mtd->_unpoint = NULL;
         mtd->_read = nand_read;
         mtd->_write = nand_write;
         mtd->_panic_write = panic_nand_write;
         mtd->_read_oob = nand_read_oob;
         mtd->_write_oob = nand_write_oob;
         mtd->_sync = nand_sync;
         mtd->_lock = NULL;
         mtd->_unlock = NULL;
         mtd->_suspend = nand_suspend;
         mtd->_resume = nand_resume;
         mtd->_reboot = nand_shutdown;
         mtd->_block_isreserved = nand_block_isreserved;
         mtd->_block_isbad = nand_block_isbad;
         mtd->_block_markbad = nand_block_markbad;
         mtd->writebufsize = mtd->writesize;


           nand_block_markbad
                -> nand_block_markbad_lowlevel
                         -> nand_markbad_bbt



  http://lxr.free-electrons.com/source/drivers/mtd/mtdcore.c

  • drivers/mtd/mtdcore.c

           mtd_block_isbad
              -> mtd->_block_isbad

           mtd_block_markbad
              -> mtd->_block_markbad


  http://lxr.free-electrons.com/source/drivers/mtd/nand/davinci_nand.c

2/15/2015

MTD-Linux Embeded File system (추후 자료 수정)

1. MTD(Memory Technology Devices)

MTD(Memory Technology Devices)란?

말그대로, Linux에서 사용되어지는 Memory Technology Device 이며, Flash Memory를
초기에는 NOR Type의 Flash Memory 지원이 되어지면서 이를 Control하기 위해서 , NAND의 출현으로 현재 그 기능이
다중화 많이 기능들이 추가되고, 이에 더불어 FTL, NTFL 등 다양한 기능이 추가하는 중이다.
NAND에 필요한 Bad Block Management 기술 들이 들어가 있다.


code code sample 

 
1.1 MTD의 기본구성


MTD의 기본구성을 살펴보면, 일단 MTD Chip Drivers가 존재하며, 각종 Flash Memory
(NAND , ONE-NAND , NOR Type) 기본 Interface 부분이 존재한다.
이런 부분들은 H/W와 밀접한 관계를 가지고 있기때문에 glue logic라고 표현을 한것이다.

상위 MTD에는 추상화되어 Char Device 와 Block Device 로 구분이 되며, Flash Memory에 접근하는 방식이 다르다.
일반적인 Disk라면, Fixed Size로 ATA , PATA, PIC Interface 로 이를 접근을 해서 Block Device로 접근을 하면된다.
하지만, Flash의 경우 write and erase operation 이 구분을 해야하며, Size도 제각각이다.
이를 Control 하고, Partition 이라는 개념을 제공하기위해서 Char Device를 제공한다.

현재는 NOR or ONENAND 보다는 NAND를 사용하거나 NAND의 부족한 기술을 HW적으로 보완해줘서 사용하는
SD Disk 같은 저장장치로 분류되겠다.
물론 SD Disk 같은 저장장치는 MTD의 사용이 필요하지 않다.

MTD의 기본설명
  https://en.wikipedia.org/wiki/Memory_Technology_Device

MTD의 FAQ (일반적인 질문 및 기본사항)
  http://www.linux-mtd.infradead.org/faq/general.html
  http://www.linux-mtd.infradead.org/archive/tech/faq.html

MTD API 및 MTD Test
  http://www.linux-mtd.infradead.org/doc/general.html


아래는 Mircorn의 기술자료 이며, 현재 MTD 구조를 보여주고 있다.
tn0025_enabling_flash_in_linux_mtd.pdf (micron)





1.2 MTD의 Device의 기본사용법 



아래 참조

  http://etutorials.org/Linux+systems/embedded+linux+systems/Chapter+7.+Storage+Device+Manipulation/7.1+MTD-Supported+Devices/

  http://processors.wiki.ti.com/index.php/MTD_Utilities



1.3 NAND를 사용할 경우 필요한 기술 


1. Wear-leveling 란 ?

Flash Memory일 경우 NAND or NOR는 File system을 사용하면, 한 영역을 자주 지우고, 쓰는 경향이 존재한다.
하지만, Flash Memory에는 Erase와 Write의 수명이 존재하기 때문에 이를 방지하기 위해서 Flash Memory에 Level을 두어 여러군데에 골고루 사용하도록 하는 기술이다.

  http://kr.apacer.com/business/technology/wear-leveling


2. BBM(Bad Block Management)
NAND는 NOR Type의 Flash와 달리 기본적으로 Bad Block이 존재하며, 이를 보완하기 위해 Bad Block Management 기술이 필요하다.
이 Bad Block도 Factory Bad Block과 Run Time Bad Block 로 크게  두 가지로 분류가 되며, 이 관리를 제대로 해야 저장장치로서의 신뢰성을 얻을 수 있다.

제조사는 Factory Bad Block일 경우 OOB에 이 정보를 알려주며, 그리고 현재 MTD 인 경우 따라 다르겠지만,
OOB 중 2 Byte를 사용하여 Bad Block 관련하여 사용한다.

  • BBT(Bad Block Table)
BBM의 한 종류로 MTD에서 사용하는 기술이며, Bad Block 정보를 가지고 Bad Block을 판단할수 있지만, Factory Bad Block과 Worn Bad Block은 구분할 수가 없다.
그래서 2 Bit를 이용하여 기본적으로 2개의 Block을 사용하여 Table을 만들어 이를 관리한다.


3. Gabage Collection (GB)

RAM과 함께 사용되어지는 기술이며, 이는



SSD Disk 및 eMMC 관련기술 (NFTL)
  http://www.qdpma.com/storage/SSD.html



1.4 Raw Flash File System 과 FTL 

MTD에서는 사용되어지는 File System은 두가지로 보면될 것같다. 현재 거의 주류가 raw NAND or FTL Firmware를 포함하여,
NAND을 사용할때 필요한 기술들을 HW 상에서 모두 동작하게 하는 저장장치일 것이다.

FTL Firmware 기능을 포함한 것이, 대표적인 것들이  MMC, eMMC, SD, SSD , USB Memory 일 것이다.

Raw Flash File System은 일반적으로 Flash Memory에 MTD 상위에 있는 File System을 말한다.
하지만, 여기에는 복합적인 기능이 필요하다.


  http://www.linux-mtd.infradead.org/doc/ubifs.html#L_raw_vs_ftl






http://www.linux-mtd.infradead.org/~dwmw2/mtd-upper-layers.jpeg


http://image.slidesharecdn.com/evaluation-of-flash-file-systems-for-large-nand-flash-memory4871/95/evaluation-of-flash-file-systems-for-large-nand-flash-memory-5-728.jpg?cb=1271316564




위의 MTD 구성 간단히 보자.
NAND의 NFTL은 뒤에서 다시 보자.
NFTL을 사용하지 않을 경우를 MTD-RAW라고 하는데 이와 비교해서 보자.



  1. MTD와 NAND 연결 
  2. MTD와 MMC, eMMC, SD, SSD 와 연결 (NFTL 필요)


  • MTD- User Modules
  1. NFTL (NAND Flash Translation Layer)
  2. FTL(Flash Translation Layer)
  3. MTD-Char Device
  4. MTD-Block Device
  5. MTD-JFFS2 
  6. MTD-YAFFS/2
  7. MTD-LOGFS
  8. MTD-UBIFS

  • MTD- Chip Drivers
  1. NAND Drivers 
  2. NOR Drivers 




http://forum.falinux.com/pds/data-s2410/No11-1.pdf





1.3 MTD NFTL (Nand Flash Translation Layer)

MTD Raw를 사용하지 않고 MTD-NFTL의 기본사용이유는 Wear-Leveling 과 BBM 관리가
목적이며, 이에 대해서 좀더 자세히 알아보도록 하자.

만약 사용하지 않는다면, File system에서 이를 지원을 해야 겠다. 

  http://www.linux-mtd.infradead.org/doc/ubifs.html#L_raw_vs_ftl

https://en.wikipedia.org/wiki/Flash_file_system#Linux_flash_filesystems

https://digitalcerebrum.wordpress.com/random-tech-info/flash-memory/raw-flash-vs-ftl-devices/

  http://d1.amobbs.com/bbs_upload782111/files_46/ourdev_684405XFKZAB.pdf




2 . MTD Raw Flash File system

FTL를 사용하지 않으며, MTD위에 바로 File system을 사용하는 Filesystem를 통칭한다.
이는 Embeded에서 주로 사용이 되어지며,
Wear-leveling 은 File system에서  BBT를 MTD에서 제공을 한다.


MTD NAND 관련 기술
http://www.linux-mtd.infradead.org/tech/mtdnand/book1.html
http://www.linux-mtd.infradead.org/tech/mtdnand/r526.html
http://www.linux-mtd.infradead.org/tech/mtdnand/r743.html
http://www.linux-mtd.infradead.org/tech/mtdnand/r804.html





2.1 Kernel 설정

  http://processors.wiki.ti.com/index.php/Filesystem_in_NOR_or_NAND

  http://processors.wiki.ti.com/index.php/Flash_configuration_in_the_Kernel

  https://wiki.kldp.org/KoreanDoc/html/Kernel-KLDP/specmtd.html

  http://www.stlinux.com/howto/Flash/MTD

  NFTL vs INFTL

  http://www.tldp.org/HOWTO/Disk-on-Chip-HOWTO/intro.html


http://elinux.org/images/9/9a/CELFJamboree29-FlashFS-Toshiba.pdf




2.1 JFFS2

JFFS2 clean marker requires 8 bytes
만약 BCH8을 사용하면, 14byte *4 =56 byte,  56+8 =64byte.
BBT 정보를 사용할수 없다.


NAND read 시 Run-time bad가 발생 할 수가 있어,아래가면, AM335x JFFS2를 사용하지 않는다.

  https://en.wikipedia.org/wiki/JFFS2

  • TI가 JFFS2 지원을 중단한 이유
  1. UBIFS를 권하고 있으며, UBIFS는 JFFS2의 다음 모델이며, 향상된 기능을 가지고 있다. 
  2. ECC layout이 RBL, SPL, U-BOOT ,  ECC의 알고리즘인 BCH8이 호환이 가능. 
 
  http://processors.wiki.ti.com/index.php/AM335x_JFFS2_Support_Guide#Reasons_for_disabling_JFFS2_support


2.2 UBIFS



http://www.linux-mtd.infradead.org/doc/ubidesign/ubidesign.pdf

UBI는 완벽한 FTL(flash translation layer)는 아니지만, bad block과 wear leveling 기능을 제공을 하며,

erase block management를 제공을 한다.


UBIFS는 UBI(Unsorted Block Image)와 UBIFS로 분리된다.



UBIFS raw flash 을 위해 만들어진 FILE SYSTEM 이며, B+ Tree를 사용하여 구성이 되어있다고 한다.
처음 노키아에서 만들어져서 사용되어져 있다고 한다.



  • 장점
빠른 속도와 FILESYSTEM의 가벼운이 큰 장점이며, OOB영역을 적게 사용하여
ECC의 사용폭이 넓은 것 같다.
  • 구성
             UBIFS                /fs/ubifs
             UBI                    drivers/mtd/ubi
             MTD                  drivers/mtd
                  NAND , NOR, OneNAND

  • 아래의 예제

sudo mkfs.ubifs -q -m 2048 -e 129024 -c 1023 -r mypath  -o ubifs.img
sudo ubinize -o ubi.img -m 2048  -p 131072 -s 512 ubinize.cfg

mount 및 kernel args
$ mount -t ubifs ubi0:rootfs /mnt/ubifs
rw ubi.mtd=4,2048 rootfstype=ubifs root=ubi0:rootfs


UBIFS BAD BLOCK MARK
  http://www.linux-mtd.infradead.org/doc/ubi.html#L_torturing
  http://www.linux-mtd.infradead.org/doc/ubi.html#L_max_beb

기타자료

  https://en.wikipedia.org/wiki/UBIFS

  http://www.linux-mtd.infradead.org/faq/ubifs.html

http://wiki.linpert.de/index.php?title=UBIFS     

  http://processors.wiki.ti.com/index.php/UBIFS_Support

  http://www.linux-mtd.infradead.org/faq/ubifs.html

http://www.linux-mtd.infradead.org/doc/ubifs_whitepaper.pdf

  http://www.linux-mtd.infradead.org/doc/ubidesign/ubidesign.pdf
http://www.linux-mtd.infradead.org/doc/ubifs.pdf


1.3 YAFFS1/2




위의 unstable bits문제를 yaffs2를 교체하므로써 해결이 되었다고 한다.

  http://forum.falinux.com/zbxe/index.php?document_srl=786065&mid=device_driver

http://yaffs.net/lurker/message/20140710.203207.b2255691.it.html

https://en.wikipedia.org/wiki/YAFFS


1.1 How To make JFFS2/YAFFS2/UBIFS/CRAMFS

http://processors.wiki.ti.com/index.php/HOWTO_Create_Filesystems_on_DaVinci

http://processors.wiki.ti.com/index.php/TI81XX_PSP_UBOOT_User_Guide#Creating_UBIFS_File-System


   Benchmark result
  http://elinux.org/images/9/9a/CELFJamboree29-FlashFS-Toshiba.pdf

http://forum.falinux.com/zbxe/index.php?document_srl=786065&mid=device_driver


3 MTD FTL File-system

Flash 기반으로 NAND 관련 Contoller가 포함이된
SD Card/MMC 와 eMMC 그리고, USB Storage 사용한다.


/dev/mmcblk0

http://elinux.org/images/b/b6/EMMC-SSD_File_System_Tuning_Methodology_v1.0.pdf


https://wiki.linaro.org/WorkingGroups/KernelArchived/Projects/FlashCardSurvey


ext3/ext4

btrfs

f2fs



1/25/2015

NAND 양산문제 정리 및 다른방법

1. NAND를 이용한 양산(Mass production)

NAND를 사용하게되면 제품개발자들은 제품의 양산을 생각하게 되는데,
아래와 같이 Gang이라는 제품을 이용하여, NAND를 Write를 하여 양산을 하게된다.
양산을 진행을하게되면 Gang을 가지고 있는 업체에 위탁하여 write를 한다.

양산을 하게될 경우, 처음 겪는문제가 NAND의 불량률과 각종 Device 관련 불량률이다.
이에 관련하여 간단한 방법소개를 한다.

Gang의 대체적으로 기능을 보면, Factory Bad Block의 Skip 기능을 기본적으로 가지고 있는 것 같으며, 본인도 다시 NAND 양산을 해봐야 정확한 문제점을 파악이 가능할 것 같다.

  http://www.adc.co.kr/download/EISC_Gang/GangWriter_Manual.pdf
  http://www.mvtool.co.kr/products/product.php?query=view&code=010104&lv=1&no=187&lang=

  • 양산-A
  1. 양산방법   : Nand Image를 Gang 업체에게 전달하여 이를 양산      
  2. 양산문제   : ECC와 Bab Block에 관한 문제점 처리가 안되는 경우가 발생 
  • 양산-B
  1. 양산방법:  NAND Image와 ECC 정보를 전달하여  Gang 업체에서 양산  
  2. 양산문제:  ECC 처리부분의 문제발생여지가 존재하며 있으며, Bad block에 관한 문제 발생 
     * Bad Block의 문제보다는 ECC와 File Meta Data 문제가 발생소지로 보인다.
     * 상황에 따라 BBM도 문제소지가 있다.

  • 양산-C (본인이 양산했던방식)
  1. 양산방법: 1st 와 2nd loader인 U-Boot만 Gang 업체 전달 
  2. 추가방법: U-BOOT에서 Kernel과 File System을 굽는다. 
  3. 추가방법: U-BOOT에서 삽입된 QC프로그램으로 기본 자체검증 (사람확인)
  4. 추가방법: 최종제품 검증 및 확인    

본인이 양산했던 시절은, BBT가 생겨나기 시작했던 시절이라, U-BOOT과 Kernel 사이에
BBT도 호환이 되지 않았던 시절이며, 이를 일일이 수정을 하면서 했던 시절이다.
현재 NAND의 양산이 어떻게 되는지는 궁금하지만, 많이 궁금하지는 않다
왜냐하면 요즘은 거의 eMMC , SDDISK 및 다른 UFS 다른 매체들이 많아져있기 때문이다.

2. 기존 NAND 양산방법 정리

본인이 사용한 방식은 양산-C이며, NAND의 1st Block은 제조사가 보장이 해주기에 1st Bootloader에서는 Error가 발생할 수가 없다.
안정성을 위해서 UBOOT도 2개로 했는지 1개로 했는지 기억이 잘안난다.

위에서도 설명했듯이 UBOOT와 KERNEL에서 BBT가 호환이 되지 않던 시절이라 이부분을 강제로 변경했으며,
양산을 위해 다른 부가적인 기능을 많이 넣었던걸로 기억한다.

그리고 더불어 Upgrade Fail 위해서는 Kernel/Filesystem 부분을 두개로 나누어서 썼던걸로 기억한다.

  • BBT 관련사항 
BBT 초창기라서 수정을 해가면서 별도로 관리를 해야했으며, Kernel과 U-Boot간에 BBT를 공유했다.
BBT인 경우 2개 Block으로 구성이 되며, 하나는 여분으로 사용된다.
현재 솔직히 많이 기억이 잘 안난다.  추후 MTD 관련부분과 Filesystem을 정리를 한다면,
이부분을 다시 정리하겠다.

  • 불량률 관련사항 
양산을 진행을 하게되면, 어디 제품이든 불량률은 나오기 마련이다. 이를 최대한 감소하기 위해서
미리 진단하고 감지하는 프로그램을 넣어야한다. 이를 U-BOOT에 간단히 넣어 기본 Device Test를 진행을
하고 문제가 있는 Device는 미리 교체를 한다.

  • 현재 제안해 주시는 방식 및 정리 
본인도 궁금하며, 현재 대기업의 양산방식은 eMMC or NAND를 포함 Device로 진행되며,
아직도 NAND로 양산을 하게되면 본인도 어떻게 변화 되었는지 궁금하다.
 
   http://www.aesop.or.kr/Board_Community_QandA/34012
http://www.adc.co.kr/download/EISC_Gang/GangWriter_Manual.pdf
http://www.iwecom.co.kr/ce/forum_view.asp?board_idx=22794 



고도리님께서는 TI로 말하자면, 1st boot Loader인 UBL에서 CRC check를 넣고 U-BOOT를 각각 2개식 넣어 굽자고 제안을 했고요.
1 ~ 2: u-boot 1st
3 ~ 4: u-boot 2nd

저는 개인적으로 bad block 문제는 power-cut 문제와  전압문제인것 같습니다.
이미 한번 power-cut은 경험을 했고요.

funmoney님께서는 최신정보를 주시는 것 같습니다. 정말 감사합니다.
이부분은 저도 경험을 하지 못해 추후 다시 한다면 이방법을 으로 물어보도록하겠습니다.
양산하는 공장에서 bad block을 skip을 할수 있는 방법이 있다는 것은 몰랐으며, 그래서 상위에서 Gang 에대해 다시 보게되었네요.
Gang에서 지원이 되는것 같습니다. (bad block skip)

(예전에 이것때문에 많이 문제가 발생했던걸로 기억해서 시간이 많이 흘렀으니 많이 변화되어있겠죠)

개인적으로는 처음부터 bad block이 아닌이상 u-boot loader에 저장할 것이 없다면,
거의 이상이 없는 걸로 알고 있습니다.
그래서 저의 경우는 u-boot를 하나를 사용을 했고요. kernel 역시 하나를 사용하였습니다.
다만, 위에서 처럼 bad block skip를 하기위해서 u-boot 까지 굽고 network를 이용하여
uboot에서 bad block을 찾아가며 kernel과 filesystem을 write를 했습니다.

upgrade 안정성을 위해서 kernel과 filesystem을 두개를 사용을 했습니다.
upgrade 중 문제가 발생을 하면 복구가 가능하도록 요.

   http://www.aesop.or.kr/Board_Community_QandA/33948

3. 양산방법 정리

만약 다시 양산을 할 기회가 온다면, 그때 다시 한번 Gang Spec과 ECC의 기능
및 Filesystem Meta 정보 BBM(BBT) 를 보고 다시 한번 자세히 봐야할 것 같네요.




1/24/2015

NAND OOB 영역 및 ECC 기능

1. NAND의 OOB란? 

NAND의 구성이 Block과 Page로 구성이 되어있으며, Page가 Data와 OOB(Out of Band)로 구성이 되어 존재한다.
OOB의 Size는 항상 Page Size의 의존적이며, 주로 Page의 Data 영역의 512 byte 기준으로 16byte 정도의 영역을 차지한다.
Page size의 크기가 커지면 커지고,작으면 작어진다.

  • OOB의 저장되어지는 정보 
  1. Bad Block Information ( Factory Bad Block 의 기본정보)
  2. Bad Block Marker (2 byte or 1 byte Bad Block, first or second page of erase block)
  3. ECC (Error Correction Code)
  4. File system Meta Data(Raw Flash Filesystem) 

아래의 MTD Driver 문서를 읽어보면 ECC가 256단위로 저장되며, Bad block marker 1byte의 정보를 넣고 있다.

  • MTD Manual의 OOB정보 (autoplacement default schemes) 
  MTD의 저장되는 OOB 정보
  http://www.linux-mtd.infradead.org/tech/mtdnand/x255.html


기본적으로 Chip 제조사들은 OOB에 BBI (Bad Block Inforamtion) 정보를 넣어 Factory Bad Block을 구분이 가능하도록 한다.
하지만 Vendor 위치가 상이 하므로 이부분은 개별 Chip Datasheet를 확인해야 봐야한다.

1.1 BBM 와 Raw File System Meta Data 

OOB에는 ECC정보도 들어가지만, Raw File system 선택에 따라 그에 관련된 Meta Data도 들어가게 되며,
이 뿐만 아니라 Bad Block 관리를 위하여 BBM(Bad Block Management)이라는 Data 정보를 넣는다.
그래서 OOB Size와 ECC의 Size 계산 및 위치가 중요하다.


  • OOB 실제 사용 예 (JFFS2, BBT 사용)
OOB 64 per 2048 bytes 중 , BCH 8bit ECC를 사용할 경우  56 bytes =(14 byte * 4) 사용
처음 Bad Block Table을 생성시 Bad Block Information을 이용한다고 한다.

              Total = 56bytes

하지만, Raw Flash로 사용하고, Raw Flash 기반으로 한 File system 사용한다면, OOB Size가 문제가 될 수 있다고 한다.

대표적인 Raw NAND Filesystem JFFS2의 경우 Metadat로  Clean Marker 용도로 8byte를


Raw Flash 기반으로 둔 Filesystem(JFFS2)   (UBIFS, YAFFS)
한번 확인 필요할 것 같다.


  http://wiki.openmoko.org/wiki/NAND_bad_blocks   (Nand page)
  http://dooeui.blogspot.kr/2010/01/understanding-nand-flash-memory.html

  • Linux 의 OOB의 구성
  http://www.linux-mtd.infradead.org/tech/mtdnand/x215.html
  http://www.linux-mtd.infradead.org/tech/mtdnand/x255.html


  http://processors.wiki.ti.com/index.php/AM335x_JFFS2_Support_Guide


2 ECC(Error Correcting Code) 기능 

NAND는 기본적으로 BAD Block의 가능성과 불안정한 Bit 부분이 존재하므로, 항상 오류를 체크를 해야하며,
에러발생시 이를  탐지하고 복원을 해야한다.

  • SLC 공정에 따라 필요한 ECC
  1. 1 bit per 512 B (43 nm - 350 nm)
  2. 4 bits per 512 B (32 nm)
  3. 8 bits per 512 B (24 nm)
  4. 12? bits per 512 B (19 nm)

  • MLC 공정에 따라 필요한 ECC 
  1. 4 bits per 512 B (43 nm )

위와 같이 NAND의 Type과 공정에 따라 필요되는 ECC의 기능이 다르며, 이에 따른 알고리즘 역시 다르게 적용해야한다.

  • ECC(Error Correcting Code)의 기본기능 
NAND의 Error Bit를 Detection 과 Correction 부분이다. 이 부분은 알고리즘에 따라 탐지되는 Bit와 복원되는 Bit수도 달라진다.
처음에는 SW로 지원했지만 현재에는 거의 HW ECC가 보편화되었으며 이 선택은 이제 중요하다.
만약 MLC 까지 고려를 한다고 하며, HW ECC의 성능을 반드시 해봐야한다.


  • Error Detection 과 Correction 
아래의 Wiki에서 Error의 Detection 과 Correction 에 대해서 기본개념을 설명해주고 있다.
Error Detection 알고리즘은 CRC , Parity bits 등 존재하고 이를 복구하는 ECC는 설명해준다.

  https://en.wikipedia.org/wiki/Error_detection_and_correction


2.1 ECC 알고리즘 의 종류

아래와 같이 대표적으로 많이 사용이 되는 ECC 알고리즘과 그 성능을 자세히 알아보자.
NAND의 ECC는 Error의 Detection 알고리즘과 Correction 알고리즘이 함께 되어있는 것이며, 위에서 설명했듯이 Detection 이 된 후 Correction 이 되므로 분리해서 생각을 할수가 없다.




  • Error Correction 기능 
  1. Hamming : for 1bit                 (1bit 만)           
  2. Reed Solomon: for up to 4 bits (4 bit 까지)
  3. BCH  : For more than 4 bits    (4 bit 이상)

  • Hamming  알고리즘 
    초창기 많이 사용되어지 알고리즘이며, SW로 많이 제공되었음
  1. 1 bit correction   
  2. 2 bits error detection   (Parity 기능)
  3. requires 24 bits for 512 B ( 512 Byte 당 3 Byte 필요)
  

  • Reed Solomon  알고리즘 
    원래 CD-ROM/DVD에서 되며, DVB 및 QR Code 및 다양한 곳에서 사용
  1. 4 bits correction
  2. 5 bits error detection
  3. requires 80 bits for 512 B ( 512 Byte당 10 Byte 필요)


  • BCH (Bose, Ray-Chaudhuri and Hocquenghem)
다양한 저장장치에서 사용이 되고 있으며, 현재 많이 사용이 되는 ECC 중 하나이다.
  1. t bits correction    ( t 값은 가변적으로 변화됨)
  2. requires t*13 bits for 512 B     
  3. extra parity bit needed for error detection
  4. more complex to compute than Hamming 

BCH4/8/16  Error Correction 기능만 Byte 정리

512B 의 기준으로 Data를 계산을 하면, t=4/8/12 * 13 
BCH for 4 bits  : 52 bits = 6.5 bytes
BCH for 8 bits  : 104 bits  = 13 bytes 
BCH for 12 bits : 156 bits  = 19.5 bytes 

BCH4/8/16 Error Detection 과 Error Correction 기능 Bytes 정리 (TI에서 실제사용)

OOB Area (spare region) >= B * ( Page_Size / 512 ) + 2 + FileSystem_metadata
where
B =  8 bytes for BCH4
B = 14 bytes for BCH8 
B = 26 bytes for BCH16

Error Dectection을 알고리즘, Parity 기능이 추가되어진다고 한다.

  https://en.wikipedia.org/wiki/BCH_code


2.2 ECC 알고리즘 의 성능

TI에서 제공해주는 자료이며, 성능의 단위는 Timer의 tick 기준으로 소요된 시간을측정한것이다.
측정보드는 AM37x EVM 이며, SW ECC를 사용했을 경우 알고리즘 비교하되 1 bit를 보정시간을 기준으로 측정  
아래의 자료를 통하여, 1bit를 보정하는 시간 파악하여  알고리즘의 복잡도를 알수있다.

  • tick  계산

4.61us /120  = 3.8416666666666666666666666666667e-8
1 tick =  38.816nS

  • 1-bit correction mode  
120 timer ticks
4.61us to correct 1 error

  • 4-bit correction mode
234,000 timer ticks
9.00ms to correct 1 error with no meaningful performance difference when correcting 2 to 4 errors

  • 8-bit correction mode
244,000 time ticks
9.38ms to correct 1 error with no meaningful performance difference when correcting 2 to 8 errors


2.3 TI HW ECC 알고리즘 



  • TI -MPU의 ECC 정보
TI-MPU는 HW로 Error Detection 과 Location 기능을 제공해주며, SW로 Correction 을 제공을 해주고있다.
Location 부분은 별로 신경을 쓰지 않았지만, 생각을 해보니 중요한 정보인것 같으며, TI에서 좋은 정보를 제공해주고 있다.

  1. Error Detection  :  HW NAND Error 감지 가능한 Bit 수
  2. Error Location    :  HW NAND Error 위치 파악 기능
  3. Error Correction :  HW NAND Error 복원 

ECC support by device

HardwareBoot ROM CodeDriver Solution
Error DetectionError LocationError CorrectionError Correction
1b4b8b16b1b4b8b16b1b4b8b16b4b8b16b
DM33x/DM35x/DM36x
AM1xxx/C674x/OMAP-L1xx
EMIFAEMIFAYY
OMAP34xx/35xx
AM35xx 1.0
AM/DM37xx 1.0
GGGGYY
AM35xx 1.1
AM/DM37xx 1.1+
GPMCGYY
AM389x/C6A816x/DM816xGGGPMCGELMYY
AM387x/DM814x
AM335x
AM437x
GPMCGELMYY
Note: GPMC abbreviated to G in narrow columns and grayed out if affected by the BCH-4 erratum.



  • TI Raw NAND관련 ECC 정보 
TI에서 사용되는 HW ECC 정보 및 Raw NAND Interface , MTD 정보제공


  http://processors.wiki.ti.com/index.php/Raw_NAND_ECC

  • NAND 및 ECC의 알고리즘 및 기타 자료 

MTD 및 NAND , Raw File System 관련 자료, 자료내용 좋다.

1/23/2015

NAND 기본사항

1. FLASH Memory 

역사

플래시 메모리는 1984년 당시 도시바에서 근무하고 있던 마스오카 후지오 박사가 발명했다. 도시바에 따르면, '플래시'라는 이름은 마스오카 박사의 동료인 아리스미 쇼자가 제안했다고 한다. 왜나하면, 메모리 내용이 지워지는 과정이 마치 카메라의 플래시를 떠올렸기 때문이다. 마스오카 박사는 이 발명을 캘리포니아 새너제이에서 열렸던 IEEE 1984 International Electron Devices Meeting (IEDM)에서 발표하였다. 당시 인텔은 이 발명의 엄청난 잠재력을 보고 1988년 최초의 상업용 NOR 타입 플래시 메모리를 소개하였다.

NOR 기반 플래시는 지우기와 쓰기 시간이 긴 대신 어떤 위치에도 임의로 접근할 수 있게 주소/자료 인터페이스를 제공한다. 이 메모리는 컴퓨터 바이오스나 셋톱 박스의 펌웨어와 같이 자주 업데이트되지 않는 프로그램 코드를 저장하는 데에 알맞다. 플래시 메모리 특성상 10,000에서 1,000,000까지 지울 수 있다. NOR 기반 플래시는 초기 이동형 매체의 뿌리가 되어, 콤팩트 플래시에서 처음 사용되었으나 나중에 좀 더 싼 NAND 플래시가 쓰이기 시작했다.

NAND 플래시는 1989년에 도시바가 ISSCC에서 발표했다. NAND 플래시는 NOR 플래시에 비해 지우기와 쓰기 시간이 좀 더 빠르고 집적도가 높으며 비트당 제작비도 낮고 10배의 내구성을 자랑한다. 그러나 입출력 인터페이스는 자료에 대한 순차 접근만을 지원한다. 이것은 컴퓨터 메모리로는 조금 덜 유용하지만 개인용 컴퓨터 카드와 다양한 메모리 카드와 같은 대용량 저장 장치에 알맞다. 첫 NAND 기반 이동형 미디어 포맷은 스마트 미디어였지만, MMC, 시큐어 디지털(Secure Digital), 메모리 스틱과 XD-Picture 카드에서도 사용되고 있다. 그 밖에 RS-MMC (Reduced Size MultiMedia Card), TransFlash, miniSD 등이 다음 세대 저장 매체로 등장하고 있다. 이러한 새로운 포맷은 보통 크기가 4 제곱 센티미터 이하로 상당히 작다.


한계

플래시 메모리의 한계는 블록 내에서 특정 단위로 읽고 쓸 수 있지만, 블록 단위로 지워야 한다는 것이다. 또한 덮어 쓸 수 없으므로, 모든 블록을 지우기 전까지는 해당 자료를 변경할 수 없다.

NOR 플래시의 경우, 임의 접근 방식으로 바이트 또는 워드 단위로 읽기/쓰기 동작이 가능하지만 덮어 쓰기와 지우기 동작은 임의로 접근할 수 없다. NAND 플래시는 페이지 단위로 읽기/쓰기 동작이 가능하지만 해당 페이지를 덮어 쓰거나 지우려면 모든 블록을 지워야 한다.(NAND 플래시는 블록을 여러 페이지로 나누어 사용한다)..


  상위의 글 아래 위키자료
   http://ko.wikipedia.org/wiki/%ED%94%8C%EB%9E%98%EC%8B%9C_%EB%A9%94%EB%AA%A8%EB%A6%AC
  http://www.eetimes.com/document.asp?doc_id=1272118

  tn2919_nand_101.pdf

1.2 Flash Memory의 NAND 기본이해

Flash Memory는 두 종류이지만 거의 NAND만 사용하므로, NAND에 대해서만 언급하겠다.
나의 경우에도 NOR FLASH를 못본지 벌써 얼추 10년이 되어 가는 것 같다. 물론 이의 중간형태인 ONE-NAND도 있지만 초창기에 잠시 좀 쓰이다가 잘 사용하지 않아서 생략한다.

역시 사용하기도 편하고 빠르고 가격이 문제로 인하여 어쩔수 없이 트렌드가 NAND로 가는 것 같다.

아래의 사이트에서 너무 쉽게 설명을 해주고 있어 감사할 다름이다.



  • NAND 기술관련자료    
   개인블로그에서 NAND의 기본구조 ,타입 및 기본적인 내용 설명 및 필요기술소개
   내용이 이해하기 쉽고 좋아서 Link로 연결

   http://cappleblog.co.kr/582
   http://cappleblog.co.kr/583


   NAND의 기본구성에 대해 자세히 기술되어져 있다.
   https://www.ece.umd.edu/~blj/CS-590.26/nand-presentation-2010.pdf


2. NAND의 기본구성

NAND의 구성은  Block과 Page로 구성이 되며, Page가 모여 Block이 되는 구성이다.

1 Block  (Chip Vendor Bad Block이 아님을 보증) 
2 Block 
3 Block 
4 Block -- 1 Page ( Data + OOB)
           2 Page
           3 Page
           4 Page
           5 Page 
           ......           


  • 전형적인 Block과 Page Size 관계
  1. 32 pages of 512+16 bytes each for a block size of 16 kB
  2. 64 pages of 2,048+64 bytes each for a block size of 128 kB
  3. 64 pages of 4,096+128 bytes each for a block size of 256 kB
  4. 128 pages of 4,096+128 bytes each for a block size of 512 kB

      • NAND의 기본특성 
      1. Erase의 기본단위로  Block 단위 
      2. Read/Write 의 기본단위는 Page 단위 
      3. Erase 를 할 경우 값은 0xFF     로 변경   (NAND의 기본특성)
      4. Write 를 할 경우 값은 1 -> 0  변경    (NAND의 기본특성) 

      • Flash Memory의 Wiki 확인내용 
      1. NAND의 내구성  (Erasing 횟수 관련내용, 참조만 하고 Datasheet 참고)
      2. NAND or NOR 비교  ( NOR는 XIP 실행)
      3. NAND 년도 별의 공정의 변화 및 Trend 

         http://en.wikipedia.org/wiki/Flash_memory


      2.1 NAND Page의 기본구성 

      Page는 Write의 기본단위이며, Main Area + OOB 로 구성이 되어, 보통 Main Area 512 byte , OOB는 16byte 구성된다.
      물론 Main Area 256 였던 시절도 존재하며, 현재 2048이고 이 Size는 가변적이다.
      (상위 구성은 기본예이며, Chip Vendor에 및 Chip 따라 Size가 변경)

      설사 Main Area가 2048byte 일 경우에도 기본 Base로 512byte에 기반으로 ECC를 계산하여 OOB에 넣기 때문에 512byte는 중요

      • 1 Page 의 구성의 예
      1. Data(Main area)    : 2048 bytes
      2. OOB(Out Of Band) : 64 bytes


      • Page 2K일 경우, 2048/512 = 4 
      1. 512+16, 
      2. 512+16, 
      3. 512+16, 
      4. 512+16 


      • 삼성 SLC Type NAND 구성 (Samsung SLC)  
           K9F1G08U0M  = 8 bit Bus

                1 Page   =  (2K + 64) Bytes
                1 Block   = (2K + 64)B x 64 Page
                             = 128K +4K Bytes
                1 Device = (2K+64)B x 64Pages x 1024 Blocks = 1056Mbits = 128M bytes.

        http://wiki.openwrt.org/doc/techref/flash



      Ref.
          http://www.macronix.com/Lists/ApplicationNote/Attachments/736/AN0269V2_Introduction%20to%20NAND%20in%20Embedded%20Systems-0220.pdf


      2.2 Timing

      Nand는 기본적으로 CMD 방식으로 제어를 하며, 약간의 Timing 오류에 따라 오류가 발생을 할 수 있다고 하나 유연하므로 ,
      이 부분은 적당히 설정 하거나 주의하면 되겠다.