1 / 34

디바이스드라이버

디바이스드라이버. 모듈프로그래밍 디바이스드라이버 프로그래밍. 모듈프로그래밍. 초기 리눅스 : 커널 변경시 커널 전체를 다시 컴파일 모듈 프로그램으로 개발하면 해당 모듈만 컴파일하고 필요할 때만 동적으로 링크시켜 커널의 일부로 사용할 수 있어 효율적 자주 사용하지 않는 커널 기능은 메모리에 상주시키지 않아도 됨 확장성과 재사용성을 높일 수 있음. 모듈 프로그래밍의 특징 사건 구동형 (event-driven program) 방식으로 작성 내부에 main() 이 없음

atara
Download Presentation

디바이스드라이버

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 디바이스드라이버 모듈프로그래밍 디바이스드라이버 프로그래밍

  2. 모듈프로그래밍 • 초기 리눅스: 커널 변경시 커널 전체를 다시 컴파일 • 모듈 프로그램으로 개발하면 해당 모듈만 컴파일하고 필요할 때만 동적으로 링크시켜 커널의 일부로 사용할 수 있어 효율적 • 자주 사용하지 않는 커널 기능은 메모리에 상주시키지 않아도 됨 • 확장성과 재사용성을 높일 수 있음.

  3. 모듈 프로그래밍의 특징 • 사건 구동형(event-driven program) 방식으로 작성 • 내부에 main()이 없음 • 커널에 적재/제거하기 위한 규칙과 유틸리티가 필요 • 외부로 공개할 전역변수 사용에 주의 • 커널에 적재된 모듈 프로그램은 무제한의 특권을 가지므로 신중하게 작성해야 함

  4. 심볼 및 관련 매크로 • 전역변수와 전역 함수 이름을 심볼 테이블에 등록 • 커널 심볼 테이블의 내용은 /proc/kallsyms라는 텍스트 파일로 외부에 제공 • EXPORT_NO_SYMBOLS: 공개하지 않음 • EXPORT_SYMBOL(), EXPORT_SYMBOL_GPL(): 공개

  5. 모듈 프로그램의 기본 형태

  6. 호스트 시스템에서 모듈 생성을 위한 Makefile 기본 형태 • 타겟 시스템에서 모듈 생성을 위한 Makefile 기본 형태

  7. 실습 호스트 시스템의 커널 공개 심볼 살펴보기 • head /proc/kallsyms, tail /proc/kallsyms를 입력해 커널 심볼 테이블의 내용을 확인

  8. insmod: 모듈을 커널로 적재하는 명령 • rmmod: 제거하는 명령 • lsmod: 정상적으로 적재되었는지 확인하는 명령

  9. 실습 Hello 모듈 프로그램 작성 및 실행 • 모듈 프로그램 hello.c 작성 01 #include <linux/kernel.h> 02 #include<linux/module.h> 03 #include<linux/init.h> 04 05 static int module_begin(void) // 모듈 초기화 함수 06 { 07 printk("Hello, Module!\n"); 08 return 0; 09 } 10 11 static void module_end(void) // 모듈 마무리 함수 12 { 13 printk("Good bye!\n"); 14 } 15 16 module_init(module_begin); 17 module_exit(module_end);

  10. ② ③ ④ ⑤ 실습 9-2 Hello 모듈 프로그램 작성 및 실행 • Makefile을 작성 앞의 호스트시스템용 makefile에서 test.o→hello.o • make로 hello.ko 모듈 프로그램을 생성하고 테스트

  11. 실습 9-2 Hello 모듈 프로그램 작성 및 실행 • cat /proc/kallsyms 명령으로 커널 심볼 테이블에 있는 hello.c의 심볼들을 확인

  12. Device Driver

  13. 디바이스드라이버 개요 • 디바이스: 컴퓨터시스템의 주변 하드웨어 • 디바이스 드라이버는 디바이스 구동 프로그램 • 디바이스의 종류 • 문자 디바이스(character device) • 블록 디바이스(block device) • 네트워크 디바이스(network device) • 주번호(major number)와 부번호(minor number)로 구분 • 동일한 디바이스는 동일한 주번호를 가지며 서로 구분하기 위해 부번호를 사용

  14. 디바이스드라이버 개요 • 문자 디바이스 • 파일시스템에서 하나의 노드 형태로 존재 • 자료의 순차성을 지닌 하드웨어 • 데이터를 문자 단위 또는 연속적 바이트 흐름으로 전달하고 읽음. • 터미널, 콘솔, 키보드, 사운드카드, 스캐너, 프린터, 직렬/병렬 포트, 마우스, 조이스틱 등 • 블록 디바이스 • 파일시스템에서 하나의 노드 형태로 존재 • 데이터를 블록 단위로 입출력 • 하드디스크, 플로피 디스크, 램디스크, 테이프, CD-ROM, DVD 등

  15. 디바이스 파일 • 리눅스 시스템은 디바이스를 /dev 디렉토리에 있는 일종의 파일로 취급. 즉, 디바이스를 파일로 추상화 • 디바이스 파일은 사용자에게 보이는 디바이스 드라이버의 인터페이스 부분 • 응용 프로그램은 디바이스에 접근하기 위하여 열기, 읽기, 쓰기 등과 같은 파일 연산을 이용 • 디바이스 파일은 파일시스템에서 고유한 번호와 이름을 할당받음 • 디바이스 파일은 파일시스템의 데이터 영역을 차지하지 않고 단지 디바이스 드라이버를 접근할 수 있는 관문 역할을 수행

  16. ② 실습 호스트 시스템의 디바이스 파일 관찰 • 호스트 시스템의 디바이스 파일이 있는 /dev 디렉토리 내용관찰

  17. 디바이스 파일의 생성 • 디바이스 파일은 /dev 에서 관리 • 디바이스 파일 형식: 문자형 c , 블록형 b • 리눅스에서 사용되는 디바이스 파일의 주번호

  18. ② 실습 mknod 명령으로 디바이스 파일 생성 • 디바이스 파일을 생성하고 세부 내용 관찰

  19. 디바이스 드라이버 • 디바이스와 시스템 사이에 데이터를 주고받기 위한 인터페이스 • 표준적으로 동일한 서비스 제공을 목적 • 커널의 일부분으로 내장 • 서브루틴과 데이터의 집합체 • 디바이스의 고유한 특성을 내포

  20. file 구조체 • 파일 연산을 위한 인자 전달 방법으로 사용 • 디바이스에 필요한 자료 구조를 정의

  21. 파일 연산 구조체 • 커널은 등록된 디바이스 드라이버의 파일 연산 구조체를 참고해 응용프로그램의 요청에 대응하는 함수 호출

  22. 문자 디바이스 드라이버의 파일 연산 구조체 사용 • 전형적인 파일 연산 구조체의 선언내용 (xxx는 일반적으로 디바이스의 이름) struct file_operations xxx_fops = { .owner = THIS_MODULE, .open = xxx_open, .release = xxx_release, .read = xxx_read, .write = xxx_write, .ioctl = xxx_ioctl, };

  23. 문자 디바이스의 등록과 해제 • major : 주번호로, 0이면 사용하지 않는 주번호 중에서 동적으로 할당 • name : 디바이스의 이름으로 /proc/devices에 나타나 있음 • 반환값 : 오류 코드. 반환값이 0이거나 양수이면 성공적인 수행. 음수이면 오류 발생.

  24. 블록 디바이스의 등록과 해제 • major : 주번호로, 0이면 사용하지 않는 주번호 중에서 동적으로 할당 • name : 블록 디바이스 장치 이름 • 반환값 : 오류 코드. 0이나 양수이면 성공적인 수행. 음수이면 오류 발생

  25. 문자 디바이스 드라이버의 등록 과정

  26. 전형적인 문자 디바이스 드라이버

  27. 실습 가상 디바이스 드라이버 구현 • 가상 문자 디바이스 드라이버 프로그램 작성(10/chr_dev.c) 01 #include <linux/module.h> 02 #include <linux/kernel.h> 03 #include <linux/fs.h> 04 #include <linux/init.h> 05 06 #define CHR_DEV_NAME "chr_dev" // 디바이스 파일 이름 07 #define CHR_DEV_MAJOR 240 // 디바이스 파일의 주번호 08 09 int chr_open(struct inode *inode, struct file *filp) 10 { 11 int number = MINOR(inode->i_rdev); // 부번호를 number에 저장 12 printk("Virtual Character Device Open: Minor Number is %d\n", number); 13 return 0; 14 } 15 16 ssize_t chr_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos) 17 { 18 printk("write data: %s\n", buf); // 응용프로그램 write() 19 // 함수의 buf 값을 커널 메시지에 출력 20 return count; 21 } 22

  28. 실습 가상 디바이스 드라이버 구현 23 ssize_t chr_read(struct file *filp, const char *buf, size_t count, loff_t *f_pos) 24 { 25 printk("read data: %s\n", buf); // 응용프로그램 read() 26 // 함수의 buf 값을 커널 메시지에 출력 27 return count; 28 } 29 30 int chr_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) 31 { 32 switch(cmd) { // ioctl 함수로 전달된 cmd 값을 출력 33 case 0: printk("cmd value is %d\n", cmd); break; ………… 37 case 4: printk("cmd value is %d\n", cmd); break; 38 } 39 return 0; 40 } 41 42 int chr_release(struct inode *inode, struct file *filp) 43 { 44 printk("Virtual Character Device Release\n"); 45 return 0; 46 } 47 48 struct file_operations chr_fops = 49 { 50 .owner = THIS_MODULE, 51 .ioctl = chr_ioctl, 52 .write = chr_write, 53 .read = chr_read, 54 .open = chr_open, 55 .release = chr_release, 56 }; 57

  29. 실습 가상 디바이스 드라이버 구현 58 int sample_init(void)// 디바이스를 커널에 모듈로 적재시 수행되는 함수 59 { 60 int registration; // registration에 주번호나 반환값을 저장 61 printk("Registration Character Device to Kernel\n"); 62 registration = register_chrdev(CHR_DEV_MAJOR,CHR_DEV_NAME, &chr_fops); 63 if(registration < 0) 64 return registration; 65 printk("Major Number:%d\n", registration); 66 return 0; 67 } 68 69 void sample_cleanup(void) // 커널에서 디바이스를 제거할 때 수행되는 함수 70 { 71 printk("Unregistration Character Device to Kernel\n"); 72 unregister_chrdev(CHR_DEV_MAJOR, CHR_DEV_NAME); 73 } 74 75 MODULE_LICENSE("GPL"); 76 module_init(sample_init); 77 module_exit(sample_cleanup);

  30. 실습 가상 디바이스 드라이버 구현 • Make 유틸리티를 실행해 모듈 생성

  31. 실습 10-3 가상 디바이스 드라이버 구현 • 가상 문자 디바이스를 사용하는 응용프로그램 작성 01 #include <stdio.h> 02 #include <sys/types.h> 03 #include <sys/stat.h> 04 #include <fcntl.h> 05 #include <sys/ioctl.h> 06 #include <unistd.h> 07 08 #define DEVICE_FILE_NAME "/dev/chr_dev" // 디바이스 파일 09 10 int main(int argc, char *argv[]) // argv 값을 받아 디바이스 11 { // 파일의 IOCTL cmd 값으로 사용 12 int device; 13 char wbuf[128] = "Write buffer data"; 14 char rbuf[128] = "Read buffer data"; 15 int n = atoi(argv[1]); 16 17 device = open(DEVICE_FILE_NAME, O_RDWR|O_NDELAY); 18 if( device >= 0 ) { 19 printf("Device file Open\n"); 20 ioctl(device, n); // argv 값을 디바이스 파일에 cmd 값으로 전달 21 write(device, wbuf, 10); // wbuf 값을 디바이스 파일에 전달 22 printf("Write value is %s\n", wbuf); 23 read(device, rbuf, 10); 24 printf("read value is %s\n", rbuf); 25 } 26 else 27 perror("Device file open fail"); 28 29 return 0; 30 }

  32. ② 실습 10-3 가상 디바이스 드라이버 구현 • 응용프로그램을 타겟 시스템용으로 교차 컴파일 • 디바이스 드라이버 모듈 chr_dev.ko 파일과 컴파일한 응용 프로그램 chr_appl을 타겟 시스템으로 전송 • 디바이스 드라이버 모듈을 적재하고 적재 여부 확인

  33. ② 실습 10-3 가상 디바이스 드라이버 구현 • 디바이스 파일을 만들고 확인 • 명령행 인자를 사용해 응용 프로그램을 실행→디바이스 드라이버 모듈 제거

More Related