Wednesday, April 22, 2015

Linux Character Device Driver

@ Device Driver 동작 원리
  (1) Insert Module to Kernel
    ① $ insmod led.ko 입력 시,
    ② module_init() -> led_init() 호출
    ③ register_chrdev() 호출
      -. LED_MAJOR : LED 장치 주 번호
      -. LED_DEVNAME : LED 특수장치파일 이름, /dev/led 파일로 접근
      -. &led_fops : user 인터페이스와 kernel 루틴을 연결
    ④ LED_DEVNAME 파일을 제어하면 Kernel을 제어할 수 있게 됨

  (2) Create LED character device file
    ① $ mknod /dev/led c 240 0
    ② $ ll /dev/led
        crw-r--r--  1 root root    240,   0 2015-04-23 11:04 led

  (3) Using Device Driver in Application Program
    ① 이제 Application Layer에서 open을 호출하면 led_open 함수가 호출됨

/*
 * @file   test.c
 * @brief  Application Program for Led Control
 */

int main()
{
  int fd;
  char buf[8];
  
  fd = open("/dev/led", O_RDWR);
  read(fd , buf, MAX_BUFFER);
  write(fd, buf, MAX_BUFFER);
  close(fd);
  
  return 0;
}

/*
 * @file   led.c
 * @brief  Kernel Module Program Source, "led.ko" is created with led.c by make utility
 */

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

#define LED_MAJOR     240
#define LED_DEVNAME  "led"

...

static struct file_operations led_fops = {
    .open    = led_open,
    .close   = led_close,
    .read    = led_read,
    .write   = led_write,
    .release = led_release,
}

static int led_init(void)
{
    // 주 번호가 240인 "/dev/led" 파일을 이용하여 High-Level 인터페이스를 사용하면,
    // Kernel-Level에 연결된 함수가 호출될 수 있도록 Device 등록
    register_chrdev(LED_MAJOR, LED_DEVNAME, &led_fops);
    return 0;
}

static void led_exit(void)
{
    unregister_chrdev(LED_MAJOR, LED_DEVNAME);
}
module_init(led_init); // to be called when "insmod led.ko" command execute
module_exit(led_exit); // to be called when "rmmod led.ko" command execute

MODULE_LICENSE("GPL");

No comments:

Post a Comment