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