bootstrap

잡기 2003. 9. 14. 00:00
사로 잡혔다. 몰두했다. 3일 동안 부트로더를 잡고 있었다. 다른 일에는 손을 놓았다. 밥 먹고 세수하고 사람 만나고 술 마시러 나가는 등의 일들.

다섯 종류의 부트 로더 소스를 구해 기능을 분석해 보고 미지 리눅스에서 공개한 부트로더를 수정하기로 했다. x-modem만 지원하는 단촐한 것이지만(단촐하면서 바이너리가 80kb나 하는, 무진장 큰 것이다) 커널의 MTD를 가져와 나름대로 파티셔닝을 하거나 menuconfig를 만들어 놓는 등 '발전'의 여지가 있었기 때문이다. 난 한 놈만 조진다. 라고 생각했지만 뜻대로 되지는 않았다. 여러 가지를 건드렸다.

개발 중인 보드는 삼성의 ARM920T 코어를 사용하는 S3C2410TK 보드다. pda 개발에 사용하는 임베디드 이벌루션 보드지만 장비 컨트롤에 사용하려고 한다. 고급 언어가 필요하기 때문이다. 이름을 적은 이유는, 누군가 같은 고생을 하고 있다면 참고가 되라고.

1. 메리텍 뿐만 아니라 삼성 사이트에도 플래시 컨트롤을 하는 부트로더가 제대로 작동하는 것은 없다.
2. 삼성의 부트로더는 ADS(Arm Developement Studio)에서 컴파일하는 것이라 리눅스 크로스 컴파일은 되지 않는다.
3. 공개되어 돌아다니는(http://kelp.or.kr/) 부트로더의 BOOTP, TFTP 코드는 S3C2410TK에서 사용할 수 없다. 내 생각에는 코드 자체에 버그가 있는 것 같다.
4. S3C2410TK에는 세 종류의 플래시가 있다. 이 셋 중 최소한 두 종류를 혼합해 사용하기 때문에 부트 로더에는 그 기능들이 들어가야 한다. 거의 모든 부트 로더가 두번째 플래시의 존재(?)를 무시한다.

작업 순서: 1. Russel King의 arm patch와 samsung patch, 그리고 2410 patch를 적용한 리눅스 커널 2.4.18 컴파일. 별 이상없이 리눅스 커널은 잘 돌아간다. NAND Flash에서 약간의 문제 발생. MTD 최근 소스를 가져와 일일이 비교해 가면서 커널 패치를 하다보니 원래 버전보다 더 이상하게 작동한다. JFFS2 역시 파일 시스템 포맷할 때 에러라 줄줄이 튀어 나왔다. 어떻게든 NAND flash의 erase와 JFFS2 포맷은 제대로 되었지만 영 마음에 안 들어 YAFFS를 사용하려고 마음을 바꿨다.

2. AMD Flash가 계속 인식이 안된다. JTAG 케이블이 없어 여전히 프로그래밍은 못하고 있고 Intel Strata 플래시에서 작업중. nGCS 시그널과 Memory Bank Configuration 때문이라고 볼 수는 없었다. 이전에는 잘 되었다. 커널의 문제일 꺼라고 생각하고 (커널에서 udelay 코드를 보다가 맛이 갔다. 엉터리다. 왜 watchdog 타이머와 스핀락을 사용하지 않았을까?) 작업 방향을 바꿔, 비교적 다루기 쉽고 작은 코드량을 가진 부트로더에서 플래시를 테스트 해 보기로. 2.4.x 커널과 무관하게 작동하는 pthread는 보고 있으면 눈물이 주르륵 흘렀다. 저렇게 개판이라니...

3. Mizi reserch의 vivi bootloader를 사용하여 작업. NAND writing/verifying에 아무 이상이 없다. 삼성의 NAND Flash 커널 패치에 뭔가 이상이 있다는 쪽으로 생각을 굳혔다. 여기서도 AMD 플래시는 인식이 되지 않는다. 일단 넘어가기로 했다.

4. 하루 종일 코딩에 시간을 보냈다. 소스 코드가 워낙 이리저리 흩어져 있어 머리 속에 정리하는 데만도 시간이 한참 걸렸다. MTD 기능 추가. 각 플래시 별로 파티션을 보여주고 erase와 programming이 가능하도록 vivi 소스를 수정. 그다지 많지 않은 양이지만, 2,3 항의 테스트 때문에 시간을 많이 소모했다.

5. vivi의 x-modem으로는 영 느려터져서 안 되겠기에 ethernet을 지원하기로. 개발용 리눅스 머신에 bootp server와 tftp server를 설치. bootloader 소스중 만만한 것을 잡아 포팅. 돌아다니는 소스는 한 사람이 만든 것을 이러저러 변형한 것이었다. 다들 little endian으로 메모리를 설정하고 한 모양인지... 컴파일 한 후 작동하는 모양이 개판이다. 소스를 조금씩 수정하는 정도로 작동을 기대했으나 컴파일, 업로드, 테스트에 상당한 시간을 잡아먹었다.

작동 불량의 원인을 찾은 것 같다. cpu clock 때문이다. S3C2410 user's manual을 참조하여 BWSCON 레지스터에 CS8900A가 설치된 0x18000000(nGCS3)의 메모리 설정을 변경. Tacs = 14clk로 늘려주고 UB/LB, nWAIT 시그널을 사용하여 920T와 AHB 버스에서 교신하는 걸로.

6. 그래도 문제는 해결되지 않았다. 패킷을 면밀히 분석해 보니 EthRx() 루틴에서 이더넷 패킷을 i/o로부터 수신할 때 첫번째 word가 status, 두번째 word가 length 라는데 3번째 word의 첫번째 바이트를 스킵한 후 두번째 바이트를 실 데이터로 인정한 다음, 차례로 이어지는 데이터를 byte swap 해야지만(big endian이니까) 정상적인 ethernet packet이 된다. 의아하지만 소스 수정 후 bootp 패킷 수신 성공. 아니 간혹 성공. 왠일인지 패킷 수신할 때 어떤 것은 에러가 나고 어떤 것은 에러가 나지 않았다. 그 이후로 4 바이트의 조각난 패킷들이 연달아 수신되거나 가비지가 끼는 현상이 발생.

7. 버스의 OE와 어드레스 발리드, 데이터 발리드 시그널링에 여전히 문제가 있는 것 같다. 회로를 점검해 보니 분명히 nWAIT 시그널을 사용하는 것으로 되어 있는데... 스코프가 없어서 회로를 찍어보지는 못하고... 순전히 통빡으로 굴려서 무식하게 삽질하는 방법 밖에 안 남았군. 4년 전에 이런 교훈을 얻었음에도 불구하고; 소프트웨어에서 안되면 하드웨어를 조질 것. 새벽 4시. 불편하게 잠들었다.

8. 일어나자 마자 샤워하고 2410 매뉴얼과 8900 매뉴얼을 놓고 타이밍 차트를 비교해 봤다. 클럭 디바이더 비율을 1:2:4로 했을 때 cpu 클럭이 200mhz, AHB bus clock이 100mhz, APB bus clock이 50mhz. 이중 ahb bus clock이 cs8900a와 인터페이스하는 클럭이다. 최대값을 넘겼다. 125nsec. 하지만 상관없는데? nWAIT를 사용하므로 타이밍에 문제가 없어야 정상인데. ahb 버스 클럭을 50mhz로 낮추자 bootp 패킷을 수신한다. 커널이 사용하는 dma/irq 모드에서는 정상 작동하겠지만 i/o 모드에서는 버스 클럭이 높으면 nWAIT 시그널을 사용하더라도 정상 작동이 안되는 것인가? 하여튼.

9. bootp를 대충 마무리하고 tftp로 넘어갔다. 커다란 파일을 수신할 때 종종 프로그램이 멈춰 버렸다. 패킷 헤더의 이상이었다. 4 바이트 짜리 팬딩 패킷이 버퍼에 남아 계속 읽혔다. 이 소스는 여러 사람들이 이미 코드를 검증했을 터이니 코드 자체에 문제가 있을 꺼라고 생각하지 않고 버스 클럭에 집착했다. 8시간 동안 상황이 변하지 않았다. 확 열이 뻗쳐서 cs8900A의 매뉴얼을 통째로 읽었다. 코드는 매뉴얼 대로 만들었지만, 그 코드는 매뉴얼대로 작동하지 않았다. 다시 한번 코드를 살펴보았다. 수신 패킷 길이가 516+42 여야 하는데 516만 읽힌다. 이상하다. 코드에 대한 믿음을 깨고 수정을 시작했다. 성공. tftp 패킷을 정상 수신한다. mtd flash programming과 그것을 연결했다.

10. 버스 클럭 스피드를 100mhz로 올리면 제대로 작동하지 않는다. 이건 분명히 버스 문제다.

3일 동안 삽질한 끝에 얻은 교훈은 남의 소스를 믿지 말자..는 것 정도. 힘들다.

드라이버 하나만 남기고(그건 간단하니까) 대체로 일이 마무리 되어 가는 것 같다. 앞으로 이 작은(?) 작업을 끝내기로 한 날짜까지 10일 정도 남았다. 임베디드를 오랫만에 손대어 보고(6년 만에?) 그것도 32비트 프로세서와 무거운 os 커널을 다루는 작업은 이번이 처음이지만 의외로 순탄(?)하게 진행되는 것 같다. 여하튼 일은 잘 되어 가지만 기분은 엿같다. 커널과 부트로더, 응용 프로그램까지 1-2주 정도에 끝나고 남은 2주 동안 공상에 몰두하고 싶었는데.

이 밤에... 바람을 쐬러 나갈 수도 없고. T_T
,