There are no obvious ways of populating an address space. ioctl is the only standard file op which can do this, but that's only because ioctl can be made to do anything.
The method that I prefer is to extend the mmap interface by adding another file descriptor. This would represent the address space within which the new mapping is to be made. -1 would specify the current address space, making this interface backward compatible with the current mmap. So, the current mmap could be implemented in libc in terms of this new system call.
munmap and mprotect would also be extended to take a file descriptor to specify the address space to be changed.