반응형

 

  • 리눅스의 커널 모듈이란?
    • 모듈은 요청 시 커널에 로드 및 언로드할 수 있는 코드 조각이다.
    • 시스템을 재부팅할 필요 없이 커널의 기능을 확장한다.
      • 예를 들어, 한 가지 유형의 모듈은 커널이 시스템에 연결된 하드웨어에 액세스할 수 있도록 하는 디바이스 드라이버이다.
      • 모듈이 없으면 모놀리식 커널을 빌드하고 커널 이미지에 직접 새로운 기능을 추가해야 한다.
      • 더 큰 커널을 사용하는 것 외에도 새로운 기능을 원할 때마다 커널을 다시 빌드하고 재부팅해야 한다는 단점이 있다.
      • 따라서 모듈을 이용하면 커널 컴파일 시간을 단축할 수 있다.
    • 로드 가능한 커널 모듈(LKM, Loadable Kernel Module)은 런타임에 Linux 커널에 코드를 추가하거나 제거하는 메커니즘이다.
      • 모듈 없이 Linux 커널에 코드를 추가하려는 경우 가장 기본적인 방법은 커널 소스 트리에 일부 소스 코드 또는 파일을 추가하고 커널을 다시 컴파일하는 것이다.
      • 모듈을 사용하면 Linux 커널이 실행되는 동안 코드를 추가할 수 있다.
        • 이러한 방식으로 추가하는 코드 덩어리를 로드 가능한 커널 모듈이라고 한다.
      • 모듈은 커널이 하드웨어와 통신할 수 있도록 하는 디바이스 드라이버에 이상적이다.
        • 모듈은 /lib/modules/ 디렉터리 에서 .ko(kernel object, 커널 개체) 확장자를 가진 파일로 나타낼 수 있다.
        • 디바이스 드라이버는 모듈 형태로 구성되어 있다.
        • 파일 시스템, 메모리 매니지먼트 또한 커널 형태로 구성할 수 있다.

 

  • 로드 가능한 커널 모듈(LKM)
    • 요약
      • 로드 가능한 커널 모듈이 없으면 개발자는 새로운 기능이 필요할 때마다 기본 커널을 다시 빌드하고 재부팅해야 한다.
        • 컴파일 시간의 최대화
      • 로드 가능한 커널 모듈을 사용하면 개발자는 모듈만 다시 빌드하면 되고 대부분의 OS는 로드 가능한 커널 모듈을 지원한다.
        • 컴파일 시간의 최소화

 

  • 주요 모듈 명령어
    • lsmod
      • 현재 설치된 사용중인 모듈을 보여준다.
      • lsmod 명령은 현재 커널에 설치된 모듈을 나열하는 데 사용할 수 있다.
      • 결과는 모듈의 이름, Size 및 usage(Used by) 목록이다.
        • "Used by"(usage)는 이 모듈을 사용하는 다른 모듈의 수를 의미한다.
        • lsmod의 출력 예는 다음과 같다.
    • insmod
      • 하나의 모듈을 삽입하기 위해 사용하는 명령이다.
      • insmod(또는 insert module, 모듈 삽입) 명령을 사용하여 커널에 모듈을 삽입할 수 있다.
        • 사용자가 런타임에 커널 모듈을 로드하여 커널 기능을 확장할 수 있다.
        • 이 명령은 커널 개체 파일(.ko)을 커널에 삽입한다.
        • 예시:
          • insmod my_module.ko
    • rmmod
      • 모듈을 제거할 때 사용하는 명령이다.
      • rmmod(또는 remove module, 모듈 제거) 명령은 실행 중인 커널에서 로드 가능한 모듈을 언로드한다.
      • 조건이 있다. 사용 중이 아니어야 하고 다른 모듈에서 참조하지 않아야 한다.
      • 명령줄에서 둘 이상의 모듈 이름이 지정되면 해당 모듈은 지정된 순서대로 제거된다.
        • 이것은 스택된 모듈의 언로드를 지원한다.
      • 예:
        • rmmod my_module.ko 또는 rmmod my_module
    • modinfo
      • 모듈 정보를 얻으려고 할 때 사용하는 명령이다.
      • Linux 시스템에서 modinfo 명령은 Linux 커널 모듈에 대한 정보를 표시하는 데 사용된다.
      • 이 명령은 명령줄에 제공된 Linux 커널 모듈에서 정보를 추출한다.
      • 예시:
        • modinfo my_module.ko

 

  • 커널 모듈을 만들고 컴파일하는 방법
    • 모듈의 소스 코드는 커널 소스 트리 밖에 있을 수 있다.
    • 모듈 소스 디렉토리에 메이크파일을 넣는다.
    • 컴파일 후 컴파일된 모듈은 확장자가 .ko인 파일이다.
    • Makefile 생성
      • $ vi Makefile
        • 오브젝트 모듈:= hello_module.o
          • 컴파일할 모듈의 이름을 넣으면 된다.
        • KERNEL_DIR := /lib/modules/$(shell uname -r)/build
          • 커널 디렉토리
          • shell uname : 커널 버전이 나온다.
          • 커널 버전에 맞는 빌드 디렉토리를 넣어야 한다.
        • PWD := $(shell pwd)
          • 소스코드가 있는 디렉토리
          • Print Working Directory
        • default : $(MAKE) -C $(KERNEL_DIR) SUBDIRS=$(PWD) modules
          • default는 뒤에 아무 옵션을 주지 않았을 때 시행되는 명령어이다.
          • 커널 디렉토리와 서브 디렉토리를 넣어준다.
          • 모듈 컴파일이니 modules를 붙인다.
        • clean : $(MAKE) -C $(KERNEL_DIR) SUBDIRS=$(PWD) clean
          • clean: make clean 썼을 때 시행되는 명령어이다.
      • $make
    • 간단한 커널 모듈 작성
      • #--------- hello_module.c ---------#
        #include <linux/kernel.h> //Needed by all modules
        #include <linux/module.h> //Needed for KERN_ALERT
        #include <linux/init.h> //Needed for the macros
        
        int __init hello_module_init(void)
        {
        	printk("Hello Module!\n");
        	return 0;
        }
        
        void __exit hello_module_cleanup(void)
        {
        	printk("Bye Module!\n");
        }
        
        module_init(hello_module_init); 
        module_exit(hello_module_cleanup); 
        MODULE_LICENSE("GPL");
      • make 파일 만든 뒤 .c 파일을 만들 수 있다. 이후 세 가지 커널 헤더를 include해야 한다.
      • insmod는 해당 모듈을 로드한다. 파일의 module_init 함수를 부른다.
      • rmmod는 해당 모듈을 언로드한다. 파일의 module_exit 함수를 부른다.
    • 모듈 초기화 및 종료
      • module_init(hello_module_init)
        • 초기화 진입점
        • 모듈 삽입 시 실행할 함수(hello_module_init)
        • hello_module_init()는 모듈을 로드할 때 호출된다.
      • module_exit(hello_module_cleanup)
        • 출구 진입점
        • 모듈 제거 시 실행할 함수(hello_module_cleanup)
        • hello_module_cleanup()은 모듈을 언로드할 때 호출된다.
    • 커널 모듈에는 최소한 두 가지 함수가 있어야 한다.
      • 모듈이 커널에 insmod될 때 호출되는 "시작"(initialization) 함수(예: hello_module_init())
      • 모듈이 커널에 rmmod될 때 호출되는 "종료"(cleanup) 함수(예: hello_module_cleanup())
    • 커널 모듈 시작
      • 커널 코드를 실행하기 때문에 루트 권한이 필요하다.
      • insmod로 커널 모듈 로드해야 한다.
        • insmod hello_module.ko    // 반드시 .ko를 붙여야 한다.
        • 모듈이 로드되고 초기화 함수가 실행된다.
      • 모듈은 특정 커널 버전에 대해 컴파일되며 다른 커널에는 로드되지 않는다.
      • rmmod로 모듈 제거
        • rmmod hello_module 또는 rmmod hello_module.ko
        • 언로드 전에 모듈 종료 함수가 호출됩니다.

 


  • --------------What is Kernel Modules in Linux
    • Modules are pieces of code that can be loaded and unloaded into the kernel upon demand
    • They extend the functionality of the kernel without the need to reboot the system
      • For example, one type of module is the device driver, which allows the kernel to access hardware connected to the system
      • Without modules, we would have to build monolithic kernels and add new functionality directly into the kernel image
      • Besides having larger kernels, this has the disadvantage of requiring us to rebuild and reboot the kernel every time we want new functionality
    • A loadable kernel module (LKM) is a mechanism for adding code to, or removing code from, the Linux kernel at run time
      • Without module, if you want to add code to a Linux kernel, the most basic way to do that is to add some source codes or files to the kernel source tree and recompile the kernel
      • With module, you can add code to the Linux kernel while it is running
        • A chunk of code that you add in this way is called a loadable kernel module
      • They are ideal for device drivers, enabling the kernel to communicate with the hardware
        • A module can be represented by a file with a .ko (kernel object) extension in the /lib/modules/ director

 

  • Loadable Kernel Module
    • Summary
      • Without loadable kernel modules, developers rebuild and reboot the base kernel every time they require new functionality
        • The compile time is maximized
      • With loadable kernel modules, developers only rebuild the modules, and most OSs support loadable kernel modules
        • The compile time is minimized

 

 

  • Major Module Commands
    • lsmod
      • The lsmod command can be used to list the modules that are currently installed into the kernel
      • The result is a list of modules by name, including the memory size and usage of the module
        • “Used by” (usage) means how many other modules use this module
        • An example output of lsmod is shown here:
    • insmod
      • The insmod (or insert module) command can be used insert a module into the kernel
        • It allows the user to load kernel modules at runtime to extend the kernel functionalities
        • This command insert the kernel object file (.ko) into the kernel
        • Example:
          • insmod my_module.ko
    • rmmod
      • rmmod (or remove module) command unloads loadable modules from the running kernel
      • It tries to unload a set of modules from the kernel with the restriction that they are not in use and that they are not referred to by other modules
      • If more than one module is named on the command line, the modules will be removed in the given order
        • This supports unloading of stacked modules
      • Exmaple:
        • rmmod my_module.ko or rmmod my_module
    • Getting module information
      • modinfo command in Linux system is used to display the information about a Linux Kernel module.
      • This command extracts the information from the Linux kernel modules given on the command line.
      • Example:
        • Modinfo my_module.ko

 

  • How to make and compile kernel module
    • Source code of a module can be out of the kernel source tree
    • Put a makefile in the module source directory
    • After compilation, the compiled module is the file with .ko extension
    • Create Makefile
      • $vi Makefile
      • $make
    • Writing a Simple Kernel Module
      • #--------- hello_module.c ---------#
        #include <linux/kernel.h> //Needed by all modules
        #include <linux/module.h> //Needed for KERN_ALERT
        #include <linux/init.h> //Needed for the macros
        
        int __init hello_module_init(void)
        {
        	printk("Hello Module!\n");
        	return 0;
        }
        
        void __exit hello_module_cleanup(void)
        {
        	printk("Bye Module!\n");
        }
        
        module_init(hello_module_init); 
        module_exit(hello_module_cleanup); 
        MODULE_LICENSE("GPL");
    • Module initialization and exit
      • module_init(hello_module_init)
        • Initialization entry point
        • Function (hello_module_init) to be run at module insertion
        • hello_module_init() will be called at loading the module
      • module_exit(hello_module_cleanup)
        • Exit entry point
        • Function (hello_module_cleanup) to be run at module remove
        • hello_module_cleanup() will be called at unloading the module
    • Kernel modules must have at least two functions
      • A “start” (initialization) function (e.g., hello_module_init()) which is called when the module is insmoded into the kernel
      • An “end” (cleanup) function (e.g., hello_module_cleanup()) which is called when the module is rmmoded from the kernel
    • Launching a Kernel module
      • Needs root privileges because you are executing kernel code
      • Loading a kernel module with insmod
        • insmod hello_module.ko
        • Module is loaded and init function is executed
      • Note that a module is compiled against a specific kernel version and will not load on another kernel
    • Launching a Kernel module
      • Remove the module with rmmod
        • rmmod hello_module or rmmod hello_module.ko
        • Module exit function is called before unloading
반응형

+ Recent posts