강좌
클라우드/리눅스에 관한 강좌입니다.
리눅스 분류

Step by Step 커널 프로그래밍 강좌②

작성자 정보

  • 웹관리자 작성
  • 작성일

컨텐츠 정보

본문

Step by Step 커널 프로그래밍 강좌

모듈구현하기

 

 

지난 호에 우리는 리눅스 커널의 관한 기본적인 내용들과 함께 새로운 커널을 컴파일하기

위한 방법을 배웠다. 이번 호에는 지난 호에 이어 우리가 새롭게 컴파일한 커널에 일부가

동작할 있는 모듈 프로그래밍에 관해 알아보기로 한다. 강좌는 지난 호에서 새롭게

컴파일한 커널로 부팅하여 동작하고 있다는 가정 하에 진행하기로 한다.

 

_ 김민찬 KLDP 멤버, 전문 프로그래머

 

연재 순서

커널 프로그래밍의 환경 구축

모듈 구현하기

커널의 동기화에 관하여

커널의 시간관리 지연 함수에 대하여

파일시스템과 proc file system 사용하기

디버깅 기술에 관하여

 

1. 커널 모듈이란 ?

모듈이란 동적으로 커널 속으로 로드 또는 언로드 있는 코드의 묶음을 말한다. 이렇게 해서 얻을 있는 장점은 시스템을 재부팅하지 않고도 필요할 필요한 기능을 동적으로

커널에 추가할 있다는 점이다. 이런 것들의 가장 흔한 예는 장치 드라이버나 파일 시스템들이 있다. 만일 모듈이 없다면 이런 장치들을 위한 코드나 자주 사용하지 않는 파일 시스템을 위한 코드들을 커널을 빌드할 이미 포함한 상태로 컴파일을 해야 하므로 커널의 크기가 점점 커지게 되며 메모리 사용량 또한 증가하게 된다. 더욱 아찔한 것은 미처 생각치 못한 기능을 넣지 못했다면 필요할 마다 커널을 다시 빌드해야 한다는 점이다. 여러분은 앞으로 어떤 장치를 새로 사용하게 될지 미리 예측할 있는가?

, 현재 여러분의 시스템에는 어떤 모듈들이 사용되고 있을까? 이를 알아보는 명령어는 다음과 같다.

 

lsmod

 

명령어는 /proc/modules 읽어들어 출력하게 된다. 그렇다면 여러분들은 언제 모듈들을 로드 했는지 기억이 나는가? 커널 모듈은 kmod라는 데몬에 의해 커널이 필요로

자동적으로 로드되게 된다. 일을 담당하는 kmod라는 데몬이 커널 내에 존재하게 되며 커널이 자신이 갖고 있지 않은 새로운 기능을 필요로 modprobe라는 어플리케이션을

행시켜 필요한 모듈을 로드하게 되는 것이다. modprobe 필요한 모듈을 찾기 위해서 /etc/modprebe.conf 설정 파일을 먼저 찾게 되며 필요한 모듈을 로드하기 전에 어떤 다른 모듈

먼저 로드해야 하는지를 살피기 위하여 /lib/modules/version/modules.dep 파일을 살피게 된다. 파일은 다음 명령어를 통해 만들 있다.

 

 

depmod -a

 

modprobe 모듈간의 의존성을파악한 마지막으로 insmod라는 어플리케이션을 실행하여 커널에 모듈을 로드하게 된다. 이때 로드되는 모듈들은 /lib/modules/version/

렉토리에서 찾게 된다. 지금까지 것처럼 insmod 마지막에 실행되는 어플리케이션으로써 단지 module 로드하는 일만 하지만 modprobe insmod 실행시킬 뿐만 아니라

듈들의 위치, 상호 의존성 체크까지 알아서 해준다. 그러므로 모듈을 로드할 insmod 사용하는 것보다는 modprobe 사용하는 것이 편리할 때가 많다. 하지만 명령어를 사용할 주의해야 것이 modprobe 아래와 같이 확장자를 취하지 않는 다는 점이다. 또한 modprobe 사용하기위해서는 위에서 설명한 설정 파일들에 적절하게 명시되어 있어야 한다.

 

insmod /lib/modules/2.6.11/kernel/fs/fat/fat.ko

insmod /lib/modules/2.6.11/kernel/fs/msdos/msdos.ko

 

modprobe msdos

 

modprobe, insmod, depmod module-init-tools라는 패키지로 배포판마다 제공된다.

 

 

