260 likes | 442 Views
Device Driver. 디바이스 드라이버 개요 가상 디바이스드라이버 실습. 디바이스드라이버 개요. 디바이스 컴퓨터시스템의 주변 하드웨어 LCD, USB, Ethernet, CD, AUDIO, 등 디바이스 드라이버 물리적인 HW 장치를 다루고 관리하는 SW 로 커널의 일부분 디바이스의 종류 문자 디바이스 (character device) 블록 디바이스 (block device) 네트워크 디바이스 (network device)
E N D
Device Driver 디바이스 드라이버 개요 가상 디바이스드라이버 실습
디바이스드라이버 개요 • 디바이스 • 컴퓨터시스템의 주변 하드웨어 • LCD, USB, Ethernet, CD, AUDIO, 등 • 디바이스 드라이버 • 물리적인 HW 장치를 다루고 관리하는 SW 로커널의 일부분 • 디바이스의 종류 • 문자 디바이스(character device) • 블록 디바이스(block device) • 네트워크 디바이스(network device) • 주번호(major number)와 부번호(minor number)로 구분 • 동일한 디바이스는 동일한 주번호를 가지며 서로 구분하기 위해 부번호를 사용
디바이스드라이버 개요 • 문자 디바이스 • 파일시스템에서 하나의 노드 형태로 존재 • 자료의 순차성을 지닌 하드웨어 • 데이터를 문자 단위 또는 연속적 바이트 흐름으로 전달하고 읽음. • 터미널, 콘솔, 키보드, 사운드카드, 스캐너, 프린터, 직렬/병렬 포트, 마우스, 조이스틱 등 • 블록 디바이스 • 파일시스템에서 하나의 노드 형태로 존재 • 데이터를 블록 단위로 입출력 • 하드디스크, 플로피 디스크, CD-ROM, DVD 등의저장장치
디바이스 파일 • 리눅스 시스템은 디바이스를 /dev 디렉토리에 있는 일종의 파일로 취급. 즉, 디바이스를 파일로 추상화 • 디바이스 파일은 사용자에게 보이는 디바이스 드라이버의 인터페이스 부분 • 응용 프로그램은 디바이스에 접근하기 위하여 열기, 읽기, 쓰기 등과 같은 파일 연산을 이용 • 디바이스 파일은 파일시스템에서 고유한 번호와 이름을 할당받음 • 디바이스 파일은 파일시스템의 데이터 영역을 차지하지 않고 단지 디바이스 드라이버를 접근할 수 있는 관문 역할을 수행
① ② 실습 호스트 시스템의 디바이스 파일 관찰 • 호스트 시스템의 디바이스 파일이 있는 /dev 디렉토리 내용관찰
디바이스 파일의 생성 • 디바이스 파일은 /dev 에서 관리 • 디바이스 파일 형식: 문자형 c , 블록형 b • 리눅스에서 사용되는 디바이스 파일의 주번호
① ② 실습 mknod 명령으로 디바이스 파일 생성 • 디바이스 파일을 생성하고 세부 내용 관찰
디바이스 드라이버 • 디바이스와 시스템 사이에 데이터를 주고받기 위한 인터페이스 • 표준적으로 동일한 서비스 제공을 목적 • 커널의 일부분으로 내장 • 서브루틴과 데이터의 집합체 • 디바이스의 고유한 특성을 내포
file 구조체 • 파일 연산을 위한 인자 전달 방법으로 사용 • 디바이스에 필요한 자료 구조를 정의
파일 연산 구조체 • 커널은 등록된 디바이스 드라이버의 파일 연산 구조체를 참고해 응용프로그램의 요청에 대응하는 함수 호출
문자 디바이스 드라이버의 파일 연산 구조체 사용 • 전형적인 파일 연산 구조체의 선언내용 (xxx는 일반적으로 디바이스의 이름) struct file_operations xxx_fops = { .owner = THIS_MODULE, .open = xxx_open, .release = xxx_release, .read = xxx_read, .write = xxx_write, .ioctl = xxx_ioctl, };
문자 디바이스의 등록과 해제 • major : 주번호로, 0이면 사용하지 않는 주번호 중에서 동적으로 할당 • name : 디바이스의 이름으로 /proc/devices에 나타나 있음 • 반환값 : 오류 코드. 반환값이 0이거나 양수이면 성공적인 수행. 음수이면 오류 발생.
블록 디바이스의 등록과 해제 • major : 주번호로, 0이면 사용하지 않는 주번호 중에서 동적으로 할당 • name : 블록 디바이스 장치 이름 • 반환값 : 오류 코드. 0이나 양수이면 성공적인 수행. 음수이면 오류 발생
실습 가상 디바이스 드라이버 구현 // FILE: 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
실습 가상 디바이스 드라이버 구현 • 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 { • switch(cmd) { // ioctl 함수로 전달된 cmd 값을 출력 • case 0: printk("cmd value is %d\n", cmd); break • 34 case 1: printk("cmd value is %d\n", cmd); break; • 35 case 2: printk("cmd value is %d\n", cmd); break; • 36 case 3: 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
실습 가상 디바이스 드라이버 구현 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);
타겟 시스템에서 모듈 생성을 위한 Makefile 기본 형태 # 타겟소스가 있는디렉토리
실습 가상 디바이스 드라이버 구현 • Make 유틸리티를 실행해 모듈 생성
실습 가상 디바이스 드라이버 응용프로그램 구현 // FILE: chr_appl.c 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
실습 가상 디바이스 드라이버 응용프로그램 구현 • device = open(DEVICE_FILE_NAME, O_RDWR|O_NDELAY); • 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 }
① ② 실습 10-3 가상 디바이스 드라이버 구현 • 응용프로그램을 타겟 시스템용으로 교차 컴파일 • 디바이스 드라이버 모듈 chr_dev.ko 파일과 컴파일한 응용 프로그램 chr_appl을 타겟 시스템으로 전송 • 디바이스 드라이버 모듈을 적재하고 적재 여부 확인
① ② 실습 10-3 가상 디바이스 드라이버 구현 • 디바이스 파일을 만들고 확인 • 명령행 인자를 사용해 응용 프로그램을 실행→디바이스 드라이버 모듈 제거