49 lines
1.5 KiB
C++
49 lines
1.5 KiB
C++
#include "MemMapping.h"
|
||
|
||
#include <iostream>
|
||
#include <stdexcept>
|
||
|
||
#include <unistd.h>
|
||
|
||
|
||
MemMapping::MemMapping(int memOpenFlags, size_t addr, size_t size, int mmapProt, int mmapFlags)
|
||
{
|
||
const size_t pageMask = sysconf(_SC_PAGESIZE) - 1;
|
||
const size_t pageAddr = addr & ~(pageMask); //базовый адрес страницы
|
||
|
||
m_pageOffset = addr & pageMask; //смещение относительно начала страницы
|
||
|
||
int fd = open("/dev/mem", memOpenFlags);
|
||
if(fd < 0)
|
||
{
|
||
fprintf(stderr, "Can't open /dev/mem, flags=0x%X, %s line %i\n", memOpenFlags, __FILE__, __LINE__);
|
||
throw std::runtime_error("MemMapping failed");
|
||
}
|
||
|
||
// mmap() делается с адреса, кратного странице -> выделяемый размер нужно увеличить на величину смещения внутри страницы
|
||
m_size = size + m_pageOffset;
|
||
m_mapAddr = mmap(NULL,
|
||
m_size,
|
||
mmapProt,
|
||
mmapFlags,
|
||
fd,
|
||
pageAddr);
|
||
|
||
//После mmap регистров дескриптор больше не нужен - закрываем файл
|
||
close(fd);
|
||
|
||
if(m_mapAddr == MAP_FAILED)
|
||
{
|
||
fprintf(stderr, "MemMapping: can't mmap addr=0x%X size=0x%X errno=%i\n", addr, size, errno);
|
||
throw std::runtime_error("MemMapping failed");
|
||
}
|
||
}
|
||
|
||
|
||
MemMapping::~MemMapping()
|
||
{
|
||
if(munmap(m_mapAddr, m_size) < 0)
|
||
{
|
||
fprintf(stderr, "MemMapping: can't unmap addr=0x%X size=0x%X errno=%i\n", m_mapAddr, m_size, errno);
|
||
}
|
||
} |