2011-11-21 46 views
5

'mem_map' ifadesinin başladığı fiziksel belleği okumak için kullanıcı alanında mmap kullanmaya çalışıyorum. Tüm fiziksel sayfaları içeren bir dizi. Bu 3.0 çekirdek çalışan bir i386 makinedir.mmap: Kullanıma izin verilmiyor

kod şu şekildedir:

.... 

//define page size 
// 
#define PAGE_SIZE 0x1000 //4096 bytes 
#define PAGE_MASK (PAGE_SIZE - 1) 

.... 

    /* open /dev/mem file*/ 
    if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) { 
     printf("/dev/mem could not be opened.\n"); 
    perror("open"); 
     exit(1); 
    } else { 
    printf("/dev/mem opened.\n"); 
    } 

    /* Map one page */ 
    printf(" mem_map is at physical addr: 0x%x\n", mem_map_phy_addr); 

    map_base = mmap(0, PAGE_SIZE, PROT_READ, MAP_SHARED, fd, (mem_map_phy_addr & ~PAGE_MASK)); //mem_map_phy_addr is at 0x356f2000 

    if(map_base == (void *) -1) { 
    printf("Memory map failed. err num = %d\n",errno); 
    perror("mmap"); //failed here 
    } else { 
    printf("Memory mapped at address %p.\n", map_base); 
    } 

bir kök olarak bu koştu. çıktısı:

/dev/mem opened. 
mem_map is at physical addr: 0x356f2000 
Memory map failed. err num = 1 
mmap: Operation not permitted 

emin olmak gerekirse, ben sorunu googled ve benim /etc/sysctl.conf dosyasına aşağıdaki satırı eklendi:

vm.mmap_min_addr = 0 

Ama bu da işe yaramaz.

Mem_map işleminin bu şekilde neden yapılmasına izin verilmediğini ve etrafından nasıl geçebileceğimi herkes biliyor mu?

Teşekkürler.

+2

, 'x ~ PAGE_MASK' kullanımı yanlıştır. 64 bit sistemlerde, bu adresleri 32 bite keser. Tamamlayıcıyı almadan önce "uintptr_t" veya eşdeğer geniş tipte yayınlamalısınız. –

+0

mmap_min_addr değerini ayarlamak veya sadece conf dosyasını düzenlemek için sysctl komutunu çalıştırdınız mı? İkisini de yapmak zorundasın. –

+0

Evet, daha sonra "sysctl -p" yaptım. – user899159

cevap

8

Kernel, CONFIG_STRICT_DEVMEM etkinleştirilmiş olarak derlenmiş gibi geliyor. Bu, kullanıcının 1 MB'nin (IIRC) üzerindeki (muhtemelen hassas) fiziksel belleğe erişmesini engellemek için bir güvenlik özelliğidir. Bunu sysctl dev.mem.restricted ile devre dışı bırakabilirsiniz.

+0

Evet, .config'ım CONFIG_STRICT_DEVMEM = y var. "Sysctl dev.mem.restricted" i nasıl kullanırım? Denedim ve hata:/proc/sys/dev/mem/restrictted: Böyle bir dosya veya dizin yok. – user899159

+0

Kriteri devre dışı bırakılmış seçenekle yeniden derlemeniz gerekecek. –

+0

Tamam, CONFIG_STRICT_DEVMEM kapalıyken çekirdeği yeniden derledim. Şimdi yeni bir hatam var:/dev/mem açıldı. mem_map fiziksel adrestedir: 0x356db000 Bellek haritası başarısız oldu. err num = 22 mmap: Geçersiz değişken. Fiziksel adreste 0'ı eşlemeye kalkarsam bu olmaz. - Teşekkürler. – user899159

0

Arch Linux'lu bir APU2c4 Kartında flashrom kullanmaya çalışırken benzer bir sorun yaşadım.

Sysctl seçeneği dev.mem.restricted sistemimde mevcut değildi ve kendiliğinden derlenmiş bir çekirdek kullanmak benim için bir seçenek değildi.

Ben Grub aracılığıyla relaxed için iomem Kernelparameter ayarlayarak sorunu çalıştı: Elbette

# /boot/grub/grub.cfg 
linux /boot/vmlinuz-linux iomem=relaxed 

yeniden başlatma bu çözüm için nessesary olduğunu.

Referans: Bilginize
https://www.reddit.com/r/libreboot/comments/6wvyry/flashrom_failures_to_access/
https://www.flashrom.org/FAQ
https://www.kernel.org/doc/Documentation/admin-guide/kernel-parameters.txt

İlgili konular