3.10 이후의 커널 버전에서의 struct proc_dir_entry 사용법에 대한 질문입니다.

tyburn의 이미지

현재 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" );
tyburn의 이미지

#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
 
static int hello_proc_show(struct seq_file *m, void *v) {
  seq_printf(m, "Hello proc!\n");
  return 0;
}
 
static int hello_proc_open(struct inode *inode, struct  file *file) {
  return single_open(file, hello_proc_show, NULL);
}
 
static const struct file_operations hello_proc_fops = {
  .owner = THIS_MODULE,
  .open = hello_proc_open,
  .read = seq_read,
  .llseek = seq_lseek,
  .release = single_release,
};
 
static int __init hello_proc_init(void) {
  proc_create("hello_proc", 0, NULL, &hello_proc_fops);
  return 0;
}
 
static void __exit hello_proc_exit(void) {
  remove_proc_entry("hello_proc", NULL);
}
 
MODULE_LICENSE("GPL");
module_init(hello_proc_init);
module_exit(hello_proc_exit);

이러한 모듈 코드입니다. 이 모듈을 그대로 코딩하고 cat 명령을 해 보면, 정상적으로 hello proc!이 출력되는 것을 확인하였습니다.

seq_file이라는 생소한 헤더 파일이 쓰였는데, 이건 한 숨 자고 일어나서 살펴봐야겠군요. ㅜㅜ

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.