[OS]/Embedded

[펌] 부트로더와 플래시 메모리(1)-2

하늘을닮은호수M 2005. 6. 22. 14:41
반응형

부트로더와 플래시 메모리(1)-2
저 자 : 유영창
출판일 : 2004년 2월호

플래시 메모리의 특징
앞에서도 언급했지만 ROM은 한번 써진 상태에서는 프로그램을 이용해 해당 내용을 지울 수 없다. 이에 반해 RAM은 언제든지 내용을 수정할 수 있다. 플래시 메모리는 이 중간 형태에 속한다. 즉 프로그램에서 내용을 수정할 수 있고 전원이 꺼지더라도 기억이 가능하다.
프로그램에서 플래시 메모리의 내용을 수정할 수 있으므로 RAM과 같은 특징을 가지고 있지만 두 가지 단점이 있다. 하나는 읽고 쓰는 속도가 RAM과 같은 속도가 나오지 않는다는 것과 영역 지우기라는 처리를 수행해야 한다는 점이다. 예를 들어 ROM이라면 메모리의 0x3000 번지에 데이터를 다음과 같이 처리하면 읽어올 수 있다.

char *ptr = (char *) 0x3000;
printf( “0x3000 -> %02Xn”, *ptr );
하지만 다음과 같이 데이터를 써넣어도 데이터는 변경되지 않는다.
char *ptr = (char *) 0x3000;
*ptr = 0x45;
printf( “0x3000 -> %02Xn”, *ptr );

이에 반해 RAM은 이 출력 결과로 ‘0x3000 → 45’라는 값을 얻을 수 있다. 즉 수정이 가능한 것이다. 그러나 플래시 메모리는 RAM이나 ROM과 같은 방식으로는 절대로 처리할 수 없으며, 다른 처리가 필요하다. 플래시 메모리 중에서 ROM의 특성을 가지는 것은 NOR형 플래시인데, 이 플래시는 데이터가 플래시에 써넣어져 있다면 다음과 같은 형식의 프로그램 방식으로 내용을 읽을 수 있다.

char *ptr = (char *) 0x3000;
printf( “0x3000 -> %02Xn”, *ptr );

물론 이 예가 동작하려면 플래시 메모리의 동작하는 어드레스 공간이 0x3000 번지를 포함하고 있어야 한다. 물론 ROM과 같이 이렇게 읽기만 가능하다. 써넣기는 특이한 형태로 사용하여야 한다.
보통 플래시에 어떤 데이터의 써넣기를 시도하는 행위를 시작하면 플래시는 ROM과 같은 특성으로 읽어 버린다. 즉 일반적인 주변 디바이스 형태가 되어버린다. 이런 특성 때문에 플래시에 초기 수행을 시작하는 부트로더들은 RAM 영역으로 이동하여 플래시에 대한 처리를 수행한다. 이지부트가 처음에 프로세서 초기화 과정을 수행한 후 실제 부트로더 프로그램 코드들을 RAM 영역으로 이동한 후 이 영역에서 수행되는 이유가 바로 이것이다.
플래시의 또 다른 특성은 플래시 메모리의 특정 번지만을 수정할 수 없다는 것이다. 플래시의 데이터를 읽을 때는 바이트 단위 또는 워드 단위의 메모리를 읽어올 수 있다. 읽어오는 행위 자체에는 아무런 제약이 없다. 하지만 데이터를 써넣기 위해서는 영역 지우기라는 행위를 해야 한다. 우선 플래시의 써넣기 특징에 대하여 한번 알아보자.
RAM일 경우 하나의 바이트 데이터를 구성하기 위해서는 8비트의 상태를 가진다. 예를 들어 0x3000 번지의 값이 0x34라면 00110100이라는 비트열을 가진 상태로 된다. 이 번지에 내용을 0x5A로 수정한다고 한다면 그냥 해당 번지에 0x5A 값을 써넣으면 0x3000 번지는 10011010이라는 비트열을 가진 상태가 된다. 즉 각 비트의 값이 0에서 1로, 1에서 0으로 바로 바뀔 수가 있다.
플래시 메모리는 RAM과전혀 다른 방식으로 데이터를 써넣는다. 플래시 메모리가 초기화된 상태라면(나중에 설명하겠지만 영역 지우기가 된 상태) 0xFF 값을 갖는다. 즉 11111111이라는 비트열 값을 가진다. 이중 0x3000 번지에 0x34라는 값을 써넣으면 RAM과 같은 방식으로 00110100이라는 비트열을 갖는다. 여기까지는 RAM과 유사하다. 하지만 이렇게 0x34라는 값을 가지는 0x3000 번지에 0x5A를 써넣으면 실제 값은 0x3000 번지에는 0x10 값으로 저장된다. 이 내용을 정리하면 <표 1>과 같다.



