본문 바로가기
Linux 포팅 완료까지의 절차가 어떻게 되죠?

뭘 알아야 이해를 하지
개발자가 어플리케이션 프로그램 개발하기 전에 부트로더와 커널을 포팅해야 하죠.
부트로더와 커널은 거의 대부분 개발 보드 BSP에 다 되어 있어서 개발자가 수정할 일은 없답니다. 대부분 어플리케이션만 만들면 된답니다. 하지만 개발보드에서 실제 제품으로 만들 때는 개발 보드 BSP를 기반으로 해서 실제 제품에 맞게 소스를 수정하거나 추가를 해 주셔야 하죠. 왜냐하면 개발 보드에서 사용되는 부품과 실제 제품에서 사용되는 부품이 다르기 때문에 수정을 해야 하고 개발 보드에 없는 디바이스가 실제 제품에는 있는 경우라면 반드시 추가를 해 주셔야 한답니다. 부트로더 단계에서는 가장 먼저 실행되어야 할 파일이 Startup.s 파일이랍니다. 이제 이 정도는 기본이죠. ^^;

# 부트로더
개발자가 부트로더 포팅을 위해서는 아래의 순서대로 하시면 된답니다.

Startup.s 파일이 제일 먼저 실행되는 파일이랍니다. 리눅스에서 부트로더도 역시 Startup.s 파일이 하는 역할은 거의 같다고 보시면 된답니다. 아래와 같이 꼭 해야 되는 것은 아니지만 E에 나와 있는 것처럼 엠엠유(MMU)는 인에이블(Enable)해 주세요. 왜냐하면 캐시를 사용해서 커널이미지를 에스디램으로 복사할 때 빠르게 하기 위해서랍니다.

lowlevel_init.s 파일에서는 와치독과 인터럽트 관련된 내용을 설정한답니다.

그리고, PLL 관련된 설정도 해 준답니다.

리눅스 같은 경우는 노어 플래시보다 낸드 플래시 메모리를 많이 사용하는 편인데, 부트로더나 커널 이미지 사이즈는 작지만 파일 시스템 용량이 크기 때문에 가격이 저렴하면서도 용량이 큰 낸드 플래시 메모리를 사용한답니다. 그래서 부트로더에서 낸드 플래시 메모리를 언제든지 쉽게 접근할 수 있도록 낸드 초기화를 해 줘야 하지요. 꼭 Startup.s 파일에서 안 해 줘도 상관 없구요 main.c 파일에서도 해 줘도 된답니다.

이제 에스디램 초기화를 해 준답니다. 낸드 플래시에 있는 커널 이미지를 에스디램으로 복사하려면 에스디램 초기화가 필요하겠죠. ㅋㅋ

이제 캐시를 사용하기 위해서라도 엠엠유를 인에이블을 해요.


이제 초기화가 안된 변수를 모두 '0'으로 만들기 위해 처리하는 루틴이 실행이 되고요,

드디어 씨 언어의 시작 함수로 점프를 하지요.


일반적으로 main.c 안에 main 함수로 많이 가지만, 반드시 이렇게 할 필요는 없어요. 개발자가 프로그램 하기 나름이랍니다.

부트로더에서 가장 많이 하는 작업이 플래시 메모리에 부트로더, 커널, 파일시스템과 같은 바이너리를 쓰거나 플래시 메모리에 있는 바이너리를 에스드램으로 복사는 과정이랍니다.
리눅스 시스템은 반드시 부트로더가 필요해요. 왜냐하면 부트로더가 커널을 에스디램으로 복사한 후 실행하도록 되어 있기 때문이랍니다. 이때 커널은 zImage이며, 앞에서도 말씀 드린 바와 같이 piggz.gz으로 압축되어 있답니다. 그래서 부트로더에서 가장 중요하게 포팅해야 할 작업이 바로 플래시 메모리에 바이너리를 어떻게 넣는지에 대한 내용이랍니다. 아..그전에 시리얼 메시지가 나오도록 해 주셔야 해요. (208 챕터 참고하셔요.)
일단은 개발 보드의 BSP를 보시면 기본적으로 플래시 메모리에 대한 내용이 모두 포함되어 있기 때문에 크게 하실 일이 없답니다. 하지만 개발 보드가 아니라 실제 제품 보드를 제작하실 때는 포팅을 해 주셔야 한답니다. 왜냐하면 개발 보드에서 사용되는 플래시 메모리와 실제 제품 보드에서 사용되는 플래시 메모리가 다를 수가 있어요. 가령, 개발 보드 구매는 1월 해서 여러 가지 Test를 하다가 실제 제품 보드로 만드는 시가가 6월이라고 가정한다면, 최소한 개발 보드 구매 시쯤에서 이후 몇 개월 지나서랍니다. 조금 더 생각을 해 보면, 개발 보드 구매할 당시에 개발 보드를 만드는 회사가 보드 개발을 위해서 몇 개월 전부터 만들기 시작했다면 최소한 플래시 메모리는 년 전에 생산된 플래시 메모리라고 생각하시면 된답니다. 1년 전에 생산된 플래시 메모리를 실제 제품 보드에서 사용을 할 수가 있지만, 경제의 논리에 의해서 플래시 메모리가 계속 생산되고 있다는 보장도 없거니와 그때쯤이면 개발 보드에 있는 플래시 메모리보다 휠씬 메모리 용량도 늘고 가격도 더 저렴해져 있기 때문이죠. 그래서 실제 제품 보드를 개발하실 때는 플래시 메모리를 자유롭게 다를 수 있는 기술력이 있어야 한답니다.