2. 모듈 작성하기

, 이제 우리는 새로운 모듈을 작성할 준비가 되었다. 지금부터 여느 프로그램을 배울 때와 마찬가지로 이번에도 helloworld 모듈을 작성할 것이다. 가장 기본적인 모듈 프로그램을

통해 함수들의 역할과 기능에 대해 알아보도록 한다.

 

#include <linux/module.h> /* Needed by all modules */

#include <linux/kernel.h>/* Needed for KERN_EMERG */

#include <linux/init.h> /* Needed for the macros */

 

static int __init hello_init(void)

{

printk(KERN_ EMERG"Hello, world ");

return 0;

}

static void __exit hello_exit(void)

{

printk(KERN_EMERG "Goodbye, world ");

}

module_init(hello_init);

module_exit(hello_exit);

 

 

 

커널 모듈들은 적어도 가지의 함수는 반드시 가지고 있어야 한다. 함수들은 module_init module_exit 매크로로 등록된 함수들이다.

module_init 매크로로 등록된 함수는 insmod 명령을 통해 모듈이 커널에 등록될 호출되는 함수이며 반대로, module_exit rmmod 명령을 통해 커널에서 언로드될 호출되는 함수이다. 함수들의 선언에 붙여진 매크로는 다음과 같은 의미를 갖는다.

 

__init 매크로는 커널로 하여금 init 함수가 사용된 후 그 함수가 차지했던 메모리 공간을 회수할 있도록 하기위한 방법이다. 하지만 매크로는 모듈로 만들어진 커널드라이버들에게는 적용되지 않고 built-in 드라이버들에

게만 적용된다.

이렇게 하는 이유는 커널의 입장에서 built-in 드라이버들의 init 함수들은 한번 실행되고 나며 이상 사용되지 않을 것이기 때문에 코드들이 차지하는 메모리 공간을 회수하여 최대한 많은 메모리를 확보할 있기 때문이다.

__exit 매크로는 커널의 built-in 드라이버들을 만들어 하나의 커널 이미지를 빌드할 함수들을 커널의 이미지에서 있도록 하기 위한 방법이다.그렇게 하는 이유는 built-in 드라이버들은 커널이 살아있는 동안 메모리에서 언로드되지 않기 때문에 _exit 함수가

전혀 호출되지 않는다. 그러므로 굳이 실행되지 않는 함수를 커널의 이미지에 포함시켜 커널의 사이즈를 크게 만들필요가 없기 때문이다.

 

 

마지막으로 printk 함수는 printf 같이 단순히 console에 출력을 하기 위한 함수와는 다르다. 함수는 커널의 여러 정보들을 기록하는 사용된다. printk함수는 8개의 우선순위

이루어진 매크로들을 사용하여 출력할 있으며 우선 순위마다 아래의 표와 같은 의미를 가지고 있다. 커널의 많은함수들은 상황에 맞는 우선순위를 사용하여 정보들을 로깅하

고있다.

 

 

image001.jpg

 

여러분이 어떤 매크로도 명시하지 않는다면 default priority DEFAULT_MESSAGE_LOGLEVEL 사용하게 것이며 정보는 kernel/printk.c 다음과 같이 정의되어 있다.


/* printk's without a loglevel use this.. */

#define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING */

 

 

우선순위가 console_loglevel 값보다 커야만(, 숫자로는 작은 ) 메시지가 터미널을 통해 화면에 출력될 있다. console_loglevel 값은 필자의 시스템에는 다음과 같이 정의되어 있다.

 

#define console_loglevel (console_printk[0])

int console_printk[4] = {

DEFAULT_CONSOLE_LOGLEVEL,

/* console_loglevel */

DEFAULT_MESSAGE_LOGLEVEL,

/* default_message_loglevel */

MINIMUM_CONSOLE_LOGLEVEL,

/* minimum_console_loglevel */

DEFAULT_CONSOLE_LOGLEVEL,

/* default_console_loglevel */

};

#define DEFAULT_CONSOLE_LOGLEVEL 7 /

* anything MORE serious than KERN_DEBUG */

 

우리는 예제에서 제일 높은 우선순위를 갖는 KERN_EMERG 사용하였다. 왜냐하면 default priority 메시지는

관련자료

댓글 0
등록된 댓글이 없습니다.

공지사항


뉴스광장


  • 현재 회원수 :  60,156 명
  • 현재 강좌수 :  36,513 개
  • 현재 접속자 :  277 명