왜 이런 차이가 생기는 것일까? 이유는 간단하다. RAM과 달리 플래시 메모리는 1에서 0으로 내용이 바뀔 수는 있지만 반대로 한번 0으로 바뀐 비트는 1로 바꿀 수 없다. 0에서 1로 바뀌게 하려면 영역 지우기라는 행위를 하여야 한다. 즉 플래시 메모리는 영역 지우기라는 행위를 하여야 0에서 1로 바꿀 수 있고 단순히 쓰기만을 해서는 1에서 0으로 바꾸는 처리밖에 하지 못한다. 이런 이유로 플래시 메모리에 데이터를 쓰기 위해서는 읽기와 달리 다음과 같은 순서가 필요하다.

영역 지우기(block erase) → 쓰기(writing) → 데이터 고정(fusing or programing)

영역 지우기의 문제점
앞의 순서에서 영역 지우기는 플래시 메모리의 데이터를 모두 0xFF, 즉 11111111 비트열로 만들어 버린다. 이 영역 지우기라는 처리를 하는 것에서 프로그래머들을 괴롭히는 문제는 특정 번지만 지울 수 없다는 것이다. 즉 특정 번지의 지우기를 시도하려면 일정 크기의 블럭을 모두 지워야 한다. 이 지워지는 블럭의 단위는 플래시를 생산하는 회사마다 다르고 제품 종류마다 다르다. 그래서 플래시를 쓰기 위해서는 가장 먼저 해당 칩을 보고 블럭의 크기에 대한 정보를 획득하는 것이 필요하다.
이런 영역 지우기의 블럭 크기 제한 때문에 데이터의 자유로운 수정이 곤란하다. 예를 들어 4KB 단위의 블럭을 갖는 제품을 지운다고 가정해 보자. 0x100 번지의 내용을 바꾸려고 할 때 0x000 번지부터 0x3FF 번지의 모든 내용을 지워야 하고 해당 번지의 내용을 모두 다시 써넣어 주어야 한다. 이것이 RAM과 달리 데이터의 자유로운 수정이 불가능한 이유이다.
또 한 가지 문제는 블럭을 모두 지우기 때문에 지우는 시간이 무척 길다는 것이다. 지워지는 시간 역시 상황에 따라서 달라진다. 최대 시간은 제품마다 다르지만 경우에 따라서는 3초까지 걸리는 경우가 있다. 물론 이렇게 지우는 시간이 큰 경우는 드물고 대부분 1초 이내이지만 초 단위의 시간은 ‘프로세서의 처리 시간’ 입장에서 보면 무지막지하게 큰 경우가 된다.

데이터 써넣기의 문제점
영역 지우기를 통해서 특정 블럭의 내용이 모두 0xFF로 바뀌었다고 하더라도 데이터를 바로 써넣을 수는 없다. 항상 특정 명령을 플래시에 전달하고 데이터를 써넣어야 한다. 또한 데이터를 써넣는 단위도 버퍼라는 크기를 가진 일정한 크기를 요구하는 경우와 번지별로 써넣는 경우로 나뉜다. 일반적으로 버퍼 단위로 써넣는 경우가 쓰는 속도가 더 빠르다. 번지별로 써넣는 경우도 사실은 버퍼의 크기가 1바이트라는 의미가 되기 때문에 다를 것이 없다. 플래시에 데이터를 써넣기 위해서는 이 버퍼에 데이터를 쓴 다음 ‘데이터 고정’이라는 단계를 거쳐야 한다. 데이터 고정은 다른 말로 ‘퓨징(fusing)’이라고도 하고 프로그램이라고도 한다. 이런 이유로 플래시에 데이터를 써넣는 작업은 프로그래머에게 여러 가지를 고려하도록 만든다. NOR형 플래시 메모리는 펌웨어 프로그램의 저장으로 사용된다. 우리가 메모리를 읽는 것처럼 플래시를 읽는다면 NOR형이다. 즉 크기만큼의 어드레스를 지원한다. 그렇다고 메모리만큼 속도가 빠른 것은 아니다. 이런 종류의 칩들은 가격도 비싼데, NAND형보다 만들기가 어렵기 때문이다. 8MB 이상의 플래시를 사용한다면 대개는 인텔 제품을 사용한다(인텔 플래시는 비싸다). 대만이나 기타 제조사들은 4MB 정도만을 생산하기 때문이다. 앞에서도 설명했지만 플래시를 읽는 것은 메모리와 같지만 쓸 경우는 다음과 같은 흐름으로 쓰게 된다. 영역 지우기 시간은 대략 1~5초이며, 퓨징 시간은 200~600u초가 소요된다.
영역 지우기(block erase) → 버퍼에 데이터 쓰기(writing) → 데이터 고정(fusing or programing)
NOR형 플래시는 크게 인텔 제품과 AMD 제품군으로 볼 수 있다. EZ-X5에서 사용한 mx29lvx 계열의 제품은 대만산 제품이기는 하나 AMD 제품과 비슷한 특성을 갖는다.

