C 问题:将同一文件复制两次
我使用的是覆盆子Pi B+,我正在尝试mmapC 问题:将同一文件复制两次,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,
/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
(aka0xffffff
)当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;
}