The source data to copy "from" is the process table p_memmap entry for the user process.
To set up the source vir_addr we first need to get the endpoint value of the system task. The process number of the system task is easy. It is SYSTEM. This is a macro defined in /usr/src/include/minix as (-2). So it is not quite the index into the process table. To get the index into the kernel's version of the process table you have to add NR_TASKS (which is 4). The kernel's process table has 4 more entries than the process manager's process table.
So you could use the system task's process number to get its endpoint value by remembering to translate in the proc table by NR_TASKS:
struct vir_addr src; src.proc_nr_e = proc[SYSTEM + NR_TASKS].p_endpoint;
The "+ NR_TASKS" is necessary but easy to forget. Another macro is defined, proc_addr(nr), that returns a pointer to the proc entry of the process with process number nr. So using this macro we can write alternatively:
struct vir_addr src; src.proc_nr_e = proc_addr(SYSTEM)->p_endpoint; src.segment = D; /* D is a macro equal to 1 for Data segment */ src.offset = ??
The offset should be the virtual address in bytes of the mem_map for the user process. The process manager made this task call and must send something in the message identifying the user process. It could be the user process's pid, but the pid is not in the kernel's proc, it is in the process manager's mproc. The process manager could send the process number or the process endpoint of the user process. The process number is not stored in mproc, the endpoint is. Since the process manager system call handler will get a pointer to the user's mproc entry, it is easy to get the user's endpoint. Besides it will be needed anyway to fill in the destination vir_addr for the call to virtual_copy.
So... to get the user's entry, in the proc table, the message will contain the user's endpoint value. Suppose for a minute that we can translate this endpoint to a proc_nr for the user process. Then the src.offset can be set:
src.offset = (vir_bytes) proc_addr(proc_nr)->p_memmap;
Does this make sense?