모듈 프로그램에서는 자기만이 사용하는 전역 변수와 함수에 대해서는 static 키워드를 이용하여 보호한다고 했습니다. 또한 다른 모듈을 위해 공개할 함수는 심볼로 등록해야 된다는 말씀도 드렸습니다.

이번 시간에는 심볼에 대한 예를 들어 보려고 합니다. 심볼을 어떻게 등록하고 사용하는지에 대한 것이므로 예를 아주 간단히 올립니다.

두개의 모듈, sample 과 printf_int를 만들고 sample에서 print_int에서 제공하는 print_integer()함수를 호출하여 정수를 출력하도록 합니다.

print_int.c

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>

int   print_integer( int value)
{
   printk( "%dn", value);
}

int __init init_print_int( void)
{
  return 0;
}

void __exit exit_print_int(void)
{
}

EXPORT_SYMBOL( print_integer);

module_init( init_print_int);
module_exit( exit_print_int);

MODULE_LICENSE( "GPL" );

print_int.h

다른 모듈에서 심볼을 사용할 수 있도록 헤더파일을 준비합니다.

extern   int   print_integer( int value);

sample.c

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>

#include "print_int.h"

int __init init_sample( void)
{
  printk( KERN_ALERT "print_integer( 99) called.n" );
  print_integer( 99);
  return 0;
}

void __exit exit_sample(void)
{
  printk( KERN_ALERT "Good-bye~n" );
}

module_init( init_sample);
module_exit( exit_sample);

MODULE_LICENSE( "GPL" );

Makefile

Makefile 안에 sample.o 와 print_int.o 가 모두 지정되어 있는 것을 참고합시오.

KERNELDIR = /lib/modules/$(shell uname -r)/build

obj-m := sample.o print_int.o

KDIR  := /lib/modules/$(shell uname -r)/build
PWD   := $(shell pwd)

default:
   $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules

clean:
   rm -rf *.ko
   rm -rf *.mod.*
   rm -rf .*.cmd
   rm -rf *.o
   rm -rf .tmp_versions

예제 실행

pritn_int 모듈부터 커널에 등록합니다.

]# insmod print_int.ko

print_int를 커널에 등록하면 print_integer()는 심볼로 등록이 됩니다. /proc/kallsysms에는 모든 모듈의 심볼 정보를 가지고 있습니다. /proc/kallsysms의 내용에서 print_integer() 심볼이 제대로 올라왔는지 확인해 보겠습니다.

]# grep print_integer /proc/kallsyms
d0a70018 r __kcrctab_print_integer      [print_int]
d0a7001c r __kstrtab_print_integer      [print_int]
d0a7002c r __ksymtab_print_integer      [print_int]
d0a70000 T print_integer        [print_int]
7e3646c8 a __crc_print_integer  [print_int]
]# 

정상적으로 등록된 것을 알 수 있습니다. 이제 sample.ko를 커널에 등록할 때 마다 print_integer() 함수가 호출됩니다.

]# insmod sample.ko
print_integer( 99) called.
99
]# rmmod sample.ko
Good-bye~
]# insmod sample.ko
print_integer( 99) called.
99

lsmod로 모듈 리스트를 확인해 보면 sample과 print_int 드라이버가 목록에 출력되면서 print_int 내용에 sample이 사용하고 있음을 알 수 있습니다.

]# lsmod
Module                  Size  Used by
sample                  5632  0 
print_int               5888  1 sample


                :

]# 

sampel이 print_int의 심볼 print_integer를 사용하고 있는 상태에서 /proc/kallsysms 의 내용을 다시 확인해 보겠습니다.

]# grep print_integer /proc/kallsyms
d0a70000 U print_integer        [sample]
d0a70018 r __kcrctab_print_integer      [print_int]
d0a7001c r __kstrtab_print_integer      [print_int]
d0a7002c r __ksymtab_print_integer      [print_int]
d0a70000 T print_integer        [print_int]
7e3646c8 a __crc_print_integer  [print_int]
[root@jwCentOS 119_device_driver]# 

이렇게 sample에서 print_integer를 사용했음이 표시됩니다.

태그: *디바이스드라이버