2017-08-31 77 views
5

假设您将2个DIMM插入Intel x86-64主板。所有内存交错(库和通道)被禁用。直接内存映射到DIMM

我想要做的是从Linux kernel(版本号4.11.11)保留其中一个DIMM的物理内存空间,并公开该应用程序的物理(保留)内存空间。 DIMM将而不是移到内存通道中。我怎么会这样做呢?这个过程会是什么?我是内核开发新手,可以使用指导。

我迄今发现:

  1. 从Linux内核保留内存,您可以指定memmap=nn[KMG]$ss[KMG]引导参数。此参数将特定内存标记为从ss到ss + nn的内存保留区域。

  2. mmap可用于在一个地址PA建立进程的地址空间之间的映射对于LEN字节由文件描述符表示的存储器对象法尔兹在偏移关闭对于len字节。

的保留内存之后,我假定一些字符设备驱动程序需要公开的保留内存给用户空间应用程序?思考?


更新

还应当指出的是,需要被保留的DIMM将在它自己的专用内存通道,并没有银行或信道交织将被启用。

+0

我看不出DIMM部分如何适合整个图像。无论如何,不​​会像'/ dev/mem'那样做吗?我不知道保留的内存是否会被这样的设备映射。 –

+0

@MargaretBloom关于DIMM的含义尚不清楚?我正在尝试保留内核使用的其中一个DIMM上的所有内存。明白了吗? '/ dev/mem'表示内核可以使用的所有内存,因此不一定代表我需要的内存。 – Jonathan

+0

如果标志arg中有任何未使用的位,您可以通过'mmap'的新标志来暴露它,即定义一个'MAP_RESERVED_DIMM'。 HugeTLBFS是另一种模式:一种特殊的文件系统,您可以将文件映射到映射关于后备内存的特殊映射。我不是Linux内部专家(只是一个感兴趣的业余爱好者),但是你也可以使用char或block设备。尤其是如果你只打算一次使用一个用户空间进程,否则你如何让他们找出哪些部分已经被映射了? –

回答

0

映射/dev/mem是简单的方法。我以前做过这个。该mmapkernel source实现:

static int mmap_mem(struct file *file, struct vm_area_struct *vma) 
{ 
    size_t size = vma->vm_end - vma->vm_start; 
    phys_addr_t offset = (phys_addr_t)vma->vm_pgoff << PAGE_SHIFT; 

    /* It's illegal to wrap around the end of the physical address space. */ 
    if (offset + (phys_addr_t)size - 1 < offset) 
     return -EINVAL; 

    if (!valid_mmap_phys_addr_range(vma->vm_pgoff, size)) 
     return -EINVAL; 

    if (!private_mapping_ok(vma)) 
     return -ENOSYS; 

    if (!range_is_allowed(vma->vm_pgoff, size)) 
     return -EPERM; 

    if (!phys_mem_access_prot_allowed(file, vma->vm_pgoff, size, 
         &vma->vm_page_prot)) 
     return -EINVAL; 

    vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff, 
         size, 
         vma->vm_page_prot); 

    vma->vm_ops = &mmap_mem_ops; 

    /* Remap-pfn-range will mark the range VM_IO */ 
    if (remap_pfn_range(vma, 
       vma->vm_start, 
       vma->vm_pgoff, 
       size, 
       vma->vm_page_prot)) { 
     return -EAGAIN; 
    } 
    return 0; 
} 

您可能需要修改的唯一事情是valid_mmap_phys_addr_range(vma->vm_pgoff, size)。或者你可以编写你自己的/dev/mem驱动程序。

+0

但是这不会**分配/保留**这些物理内存区域来阻止它们被用于其他任何事情,对吗?如该评论所示,将它映射为“VM_IO”会产生什么影响? mmap(/ dev/mem)可能是一个完整答案的有用部分,但我并不认为这部分是困难的部分。 –

+0

对内核使用'mem = xx' cmdline来仅使用部分内存。例如,传递'mem = 4G'将使内核仅使用4G以下的内存,然后可以使用修改的'/ dev/mem'驱动程序来映射4G以上的内存。 –

+0

这是一个有趣的想法,应该为没有交错的OP设置工作。您确定'/ dev/mem'仍然可以访问内核其余部分认为存在的范围之外的内存吗? –