광고

커널 컴파일 했습니다. 커널 올렸습니다. 그런데 동작하지 않습니다.

막약에… 커널 올리고 부팅했는데 그냥 시리얼 메시지 나오면 아무 문제가 없죠..

하지만 이렇게 어떤 문제가 터지면 어디서 문제가 발생했고 어디를 고쳐야 하는지 알아야 하죠?

 

음하하하! 저희는 알죠

 

물론 여러분들도 알 수 있습니다. 커널 소스를 분석하고 학습하면요…

대신 시간이 걸립니다.

그 시간을 아끼시고 싶으십니까? 저희에게 맡겨 주십시오.

 

광고 였습니다.

쩝…

이 먹고사니즘이여…


처자식 때문에 뻔뻔하게 회사 광고 합니다. ( 흑흑 )

 

그런데

저희 회사가 어떤 회사 입니까?

 

자료와 기술은 공유하자라는 아주 착한 마인드를 가진 회사 아니겠습니까?

 

그래서 이렇게 보드를 사시고 학습하고자 하는 의욕이 계신 분들에게 그 비법을
일부 공개하는 것 아니겠습니까?

 

자. 이제 비법을 공개해 봅시다.

 

ARM 용 zImage

 EZ-S3C2410은 ARM 이죠

 

그래서 이후에 이야기 하는 것은 S3C2410만 해당되는 것이 아니고 ARM에 모두 해당 되는 겁니다.

 

ARM용 커널은 특별한 경우가 아니라면 zImage 형태로 만들어 집니다.

 

이 커널 이미지는 압축된 이미지죠..

 

엥?

 

커널 이미지가 압축되어 있다?

그러면 어떻게 실행 되죠?

 

예…

맞습니다.

압축된 상태에서는 실행되지 않습니다.

 

 우선 아래 그림을 봅시다.

A008_001_zImage.png
 
[A008_001_zImage.png]

그림을 보시면 아시겠지만

동작되는 진짜 커널 바이너리 이미지는 vmlinux 라고 이름이 붙습니다.

 

근데 요놈 사이즈가 좀 큽니다.

임베디드 시스템은 아무래도 저장 공간의 부족에 시달리죠..

물론 최근에 들어와서는 안 그렇습니다만

 

어쨌든 용량을 조금이라도 줄이려고

이걸 gzip 압축 프로그램을 이용하여 piggy.gz 파일로 만듭니다.

 

자 이 압축된 것이 나중에 보드에 올라 갔을 때 압축이 해제 되어야 하지 않겠습니까?

또 압축이 해제된 커널이 실행도 되어야 하지 않겠습니까?
 

이렇게 압축도 해제하고 실행도 시키는 프로그램을 head 라고 하는데 이것과 압축된 커널 이미지 piggy.gz 합쳐서 zImage 라고 이름 짓습니다.

 

처음 실행하고 압축 이미지를 풀고,
풀린 커널로 점프하도록 하는 것은 head.S 가 담당합니다.

 

압축을 해제 하는 실제 동작은 misc.c 에서 합니다.

이 부분에 대한 자세한 구조를 굳이 여기서는 말하지 않겠습니다.
귀찮잖아요 쩝~

 

그런데 말이죠..

만약 여러분이 사용하는 부트로더가 압축을 푸는 루틴을 가지고 있으면 piggy.gz 만 사용해서 부팅할 수 있습니다.

 

그런데 굳이 그래야 할 이유가 있을까요?  이미 커널에서 지원하는데

또 만들면 귀찮잖아요…

그쵸?

 

 zImage 와 콘솔용 또는 메시지 표출용 시리얼 포트

 자 어쨌든 zImage 가 동작하면서 압축을 풀겠죠?

 

그런데

zImage 가 수행되면서 “나 압축 푸는 중이야” 하는 것을 사용자에게 알려주어야
사용자가 답답해 하지 않겠죠?

 

그래서 압축을 해제 하면서 메시지를 표출 하는데

