3.10 이후의 커널 버전에서의 struct proc_dir_entry 사용법에 대한 질문입니다.
현재 proc 파일 시스템 부분을 진행하고 있습니다만,
제가 참고하고있는 책(한빛미디어, IT EXPERT : 리눅스 커널 프로그래밍, 2006)에서 다루는 버전은 2.6버전이고 현재 kernel.org에서 구한 버전은 4.3.3이라서
차이가 큽니다. 때문에 어차피 배울 거 변경 사항이 있으면 그건 구글링으로 찾아본다는 방침으로 지금까지 해왔습니다만, 구글링으로도 제대로 된 답을 제 능력으로는 찾을 수 없었기에 질문드립니다.
3.10 버전 이후에서는 create_proc_entry 함수가 아예 삭제되고, proc_create로 대체되었으며, linux/proc_fs.h에서 정의되어있던 struct proc_dir_entry의 정의가 fs/proc/internal.h로 이동되었다는 사실까진 알아냈습니다.
// 선언 static struct proc_dir_entry *simple_proc = NULL; static char* buf[100]; ... // file_operations static struct file_operations simple_fops = { .owner = THIS_MODULE, .read = my_read, .write = my_write }; // create simple_proc = proc_create( "simple", 0, NULL, &simple_fops ); /* 구 버전에서의 지정 simple_proc->data = buf; simple_proc->read_proc = my_read; */ ...
구 버전 방식으로 직접 지정하게 되면, dereferencing pointer to incomplete type 에러를 '지정' 섹션의 두 줄에서 출력하며 빌드되지 않습니다.
internal.h를 직접 include 하면 빌드가 가능하겠지만, 일부러 숨겨 놓은 것인데 그렇게 include하라고 만들어 놓았을 것 같지는 않으니 분명 다른 사용법이 있을 텐데, 그걸 찾지 못하고 있습니다.
proc_create 함수가 4번째 인수로 file_operations 구조체를 요구하는 점에서 착안하여 file_operations 구조체를 만들어 넣어줬습니다만, data는 여전히 지정할 방법을 모르겠습니다.
혹시 알고 계시는 분 계시면 친절하게 답변 부탁드립니다.
참고를 위하여 코드를 한 번 올려보겠습니다.
// 입력한 데이터를 그대로 반환하는 simple proc 파일 #include <linux/init.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/slab.h> #include <linux/proc_fs.h> // procfs 관련 자료구조 #include <asm/uaccess.h> static struct proc_dir_entry *simple_proc = NULL; static char buf[100]; // /proc/simple을 읽을 때 호출되는 my_read static int my_read( char* page, char **start, off_t off, int count, int *eof, void* data ) /* * 매개변수 설명 * page : 전달할 데이터를 저장할 공간 start : 스트림 데이터의 시작 위치, 대개는 다루지 않으므로 쓰지 않는다. off : 현재 처리중인 파일의 현재 위치 count : 버퍼의 크기를 바이트 단위로 지정 eof : 파일의 끝을 설정 */ { int len; len = sprintf( page, "[Msg] %s\n", (char *) data ); // page에, data의 내용을 출력한다. data는 앞에서 선언한 buf와 연결될 것. // page는 각 proc 항목에 할당된 데이터 공간, page 단위(4096byte)로 할당. // echo 효과이므로, 그대로 출력하는 것으로 충분. *eof = 1; // 데이터 처리 완료로 설정 return len; } // my_write static int my_write( struct file *file, const char *buffer, unsigned long count, void *data ) { char *kernel_data; kernel_data = (char*) data; copy_from_user( kernel_data, buffer, count ); // NULL 문자 표시 kernel_data[count] = '\0'; if( kernel_data[ count - 1 ] == '\n' ) kernel_data[ count - 1 ] = '\0'; return count; } static struct file_operations simple_fops = { .owner = THIS_MODULE, .read = my_read, .write = my_write }; int __init simple_init( void) { simple_proc = proc_create( "simple", 0, NULL, &simple_fops ); if( simple_proc == NULL ) return -ENOMEM; // error : NO MEMORY return 0; } void __exit simple_exit(void) { remove_proc_entry( "simple", NULL ); // /proc/simple 삭제 } module_init( simple_init ); module_exit( simple_exit ); MODULE_LICENSE( "GPL" );
조금 더 찾아보니, 간단한 코드 하나는 찾을 수 있었습니다.
이러한 모듈 코드입니다. 이 모듈을 그대로 코딩하고 cat 명령을 해 보면, 정상적으로 hello proc!이 출력되는 것을 확인하였습니다.
seq_file이라는 생소한 헤더 파일이 쓰였는데, 이건 한 숨 자고 일어나서 살펴봐야겠군요. ㅜㅜ
댓글 달기