본문 바로가기

Programming/General

nand flash - ftl(last, ECC, FSOC)

출처 :

http://kin.naver.com/open100/detail.nhn?d1id=1&dirId=10103&docId=422528&qb=ZWNjIGJsb2Nr&enc=utf8&section=kin&rank=1&search_sort=0&spq=0&pid=g6aYQloi5T8ssbtsL8ssss--165317&sid=TKFWy7cioUwAAHDlbYM

http://blog.naver.com/gosuyk?Redirect=Log&logNo=50186594



 

NAND를 많이 써본 경험에 의해 몇가지를 정리해봅니다.

 

1. NAND의 Write 특성

 

NAND는 Erase를 하면 모든 데이터가 0xFF로 바뀌게 됩니다.

이를 NAND로직을 통해 비트가 1인 녀석들을 0으로 바꾸게 되는 것이죠.

따라서 비트가 0인 녀석을 1로 바꾸는 것은 불가능합니다.

오직 Erase명령을 통해 데이터를 0xFF로 바꾼 후에야 원하는 Write가 가능하게 되는 것입니다.

 

2. NAND의 안정성

 

사실 NAND라는 스토리지는 가격이나 데이터 보존성은 매우 좋지만 데이터의 오퍼레이션 중 Power가 나가는 동작 즉, Power Failure에 매우 약한 특성을 보여줍니다.

때문에 Spare 영역이란 것을 두고 ECC를 이용해 이를 극복하려 합니다.

 

그러나 ECC 마저도 Bad Block이라는 복병을 만나게 되면 더이상 그 블록은 사용이 불가능한 블록이 되고 맙니다.

 

3. Spare 영역

 

Spare영역은 특별히 정해진 부분이 없습니다.

다만 대부분의 밴더가 각 블록의 0번 페이지의 스페어영역 5번 바이트를 배드블럭 마킹으로 사용하고 있습니다.

 

삼성 권고사항에 따르면 6,7,8번 바이트는 3바이트 ECC로 사용하고 9,10번 바이트는 S-ECC로 사용하라고 하고 있습니다만 WinCE에서는 5번 바이트만 배드블록 마커로 사용하고 0~3은 LBN (즉, 로지컬 블록 넘버 : 논리 블록 번호)로 사용하고 있습니다.

 

CPU에 따라서 ECC가 3바이트가 넘는 경우에도 삼성의 권고사항은 따르지 않습니다.

 

그러나 여전히 중요한 점은 0번페이지의 스페어영역 5번바이트는 배드블록 마킹이라는 것입니다.

 

4. Factory bad block

 

NAND는 NOR와는 달리 공장 출하시의 새 NAND조차 불량 블록을 가지고 있을 수 있습니다.

이 불량 블록은 일반 배드블록과도 특성이 다릅니다.

뭐 하여튼 이 Factory bad block의 마킹을 위에서 말한 각 블록 0번페이지 스페어5번바이트에 표시합니다.

 

Factory bad block 역시 NAND의 블록이기 때문에 Erase에 의해 모든 데이터가 0xFF로 바뀔 수 있습니다.

따라서 NAND를 Erase할 때에는 Bad block marking을 확인하여 Erase해야 합니다.

즉, 절대 Factory bad block은 Erase해서는 안됩니다.

 

Factory bad block은 데이터를 읽고 쓸 때 성공할 수도 있습니다.

그러나 다음번 읽었을 때 엉뚱한 데이터를 출력하게 됩니다.

따라서 절대로 사용해서는 안되는 Block입니다.

 

5. Run-time bad block

 

NAND의 특성때문에 멀쩡한 블록이 배드블록화 되는 경우도 있습니다.

대부분의 경우에는 더이상 사용하면 안되는 것이 맞습니다만, 단순히 일시적인 장애로 인해 배드블록으로 판정이 나는 경우도 있습니다.

이것은 엔지니어와 그의 보스의 기획과 결정에 의해 선택될 정책입니다.

 

한가지 특이한 점은 모든 벤더가 0번 블록에 대해서는 Bad 가 나지 않는다고 보장한다는 점입니다.

(사실은 Bad가 나지 않는 것이 아니라 Bad가 날 경우 NAND Boot를 지원하는 CPU에서 0번 블록을 제대로 Read할 수 없기 때문에 더이상 해당 NAND는 쓸 수 없는 것입니다.

개인적으로 특별히 bad에 강하다고는 생각하지 않습니다.

단지, 부트로더가 올라가는 영역이라 Write횟수가 적고 Read횟수 또한 적기 때문이 아닐까..)

 

 

6. bad block management

 

너무나 많은 방법들이 있기 때문에 무엇이 답이다! 라고 할만한 것이 없습니다.

대표적인 방법들을 보자면,

 

Bad block table을 이용하는 방법이 있습니다.

이 방법은 특정 영역을 table로 이용하여 실제 NAND의 Physical block number와 접근하려는 Logical block number를 연결해 주는 방식입니다.

