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 Answers1

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.