2012. 11. 6. 15:41

펌웨어에서 디바이스 제어 시 read() write() 만으로 해결 안되는 문제에 도달했을때 우리는 ioctl() 을 사용하여 해결 할수 있다.

 

[출처 : http://wiki.kldp.org/KoreanDoc/html/EmbeddedKernel-KLDP/device-understanding.html]

 

모듈은 등록될 때 디바이스 번호를 등록하고 이와 함께 file_operations 라는 구조체를 커널에 알려준다. file_operations는 include/linux/fs.h에 정의되어 있고 다음과 같다.

/*
 * NOTE:
 * read, write, poll, fsync, readv, writev can be called
 *   without the big kernel lock held in all filesystems.
 */
struct file_operations {
	struct module *owner;
	loff_t (*llseek) (struct file *, loff_t, int);
	ssize_t (*read) (struct file *, char *, size_t, loff_t *);
	ssize_t (*write) (struct file *, const char *, size_t, loff_t *);
	int (*readdir) (struct file *, void *, filldir_t);
	unsigned int (*poll) (struct file *, struct poll_table_struct *);
	int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
	int (*mmap) (struct file *, struct vm_area_struct *);
	int (*open) (struct inode *, struct file *);
	int (*flush) (struct file *);
	int (*release) (struct inode *, struct file *);
	int (*fsync) (struct file *, struct dentry *, int datasync);
	int (*fasync) (int, struct file *, int);
	int (*lock) (struct file *, int, struct file_lock *);
	ssize_t (*readv) (struct file *, const struct iovec *, unsigned long, loff_t *);
	ssize_t (*writev) (struct file *, const struct iovec *, unsigned long, loff_t *);
	ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
	unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
};

 

 

 

 

 

int main()
{
int fd; char buf[256];

fd = open("/dev/hdd_info", O_RDWR);
ioctl(fd, 0, buf);

printf("buf : %s\n", buf);
close(fd);
return 0;
}

 

ioctl로 장치에게 동작 명령 내리고 출력하고 다시 장치를 닫는 코드이다.

 

ioctl은 장치에게 그냥 이미 정의되어있는 명령을 내리는(함수를 호출하는) 놈이라는 것을 알게 되었다

대신 장치를 우선 open으로 열고 인자로 그 file descriptor랑 가운데 request number를 넣어서 어떤 함수를 호출할지를 정하여 호출한다.

Posted by k1rha