C 问题:将同一文件复制两次

C 问题:将同一文件复制两次,c,raspberry-pi,mmap,C,Raspberry Pi,Mmap,我使用的是覆盆子Pi B+,我正在尝试mmap/dev/mem的两个不同部分-第一个可以从位置0x2020 0004(0x04字节长)设置两个管脚函数,另一个可以从位置0x2021 4000(0x1C字节长) static uint32\u t*initMapMem(intfd、uint32\u t addr、uint32\u t len) { 返回(uint32_t*)mmap((void*)0x0,len, PROT|u READ | PROT|u WRITE | PROT|u EXEC,

我使用的是覆盆子Pi B+,我正在尝试mmap
/dev/mem
的两个不同部分-第一个可以从位置
0x2020 0004
0x04
字节长)设置两个管脚函数,另一个可以从位置
0x2021 4000
0x1C
字节长)

static uint32\u t*initMapMem(intfd、uint32\u t addr、uint32\u t len)
{
返回(uint32_t*)mmap((void*)0x0,len,
PROT|u READ | PROT|u WRITE | PROT|u EXEC,
地图共享|地图锁定|,
fd,addr);
}
int初始化(无效){
int-fd;
fd=打开(“/dev/mem”,O_RDWR | O_SYNC);
如果(fd<0)
{
fprintf(stderr,“此程序需要根权限。请尝试使用sudo。\n”);
返回1;
}
pinReg=initMapMem(fd,0x20200004,0x4);
bscReg=initMapMem(fd,0x20214000,0x1C);
关闭(fd);
如果(bscReg==MAP_失败)
{
fprintf(stderr,“错误,mmap失败。\n”);
返回1;
}
如果(pinReg==映射_失败)
{
fprintf(stderr,“错误,mmap失败。\n”);
返回1;
}
返回0;
}
initialise()
main()
调用。使用
gdb
单步执行程序时,我发现
bscReg
位置正确,但
pinReg
返回为
MAP\u FAILED
(aka
0xffffff
)当
errno
设置为
EINVAL
时,无论以何种方式执行,
pinReg
都会在
mmap
第一次或第二次执行时发现自己是
MAP\u失败的


如何将
pinReg
设置为有效值?

第一个
mmap()
失败,因为您尝试映射的偏移量(
0x20200004
)未对齐页面。请在
0x20200000
处创建一个大小至少为8的映射,然后在偏移量
0x4

Aaah处写入。这就是它失败的原因。我以为只映射我需要的东西会让我感到害羞。我最终映射了
0x0
,偏移量
0x2020000
,长度
0x8
,所以我仍然可以使用现有的
initMapMem
方法-不管怎样都能工作。感谢您的帮助!(如果我知道RasPi的内存页大小是多少,会有帮助的…)我会在网站允许的情况下尽快接受它。几乎所有架构(包括ARM)的内存页大小都是4K。值得一提的是
sysconf(\u SC\u PAGESIZE)
也将为您提供页面大小(尽管在这种情况下不太可能更改).@Ulfalizer事实上,对于任何给定的体系结构来说,它实际上都是一个常数。增加它将是一个破坏ABI的变化,因为它将使现有二进制文件中的部分不再与页面对齐。@Daskwuff:我的意思是,这是特定于设备的代码,不可能被移植到其他体系结构。:)
static uint32_t * initMapMem(int fd, uint32_t addr, uint32_t len)
{
    return (uint32_t *) mmap((void*)0x0, len,
       PROT_READ|PROT_WRITE|PROT_EXEC,
       MAP_SHARED|MAP_LOCKED,
       fd, addr);
}

int initialise(void) {
   int fd;

   fd = open("/dev/mem", O_RDWR | O_SYNC) ;

   if (fd < 0)
   {
      fprintf(stderr, "This program needs root privileges.  Try using sudo.\n");
      return 1;
   }

   pinReg = initMapMem(fd, 0x20200004, 0x4);
   bscReg = initMapMem(fd, 0x20214000, 0x1C);

   close(fd);

   if (bscReg == MAP_FAILED)
   {
      fprintf(stderr, "Bad, mmap failed.\n");
      return 1;
   }
   if (pinReg == MAP_FAILED)
   {
      fprintf(stderr, "Bad, mmap failed.\n");
      return 1;
   }
   return 0;
}