임베디드 시스템에서는 메시지 표출 방법으로 주로 시리얼 포트를 이용하죠

 

당연히 zImage 의 실행 소스 부분에 이 시리얼 포트를 사용하는 부분이 있죠

 

그렇다면 아무런 메시지가 나오지 않았다는 것은
이 시리얼 포트로 데이터를 전송하는 부분이 문제가 있는 것이겠죠?

 

물론 다른 이유도 있겠지만

 

우선 이 부분부터 의심해 봅시다.

 

왜냐하면

 

이지보드는 다른 회사의 평가 보드와 다르게 콘솔용 시리얼 포트로 사용되는 포트가첫번째 것이 아니기 때문입니다.

판매되는 평가 보드들에 동작되는 부트로더와 커널은  메시지를 표출하기 위해서 MCU 의 첫번째 시리얼 포트를 콘솔용 시리얼로 사용하도록 설정되어 있습니다.

 

그에 반해 저희 이지보드는 보통 세번째 것을 이용합니다.

 

왜냐하면

 

커널 콘솔용 시리얼 포트로 사용되거나 부트로더 진행 표시 및 입출력용으로 사용되면 다른 목적으로 사용이 곤란해 집니다.

 

그래서 저희는 가장 나쁜 성능을 가지는 포트나 가장 사용이 안될 가능성이 높은 것으로 시리얼 포트를 선택한 겁니다.

 

주로 세번째 시리얼 포트들이 가장 나쁜 성능을 가지고 있기 때문입니다 .

 

처리 속도가 낮거나 적외선 시리얼 포트용으로 사용되는 경우도 많습니다.

 

이런 차이로 인해서

기존의 유부트나 커널 환경 설정의 기본 조건이 되지 않아서 처음 커널 메시지를 보지 못하는 수가 있습니다.

그래서 가장 먼저 이 부분을 의심하는 겁니다.

 

부팅 과정과 시리얼 포트

이쯤에서 리눅스가 정상적으로 부팅 되면서 거치는 프로그램의 종류와 시리얼 포트에 대하여 그림으로 알아 봅시다.

 A008_002_booting.png
[A008_002_booting.png]

허허~~

의외로 응용 프로그램까지 오는 동안 많은 과정을 거치죠?

 

이 그림을 글로 정리하면 다음과 같습니다.

 

1) 보드가 부팅된 후 동작하는 이지부트에서  시리얼을 초기화 합니다.
2) 이후로 프로그램상에서는 printf 라는 함수를 이용하여 출력 할 수 있습니다.
3) 이때 사용되는 시리얼 포트는 3번째 것 입니다.
4) 이지부트가 zImage를 메모리에 올린 후 실행시킵니다.
5) zImage 의 head 프로그램이 실행되면 arch_decomp_setup 이라는 시리얼 초기화를 위해서 매크로 함수를 호출합니다.
6) 이후 압축 해제 진행 과정을 표시하기 위해서 putc 라는 매크로 함수를 호출 합니다.
7) 커널이 동작되면 커널의 상태를 표출하기 위해서 이지부트에서 전달된 커널 커맨드중 console= 으로 설정된 디바이스 드라이버를 이용하여 커널 메시지를 표출합니다.
8) 커널 부팅 프로세스가 모두 끝난후 init 프로세서에서는 시리얼 터미널 프로그램을 동작 시켜 login 상태로 대기 합니다.
9) Login 프로그램으로 사용되는 것이 getty 라는 프로그램인데 이때 시리얼 디바이스를 지정합니다.
10) 정상적인 부팅 과정이 끝난 후 응용프로그램이 동작합니다.
11) 만약 응용 프로그램이 시리얼 포트를 사용한다면 /dev/ttyS… 를 이용합니다.

 

여러분은 이제 깨닫는 것이 있으실 겁니다.

 

즉 부팅까지 여러 프로그램이 동작되어 가는데 각 진행 프로그램마다 사용되는 시리얼 포트가 달라질 수 있다는 것을..

그래서 이 부분을 하나로 통일 하는 과정이 필요한 겁니다.