스트라타 플래시/부트블럭 플래시
플래시 메모리의 종류를 설명하기 위해서는 인텔 제품의 예를 들면 편리하므로 일단 인텔 제품을 예를 들겠다. 인텔 플래시는 크게 스트라타 플래시부트블럭 플래시로 나뉜다. 차이점을 알아보자.
부트블럭의 경우 쓰기시에 한 개의 워드만을 쓸 수 있지만 스트라타는 16개의 워드를 쓸 수 있다. 이런 특성상 퓨징 시간이 그만큼 줄어들어 전체적으로 데이터를 쓰는 시간이 빠르다. 스트라타도 한 개의 워드씩 쓸 수 있다.
스트라타의 블럭(지우기시에 지워지는 크기)은 128KB이면 부트블럭은 64KB이다. 이 차이점은 단점도 장점도 될 수 있다. 많은 양의 데이터를 쓴다면 블럭이 큰 쪽이 시간에서 유리하지만 작은 양의 데이터를 자주 쓴다면 부트블럭이 유리하다. 쓰기 위해서는 지워야 하기 때문에 블럭의 데이터는 모두 소멸된다. 필요한 데이터만을 쓰려고 한다면 블럭의 데이터를 메모리로 읽어오고 변경된 내용을 메모리에 적용한 후 이것을 다시 플래시에 쓰게 되는데, 이 때는 블럭이 작은 쪽이 유리하다.
부트블럭은 Bottom or Top이라는 형태가 존재한다. Bottom은 0x0000 주소, Top은 플래시의 마지막 블럭 주소를 말하며, 이곳이 16개의 작은 블럭(4KB)으로 나뉘어 있다. 즉 4MB의 부트블럭 플래시는 (63[64KB*63])+(16개의 블럭[4KB*16])이 있는 것이다. 그러나 스트라타는 이런 영역이 없다. 부트블럭 플래시의 용량은 1MB, 2MB, 4MB 스트라타는 4MB, 8MB, 16MB가 출시되어 있다. 다른 회사의 플래시는 인텔의 부트블럭 플래시와 비슷한 구조를 가지고 있다.

NAND형 플래시
NAND형 플래시가 NOR형 플래시와 다른 점은 ROM 형태의 읽기가 불가능하다는 점이다. 데이터를 읽기 위해서는 특정 블럭의 크기를 모두 읽어와야 하고 써넣기 위해서는 특정 블럭 크기 단위로 써넣어야 한다. 이런 이유로 NAND형 플래시는 펌웨어 프로그램용으로 사용할 수 없다. 이런 특성 때문에 대부분 MP3 플레이어나 USB 이동형 디스크 또는 Disk On Module 같은 장비에 주로 사용한다. 이외의 특성은 NOR형과 대부분 동일하다.
일반적인 메모리 소자와 같은 특성이 없음에도 불구하고 읽고 쓰는 속도가 매우 빠르고, 플래시 메모리의 특징 중 하나인 영역 지우기에 소모되는 시간이 매우 작아서 하드디스크와 같은 보조기억장치의 대용으로 많이 사용한다. 아무래도 반도체이기 때문에 진동과 같은 기계적 특성에 강하고 소모되는 전력이 적기 때문이다. 또한 지원하는 메모리의 특성상 가격에 비해서 저장 크기가 무척 크다. 최근에 NAND의 품귀 현상 때문에 상당히 가격이 올라갔지만 조만간 해결될 것으로 예상된다(가격이 많이 올라갔다고 해도 NOR형 플래시, 특히 인텔 제품에 비해서는 현저히 가격이 싸다).

반응형