노무현 대통령 배너


2006. 6. 20. 12:33

양산시에 문제되는 NAND의 배드 테이블 관리기법

양산시에 문제되는 NAND의 배드 테이블 관리기법
글쓴이 : 이영진 (2004년 06월 02일 오후 04:12) 읽은수: 2,975 [ 체험수기 인쇄용 페이지 ]
(주) 시그마컴 연구3팀 제공

또다시 ^^ 부족한 내용이지만 글 하나 더 올리겠습니다.
NAND의 경우 0번블럭만이 불량이 아니라고 보장을 해줍니다.
실제 다른 블럭의 경우에는 배드블럭이 있을수도 있지요.
저희가 개발했던 제품은 PMON이라는 부트로더가 NAND에 커널과 루트 이미지 등을 이더넷으로부터 전송받아
NAND에 기록하게 됩니다. 다행스럽게도 PMON에 배드블럭체크루틴이 포함되어 있어 양산시에 이것을 이용할 방법을 찾아봤습니다.

NAND의 첫번째 블럭(0번)은 배드 테이블로 이용합니다.
배드 테이블은 char타입의 1024개의 배열로 지정하며 실제 물리적인 자료영역은
1번 블럭부터 시작합니다. PMON은 NAND를 검사하여 배드테이블을 작성하게 됩니다.

간략히 16개로 줄여서 묘사하겠습니다.

0~15까지의 물리적인 블럭이 있습니다. 여기서 3번과 6번이 배드 블럭입니다.
그러면 배드 테이블은 다음과 같이 구성됩니다.
{0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, ...}
즉 배드가 나면 배드난 블럭을 스킵하고 다음 블럭을 이용하게 됩니다.
배드테이블에 기록하는 것은 누적 배드블럭의 수입니다.
4번 블럭을 읽으려면 배드 테이블의 값이 1 이므로 이전에 배드가 하나 있었으니 하나 밀려서 이용하라는 의미입니다.
물론 또한 0번블럭또한 배드테이블이 점유하고 있으니 실제로는 두개가 밀려야 하지요.

drivers/mtd/mtdpart.c에 논리 주소를 물리 주소로 변환하는 매크로를 작성하였습니다.

#define ADJUST_OFFSET(adjust)
do {
int base, offset;
base = ((adjust+part->offset)>>14);
offset = bad_table[base]+1;
while (base+offset != base+bad_table[base+offset]+1) {
offset = bad_table[base+offset]+1;
}
adjust += offset<<14;
} while(0)

이것은 다음처럼 이용됩니다.

static int part_read (struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf)
{
struct mtd_part *part = PART(mtd);

if (from >= mtd->size)
len = 0;
else if (from + len > mtd->size)
len = mtd->size - from;

ADJUST_OFFSET(from);
if (part->master->read_ecc == NULL)
return part->master->read (part->master, from + part->offset,
len, retlen, buf);
else
return part->master->read_ecc (part->master, from + part->offset,
len, retlen, buf, NULL, &mtd->oobinfo);
}

이와 같은 방식으로 부트로더에서 NAND에 기록을 할때 배드를 건너뛰고 기록을 하고
배드 테이블을 작성하면 리눅스가 부팅후에 그 테이블을 참조해서 올바른 블럭을 이용하도록 하는 것입니다.

물론 이건 양산시에만 적용될수 있으며 그 이후에 발생하는 배드블럭은 리눅스의 몫입니다.

참고로 아래는 atd_mtd_partitoin()시에 배드 테이블을 읽어오는 로직입니다.

master->read(master, 0, 1024, &i, bad_table);
if (i<1024) {
printk("Caution!!! badtable size %d too smalln", i);
}

근데.. 소스 들여쓰기가 죄다 깨져서 올라가는군요.. ㅡ,ㅡㅋ

그럼 좋은 하루 되세요.

* 주1) char타입이라 256개까지의 배드만 핸들링이 가능합니다. 256개가 넘는 배드 블럭이 있는 NAND의 경우 우리팀의 결론은 "버려~"입니다.
* NAND사이즈에 따라 1024의 수치를 변경하시면 됩니다.
아참 여기서 블럭크기는 16KB입니다. 그래서 블럭넘버를 얻기 위해 14비트 쉬프트 한것이구요.

양산시에 문제되는 NAND의 배드 테이블 관리기법 | 답장: 4개(RSS) | 본문에 답장
정렬 :
답장 익명 (2004년 06월 03일 오전 02:47)
좋은 내용 감사합니다.
[ 이글에 답장 | 본문에 답장 ]

답장 익명 (2004년 08월 03일 오전 09:44)
물론 또한 0번블럭또한 => 물론 또한 6번블럭또한
[ 이글에 답장 | 본문에 답장 ]

답장 익명 (2004년 09월 20일 오후 01:04)
아~ ^^ 그거 0번 블럭 또한이 맞습니다.

뭐 구현의 차이겠지만 배드테이블(0번 블럭) 자체도 1블럭을 점유하고 있잖아요?

그래서 테이블에 1이면 1을 더해줘야 한다는 의미였어요 ^_^;
[ 이글에 답장 | 본문에 답장 ]

답장 익명 (2004년 11월 23일 오후 04:07)
>>14 는 >> 17이 아닌가요?
[ 이글에 답장 | 본문에 답장