For some reason my mmap
failed with an Invalid argument
message even though my offset is page aligned. Page size is 4096 bytes. Also CONFIG_STRICT_DEVMEM
is disabled, i.e. I can access memory above 1MB.
Here is my code:
void *mmap64;
off_t offset = 0x000000d9fcc000;
int memFd = open("/dev/mem", O_RDWR);
if (-1 == memFd)
perror("Error ");
mmap64 = mmap(0, getpagesize(), PROT_WRITE | PROT_READ, MAP_SHARED, memFd, offset);
if (MAP_FAILED == mmap64) {
perror("Error ");
return -1;
}
Can someone explain why this is happening?
EDIT
Here is the strace
of my code
execve("./to_phys_test", ["./to_phys_test", "-r"], [/* 18 vars */]) = 0
brk(0) = 0x2012000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe240a2c000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=162063, ...}) = 0
mmap(NULL, 162063, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fe240a04000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P \2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1840928, ...}) = 0
mmap(NULL, 3949248, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fe240447000
mprotect(0x7fe240601000, 2097152, PROT_NONE) = 0
mmap(0x7fe240801000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1ba000) = 0x7fe240801000
mmap(0x7fe240807000, 17088, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fe240807000
close(3) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe240a03000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe240a01000
arch_prctl(ARCH_SET_FS, 0x7fe240a01740) = 0
mprotect(0x7fe240801000, 16384, PROT_READ) = 0
mprotect(0x601000, 4096, PROT_READ) = 0
mprotect(0x7fe240a2e000, 4096, PROT_READ) = 0
munmap(0x7fe240a04000, 162063) = 0
open("/dev/mem", O_RDWR) = 3
open("/dev/my_kmodule", O_RDWR) = 4
ioctl(4, 0x40086e00, 0x7ffc72b334b0) = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe240a2b000
write(1, "sa.size = 44\n", 13) = 13
write(1, "sa.addr_uint64_t = d9047000\n", 28) = 28
write(1, "sa.addr_void_ptr = 0xd9047000\n", 30) = 30
write(1, "PAGE_SIZE = 4096\n", 17) = 17
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, 3, 0xd9047000) = -1 EINVAL (Invalid argument)
dup(2) = 5
fcntl(5, F_GETFL) = 0x8002 (flags O_RDWR|O_LARGEFILE)
brk(0) = 0x2012000
brk(0x2033000) = 0x2033000
fstat(5, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe240a2a000
lseek(5, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)
write(5, "Error : Invalid argument\n", 25) = 25
close(5) = 0
munmap(0x7fe240a2a000, 4096) = 0
exit_group(-1) = ?
+++ exited with 255 +++
mmap
andperror
in a device driver? I have doubts ... And Joda conditions not using you should. Compilers checking will this for you. – too honest for this sitemmap
andperror
? – flashburnd9fcc000
come from? What are you expecting to find there? If it's not a valid physcal address,mmap
will returnEINVAL
. Also, have you looked to see if the kernel is telling you anything indmesg
? – Jonathon Reinhartperror
doesn't cause the program to exit. So, if youropen("/dev/mem")
fails (because you don't haveCAP_SYS_RAWIO
), you'llperror
the message, but then continue to try and pass-1
for thefd
argument tommap
. Also, this is x86, right? As this is an architecture-specific feature of the kernel, it would be best to indicate the architecture in your tags. – Jonathon ReinhartCONFIG_STRICT_DEVMEM
. The original kernel is4.4.0-34-generic
onUbuntu 14.04 LTS
– flashburn