proc 파일 시스템
- procfs를 통해 커널 정보를 사용자 영역에서 접근
1. 커널이 관리하는 모든 프로세스(응용프로그램) 정보와 시스템 정보 제공.
* 프로세스 상태. CPU사용률, 인터럽트, 네트워크 패킷 전송량, 적재된 모듈 등.
2. 모듈을 구현할 때 proc 파일시스템 관련 커널 API를 통해 사용자 영역과 통신 가능.
* linux/proc_fs.h
- procfs를 사용하는 이유는?
1. 파일 시스템의 오버헤드를 줄일 수 있음
* 일반적인 파일시스템은 inode와 superblocks과 같은 객체를 통해 관리.
2. 물리적인 파일시스템 장치를 필요로 하지 않음.
*proc는 커널 메모리에서 동작하는 가상 파일시스템으로 커널에서 직접 관리.
3. 죄적화된 파일 작업 수행
* /proc 디렉터리에 일반 파일처럼 보이므로 스크립트에서도 참조 가능.
proc 파일시스템 -proc 자료구조
- proc_dir_entry 구조체
1. /proc 경로에 생성되는 디렉터리 또는 파일을 관리하기 위한 자료구조.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | struct proc_dir_entry { ... const char *name; mode_t mode; ... struct proc_dir_entry *next, *parent, *subdir; void *data; ... struct file_operations * proc_fops; }; | cs |
* name : 파일이름
* mode : 파일이 생성될 때 부여되는 권한
* next, parent, subdir : 연결 리스트로 관리하는 /proc 디렉터리
* data : proc 파일에서 읽은 데이터 반환
* proc_fops : read/ write 콜백 함수를 설정하여 모듈과 응용프로그램 사이 데이터 교환.
proc 파일시스템 - proc 파일 생성 및 제거
- proc 파일 생성은 모듈을 적재할 때 실행되는 함수에서 구현
1. /proc에 파일 생성
* proc_create()
2. /proc에 하위 디렉터리를 생성 한 후 하위 디렉터리에 파일 생성
* proc_mkdir()
* proc_create()
- proc 파일 제거는 모듈을 제거할 때 실행되는 함수에서 구현
1. remove_proc_entry()
2. proc_mkdir(), proc_create()로 생성한 디렉터리와 파일 제거
procfs사용 예제
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | #include <linux/module.h> #include <linux/seq_file.h> #include <linux/proc_fs.h> #include <asm/uaccess.h> #define MODULE_NAME "mod_procfs" #define FOO_FILE "foo" #define FOO_LEN 8 struct data_t { char name[FOO_LEN + 1]; char value[FOO_LEN + 1]; }foo_data; static struct proc_dir_entry *example_dir, *foo_file; static ssize_t write_foo(struct file *file, const char *buf, size_t count, loff_t *pos) { int len; len = (count > FOO_LEN) ? FOO_LEN : count; if (copy_from_user(foo_data.value, buf, len)) return -EFAULT; foo_data.value[len] = 0x00; printk("%s count:%d\n", foo_data.value, count); return len; } static int foo_proc_show(struct seq_file *m, void *v) { // printk("%s\n", (char *)m->private); seq_printf(m, "%s = %s\n", foo_data.name, foo_data.value); return 0; } static int foo_proc_open(struct inode *inode, struct file *file) { // return single_open(file, foo_proc_show, "private_data"); return single_open(file, foo_proc_show, NULL); } // file_operations 구조체 초기화 // c99 버전부터 아래와 같은 방식으로 초기화 가능 static const struct file_operations foo_proc_fops = { .owner = THIS_MODULE, //파일을 열때 불려지는 함수 .open = foo_proc_open, // 파일을 읽을때 불려지는 함수 .read = seq_read, // 파일을 쓸때 불려지는 함수 .write = write_foo, .llseek = seq_lseek, .release = single_release, }; static int mod_procfs_init(void) { example_dir = proc_mkdir(MODULE_NAME, NULL); if(example_dir == NULL){ printk("example_dir: error proc_mkdir\n"); return -EEXIST; } strcpy(foo_data.name, "foo"); strcpy(foo_data.value, "dream"); // procfs 파일 생성 foo_file = proc_create(FOO_FILE, 0646, example_dir, &foo_proc_fops); //파일이름,퍼미션, 디렉토리, file_operations 구조체 if(foo_file == NULL){ printk("foo_file: error \n"); return -EEXIST; } printk("%s\n", __FUNCTION__); return 0; } static void mod_procfs_exit(void){ // 디렉토리, 파일 삭제 remove_proc_entry(FOO_FILE, example_dir); // ^ 파일이 위치하고있는 디렉토리 remove_proc_entry(MODULE_NAME, NULL); printk("%s\n", __FUNCTION__); } module_init(mod_procfs_init); module_exit(mod_procfs_exit); MODULE_AUTHOR("PlanX Studio"); MODULE_DESCRIPTION("mod_procfs"); MODULE_LICENSE("Dual BSD/GPL"); |
출처 : 인지소프트웨어 기술포럼 ( 전유진 강사님 수업자료)
'임베디드 > 디바이스 드라이버' 카테고리의 다른 글
Misc 디바이스 드라이버1 (0) | 2017.12.26 |
---|---|
디바이스 드라이버 구조 (0) | 2017.12.26 |
SYSFS (1) | 2017.12.26 |
GPIO 제어 (0) | 2017.12.26 |
커널 모듈 구현 (0) | 2017.12.21 |