메뉴 바로가기 검색 및 카테고리 바로가기 본문 바로가기

한빛출판네트워크

한빛랩스 - 지식에 가능성을 머지하다 / 강의 콘텐츠 무료로 수강하시고 피드백을 남겨주세요. ▶︎

IT/모바일

x86 기반 PC를 이용한 리눅스 커널 모듈 프로그래밍 학습에 관한 방법론 제시

한빛미디어

|

2004-12-06

|

by HANBIT

15,855

저자: 임영규 / GNOME LINUX R&D / imlinux70@hanafos.com


1. 서론

임베디드 시스템이란 단어와 함께 리눅스는 그 동반자적인 역할을 충분히 해 내고 있는 것은 사실이다. 다양한 임베디드 교육용 개발 툴 킷이 있음에도 불구하고 이를 학습하기란 비용면에서 그리 만만한 것은 아니다. 따라서 x86기반 PC에서 리눅스 OS를 이용하여 디바이스 드라이버를 개발해 보는 방법론을 제시한다. 아직까지 가장 많이 사용되고 있는 리눅스 커널이 2.4.x버전인 점을 고려하여 이 커널을 이용하는 방법을 알아본다.


2. 본론

우선 본 과제를 위하여 리눅스 운영체제를 설치하며, 레드햇 리눅스 9을 이용하여 커널 모듈 프로그래밍을 시작해 보기로 한다. 일반적으로 리눅스 배포판은 그 수가 상당하다. 이것은 각 배포판의 커널 버전이 서로 다르다는 것을 의미하며, 또 벤더(vender)에 따라서 해당 커널을 보호 할 목적으로 버전제어 및 벤더의 라이센서(license) 제어를 포함하여 컴파일한 커널을 이용한다. 이러한 이유로 임베디드 리눅스 기반의 모듈 프로그래밍을 배우고자 하는 이들로 하여금 x86이 아닌 다른 CPU core를 선택하게 한다. 따라서 비싼 개발용 보드를 구입하기란 그리 만만치 않은 것이 현실이다.

본 글에서는 x86기반 PC에서 커널 모듈을 작성하고 컴파일 하며, 또 모듈을 적재하여 그 결과를 확인해 보는 과정을 제시하는데 필요한 기본 지식을 제시한다. 일단 리눅스가 설치가 되면 커널 개발을 위한 도구들이 설치되었는지 확인해 보아야 한다. 시스템 설정의 응용 프로그램 추가 및 제어 메뉴를 실행 한 후 다음 사항을 확인하여야 한다.

       *. 개발도구 패키지, 커널 개발 패키지 설치 확인

2.1 Warning

이제 리눅스 커널을 이용하여 모듈 프로그래밍 하는 방법에 대하여 알아보자. 앞서 설명한 바와 같이 vender들은 자사의 커널 core를 보호 및 라이센서를 문제 삼아 타 환경에서 개발된 모듈을 자사의 커널에 이식 되는 것을 방지한다. 따라서 간단한 모듈을 작성하고 실제 insmod로 모듈을 로딩해 보면 경고 메시지가 출력되는 것을 확인할 수 있다.

xxx.o will taint the kernel : no license
See http://www.tux.org/lkml/#export-tainted for information about tainted modules

따라서 다음과 같은 방법으로 경고 메시지를 제거 할 수 있다.

MODULE_LICENSE("GPL");

2.2 Set Version

커널의 버전 번호가 다른 경우 작성한 모듈을 커널에 로딩할 수 없는 문제가 발생한다. 이것은 배포판 리눅스의 커널과 학습을 위해 커널을 제공하는 해당 사이트로부터 새로운 커널을 다운 받아 특정 디렉터리에 저장하고 이를 이용하여 모듈을 컴파일 했을때 발생한다. 이를 해결하기 위하여 배포판이 만들어 진 커널 컴파일 config 파일을 확인해 보아야 한다. 레드햇 리눅스의 경우 /boot 디렉터리에 config-2.4.20-8이라는 파일이 있다. 이것을 /usr/src/linux-2.4.20-8에 .config 파일로 복사 한 다음 커널 컴파일을 위한 환경 설정 설정을 다음 명령을 사용하여 확인해 볼 수 있다.