최근에는 대부분 낸드 플래시 메모리를 사용하기 때문에 낸드 플래시 메모리 관련해서 포팅해야 할 사항을 알아보죠. 우선 낸드 플래시 지우는 과정이랍니다. 플래시 메모리가 모두 비워져야 쓸 수가 있기 때문에 지우는 과정에 대해 포팅을 해야 한답니다.

정상적으로 잘 지워진다면, 쓰기를 해야 하죠. 이러한 프로그램은 개발자가 모두 만드는 것이 아니라 기본 BSP에 들어 있답니다. 하지만 이 BSP는 어디까지나 개발보드에 있는 플래시 메모리 이기 때문에 실제 제품 보드에서 사용하는 플래시 메모리와 다를 수 있으니 이 소스를 참고해서 만들면 된답니다.

부트로더가 낸드 플래시에 있는 커널 이미지를 에스디램으로 복사하기 위해서는 낸드 플래시 메모리를 읽어야겠죠?

# 커널
이제 커널 부분을 살펴보도록 하죠. 개발 보드 전원을 넣고 시리얼을 통해 메시지를 보면 아래와 같은 메시지가 보인답니다.
...................................................................
...............Uncompressing Linux...done, booting the kernel

이 메시지는 부트로더가 낸드 플래시에 있는 커널 바이너리인 zImage를 에스디램으로 복사를 한 후 zImage를 스스로 압축을 풀었다 라는 의미죠. zImage 파일은 압축된 piggy.gz과 head.o 파일 그리고 misc.o 파일이 하나로 압축되어 있다고 이야기를 했었죠. 커널 컴파일을 하고 난 후 $kernel\arch\arm\boot\compressed\ 폴더를 보시면 파일들을 보실 수가 있어요. 여기서 순수한 커널은 piggy.gz 파일이고, 압축 푸는 알고리즘이 들어 있는 파일은 misc.c 파일이랍니다. misc.c 파일이 piggy.gz 파일을 압축 풀면서 나타나는 메시지랍니다. gunzip함수에서 압축을 풀어 준답니다.


압축이 모두 풀리고 나면 커널이 동작을 한답니다. $kernle/init/main.c 파일의 start_kernel 함수가 가장 먼저 실행한답니다. 개발 보드 BSP를 가지고 커널 포팅을 한다면 크게 수정하실 일은 없어요. 실제 제품 보드를 제작한다면, 흔히 발생할 수 있는 것이 커널 패닉과 같은 에러랍니다. 이러한 에러를 줄이기 위해서는 커널 컴파일하기 전, 옵션에서 커널 디바이스 드라이버를 최소한으로 선택해서 점차 늘이는 방식으로 하시면 문제 찾기가 더 수월하답니다. 커널 디바이스 드라이버는 커널에 많이 포함 될 수록 부팅 시간이 많이 걸리기 때문에 부팅 시간을 줄이기 위해서라도 부팅시 반드시 필요한 디바이스 드라이버만 포함시키고 부팅 후 insmod로 디바이스 드라이버를 올려 보는 것도 좋은 방법이랍니다.
커널이 부팅되는 과정을 2.6.21버전으로 간단히 분석을 해 보죠.

커널 쓰레드가 시작되면, Ramdisk를 마운트하기 위한 함수인 init_post로 점프를 한답니다.


커널이 파일시스템을 마운트 한 후에 반드시 init 프로세스를 실행해야 하므로 해당 경로 중에 한 곳에만 init 파일을 넣어 주면 되요. 하지만 여기서도 주의 하셔야 될 사항이 커널 컴파일 했을 때 사용한 크로스 컴파일러 버전과 init 프로세스를 컴파일 한 크로스 컴파일러 버전이 같아야 큰 문제가 없답니다. 만약, 버전이 맞지 않다면 부팅 시 문제가 발생한답니다. 참고로 알아 두시면 좋을 것 같네요.

# 파일 시스템
파일 시스템에서 가장 중요한 것은 init 프로세스와 어플리케이션 제작이랍니다.
기본적인 파일 시스템 폴더를 구성하고, 각 해당 폴더에다 필요한 파일들을 넣어 두고 난 후 최종 목표는 어플리케이션을 만들어 실행을 해 보는 거랍니다.
우선 기본적인 파일 시스템 폴더를 구성하는 방법에 대해 알아보죠.
개발보드 BSP에 보면 filesystem_root.bz2 처럼 압축된 루트 파일 시스템이 있습니다.
우선 압축을 풀어 보면, 파일 시스템 폴더와 각종 파일들이 들어 있답니다.


개발자가 원하는 어플리케이션 구현해서 적당한 곳에 넣어 두거나 새로운 폴더를 만들어 어플리케이션을 관리해도 된답니다.


간단한 어플리케이션 하나를 만들어 보아요.

그리고 컴파일을 해 보죠.


컴파일된 main 파일을 example/폴더에 넣어 두세요.

마지막으로 파일 시스템을 만들어 보죠.


Ramdisk와 application까지 모두 완료했습니다. 낸드 플래시에 부트로더, 커널, 램디스크를 넣고 부팅을 하면 되겠죠

이제 이와 같은 방법으로 어플리케이션을 개발하면 된답니다.

Linked at 친절한 임베디드 시스템 개발자.. at 2010/09/29 23:53

... sp; 404 ARM 프로세서에 Linux 포팅을 위한 준비사항은? 405 Linux 포팅 완료까지의 절차가 어떻게 되죠? 406 Linux에서 라이브러리를 만드는 방법은? 40 ... more

친절한 임베디드 시스템 개발자 되기 강좌 글 전체 리스트 (링크) -



댓글





친절한 임베디드 개발자 되기 강좌 글 전체 리스트 (링크) -