Presentation is loading. Please wait.

Presentation is loading. Please wait.

5장. Enhanced Char Driver Operations 과제

Similar presentations


Presentation on theme: "5장. Enhanced Char Driver Operations 과제"— Presentation transcript:

1 5장. Enhanced Char Driver Operations 과제
김희자

2 목차 하드웨어 제어 iotcl 예제 블로킹 sleepy 예제 비블로킹 nbtest 예제 순천향대학교 정보기술공학부 김 희 자

3 하드웨어 제어 ioctl 예제 순천향대학교 정보기술공학부 김 희 자

4 scull ioctl 실행 [root@UPnP1 scull]# make
scull]# sh scull_load scull]# cc myioctl.c -o myioctl scull]# ./myioctl quantum: 4000 순천향대학교 정보기술공학부 김 희 자

5 소스 분석 : scull.h #define SCULL_IOC_MAGIC 'k'
#define SCULL_IOCRESET _IO(SCULL_IOC_MAGIC, 0) #define SCULL_IOCSQUANTUM _IOW(SCULL_IOC_MAGIC, 1, scull_quantum) #define SCULL_IOCSQSET _IOW(SCULL_IOC_MAGIC, 2, scull_qset) #define SCULL_IOCTQUANTUM _IO(SCULL_IOC_MAGIC, 3) #define SCULL_IOCTQSET _IO(SCULL_IOC_MAGIC, 4) #define SCULL_IOCGQUANTUM _IOR(SCULL_IOC_MAGIC, 5, scull_quantum) #define SCULL_IOCGQSET _IOR(SCULL_IOC_MAGIC, 6, scull_qset) #define SCULL_IOCQQUANTUM _IO(SCULL_IOC_MAGIC, 7) #define SCULL_IOCQQSET _IO(SCULL_IOC_MAGIC, 8) #define SCULL_IOCXQUANTUM _IOWR(SCULL_IOC_MAGIC, 9, scull_quantum) #define SCULL_IOCXQSET _IOWR(SCULL_IOC_MAGIC,10, scull_qset) #define SCULL_IOCHQUANTUM _IO(SCULL_IOC_MAGIC, 11) #define SCULL_IOCHQSET _IO(SCULL_IOC_MAGIC, 12) 순천향대학교 정보기술공학부 김 희 자

6 소스 코드 분석 : scull_ioctl() 1/5
int scull_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { int err = 0, tmp; int ret = 0; if (_IOC_TYPE(cmd) != SCULL_IOC_MAGIC) return -ENOTTY; if (_IOC_NR(cmd) > SCULL_IOC_MAXNR) return -ENOTTY; if (_IOC_DIR(cmd) & _IOC_READ) err = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd)); else if (_IOC_DIR(cmd) & _IOC_WRITE) err = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd)); if (err) return -EFAULT; 순천향대학교 정보기술공학부 김 희 자

