2017-08-31 92 views
5

Bir Intel x86-64 ana kartına takılı 2 DIMM'in olduğunu varsayalım. Tüm bellek araları (banka ve kanal) devre dışıdır.DIMM'e Doğrudan Bellek Eşleme

Yapmaya çalıştığım şey, bu DIMM'lerden birinin fiziksel bellek alanını Linux kernel (sürüm 4.11.11) için ayırmak ve bir uygulama için bu fiziksel (ayrılmış) bellek alanını açığa çıkarmaktır. DIMM'ler, numaralı telefonun bellek kanallarına taşınmaması için olacaktır. Bunu yapmayı nasıl başarabilirim? Süreç ne olurdu? Çekirdek geliştirme konusunda yeniyim ve rehberlik yapabilirim.

Ben şimdiye kadar bulduk Ne:

  1. Eğer memmap=nn[KMG]$ss[KMG] önyükleme parametresini belirtebilirsiniz Linux çekirdeğinden bellek rezerve etmek. Bu parametre, belirli hafızayı ss'den ss + nn'ye ayrılmış bir bellek bölgesi olarak işaretler.

  2. mmap dosya tanımlayıcı tarafından temsil bellek nesnesine len bayt için bir adres pa de Fildes bir sürecin adres alanı arasında bir eşleme kurmak için kullanılabilir de kapalı ofset len için bayt.

Bellek ayrıldıktan sonra, ayrılmış bellekleri kullanıcı alanı uygulamasına göstermek için bazı karakter aygıt sürücüsünün gerekli olduğunu mu varsayıyorum? Düşünceler?


Güncelleme

Ayrıca ayrılmış olması gerekir DIMM o kendi özel bellek kanalı ve hiçbir banka ya da kanal binişimi etkinleştirilecek olacağını belirtmek gerekir. Eşleştirme

+0

DIMM parçasının resmin tamamına nasıl uyduğunu anlamıyorum. Neyse,/dev/mem' gibi bir şey yapmaz mı? Ayrılmış hafızanın böyle bir cihaz tarafından mı eşleştirileceğini bilmiyorum. –

+0

@MargaretBloom DIMM hakkında net olmayan nedir? Çekirdek tarafından kullanılan DIMM'lerden birindeki tüm belleği ayırmaya çalışıyorum. Anlaşıldı mı? '/ dev/mem', çekirdeğin kullanabileceği tüm belleği temsil eder ve bu nedenle ihtiyaç duyduğum şeylerin mutlaka temsilcisi değildir. – Jonathan

+0

Bayrak argümanında kullanılmayan bitler varsa, 'mmap' için yeni bir bayrakla, yani bir 'MAP_RESERVED_DIMM' tanımlayın. HugeTLBFS başka bir modeldir: yedekleme belleği hakkında özel bir şeyle eşleşmeleri almak için dosyaları eşleştirebileceğiniz özel bir dosya sistemi. Linux internals konusunda uzman değilim (sadece ilgilenen bir amatör), ama bir char veya blok cihaz fikriniz de işe yarayabilir. Özellikle, sadece bir kullanıcı-alanı sürecini tek seferde kullanmayı planlıyorsanız, aksi halde hangi bölümlerin zaten haritalandığını öğrenmelerine nasıl izin veriyorsunuz? –

cevap

0

Eşleme /dev/mem basit bir yoldur. Bunu daha önce yapmıştım. mmapkernel source dan uygulamak: Değiştirmeye gerekebilir

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; 
} 

tek şey valid_mmap_phys_addr_range(vma->vm_pgoff, size) olduğunu. Veya kendi sürümünüzü /dev/mem sürücüsüne yazabilirsiniz.

+0

Ancak bu, başka herhangi bir şey için kullanılmasını önlemek için fiziksel belleğin bu bölgelerini ** ayırmaz/rezerve etmez, değil mi? Ve bu yorumun gösterdiği gibi 'VM_IO' olarak haritalandırılmasının sonuçları nelerdir? mmap (/ dev/mem) tam bir cevabın faydalı bir parçası olabilir, ama bu kısmın zor kısmı olduğunu düşünmedim. –

+0

Sadece belleğin bir kısmını kullanmak için çekirdek için 'mem = xx' cmdline 'ı kullanın. Örneğin, 'mem = 4G' komutunun çekilmesi, çekirdeği yalnızca 4G'nin altında bir bellek kullanır, daha sonra 4G'nin üzerinde mmap belleği belleğe almak için değiştirilmiş'/dev/mem' sürücüsünü kullanabilirsiniz. –

+0

Bu ilginç bir fikir ve OP'nin kurulumunda hiçbir serpiştirmeyle çalışmalı./Dev/mem’in, kernelin geri kalanı var olduğunu düşündüğü aralık dışında belleğe erişebileceğinden emin misiniz? –