0

// The c code shown here works:

int fd = open("/dev/gpiomem", O_FLAGS);
printf("fd = %d\n", fd);
long int* addr = mmap(0,
                     0x1000,
                     PROT_RDWR,
                     MAP_SHARED,
                     fd,
                     0);
if (*addr == -1)
{
    printf("mmap() failed.");
    exit(1);
}
printf("addr = %x\n", addr);

// But the assembly code shown here gives me EINVAL

mov     r0, #0
mov     r1, #0x1000
mov     r2, #PROT_RDWR
mov     r3, #MAP_SHARED
ldr     r4, =fileDescriptor
ldr     r4, [r4]
mov     r5, #0
bl      mmap   <== this fails with r0 = -1

When I step into mmap in gdb I see the following:

(gdb) s __GI___mmap (addr=0x0, len=4096, prot=3, flags=1, fd=0, offset=74548) at ../sysdeps/unix/sysv/linux/mmap.c:38 38 ../sysdeps/unix/sysv/linux/mmap.c: No such file or directory.

r0 through r5 were correct before issuing the call to mmap. It looks like fd and offset are getting clobbered.

Any suggestions would be greatly appreciated?

1 Answer 1

1

That was dumb! I forgot to push R5 and R4 onto the stack. The 32-bit Raspberry Pi only allows 4 parameters (R0 - R3) to be passed directly. Additional parameters must be passed on the stack.

1
  • Please accept your own answer with a click on the tick on its left side. Only this will finish the question and it will not pop up again year for year.
    – Ingo
    May 10, 2020 at 9:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.