임베디드에서 소프트웨어 베이스 메모리 테스트
꽤 오래간만에 KLDP에 글을 올리는 것 같습니다. 먹고 사느라 바쁘군요...^^;
얼마전에 찾은 좋은 문서가 있길래 번역해 봤습니다. 나중에라도 누군가가 필요하면 도움이 되겠지요.
이 글은 http://www.esacademy.com/en/library/technical-articles-and-documents/miscellaneous/software-based-memory-testing.html 의 내용을 제 맘대로 번역한 글입니다. 번역의 품질이 매우 허접하므로 정확한 내용을 원하시는 분은 원문 링크로 들어가서 원문을 확인하시길 바랍니다.
거의 모든 임베디드 개발자가 각자의 관점에서 개발해야 하는 소프트웨어 중 하나가 메모리 테스트하는 코드이다. 보통 프로토타입 하드웨어가 준비되면, 하드웨어 디자이너는 주소와 데이터 라인을 제대로 와이어링 했다고 우리를 안심시킨다. 그리고 여러 메모리 칩이 제대로 동작한다고 한다. 그래도 시스템이 리셋 될 때마다 온보드 RAM을 테스트하는 것이 더 바람직하다. 임베디드 소프트 웨어 개발자가 RAM 테스트 코드를 작업해 놓으면, 펌웨어는 보드 디자인 할 때 발견하지 못한 문제를 찾아 낼 수 있다.
메모리 테스트는 매우 단순한 것으로 보인다. 그러나 이 단순한 테스트는 찾기 힘든 미묘한 메모리의 문제를 보다 쉽게 찾을 수 있도록 도와준다. 사실은 많은 임베디드 시스템이 메모리 테스트를 포함하고 있다. 하지만 이것들은 매우 중대한 메모리 문제만 감지할 수 있다. 예를 들면 보드에서 메모리 칩이 떨어져 나갔거나 하는 등의 말도안되는 일들만 감지한다는 것이다. 사실상 무용지물이란 소리다.
메모리 테스트의 목적은 메모리 디바이스의 각 저장 영역이 제대로 동작하는 것을 확인하는 것이다. 다시 말해, 여러분이 숫자 50을 특정 주소에 저장했다면, 여러분은 그 숫자가 그 메모리 주소에 계속 저장되어 있는 것을 기대한다. 만약 다른 숫자를 같은 메모리 번지에 저장하면 그 때 메모리의 값이 바뀌어야 한다. 기본적인 메모리 테스트의 아이디어가 바로 이것이다. 특정 데이터 세트를 특정 메모리 주소에 쓰고 그것을 다시 읽어서 제대로 써 졌는지 확인하는 것이다. 만약 메모리 디바이스에서 읽은 모든 값이 썻던 값과 일치한다면 해당 메모리 디바이스는 테스트를 통과했다고 말할 수 있다. 밑에서 보겠지만, 여러분은 테스트 결과가 충분히 의미를 가질 수 있도록 메모리 테스트에 사용할 데이터 값만 신중하게 선택하면 된다.
따라서, 메모리 테스트는 메모리에 저장되어 있는 값을 변경해야 한다. 메모리 테스트 과정을 진행하면서 여러분은 메모리에 데이터를 덮어쓰기 해야 한다. 테스트 대상이 되는 메모리 디바이스가 비휘발성 메모리라 할 지라도 덮어쓰기를 해야 한다. 이것은 꽤나 위험한 짓이다. 그래서 이 문서에서 설명하는 메모리 테스트는 일반적으로 RAM을 테스트하는데에만 사용한다. 물론, 비휘발성 메모리, 예를 들면 플래시 메모리에 별로 중요하지 않은 데이터가 들어 있다면 이 문서에서 설명하는 알고리즘을 동일하게 적용할 수 있다.
흔한 메모리 문제
메모리 테스트 알고리즘을 구현하기 전에, 여러분은 메모리 문제가 어떤 종류로 발생하는 지 알고 가는것이 좋다. 한가지 흔한 소프트웨어 엔지니어들 사이의 오해는 대부분의 메모리 문제는 메모리 칩 내부에서 발생한다고 믿는 것이다. 하지만 경험상 이런류의 문제는 거의 없다고 보면 된다. (요새 메모리를 얼마나 잘 만드는데!) 메모리 생산 회사는 매우 다양한 후 공정 테스트를 진행한다. 그래서 불량 칩이 출시될 가능성은 거의 없다고 보면 된다.
여러분이 맞닥드릴 수 있는 메모리 칩 문제는 주로 매우 심각한 불량들이다. 이 문제들은 주로 물리적이거나 전기적으로 칩에 큰 충격이 가해져서 생기는 것들이다. 이런 심각한 문제들은 흔하지 않으며 메모리 칩에 크게 피해를 입힌다. 그래서 잘 만들어진 테스트 알고리즘으로 검사했는데 매우 많은 영역에 문제가 발생하면 칩에 물리적이거나 전기적인 충격이 가해져서 문제가 생겼다고 추정할 수 있다.
내 경험상 대부분의 흔한 메모리 문제의 원인은 보드 회로 문제였다. 일반적으로 회로 문제는 프로세서와 메모리 사이의 와이어링이거나 메모리 칩이 납땜되어 있지 않거나(!), 메모리칩이 잘못 납땜되어 있는 경우들이다.
훌륭한 메모리 테스트 알고리즘은 이 문제들을 감지해 낼 수 있어야 한다. 그러면 회로 문제에는 어떤것들이 있는지 자세히 알아보자.
배선 문제
배선 문제는 설계 오류이거나 보드 생산 오류이거나 생산이후 보드에 충격이 가해져서 발생할 수 있다. 메모리 칩과 프로세서 사이에 연결된 와이어는 다음 세 종류 중 하나이다. 어드래스 라인, 데이터 라인, 컨트롤 라인. 어드래스 라인과 데이터 라인은 메모리의 주소 위치를 결정하고 데이터를 전송하는데 각각 사용한다. 컨트롤 라인은 프로세서가 데이터를 전송할 때 데이터를 쓸것인지 읽을 것인지를 결정해 주는 것이다. 불행히도, 하나 혹은 그 이상의 이 와이어들이 잘못된 경로로 이어져 있거나 손상되어있거나 쇼트되어 있거나 단선되어(끊어져) 있을 수가 있다. 이런 문제들은 납땜이나 생산 공정상의 문제 때문에 주로 발생한다.
메모리 디바이스와 프로세서간의 전기적 연결 문제는 메모리 디바이스를 이상하게 동작하게 만든다. 데이터가 이상하게 저장된다든가 데이터가 잘못된 주소에 저장된다든가 아니면 데이터가 전혀 저장되지 않는다. 이런 증상들은 각각 데이터 라인, 어드래스 라인, 컨트롤 라인의 와이어링 문제로 설명할 수 있다.
데이터라 라인의 문제는, 몇몇 데이터 비트가 언제나 항상 “같이 맛탱이 간다”. 예를 들면 두개 혹은 그 이상의 비트가 언제나 같은 값을 가진다. 비슷하게, 데이터 비트가 항상 1이거나 항상 0으로 보일 수도 있다. 이 문제는 데이터 비트를 모두 0이나 1로 써서 연속된 데이터를 전송해 보면 감지할 수 있다.
만약 어드래스 라인에 쓰기 문제가 있다면, 두 곳의 메모리 위치에 있는 데이터가 중첩될 가능성이 있다. 다시 말해, 특정 주소에 데이터를 썼는데 실제로는 다른 주소에 데이터가 덮어쓰기 된다는 것이다. 어드래스 라인의 특정 비트 와이어가 쇼트되거나 단선되어 있으면 발생한다.
나머지는 컨트롤 라인이 쇼트되거나 단선되었을 때이다. 이론적으로는 컨트롤 라인의 문제를 감지하는 테스트를 만들 수 있지만, 실제로는 잘 안된다. 대부분의 컨트롤 시그널 동작이 프로세서나 메모리 아키텍처에 의해서 정의되어 있기 때문이다. 그나마 다행인 것은, 컨트롤 라인에 문제가 생기면 당연히 메모리가 제대로 동작하지 않는다. 그래서 다른 메모리 테스트를 돌릴 때 감지된다. 만약 여러분이 메모리 컨트롤 라인의 문제를 의심하면(다른 메모리 테스트 코드에서 문제가 발생하면), 컨트롤 라인을 제어하는 테스트 코드를 만들기(매우 빡세다) 전에 보드 디자이너에게 조언을 구하는 것이 편하게 일할 수 있는 방법이다.
메모리 칩이 없다.
메모리 칩이 없는건 쉽게 찾을 수 있다. (그냥 보드 보면 되잖아..) 그런데 실제로 칩이 없음에도 메모리 테스트를 대충 만들면 이걸 감지해 내지 못한다. 예를 들어 1을 첫 번째 메모리 위치에 쓰고, 다시 읽는다. 그리고 2를 두 번째 메모리 위치에 쓰고 다시 읽는다. 이어서 3을 세 번째 메모리에 쓰고 다시 읽는다. 메모리를 쓰고 바로 이어서 다시 읽는다면 데이터 라인에 직전에 쓰기 할 때 사용했던 전류가 남아 있다. 그래서 해당 전류가 그대로 피드백 되어 읽혀진다. 실제로 칩이 없는데도 읽혀진다는 거다!
메모리 칩이 없어진걸 알기 위해서는 테스트를 달리 해야 한다. 데이터를 쓰고 바로 읽는 대신에, 연속해서 데이터를 쓴 다음 이어서 관련 데이터를 연속해서 읽는 방식을 사용하는 것이다. 예를 들면, 1을 첫 번째 위치에 2를 두 번째 위치에 3을 세 번째 위치에 쓰고 다시 첫 번째 위치에서 읽고 검증하고 두 번째 위치에서 읽고 검증하고 세 번째 위치에서 읽고 검증하는 것이다. 그리고 각 위치에 쓰는 데이터 값을 서로 구분 가능하도록 하면 어떤 메모리 칩이 없는지 쉽게 확인할 수 있다. 첫 번째 값을 읽었는데 1이 아니라 마지막 값인 3이 읽혔다면 첫 번째 칩이 없는 것이라고 볼 수 있다.
칩이 잘못 꼽혀 있다.
메모리 칩이 눈에는 보이지만 소켓에 잘못 꼽혀 있는 경우가 있다. 이런 경우에 메모리는 쓰기에 문제가 발생하거나 칩이 없을 때와 비슷한 동작을 보인다. 다시 말해, 메모리 칩의 핀 중 일부가 소켓에 안 꼽히거나 다른 위치에 잘못 꼽혀 있는 것이다. 이 핀들은 데이터 버스나 어드래스 버스나 컨트롤 버스의 일부 일 수도 있다. 그래서 쓰기 문제 검출 테스트나 칩이 없어진 것을 찾는 테스트를 계속 하면 칩이 잘 못 꼽힌 문제는 자동으로 찾아진다.
테스트 전략 구상
계속 읽기 전에, 위에 서술한 메모리 문제의 종류를 빠르게 훑어보길 바란다. 우리는 이 문제들을 찾아 낼 수 있다. 메모리 칩은 내부 에러가 거의 없다고 보면된다. 그러나 만약 내부 에러가 있다면, 그것은 심각한 문제이고 테스트로 검출 해 내야 한다. 그리고 보다 흔한 문제들은 회로 문제나 메모리 칩이 없거나 메모리 칩이 잘못 꼽힌 상황들이다. 다른 메모리 문제들이 발생할 수도 있지만, 여기에 설명한 것들이 가장 일반적이다.
테스트 데이터를 선택하고 주소 순서를 선택하는 작업은 신중하게 해야 한다. 테스트 코드는 위에서 설명한 모든 메모리 문제를 찾아 낼 수 있다. 그리고 테스트 코드는 작고 효율적이며 읽기 편하다. 테스트 코드에 메모리 문제에 대한 보다 자세한 정보가 작성되어 있다.
메모리 테스트 코드는 다음 세 가지로 작업되었다. 데이터 버스 테스트, 어드래스 버스 테스트 그리고 디바이스 테스트이다. 앞의 두 테스트는 전기 회로 배선 문제와 칩이 잘못 꼽혀 있는지 여부를 확인한다. 세 번째 테스트는 칩이 없는 것등 심각한 문제를 확인한다. 의도하지 않은 결과로, 디바이스 테스트는 컨트롤 버스 배선 문제를 발견할 수 있다. 다만 컨트롤 버스 문제에 대한 유용한 정보는 제공하지 못한다. 단지 문제가 있음을 찾을 수 있을 뿐이다.
이 세 테스트를 실행하는 순서는 중요하다. 적절한 순서는 데이터 버스 테스트를 먼저하고 이어서 어드래스 버스 테스트를 하고 마지막으로 디바이스 테스트를 하는 것이다. 왜냐면 어드래스 버스 테스트는 데이터 버스가 동작해야 돌릴 수 있고, 디바이스 테스트의 결과는 어드래스 버스와 데이터 버스가 정상이 아닌한 의미가 없기 때문이다. 만약 테스트가 실패하면 여러분은 보드 디자이너와 함께 문제가 발생한 지점부터 같이 문제를 해결하면 된다. 데이터나 어드래스 테스트가 실패하면, 보드 디자이너는 아마 금방 문제를 해결 할 수 있을 것이다.
데이터 버스 테스트
첫 번째는 데이터 버스 배선 테스트이다. 프로세서가 데이터 버스에 실어서 전달한 데이터를 메모리 디바이스가 제대로 전달받았는지를 확인해야 한다. 가장 확실한 테스트 방법은 가능한 모든 데이터 값을 메모리 디바이스에 쓰고 그것을 다시 읽어서 검증하는 방법이다. 하지만 다르게 보면 이 방법은 가장 비효율적인 방법이기도 하다. 가장 빠른 테스트 방법은 버스를 한 비트씩 테스트 하는 것이다. 데이터 버스의 각 비트 라인이 다른 데이터 비트 라인과 독립적으로 0에서 1로 값이 변경된다면 데이터 버스 테스트는 성공한것이다.
각 비트를 독립적으로 테스트하는 좋은 방법은 흔히 말하는 “걸어가는 1의 테스트”를 하는 것이다. 아래 Table 1에서 이 테스트의 8비트 버전이 어떻게 동작하는지 보여준다. 이름 처럼, 이 테스트는 1이 각 비트 라인을 순서대로 한 번씩 찍고 “걸어간다”. 데이터 값의 갯수는 데이터 버스의 크기와 같다. (8비트면 8번, 16비트면 16번..)
현재 우리는 데이터 버스 테스트만 진행하고 있다. 그래서 데이터를 모두 같은 메모리 주소에 저장하고 확인해도 된다. 메모리 주소는 메모리 디바이스 내부에 아무 주소여도 상관없다. 만약 메모리 칩이 여러 개라면 각 메모리 칩에 해당하는 주소에 각각 테스트를 수행하면 된다.
“걸어가는 1의 테스트”를 수행할 때는 첫 번째 데이터를 쓰고 바로 읽어서 검증한다. 그리고 두 번째 데이터를 쓰고 또 바로 읽어 검증한다. 읭? 아까는 이렇게 하면 칩이 없을 때를 감지하지 못한다고 하지 않았나? 그렇다. 감지하지 못한다. 일단 지금은 데이터 버스만 테스트하는 것이기 때문이다. 그래서 이 테스트는 심지어 칩이 보드에 없을 때도 잘 동작한다.
아래 함수 memTestDataBus()는 “걸어가는 1의 테스트”를 어떻게 만드는지 C 언어로 구현했다. 메모리의 주소를 파라메터로 넘기고 해당 주소에 데이터 세트를 테스트 한다. 데이터 버스가 제대로 동작하면 이 함수는 0을 리턴한다. 아니면 테스트에 실패한 데이터 값을 리턴한다. 리턴 값으로 찾을 수 있는 비트 값이 바로 첫 번째로 테스트에 실패한 데이터 버스 비트 라인이된다.
typedef unsigned char datum; /* Set the data bus width to 8 bits. */ datum memTestDataBus(volatile datum * address) { datum pattern; /* * Perform a walking 1's test at the given address. */ for (pattern = 1; pattern != 0; pattern <<= 1) { /* * Write the test pattern. */ *address = pattern; /* * Read it back (immediately is okay for this test). */ if (*address != pattern) { return (pattern); } } return (0); } /* memTestDataBus() */
어드래스 버스 테스트
데이터 버스 테스트가 통과하고 나면, 다음에는 어드래스 버스 테스트를 진행한다. 어드래스 버스에 문제가 생기면 메모리 위치에 덮어쓰기 같은 문제가 생긴다는 것을 기억하라. 덮어쓰기가 생기는 주소 위치는 여러개가 생길 수 있다. 그러나 모든 조합 가능한 메모리 주소를 모두 확인할 필요는 없다. 여러분은 다른 어떤 것의 영향도 받지 않고 각 어드래스 핀이 0에서 1로 제대로 세팅되는 것만 확인하면 된다.
조합 가능한 최소한의 주소 세트는 “2의 N승”으로 만들 수 있다. 이 주소들은 “걸어가는 1의 테스트”에서의 데이터 값 세트와 비슷하다. 서로 관련된 메모리 주소는 0001h, 0002h, 0004h, 0008h, 0010h, 0020h 이다. 그리고 0000h는 반드시 먼저 테스트 되어야 한다. 주소가 중첩되는 문제는 구현상의 어려움이 있다. 특정 주소에 데이터를 쓰고 나면 다른 나머지 모든 주소 위치에 대해서 덮어 쓰기가 되었는지를 확인해야 하기 때문이다.
MSB에서 몇 비트는 메모리 칩에 의해서 자동으로 선택된다. 그리고 LSB에서 몇 비트는 데이터 버스가 8비트보다 클 때 의미가 없다.(뭔 소리야? 아마 워드 단위로 메모리 억세스 하면 메모리 주소를 바이트 단위로 억세스 안하니까?) 이 여분의 비트는 상수로 유지해서 테스트 해야 할 메모리 주소의 갯수를 최소화 할 수 있다. 예를 들어, 프로세서가 32비트 어드래스 비트를 가지고 있는데(최대 4GB까지 억세스 가능) 여러분은 128KB 블록 메모리만 테스트하고 싶다면, MSB의 15개 비트는 여분으로 남으므로 이를 상수로 처리해 버린다. 그리고 LSB의 17개 비트만 사용한다.
두 메모리 위치에 덮어 쓰기가 안되는 것을 확인 하기 위해서는 먼저 초기 데이터를 각각의 2의 N승 메모리 주소 오프셋에 쓴다. 그리고 새로운 값(초기 값의 반전값이 좋다)을 첫 번째 오프셋 주소에 쓴다. 그 후에 각 2의 N승 주소의 값을 읽어서 최초 값이 제대로 들어가 있는지를 확인한다. 만약 여러분이 특정 어드래스 비트 테스트에서 초기 데이터가 아닌 두 번째 쓰기한 데이터를 발견했다면 해당 데이터 버스 비트 라인에 문제가 있는 것이다. 문제가 없다면 동일 한 테스트를 오프셋을 옮겨 가면서 진행한다.
아래 함수 memTestAddressBus()는 위에 설명한 테스트를 C로 구현한 것이다. 함수는 파라메터 2개를 받는다. 첫 번째 파라매터는 베이스 주소이다. 두 번째 파라메터는 메모리 크기이다. 각 메모리 칩마다 설정된 베이스 주소를 넣고 해당 메모리 칩의 크기(용량)를 넣으면 된다. 메모리 칩의 크기를 알아야 사용하는 어드래스 버스 비트 라인의 갯수를 계산할 수 있기 때문이다. 어드래스 버스 테스트가 실패하면 실패한 위치의 비트 값이 리턴된다. 아니면 NULL이 리턴되고 성공으로 간주한다.
datum * memTestAddressBus(volatile datum * baseAddress, unsigned long nBytes) { unsigned long addressMask = (nBytes/sizeof(datum) - 1); unsigned long offset; unsigned long testOffset; datum pattern = (datum) 0xAAAAAAAA; datum antipattern = (datum) 0x55555555; /* * Write the default pattern at each of the power-of-two offsets. */ for (offset = 1; (offset & addressMask) != 0; offset <<= 1) { baseAddress[offset] = pattern; } /* * Check for address bits stuck high. */ testOffset = 0; baseAddress[testOffset] = antipattern; for (offset = 1; (offset & addressMask) != 0; offset <<= 1) { if (baseAddress[offset] != pattern) { return ((datum *) &baseAddress[offset]); } } baseAddress[testOffset] = pattern; /* * Check for address bits stuck low or shorted. */ for (testOffset = 1; (testOffset & addressMask) != 0; testOffset <<= 1) { baseAddress[testOffset] = antipattern; if (baseAddress[0] != pattern) { return ((datum *) &baseAddress[testOffset]); } for (offset = 1; (offset & addressMask) != 0; offset <<= 1) { if ((baseAddress[offset] != pattern) && (offset != testOffset)) { return ((datum *) &baseAddress[testOffset]); } } baseAddress[testOffset] = pattern; } return (NULL); } /* memTestAddressBus() */
디바이스 테스트
어드래스와 데이터 버스 와이어링이 정상이라면, 이제 메모리 디바이스 자체가 문제 없는지 확인해 볼 차례이다. (흔히 영어 문장을 직역해서 무결성 테스트(integrity test)라고 하는데, 나는 개인적으로 무결성이라는 단어가 뭔가 안어울린다고 느껴진다..) 디바이스의 모든 비트가 0이나 1을 유지할 수 있는지 테스트 하는 것이다. 이것은 만들기 매우 쉽다. 하지만 앞서 두 테스트보다 동작에 시간이 오래 걸린다.
디바이스 테스트를 완료하기 위해서, 여러분은 모든 메모리 로케이션에 쓰기, 검증하기를 두 번씩해야 한다. 여러분은 첫 번째 데이터 값으로 아무 값이나 선택해도 된다. 두 번째 값은 비트가 반전된 값을 사용한다. 메모리 칩이 없는 경우까지 확인하기에 좋은 테스트 값은 “증가하는 값”이다.
증가하는 값 테스트는 아래 표를 보면 어떻게 동작하는 건지 알 수 있다. 당연히 반전 값은 감소하는 값 테스트가 된다.
아래 함수 memTestDevice()는 단순하게 2-pass 형태로 증가/감소 테스트를 하는 것이다. 파라매터 두 개를 받는다. 첫 번째 파라메터는 베이스 주소이고 두 번째 파라매터는 byte 단위로 계산한 전체 메모리 용량이다. 이 함수가 NULL을 리턴하면 테스트에 성공한 것이고 아니면 실패한 것이다.
datum * memTestDevice(volatile datum * baseAddress, unsigned long nBytes) { unsigned long offset; unsigned long nWords = nBytes / sizeof(datum); datum pattern; datum antipattern; /* * Fill memory with a known pattern. */ for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++) { baseAddress[offset] = pattern; } /* * Check each location and invert it for the second pass. */ for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++) { if (baseAddress[offset] != pattern) { return ((datum *) &baseAddress[offset]); } antipattern = ~pattern; baseAddress[offset] = antipattern; } /* * Check each location for the inverted pattern and zero it. */ for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++) { antipattern = ~pattern; if (baseAddress[offset] != antipattern) { return ((datum *) &baseAddress[offset]); } } return (NULL); } /* memTestDevice() */
다 넣어 봅시다
시작 주소가 0x00000000이고 크기가 64KB인 SRAM을 테스트하는 코드를 만들어 보자. 위에서 만든 세 테스트를 순서대로 적용할 것이다. 공통적으로 첫 번째 파라메터는 베이스 주소이다. 데이터 버스 크기가 8비트 보다 크면 몇몇 부분 수정을 해야 한다.
int memTest(void) { #define BASE_ADDRESS (volatile datum *) 0x00000000 #define NUM_BYTES 64 * 1024 if ((memTestDataBus(BASE_ADDRESS) != 0) || (memTestAddressBus(BASE_ADDRESS, NUM_BYTES) != NULL) || (memTestDevice(BASE_ADDRESS, NUM_BYTES) != NULL)) { return (-1); } else { return (0); } } /* memTest() */
C 언어로 테스트가 작성되어 있어서 한 가지 문제가 생길 가능성이 있는 상황이 생긴다. C 언어는 스택을 사용하는데 스택은 당연히 메모리이다. 만약 스택이 사용하는 메모리와 테스트 대상이 되는 메모리 디바이스가 같은 것이라면 문제가 생길 수 있다. 이럴 때는 시스템이 메모리 디바이스를 두 개 이상 가지고 있어야 제대로된 테스트를 할 수 있다. 예를 들어 SRAM과 DRAM이 달려 있는 시스템이라면 DRAM을 테스트할 때는 스택 주소를 SRAM 영역에 놓고, SRAM을 테스트 할 때는 스택 주소를 DRAM 영역에 놓는 것이다.
메모리는 임베디드 시스템에서 매우 중요한 부품이기 때문에 메모리 테스트는 임베디드 소프트웨어의 최종 버전에 포함되는 것이 여러모로 좋다. 그래서 메모리 테스트를 포함한 다른 하드웨어 테스트를 매번 전원이 들어올 때마다 수행하는 것이 좋다.
댓글
OS 만들기 2탄 기대하고있습니다.
8년이 지난 지금도 임베디드 OS만들기 만큼 좋은 책을 찾아볼 수 없네요.
열심히 보고 직접 만들면서 이해할 수 있게 해주셔서 감사합니다.
OS 만들기 2탄 제작되고 있는 중인가요? 완전 기대하고 있습니다.
어어어어어??/
어어어어어?????
컴퓨터 아나토미 쓰신 저자분이신군요!
쓰신 책 보시고, 컴퓨터 하드웨어에 관심이 생겨서 지금 자료를 만들고 있는데, 어셈블리 명령어 코드를 어떻게 만들까 이름붙일까 생각하다가 우연히 들어오게 됬어요! 이런 우연이!
댓글 달기