7 소스 코드 분석 : scull_ioctl() 2/5
switch(cmd) { case SCULL_IOCRESET: scull_quantum = SCULL_QUANTUM; scull_qset = SCULL_QSET; break; case SCULL_IOCSQUANTUM: /* Set: arg points to the value */ if (! capable (CAP_SYS_ADMIN)) return -EPERM; ret = __get_user(scull_quantum, (int *)arg); case SCULL_IOCTQUANTUM: /* Tell: arg is the value */ scull_quantum = arg; case SCULL_IOCGQUANTUM: /* Get: arg is pointer to result */ ret = __put_user(scull_quantum, (int *)arg); 순천향대학교 정보기술공학부 김 희 자

8 소스 코드 분석 : scull_ioctl() 3/5
case SCULL_IOCQQUANTUM: /* Query: return it (it's positive) */ return scull_quantum; case SCULL_IOCXQUANTUM: /* eXchange: use arg as pointer */ if (! capable (CAP_SYS_ADMIN)) return -EPERM; tmp = scull_quantum; ret = __get_user(scull_quantum, (int *)arg); if (ret == 0) ret = __put_user(tmp, (int *)arg); break; case SCULL_IOCHQUANTUM: /* sHift: like Tell + Query */ scull_quantum = arg; return tmp; 순천향대학교 정보기술공학부 김 희 자

9 소스 코드 분석 : scull_ioctl() 4/5
case SCULL_IOCSQSET: if (! capable (CAP_SYS_ADMIN)) return -EPERM; ret = __get_user(scull_qset, (int *)arg); break; case SCULL_IOCTQSET: scull_qset = arg; case SCULL_IOCGQSET: ret = __put_user(scull_qset, (int *)arg); case SCULL_IOCQQSET: return scull_qset; 순천향대학교 정보기술공학부 김 희 자

10 소스 코드 분석 : scull_ioctl() 5/5
case SCULL_IOCXQSET: if (! capable (CAP_SYS_ADMIN)) return -EPERM; tmp = scull_qset; ret = __get_user(scull_qset, (int *)arg); if (ret == 0) ret = put_user(tmp, (int *)arg); break; case SCULL_IOCHQSET: scull_qset = arg; return tmp; 순천향대학교 정보기술공학부 김 희 자

11 scull ioctl 예제 변경 및 실행 1/2 #include <stdio.h>
#include <fcntl.h> #include "/usr/src/linux/include/asm/ioctl.h" #define SCULL_IOC_MAGIC 'k' #define SCULL_IOCTQUANTUM _IO(SCULL_IOC_MAGIC, 3) #define SCULL_IOCGQUANTUM _IOR(SCULL_IOC_MAGIC, 5, quantum) int main(int argc, char *argv[]) { int fd, n; int quantum = 0, read_quantum = 0; if(argc > 1) quantum = atoi(argv[1]); fd = open("/dev/scull1", O_RDWR, 0); 순천향대학교 정보기술공학부 김 희 자

12 scull ioctl 예제 변경 및 실행 2/2 // 커널의 퀀텀 크기 변경하기
if(!ioctl(fd, SCULL_IOCTQUANTUM, quantum)) printf("write quantum : %d\n", quantum); else printf("write quantum error\n"); // 커널의 퀀텀 크기 읽어오기 (변경 확인) if(!ioctl(fd, SCULL_IOCGQUANTUM, &read_quantum)) printf("read quantum: %d\n", read_quantum); printf("!! Something must be wrong\n"); return 0; } // 실행 결과 scull]# ./myioctl 2000 write quantum : 2000 read quantum: 2000 순천향대학교 정보기술공학부 김 희 자

13 블로킹 sleepy 예제 순천향대학교 정보기술공학부 김 희 자

14 sleepy 실행 1/2 // 컴파일 misc-modules]# gcc -Wall -D__KERNEL__ -DMODULE -I/usr/src/linux/include -O2 -I.. -c -o sleepy.o sleepy.c // 모듈 적재 misc-modules]# /sbin/insmod sleepy.o // 모듈 적재 확인 misc-modules]# more /proc/modules sleepy (unused) scull …… // 디바이스 드라이버 파일 주번호 확인 misc-modules]# more /proc/devices Character devices: 1 mem 2 pty ... 253 sleepy 254 scull 순천향대학교 정보기술공학부 김 희 자

15 sleepy 실행 2/2 // 디바이스 노드 만들기
misc-modules]# mknod /dev/sleepy c 253 0 misc-modules]# ls -l /dev/sleepy crw-r--r root root , 월 12 20:24 /dev/sleepy // sleepy_read 실행 misc-modules]# cat /dev/sleepy > test.out & [1] 21917 // sleepy_write 실행 misc-modules]# ls > /dev/sleepy [1]+ Done cat /dev/sleepy >test.out misc-modules]# tail /var/log/messages Apr 12 23:01:26 UPnP1 kernel: sleepy_read Apr 12 23:01:34 UPnP1 kernel: write Apr 12 23:01:34 UPnP1 kernel: sleep awoken // ctrl+c를 누를 때 인터럽트에 의해 종료되는 경우  수면 상태에서 바로 빠져 나옴 misc-modules]# cat /dev/sleepy > test.out misc-modules]# 순천향대학교 정보기술공학부 김 희 자

16 소스 코드 분석 : sleepy_init()
int sleepy_major=0; struct file_operations sleepy_fops = { read: sleepy_read, write: sleepy_write, }; // sleepy.o 모듈 적재시 실행 int sleepy_init(void) { int result; SET_MODULE_OWNER(&sleepy_fops); /* * Register your major, and accept a dynamic number */ result = register_chrdev(sleepy_major, "sleepy", &sleepy_fops); if (result < 0) return result; if (sleepy_major == 0) sleepy_major = result; /* dynamic */ return 0; } 순천향대학교 정보기술공학부 김 희 자

17 소스 코드 분석 : read(), write()
DECLARE_WAIT_QUEUE_HEAD(wq); // 대기 큐가 정적으로 선언된 경우 초기화 // /dev/sleepy 노드에 데이터를 읽는 경우 실행 ssize_t sleepy_read (struct file *filp, char *buf, size_t count, loff_t *pos) { printk(KERN_DEBUG "process %i (%s) going to sleep\n", current->pid, current->comm); interruptible_sleep_on(&wq); printk(KERN_DEBUG "awoken %i (%s)\n", current->pid, current->comm); return 0; /* EOF */ } // /dev/sleepy 노드에 데이터를 쓰는 경우 실행 ssize_t sleepy_write (struct file *filp, const char *buf, size_t count, loff_t *pos) printk(KERN_DEBUG "process %i (%s) awakening the readers...\n", wake_up_interruptible(&wq); return count; /* succeed, to avoid retrial */ 순천향대학교 정보기술공학부 김 희 자

18 비블록킹 nbtest 예제 순천향대학교 정보기술공학부 김 희 자

19 nbtest 실행 [root@UPnP1 misc-progs]# cc nbtest.c -o nbtest
misc-progs]# ./nbtest 3 test 순천향대학교 정보기술공학부 김 희 자

20 nbtest 소스 분석 char buffer[4096]; int main(int argc, char **argv) {
int delay=1, n, m=0; if (argc>1) delay=atoi(argv[1]); fcntl(0, F_SETFL, fcntl(0,F_GETFL) | O_NONBLOCK); /* stdin */ fcntl(1, F_SETFL, fcntl(1,F_GETFL) | O_NONBLOCK); /* stdout */ while (1) { n=read(0, buffer, 4096); if (n>=0) m=write(1, buffer, n); if ((n<0 || m<0) && (errno != EAGAIN)) break; sleep(delay); } perror( n<0 ? "stdin" : "stdout"); exit(1); 순천향대학교 정보기술공학부 김 희 자


Download ppt "5장. Enhanced Char Driver Operations 과제"

Similar presentations


Ads by Google