---
title: "NAND 불량 block 표시는 지우기 전에 읽어야 한다"
author: "브레이브브라우저쓰자"
published_at: "2026-10-12T13:16:01.368Z"
updated_at: "2026-10-06T00:13:32.963Z"
tags: ["bad block marker"]
canonical_url: "https://ariser.io/@writer_a9817d5a8de0/nand-%EB%B6%88%EB%9F%89-block-%ED%91%9C%EC%8B%9C%EB%8A%94-%EC%A7%80%EC%9A%B0%EA%B8%B0-%EC%A0%84%EC%97%90-%EC%9D%BD%EC%96%B4%EC%95%BC-%ED%95%9C%EB%8B%A4"
ai_assisted: true
---

# NAND 불량 block 표시는 지우기 전에 읽어야 한다

이 글은 AI가 활용됐습니다.

[원문](https://ariser.io/@writer_a9817d5a8de0/nand-%EB%B6%88%EB%9F%89-block-%ED%91%9C%EC%8B%9C%EB%8A%94-%EC%A7%80%EC%9A%B0%EA%B8%B0-%EC%A0%84%EC%97%90-%EC%9D%BD%EC%96%B4%EC%95%BC-%ED%95%9C%EB%8B%A4)

새 NAND를 연결한 뒤 모든 block을 지워 깨끗하게 시작했다. 그런데 이후 불량 block을 구분할 정보가 사라질 수 있다. 제조사가 출하 전에 적어 둔 Bad Block Marker도 flash의 특정 위치에 저장되기 때문이다. 초기화가 필요한 장치라고 해서 erase가 첫 작업이어야 하는 것은 아니다.

Bad Block Marker는 제조사가 사용할 수 없다고 판정한 block을 표시한다. controller가 처음 저장 공간을 배치할 때 읽어야 하는 정보이며, 정상 데이터처럼 지우고 새로 만들 내용을 뜻하지 않는다.

## 먼저 읽어야 하는 위치가 정해져 있다

[Alliance Memory SPI NAND Rev.1.0의 13절 Block Management](https://www.alliancememory.com/wp-content/uploads/AS5F34G04SND-08LIN_AllianceMemory_SPI_NAND_Flash_July2020_Rev1.0_1.pdf)은 program이나 erase 전에 각 block의 첫 page에서 첫 spare 위치를 확인하도록 명시한다. 이 위치에 FFh가 아닌 값이 있으면 factory bad block으로 처리한다. 문서의 bad mark 값은 00h다.

이 제품군은 불량 block의 첫 page 여러 위치에 표시를 시도하지만, 모든 위치의 program 성공을 보장하지 않는다. 첫 spare 위치를 보장하는 이유다. main data가 FFh처럼 보인다고 정상 block이라고 판단하거나, 임의 byte 하나만 검사하면 정해진 판정 위치를 놓친다.

여기서의 위치와 규칙은 이 datasheet의 해당 부품들에 대한 것이다. 다른 NAND는 첫 두 page나 다른 marker 위치를 지정할 수 있으므로, 한 driver의 상수를 그대로 복사하지 않는다.

## block 번호를 row와 column으로 바꾸기

같은 문서의 AS5F31G04SND-08LIN은 block당 64page, page당 main data 2048byte와 spare 64byte를 갖는다. block 12의 marker를 확인하려면 첫 page의 row는 12×64=768, 즉 0x300이다. page cache에 이 row를 가져온 뒤 첫 spare byte인 column 2048, 즉 0x800을 읽는다.

row 768의 column 0은 main data의 시작이며 marker 위치가 아니다. row 769의 column 0x800은 둘째 page다. 주소 하나만 맞아서는 정해진 factory 정보를 읽은 것이 아니다. page-to-cache 완료와 정확한 column 출력까지 이어져야 한다.

이 위치는 1.3절의 memory mapping과 1.4절의 spare layout에서 확인할 수 있다. 내부 ECC의 parity 영역과 marker를 혼동하지 않는 것도 중요하다. 이 부품의 첫 spare metadata byte는 ECC로 보호되지 않는 구간에 있다.

## erase한 FFh는 정상 판정 근거가 될 수 없다

marker가 00h였던 block을 먼저 erase하면, 지워진 셀이 FFh로 읽히거나 원래 표시가 다른 형태로 변할 수 있다. 불량 block이기 때문에 erase 결과 자체도 보장되지 않는다. 어느 쪽이든 사전 판정을 기록하지 않았다면, 후속 FFh를 보고 “factory good이었다”고 복원할 수 없다.

그래서 초기 scan으로 확인한 block 상태를 controller가 사용할 table에 보존하고, allocator가 해당 block을 선택하지 않도록 연결한다. scan을 한 번 수행했다는 사실보다 그 결과가 이후 erase·program 경로에도 적용되는지가 중요하다.

table을 비휘발성으로 저장한다면 그 사본의 무결성과 전원 차단 복구도 필요하다. marker를 읽은 결과를 휘발성 memory에만 남겼다가 지운 뒤 잃어버리면 다음 부팅의 scan은 원래 상태를 재구성하지 못할 수 있다. 실제 장치에 맞는 보존 정책이 있어야 한다.

## 전체 block 수가 전부 가용 공간은 아니다

13절 표에서 1024block 구성의 최소 valid block 수는 1004다. 이 최소값으로 main data 용량만 계산하면 1004×64×2048byte=125.5MiB다. 전체 1024block의 main 용량 128MiB와 2.5MiB 차이가 난다.

이는 모든 출하 제품에 정확히 20개 불량 block이 있다는 뜻이 아니다. 초기 가용 block의 최악 조건을 sizing에 반영한 계산이다. 관리 table, runtime spare와 상위 format에 쓰는 공간은 여기서 더 빠질 수 있다.

출하 marker와 사용 중 failure 기록도 다르다. 과거 factory scan에서 정상인 block도 나중에 문제가 생길 수 있다. 반대로 P_FAIL은 보호된 영역이나 잘못된 주소에 program을 시도해도 설정될 수 있으므로, flag 하나만 보고 wear의 증거라고 결론내리기 전에 command 조건을 확인한다.

Bad Block Marker의 가치는 그 byte의 크기보다 읽는 시점에 있다. **지우기 전에 정해진 위치를 읽고, 판정 결과를 보존하며, 이후 주소 배치에 반영해야 한다.** 새 NAND를 깨끗하게 만드는 일은 사용할 수 있는 block을 구분한 다음에 시작된다.

