scull device 사용 예 강서일(20059032) 최정욱(20059033)
목차 소스 코드 분석 예제 실행 및 결과 분석 Makefile scull.h main.c scull_load scull_init_module, scull_open, scull_write, scull_read scull_load scull_unload 예제 실행 및 결과 분석
소스 코드 분석 : Makefile main.c main.o pipe.c Makefile pipe.o access.c scull.h main.c main.o pipe.c Makefile pipe.o access.c access.o
소스 코드 분석 : scull.h #define SCULL_MAJOR 0 /* dynamic major by default */ #define SCULL_QUANTUM 4000 #define SCULL_QSET 1000 typedef struct Scull_Dev { void **data; struct Scull_Dev *next; /* next listitem */ int quantum; /* the current quantum size */ int qset; /* the current array size */ unsigned long size; devfs_handle_t handle; /* only used if devfs is there */ unsigned int access_key; /* used by sculluid and scullpriv */ struct semaphore sem; /* mutual exclusion semaphore */ } Scull_Dev; #define TYPE(dev) (MINOR(dev) >> 4) /* high nibble */ #define NUM(dev) (MINOR(dev) & 0xf) /* low nibble */
소스 코드 분석 : main.c 분석 대상 함수 int scull_init_module int scull_open ssize_t scull_write ssize_t scull_read
소스 코드 분석 : scull_init_module() int scull_init_module(void) { /////////////생략///////////// result = register_chrdev(scull_major, "scull", &scull_fops); if (result < 0) { printk(KERN_WARNING "scull: can't get major %d\n",scull_major); return result; } if (scull_major == 0) scull_major = result; /* dynamic */ return 0; /* succeed */
소스 코드 분석 : scull_open() int scull_open(struct inode *inode, struct file *filp) { Scull_Dev *dev; /* device information */ int num = NUM(inode->i_rdev); int type = TYPE(inode->i_rdev); if (!filp->private_data && type) { if (type > SCULL_MAX_TYPE) return -ENODEV; filp->f_op = scull_fop_array[type]; return filp->f_op->open(inode, filp); /* dispatch to specific open */ } if ( (filp->f_flags & O_ACCMODE) == O_WRONLY) { if (down_interruptible(&dev->sem)) { MOD_DEC_USE_COUNT; return -ERESTARTSYS; scull_trim(dev); /* ignore errors */ up(&dev->sem); return 0; /* success */
소스 코드 분석 : scull_trim() int scull_trim(Scull_Dev *dev) { Scull_Dev *next, *dptr; int qset = dev->qset; /* "dev" is not-null */ int i; for (dptr = dev; dptr; dptr = next) { /* all the list items */ if (dptr->data) { for (i = 0; i < qset; i++) if (dptr->data[i]) kfree(dptr->data[i]); kfree(dptr->data); dptr->data=NULL; } next=dptr->next; if (dptr != dev) kfree(dptr); /* all of them but the first */ dev->size = 0; dev->quantum = scull_quantum; dev->qset = scull_qset; dev->next = NULL; return 0;
소스 코드 분석 : scull_write()(1/3) ssize_t scull_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos) { Scull_Dev *dev = filp->private_data; Scull_Dev *dptr; int quantum = dev->quantum; int qset = dev->qset; int itemsize = quantum * qset; int item, s_pos, q_pos, rest; ssize_t ret = -ENOMEM; if (down_interruptible(&dev->sem)) return -ERESTARTSYS;
소스 코드 분석 : scull_write()(2/3) item = (long)*f_pos / itemsize; rest = (long)*f_pos % itemsize; s_pos = rest / quantum; q_pos = rest % quantum; dptr = scull_follow(dev, item); if (!dptr->data) { dptr->data = kmalloc(qset * sizeof(char *), GFP_KERNEL); if (!dptr->data) goto out; memset(dptr->data, 0, qset * sizeof(char *)); } if (!dptr->data[s_pos]) { dptr->data[s_pos] = kmalloc(quantum, GFP_KERNEL); if (!dptr->data[s_pos])
소스 코드 분석 : scull_write()(3/3) if (count > quantum - q_pos) count = quantum - q_pos; if (copy_from_user(dptr->data[s_pos]+q_pos, buf, count)) { ret = -EFAULT; goto out; } *f_pos += count; ret = count; if (dev->size < *f_pos) dev-> size = *f_pos; out: up(&dev->sem); return ret;
소스 코드 분석 : scull_load module="scull" device="scull" mode="664" /sbin/insmod -f ./$module.o $* || exit 1 major=`cat /proc/devices | awk "\\$2==\"$module\" {print \\$1}"` rm -f /dev/${device}[0-3] mknod /dev/${device}0 c $major 0 mknod /dev/${device}1 c $major 1 mknod /dev/${device}2 c $major 2 mknod /dev/${device}3 c $major 3 ln -sf ${device}0 /dev/${device} chgrp $group /dev/${device}[0-3] chmod $mode /dev/${device}[0-3] ////////////////////////이하 생략////////////////////////
소스 코드 분석 : scull_unload module="scull" device="scull" /sbin/rmmod $module $* || exit 1 rm -f /dev/${device} /dev/${device}[0-3] rm -f /dev/${device}priv rm -f /dev/${device}pipe /dev/${device}pipe[0-3] rm -f /dev/${device}single rm -f /dev/${device}uid rm -f /dev/${device}wuid
예제 실행 및 결과 분석(1/3)
예제 실행 및 결과 분석(2/3)
예제 실행 및 결과 분석(3/3)