static int __init chrdev_init(void)
{
int result;
result = register_chrdev(63, "chrdev_dd",&chrdev_fops);
if(result<0)
{
printk("chrdev_dd: 에러!\");
return result;
}
return result;
}

int chrdev_open(struct inode *inode, struct file *filp){
 MOD_INC_USE_COUNT;
 return 0;
}

static ssize_t chrdev_read(struct file * file, char *buffer, size_t, count, loff_t *offset){
 chrdev_buff = *chrdev_addr;
 copy_to_user(buffer, &chrdev_buff, size);
}

static ssize_t chrdev_write(struct file *file, const char *buffer, size_t length, loff_t *offset){
  int value, *keyReg;
  ......생략...........
  get_user(value,(int*)buffer);
  *chardev_wr_addr = ~value;
 .......생략..........
}

int chrdev_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
    return 0;
}

int chrdev_release(struct inode *inode,struct file *filp){
MODE_DEC_USE_COUNT;
return 0;
}

struct file_operations chrdev_fops = {
open : chrdev_open;
read : chrdev_read;
write : chrdev_write,
ioctl : chrdev_ioctl,
release : chrdev_release,
};

module_init(chrdev_init)l
module_exit(chrdev_cleanup);


 

 

 

 

 

위에서 module_init(chrdev)init);문에 의해 디바이스 드라이버가 메모리에 로드될 때 chrdev_init()함수가 실행되며 이때 등록함수 register_chrdev()가 호출된다. 함수에서 인수로 디바이스 주번호 63 디바이스명은 chrdev_dd file_operations 구조체 포인터는 chrdev_fops를 사용한다. 커널 레벨에서의 문자 출력 함수인 printk()문은 등록 실패시 실행된다.

 

 

응용프로그램에서 open("/dev/chrdev_dd", O_RDWR) 식으로 open()함수를 호출하면, 커널 내부에서는 /dev 디렉터의 디바이스 파일 chrdev_dd에 할당된 디바이스 주(major) 번호를 가지고 chardevs[] 배열에서 해당하는 문자 디바이스 드라이버의 file_operations 구조체 멤버 (*open)이 가리키는 chrdev_open()함수를 호출한다.

 

디바이스 파일 chrdev_dd의 오픈에 성공하면 파일 디스크립터를 얻게 되고 이후 응용프로그램에서는 이 파일 디스크립터를 사용해 해당 디바이스에 접근(read/write)할 수 잇다. 이 open()함수는 디바이스를 초기화하고 필요한 자원을 할당받으며 MOD_INT_USE_COUNT 매크로를 이용해서 카운트 값을 1 증가시켜 디바이스 드라이버가 사용중임을 표시한다.

 

 

여기서 file_operations 구조체 chrdev_fops에는 응용프로그램의 open(), read(), write(), ioctl(), release()에 대응하는 디바이스 드라이버 내부 함수 chrdev_open(),chrdev_read(), chrdev_write, chrdev_ioctl(), chrdev_release()를 각각 정의하고 있다.

 

chrdev_read() 함수에서는 실제 디바이스 주소로부터 데이터를 읽어온 후 이를 copy_to_user 매크로를 사용해 to포인터가 가리키는 사용자 메모리로 from 포인터가 가리키는 커널 메모리에 있는 내용을 복사한다.

 

디바이스에 데이터를 출력하기 위해 응용프로그램에서 write() 함수를 호출하면 이때 문자 디바이스 드라이버 내의 함수 chrdev_write()가 실행된다. chrdev_write()에서는 디바이스에 데이터를 쓰기 전에 copy_from_user(to, from, n) 매크로를 사용해 from 포인터가 가리키는 사용자 메모리 영역의 내용을 to 포인터가 가리키는 커널 메모리 영역으로 복사한다.

 

응용프로그램에서 ioctl() 함수를 호출하면 디바이스 드라이버 내의 함수 chrdev_ioctl()가 실행된다. 응용프로그램에서 read()나 write() 함수는 디바이스와 데이터를 주고 받는데 주로 사용하며, 이를 통해 디바이스의 기능 자체를 제어하기는 적합치 않은 경우가 있다. 이런 경우 디바이스 자체를 제어하는 특수 기능은 ioctl()을 통해서 한다.

블로그 이미지

종환 Revolutionist-JongHwan

github.com/alciakng 항상 겸손하자.