program tip

Linux 커널 모듈 내에서 파일 읽기 / 쓰기

radiobox 2020. 9. 10. 07:35
반응형

Linux 커널 모듈 내에서 파일 읽기 / 쓰기


커널에서 파일을 읽고 쓰면 안되는 이유에 대한 모든 토론을 알고 있습니다. 대신 / proc 또는 netlink사용 하여이를 수행하는 방법을 알고 있습니다. 어쨌든 읽기 / 쓰기를 원합니다. 또한 드라이빙 미 너트-커널에서 절대하지 말아야 할 일도 읽었습니다 .

그러나 문제는 2.6.30이 sys_read(). 오히려 SYSCALL_DEFINE3. 따라서 모듈에서 사용하면 다음과 같은 경고가 표시됩니다.

WARNING: "sys_read" [xxx.ko] undefined!
WARNING: "sys_open" [xxx.ko] undefined!

insmod링크가 올바르게 발생하지 않기 때문에 분명히 모듈을로드 할 수 없습니다.

질문 :

  • 2.6.22 이후 커널 내에서 읽고 쓰는 방법 ( 내 보낸 sys_read()/ sys_open()내 보내지 않음)?
  • 일반적으로 SYSCALL_DEFINEn()커널 내 에서 매크로 래핑 된 시스템 호출을 사용하는 방법은 무엇입니까?

가능하면 파일 I / O를 피해야합니다. 주요 아이디어는 "한 단계 더 깊게"가서 syscall 핸들러 대신 VFS 레벨 함수 를 직접 호출하는 것입니다.

다음을 포함합니다 :

#include <linux/fs.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
#include <linux/buffer_head.h>

파일 열기 (열기와 유사) :

struct file *file_open(const char *path, int flags, int rights) 
{
    struct file *filp = NULL;
    mm_segment_t oldfs;
    int err = 0;

    oldfs = get_fs();
    set_fs(get_ds());
    filp = filp_open(path, flags, rights);
    set_fs(oldfs);
    if (IS_ERR(filp)) {
        err = PTR_ERR(filp);
        return NULL;
    }
    return filp;
}

파일 닫기 (닫기와 유사) :

void file_close(struct file *file) 
{
    filp_close(file, NULL);
}

파일에서 데이터 읽기 (pread와 유사) :

int file_read(struct file *file, unsigned long long offset, unsigned char *data, unsigned int size) 
{
    mm_segment_t oldfs;
    int ret;

    oldfs = get_fs();
    set_fs(get_ds());

    ret = vfs_read(file, data, size, &offset);

    set_fs(oldfs);
    return ret;
}   

파일에 데이터 쓰기 (pwrite와 유사) :

int file_write(struct file *file, unsigned long long offset, unsigned char *data, unsigned int size) 
{
    mm_segment_t oldfs;
    int ret;

    oldfs = get_fs();
    set_fs(get_ds());

    ret = vfs_write(file, data, size, &offset);

    set_fs(oldfs);
    return ret;
}

동기화는 파일을 변경합니다 (fsync와 유사) :

int file_sync(struct file *file) 
{
    vfs_fsync(file, 0);
    return 0;
}

[편집] 원래는 최신 커널 버전에서 사라진 file_fsync 사용을 제안했습니다. 변경을 제안했지만 변경이 거부 된 가난한 사람 덕분입니다. 검토하기 전에 편집이 거부되었습니다.


Since version 4.14 of Linux kernel, vfs_read and vfs_write functions are no longer exported for use in modules. Instead, functions exclusively for kernel's file access are provided:

# Read the file from the kernel space.
ssize_t kernel_read(struct file *file, void *buf, size_t count, loff_t *pos);

# Write the file from the kernel space.
ssize_t kernel_write(struct file *file, const void *buf, size_t count,
            loff_t *pos);

Also, filp_open no longer accepts user-space string, so it can be used for kernel access directly (without dance with set_fs).

참고URL : https://stackoverflow.com/questions/1184274/read-write-files-within-a-linux-kernel-module

반응형