rt-thread icon indicating copy to clipboard operation
rt-thread copied to clipboard

[Feature] 请问在RT-Smart中,为什么使用mmap完成文件映射时会显示权限不足,可能的问题有哪些

Open WangShuoran opened this issue 9 months ago • 3 comments

Describe problem solved by the proposed feature

我使用mmap()的例程如下:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>

int main(int argc, char *argv[]) {

#ifdef _SC_MAPPED_FILES
    long result = sysconf(_SC_MAPPED_FILES);
    if (result == -1) {
        perror("sysconf");
        printf("可能系统不支持内存映射\n");
    } else {
        printf("系统支持内存映射,sysconf(_SC_MAPPED_FILES) 返回 %ld\n", result);
    }
#else
    printf("_SC_MAPPED_FILES 未定义,可能系统不支持内存映射\n");
#endif

    if (argc < 2) {
        fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    const char *filename = argv[1];

    // 打开文件
    int fd = open(filename, O_RDONLY);
    if (fd == -1) {
        perror("open");
        exit(EXIT_FAILURE);
    }

    // 获取文件大小
    struct stat sb;
    if (fstat(fd, &sb) == -1) {
        perror("fstat");
        close(fd);
        exit(EXIT_FAILURE);
    }

    size_t length = sb.st_size;

    // 将文件映射到内存
    void *addr = mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, 0);
    if (addr == MAP_FAILED) {
        perror("mmap");
        close(fd);
        exit(EXIT_FAILURE);
    }

    // 关闭文件描述符
    close(fd);

    // 读取并输出文件内容
    write(STDOUT_FILENO, addr, length);

    // 解除内存映射
    if (munmap(addr, length) == -1) {
        perror("munmap");
        exit(EXIT_FAILURE);
    }

    return 0;
}

得到的结果是如下结果

Image

我找了ChatGPT分析可能的问题: 在使用 mmap 函数时遇到 "Operation not permitted" 错误,可能由以下原因导致:

内核配置限制:某些系统内核启用了 CONFIG_STRICT_DEVMEM 配置选项,该选项限制用户空间对物理内存的直接访问,以增强系统安全性。当该选项启用时,尝试通过 /dev/mem 访问物理内存可能会被拒绝,导致 "Operation not permitted" 错误。

文件权限不足:尝试映射的文件可能具有限制性的权限设置,导致当前用户无法执行所需的内存映射操作。

映射类型与文件权限不匹配:如果尝试以可写方式映射一个只读文件,可能会导致权限错误。在这种情况下,使用 MAP_PRIVATE 标志而非 MAP_SHARED 可能会绕过此限制。

可能的解决方案:

检查并修改内核配置:如果系统启用了 CONFIG_STRICT_DEVMEM,可以考虑重新编译内核,将该选项禁用。这需要在内核配置文件中将 CONFIG_STRICT_DEVMEM 设置为 n,然后重新编译并安装内核。

调整文件权限:确保被映射的文件具有适当的权限,使当前用户能够执行所需的内存映射操作。这可能需要修改文件的权限设置或以具有更高权限的用户身份运行程序。

匹配映射类型与文件权限:如果文件是只读的,尝试使用 MAP_PRIVATE 标志进行映射,以避免权限冲突。

其中文件权限和映射类型与文件权限不匹配这两个我都查看了,没有问题。想问是不是第一个问题导致的?如何排查?

并且希望问一下RT-Smart是支持mmap()和munmap()吗?

Describe your preferred solution

No response

Describe possible alternatives

No response

WangShuoran avatar Mar 20 '25 05:03 WangShuoran

需要给出详细信息,例如哪个架构,哪个版本,针对文件的mmap,还包括文件系统是否支持了mmap。mmap部分,一些点也可以以调试方式,从用户态调试到内核态中,查看最终的问题。

BernardXiong avatar Mar 24 '25 15:03 BernardXiong

OK,谢谢熊大,我使用的是K230支持您系统的RTT版本,在他们的平台上不支持这个功能。 根据您说的信息,在咱们的系统中是已经默认支持了是吗?因为我在调用其他类似popen()/pread()/pwrite()也在这个平台不支持。 综合这些问题都是K230原厂的问题是吗?

WangShuoran avatar Apr 05 '25 03:04 WangShuoran

是什么文件系统呢?应该说不是系统不支持,而是文件系统是否支持。

BernardXiong avatar Apr 09 '25 02:04 BernardXiong