임베디드 시스템에 있어서 하드웨어 초기화, 이니셜라이즈는 여러 stage 에서 일어나게 된다.
따라서 원하는 값으로 하드웨어를 초기화 하기 위해서 모든 stage 들을 점검해야 할 필요가 있다.
팝노이즈와 같은 유형이 대표적인 하드웨어 초기화 오류로서 모든 stage 에 걸쳐서 일관된 제어가 이루어지지 않으면 팝노이즈가 발생하게 된다. 예를 들어 부트로더에서 앰프를 켜놨는데, OS 에서 재차 앰프를 확인사살한다고 껐다 켜버린다면, 십중팔구 팝노이즈가 발생하게 되는 것이다.
이런 설정값들은 특히 자동제어 부분에 있어서 중대한 미스로 발전될 가능성이 크다.
이를 막기 위해서는 하드웨어 스펙, 특히 GPIO 와 같은 주요 제어터미널의 상세를 확립하고,
각 stage 또는 layer 별로 하드웨어 초기화의 명세가 필요하다.
이를 위해 하드웨어 초기화가 일어나는 stage 들을 설명해 본다.
본 stage 열거는 가장 최악의, 가장 비대한, 그러나 어쩔 수 없이 이런 환경까지 써야 하는 경우를 상정한 것이다.
원래 임베디드 시스템들은 부트로더를 하나만 가지는 것이 일반적이었으나 최근에는 이미 만들어져있는 부트로더들을 별 수정없이 사용하기 위하여 부트로더 스테이지를 구분하곤 한다.
첫번째 부트로더는 NOR 나 NAND(2410 의 경우) 에 적재되어 자신의 실제 기능 코드들을 NOR 또는 NAND 에서 RAM 으로 옮겨놓는 역할을 한다. 여기서 최소한의 하드웨어 초기화가 이미 일어난다. 예를 들어 어플리케이션 덩치는 큰 데 CPU 내장 NOR 수백킬로바이트만 사용해야 하는 경우 이런 부트로더가 존재한다. 물론 부트로더 자체는 수십 킬로바이트 밖에 안 되지만...
두번째 부트로더는 주로 u-boot, ppcboot, blob, eboot 등의 기존 검증된 부트로더들이 사용된다. 나 같은 경우는 다 통합해버리고 최소 소스 코드로 커스텀하게 눌러버리는 편이지만. 사실, 돌아다니는 부트로더는 너무 비대하고.................. 어렵다 -_-;
두번째 부트로더가 3rd. 부트로더가 될 수도 있다. 이는 첫번째 부트로더를 넣을 수 있는 공간이 너무 작을 경우 첫 번째 부트로더를 쪼개서 만드는 경우가 해당한다. 예를 들어 2410의 NAND 부트기능을 이용하면 4kb 를 사용할 수 있는데 4kb 를 가지고 본격적인 부트로더, 즉 u-boot 따위를 올리고 업데이트 하는 관리프로그램을 넣기에는 부족하기 때문이다. 여기서는 본격적인 하드웨어 초기화가 대부분 다 일어난다.
슬립기능을 이용하여 OS 의 부팅을 담당시킨다면, -사실 슬립은 OS와 부트로더 양단에서 동시에 지원가능하다- 다시 부트로더 안에서 하드웨어 초기화의 stage 가 나누어진다. 슬립인 전에 이루어지는 초기화와 슬립아웃 후에 이루어지는 초기화 사이에 일관성있는 고려가 있어야 한다.
위 부트로더들의 하드웨어 초기화에서 또 주의해야 할 점은 많은 하드웨어 초기화가 초기 부팅 - 주로 ASM - 영역에 상수값들로서 숨어 있을 수가 있다는 것이다. 이를 면밀히 체크해야 한다. ASM 코드에서는 일일이 셋팅하려 들지 말고 C 점프까지만 책임 진 후에 C 코드에서 보기좋고 만만하게-_- 설정하는 것이 상책이다.
u-boot 등이 여기까지 내려올 수 있다고 위에서 설명하였다. 여기서도 하드웨어 초기화가 일어난다. ppcboot 등은 너무나 모듈화가 잘 되어 있어서 보통의 펌웨어 프로그램들과는 달리 각 디바이스가 단독 모듈처럼되어 있다. 이 경우 빠뜨리기 쉬운 것은 하드웨어 초기화를 하는 코드가 main 함수 주변부와 디바이스 드라이버에 중복으로 혼재할 수 있다는 것이다.
OS 의 초기화 코드는 다시 공급자 부분과 커스텀 부분이 따로 존재 한다. 공급받은 OAL 영역에서도 이미 초기화가 이루어지고 있고, 개발자는 자신이 주로 담당하는 초기영역에서 하드웨어 초기화를 다시 한다. 이러면 벌써 또 중복이므로 일관성 체크를 해야 한다.
OS 쪽에서는 디바이스 드라이버를 어태치, 디태치 하는 부분, 또는 선행적재 하는 부분에 있어서 하드웨어 초기화가 존재한다. OS 초기화에 아싸리 다 쳐넣던가. 드바이스 드라이버로 다 가져온다든가 하는 일이 생각보다 쉽지 않다. 역시 일관성 체크를 해야 한다. 게다가 공용 자원은 어디서 핸들링 할 것인가의 문제도 있다.
일반적인 시스템이라면 부트로더에서의 슬립은 파워버튼으로만 사용하고 OS에서 제대로 슬립시킬 것이다. 슬립 인 전의 하드웨어 초기화와 슬립 아웃 전의 하드웨어 초기화를 제대로 검증해야 한다. 물론 MMU 로서 인터럽트 벡터를 다 옮겨놓지 않고 부트로더 개발자와 긴밀히 협업하여 대통합 시키는 것이 나는 더 심플하다고 생각한다. - 사실, 이 쪽 프로젝트를 제대로 해 본 것은 아니어서 맞는 말인지 아닌 지는 모르겠다-
게다가 슬립인, 아웃 전에 디바이스 드라비버 쪽까지 디태치, 어태치, 또는 노티파이 등이 일어나서 하드웨어와 관계된 일이 일어난다면 이쪽 코드들을 다 점검해야 한다.
어플리케이션에서 특정 디바이스 드라이버를 오픈하면서 설정하는 값들이 제어에 영향을 미칠 수가 있다. 보통 경험많은 개발자라면 앞뒤 레이어가 엉망이라는 가정하에 앞선 값을 보관하고 탈출시에 복구한다. 그러나 사실 신뢰성이 있어야 하는 스탠드얼론형 제품이라면 OS 개발자와 협의하여 초기화 없이 바로 사용가능한 상태여야 팝노이즈 같은 것이 발생을 하지 않는다. OS 부팅시에 앰프off 였고 어플리케이션이 앰프on 를 그때 그때 한다면 앰프를 사용할때마다 팝노이즈가 발생할 것이다.
문서 버전 0.5 잠시 정리할 필요가 있어서 써봤다.