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