Bad Block의 용인 가능한 최대 갯수를 결정하고 그 만큼 NAND의 Block을 Reseve하기 때문에 NAND의  낭비율이 상당히 높습니다.

또한 table을 어디에 저장하고 어떻게 운용할 것인가... 하는 구현 난이도가 높은 점도 단점입니다.

하지만 제대로 구현하면 Random Access도 가능할 정도로 멋진 시스템이 됩니다.

물론 안정성도 굉장히 높아지게 됩니다.

Storage에서 bad block management를 한다면 역시 이방법입니다.

 

Skip을 통해 bad block을 회피하는 방법도 있습니다.

이것은 bad block이라고 판단되는 블록(즉, Write한 후 verify과정에서 실패나는 블록)을 bad marking해버리고 다음블록에 원하는 데이터를 쓰는 방식입니다.

이 방법은 오직 NAND를 순서대로 쓰는 경우에만 통용될 수 있습니다.

즉, 랜덤하게 억세스 해야 하는 경우라면 불가능합니다.

그러나 배드블록에 의한 NAND 낭비율은 가장 적다고 할 수 있겠습니다.

WinCE에서는 주로 부트로더나 EBoot에 이런 방법을 쓰곤 합니다.

Storage 영역에서는 절대 사용이 불가능한 방법입니다.

 

Spare영역을 이용한 방법도 있습니다.

즉, Spare에 LBN을 적어두고 사용하는 방법입니다.

여러가지 방식이 있지만 다음 블럭의 실제 번호를 적는 링크방식이 선호됩니다.

그러나 Bad Block은 Spare도 믿을 수 없기 때문에 크게 쓰이는 방법은 아닙니다.

 

H/W적으로 처리하는 경우도 드물지만 존재합니다.

OneNAND나 M-DOC 같은 칩들이 대표적입니다.

 

S/W적으로 처리하는 경우도 있습니다.

주로 파일시스템에서 지원하게 됩니다.

M-DOC의 TrueFS나 Zeen정보통신의 ZFS-ZFTL이 대표적입니다.


ECC :

현재 yaffs, nand device driver에 구현되어 있는 ECC는 2bit EDC,ECC를 지원하며(256Byte 당 1bit) 그 이상의 error를 detect하고 있다.

일반적으로 SLC에서는 512byte당 1~2bit ECC를 지원하도록 권고하고 있지만, MLC는 512B당 4bit ecc또는 그 이상을 지원해야 한다.

SLC에서 현재쓰고 있는 (yaffs, nand device driver) ECC는 Hamming code를 기반으로 한다. 하지만 MLC를 사용하기 위해서는 hamming이 아닌 Reed-Solomon이나 다른 알고리즘을 써야한다. (http://www.eccpage.com/ ?? 여기를 확인해보면 관련 자료가 있음)

 

OOB 영역안에 ECC data가 저장되어야 하는데, 만약 Reed-Solomon을 쓸 경우에는 기존 Hamming보다 더욱 많은 자릿수를 필요로 한다. (24바이트에서 40바이트로 늘어난다.) 그럼 nand flash file system인 yaffs를 못 쓰게 되며, FTL의 필요성이 여기서 기인한다. 즉 기존의 yaffs를 못 쓰기 때문에 ftl을 이용하여 yaffs가 아닌 타 file system이 이용되도록 해야 하는 것이다. 그래야 nand flash에 kernel, file system 이미지를 올려서 사용 가능하기 때문이다.

 

참고로, MTD 를 이용해 linux booting이 진행 될 경우 bootloader에서 확인해보면

1. bootloader에선 해당 nand flash의 physical address에서 특정 메모리 번지로 데이터를 read하고,

2. zImage 일 경우, 압축 해제후 커널 부팅이 진행될 메모리 위치로 copy를 진행

   아니면, uImage일 경우 커널 부팅이 진행될 메모리 위치로 바로 read

3. 커널의 초기화를 진행하고

4. bootloader에서 kernel이 전해준 argument을 이용해 filesystem 이미지를 찾는다.

5. file system 이미지가 nand 에 있으면 메모리에 필요한 부분만을 복사한뒤, 메모리에 file system을 구성하여 기타 부팅 과정을 완료

 

이때, file system 이미지나 kernel의 이미지가 깨졌을 경우, 문제가 심각해질 수 있다. 즉 ECC가 nand flash에서는 매우 중요!

 

FSOC :

FTL이 중간 layer단으로 자리잡을 경우, 내부 overhead로 인하여 nand flash의 성능이 제대로 나오지 않는다. 소프트웨어로 구현되어 있으니깐! 그럼 이 부분을 하드웨어로 옮기면 속도가 좋아지지 않을까? 즉, FTL의 기능을 하드웨어로 옮긴 것이 FSOC이다.

nand flash로 되어 있는 sdcard나 기타 저장장치를 보면 실제 크기보다 적은 크기를 출력하는데, FSOC가 하드웨어로 내부로 구현되어 있으며, 해당 데이터를 일정량의 Block을 이용하여 사용하기 때문이다.