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");

cs





출처 : 인지소프트웨어 기술포럼 ( 전유진 강사님 수업자료)

'임베디드 > 디바이스 드라이버' 카테고리의 다른 글

Misc 디바이스 드라이버1  (0) 2017.12.26
디바이스 드라이버 구조  (0) 2017.12.26
SYSFS  (1) 2017.12.26
GPIO 제어  (0) 2017.12.26
커널 모듈 구현  (0) 2017.12.21

+ Recent posts