본문 바로가기
C++ 200제/코딩 IT 정보

리눅스 PROC 3. 파일 시스템 프로그래밍 예제

by vicddory 2017. 3. 20.

리눅스 PROC 3. 파일 시스템 프로그래밍 예제


4-5. Proc 파일 시스템을 이용한 예제

4-5 예제 1 : Helloword(1)


리눅스 PROC 파일 시스템 프로그래밍 예제 HelloWorld.txt


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
#include <linux/module.h>    /* Specifically, a module */
#include <linux/kernel.h>    /* We're doing kernel work */
#include <linux/proc_fs.h>    /* Necessary because we use the proc fs */
 
#define procfs_name "helloworld"
 
struct proc_dir_entry *Our_Proc_File;
 
int procfile_read(char *buffer, char **buffer_location,
                  off_t offset, int buffer_length, int *eof, void *data)
{
    int ret;
    
    printk(KERN_INFO "procfile_read (/proc/%s) called\n", procfs_name);
    
    if (offset > 0) {
        /* we have finished to read, return 0 */
        ret  = 0;
    } else {
        /* fill the buffer, return the buffer size */
        ret = sprintf(buffer, "HelloWorld!\n");
    }
 
    return ret;
}
 
int init_module()
{
    Our_Proc_File = create_proc_entry(procfs_name, 0644NULL);
    
    if (Our_Proc_File == NULL) {
        remove_proc_entry(procfs_name, &proc_root);
        printk(KERN_ALERT "Error: Could not initialize /proc/%s\n", procfs_name);
        return -ENOMEM;
    }
 
    Our_Proc_File->read_proc = procfile_read;
    Our_Proc_File->owner      = THIS_MODULE;
    Our_Proc_File->mode      = S_IFREG | S_IRUGO;
    Our_Proc_File->uid      = 0;
    Our_Proc_File->gid      = 0;
    Our_Proc_File->size      = 37;
 
    printk(KERN_INFO "/proc/%s created\n", procfs_name);    
    return 0;    /* everything is ok */
}
 
void cleanup_module()
{
    remove_proc_entry(procfs_name, &proc_root);
    printk(KERN_INFO "/proc/%s removed\n", procfs_name);
}
cs

helloworld - proc file 생성

1. procfs1.c 소스 –make-> procfs1.ko

2. inmod procfs.ko

3. /proc/helloworld   proc file 생성


proc_예제_-_proc_file_생성[리눅스 PROC 파일 시스템 프로그래밍 예제] proc file 생성


hellworld - proc file read

int procfile_read  => sprintf(buffer, "HelloWorld!\n");


proc_예제_-_proc_file_읽기[Linux PROC Programming] proc file 읽기


4-5. 예제 2 : Scull (char device)

scull 디바이스의 메모리 디바이스 구조 정보를 확인하기 위한 proc file 생성


scull_creat_proc

읽기 전용 proc 파일을 생성

scull_read_procmem 함수를 읽기 함수의 callback 함수로 지정


1
2
3
4
static void scull_create_proc(void){    
    create_proc_read_entry("scullmem"0 /* default mode */NULL /* parent dir */
                scull_read_procmem,    NULL /* client data */);
}
cs

scull_read_procmem

scull 디바이스의 메모리 디바이스 구조 정보를 읽어 들인다

- scull 디바이스별 qset, quantum, 총사이즈

- qset 주소, qset의 data 주소

- qset->data에 저장된 각 quantum 주소


scull_read_procmem


리눅스 PROC 파일 시스템 프로그래밍 예제 : scull_read_procmem.txt


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
int scull_read_procmem(char *buf, char **start, off_t offset, int count, int *eof, void *data)
{
     int i, j, len = 0;
     int limit = count - 80/* Don't print more than this */
 
     for (i = 0; i < scull_nr_devs && len <= limit; i++) {
 
    struct scull_dev *= &scull_devices[i];
    struct scull_qset *qs = d->data;
 
    if (down_interruptible(&d->sem))  // 세마포어를 얻지 못하면 휴면
        return -ERESTARTSYS;
    len += sprintf(buf+len,"\nDevice %i: qset %i, q %i, sz %li\n", i, d->qset, d->quantum, d->size);
 
    for (; qs && len <= limit; qs = qs->next) { /* scan the list */
        len += sprintf(buf + len, "  item at %p, qset at %p\n", qs, qs->data);
        if (qs->data && !qs->next) /* dump only the last item */
            for (j = 0; j < d->qset; j++) {
                       if (qs->data[j])
                len += sprintf(buf + len,"    % 4i: %8p\n",
                             j, qs->data[j]);
            }
        }
        up(&scull_devices[i].sem);
    }
 
    *eof = 1;
 
    return len;
}
cs


scull_remove_proc

scullmem의 proc파일을 제거


1
2
3
static void scull_remove_proc(void){    /* no problem if it was not registered */
    remove_proc_entry("scullmem"NULL /* parent dir */);    
}
cs


실습 : make

#define SCULL_DEBUG  // main.c 코드에 추가하여 정의

make -> ‘scullmem’ proc file 생성됨


proc_예제_-_make[Linux PROC Programming] make

실습 : procfile 확인

/proc 폴더에 scullmem 파일 생성


proc_예제_-_scullmem_파일_생성[리눅스 PROC 파일 시스템 프로그래밍 예제] scullmem 파일 생성


Scullmem 개요


Scullmem_개요[Linux PROC Programming] Scullmem 개요


실습 : scullmem의 사용


scull 디바이스에 쓴 후 scullmem를 읽기


scullmem의_사용[Linux PROC Programming] scullmem의 사용

scullmem를 이용한 응용프로그램


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
 
char buffer[1024= "Writing to scull device!!!\n";
char readBuff[1024];
 
int main(int argc, char *argv[])
{
    int fd,i,n=0;
 
    fd=open("/dev/scull1",O_WRONLY,0);
 
    for(i=0;i<1200;i++)
        n += write(fd,buffer,strlen(buffer)); /*1024 * 1500 크기에 데이터를 scull에 기록*/
 
    printf("Size of writing to sucll : %d \n\n",n);  /* 기록한 총사이즈
    fd = open("/proc/scullmem",0,0);    /*scullmem proc file 열기
    while((n=read(fd,readBuff,1024);    /*proc file 읽기
    printf("%s",readBuff);    /*읽은 데이터를 콘솔에 디스플레이
    
    close(fd);        /*파일 닫기
    return 0;
}
cs


응용프로그램의 실행

다음과 같이 응용프로그램에서 일반 파일을 열듯 사용한다.


/proc 하위에 생성되있는 프로세서, 메모리, 디바이스 정보 등의 proc file도 사용자가 응용프로그램에서 구조체를 정의 해놓고, scanf()등을 사용하여 해당 정보를 간단하게 추출하고 저장하여 사용한다.


proc_예제_-_파일_실행[Linux PROC Programming] 파일 실행



리눅스 PROC 3. 파일 시스템 프로그래밍 예제

댓글