1. make menuconfig with consol
2. make xconfig with X-window

Loadable Module 메뉴에 보면 Set version이 *가 있는 것을 확인 할 수 있다. 즉 Yes를 의미한다. 이러한 이유로 커널 버전이 2.4.20-8과 다른 커널을 이용하여 모듈 source를 컴파일 한 경우 해당 모듈은 로딩되지 않는다. 따라서 Set version을 No, 즉 * 제거하고 난 후에 커널을 다시 컴파일 하여야 한다. 또한 멀티 부팅 환경을 사용하기를 원한다면 lilo, grub를 재 설정하여야 한다.

2.3 Sample hello

위에서 제시한 경고 및 set version이 해결 되었다면 간단한 hello world 모듈을 작성하고 컴파일, 로딩해 보는 과정에 대하여 알아보자.

/* 
start of hello sample 
*/

#include
#include
#include

int hello_init(void );
void hello_exit();

static int hello_init(void)
{
   printk("hello, world\n");
   return 0; // 반드시 0을 리턴해야 한다.
}

static void hello_exit(void)
{
   printk("bye\n");
   return 0; // 반드시 0을 리턴해야 한다.
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");
/* 
end of hello sample 
*/


2.4 컴파일, 로딩

이제 커널을 컴파일 해야 한다. 우선 set version이 Yes인 상태에서, 즉 레드햇 리눅스9을 전재로 컴파일 하는 경우 다음과 같다.

# gcc -D__KERNEL__ -DMODULE -Wall -O2 -isystem /lib/modules/`uname -r`/build/include -c hello.c

만약 set version을 해제 한 경우라면 우선 커널을 저장한 디렉터리로 이용한 다음 커널 디렉터리의 include 디렉터리로 이동하여 다음 명령을 실행하여 CPU core가 어떤 종류인지 링크를 제공해 주어야 한다. 일반적으로 x86의 경우 i386을 의미함으로 다음과 같이 할 수 있다.

# ln -s asm-i386 asm

그리고 커널을 컴파일 하면 되는데 이때 헤드 파일이 저장된 디렉터리를 명시해 주어야 한다. 리눅스 커널이 2.4.22이고 /usr/local/linux-2.4.22에 커널 소스를 저장해 둔 경우라면

# gcc -D__KERNEL__ -DMODULE -Wall -O2 -I/usr/local/linux-
2.4.22/include /lib/modules/`uname -r`/build/include -c hello.c

-I 옵션에서 해더 파일이 저장된 디렉터리를 명확히 명시하면 된다.

이제 모듈이 만들어 지면 insmod로 커널에 로딩해 본다.

# insmod ./hello.o

아무런 경고 없이 잘 로딩 될 것이다. 그리고 위 예제에서 hello, world라는 메시지를 출력하라고 했는데 이것은 log 메시지에 기록된다. 따라서 log 메시지를 확인해 보면 된다.

# dmesg | less

모듈 제거는 rmmod hello로 하면 되고 dmesg로 bye를 확인해 보면 된다.


3. 결론

커널 모듈 프로그래밍은 임베디드 시스템에 있어 가장 기본적이면서 어려운 부분에 해당한다. 그러나 실제 이를 학습하기 위해서는 대부분 최근에 많이 사용되는 CUP core, 즉 삼성,ARM,Xscale등 RISC CPU core를 이용한 것이기 때문에 학습기회 제공이 그리 쉬운 것은 아니며 또한 비용 문제로 많은 어려움이 있다. 그러나 본 논문에서 제시하는 방법을 이용하여 커널 프로그래밍에 대한 기본을 익히고 x86 CPU core에 대해서만 잘 이해한다면 다른 core에 대한 상대적 기초지식을 얻을 수 있다. 나날이 발전하는 세상을 따라가기에는 많은 어려움이 있는 것이 초심자들일 것이다. 앞으로 많은 연구 대상이 x86에서 이루어지기를 기대해 본다.

4. 참고

1. 레드햇 리눅스 9(한빛미디어, 2003)
2. 임베디드 리눅스 시스템 구축하기(한빛미디어, 2004)
3. 리눅스 모듈 프로그래밍 2.4.x
TAG :
댓글 입력
자료실

최근 본 상품0