passing argc, argv and envp to main()

This commit is contained in:
Balazs Gerofi
2012-05-10 22:07:23 +09:00
parent 97d4c85195
commit 7c85ac93e8
8 changed files with 228 additions and 15 deletions

View File

@ -49,7 +49,7 @@ int __kprintf(const char *format, ...)
/* Copy into the local buf */
va_start(va, format);
len += vsnprintf(buf + len, KPRINTF_LOCAL_BUF_LEN - len, format, va);
len += vsnprintf(buf + len, KPRINTF_LOCAL_BUF_LEN - len - 2, format, va);
va_end(va);
/* Append to kmsg buffer */
@ -74,7 +74,7 @@ int kprintf(const char *format, ...)
/* Copy into the local buf */
va_start(va, format);
len += vsnprintf(buf + len, KPRINTF_LOCAL_BUF_LEN - len, format, va);
len += vsnprintf(buf + len, KPRINTF_LOCAL_BUF_LEN - len - 2, format, va);
va_end(va);
/* Append to kmsg buffer */

View File

@ -28,6 +28,11 @@ static void process_msg_prepare_process(unsigned long rphys)
int i, npages, n;
struct process *proc;
unsigned long addr;
char *args_envs, *args_envs_r;
unsigned long args_envs_p, args_envs_rp;
char **argv;
int argc, envc, args_envs_npages;
char **env;
sz = sizeof(struct program_load_desc)
+ sizeof(struct program_image_section) * 16;
@ -97,8 +102,89 @@ static void process_msg_prepare_process(unsigned long rphys)
cpu_local_var(scp).response_pa,
VR_RESERVED);
/* Map, copy and update args and envs */
addr = e;
e = addr + PAGE_SIZE * ARGENV_PAGE_COUNT;
args_envs = aal_mc_alloc_pages(ARGENV_PAGE_COUNT, 0);
args_envs_p = virt_to_phys(args_envs);
add_process_memory_range(proc, addr, e,
args_envs_p,
VR_RESERVED);
dkprintf("args_envs mapping\n");
dkprintf("args: 0x%lX, args_len: %d\n", p->args, p->args_len);
// Map in remote physical addr of args and copy it
args_envs_npages = (p->args_len + PAGE_SIZE - 1) >> PAGE_SHIFT;
dkprintf("args_envs_npages: %d\n", args_envs_npages);
args_envs_rp = aal_mc_map_memory(NULL, (unsigned long)p->args, p->args_len);
dkprintf("args_envs_rp: 0x%lX\n", args_envs_rp);
args_envs_r = (char *)aal_mc_map_virtual(args_envs_rp, args_envs_npages,
PTATTR_WRITABLE);
dkprintf("args_envs_r: 0x%lX\n", args_envs_r);
dkprintf("args copy, nr: %d\n", *((int*)args_envs_r));
memcpy_long(args_envs, args_envs_r, p->args_len + 8);
/* TODO: add a virtual_unmap function, that really does only unmap
* the virtual address and doesn't drop the physical page itself!! */
//aal_mc_unmap_virtual(args_envs_r, args_envs_npages);
//aal_mc_unmap_memory(NULL, args_envs_rp, p->args_len);
dkprintf("envs: 0x%lX, envs_len: %d\n", p->envs, p->envs_len);
// Map in remote physical addr of envs and copy it after args
args_envs_npages = (p->envs_len + PAGE_SIZE - 1) >> PAGE_SHIFT;
dkprintf("args_envs_npages: %d\n", args_envs_npages);
args_envs_rp = aal_mc_map_memory(NULL, (unsigned long)p->envs, p->envs_len);
dkprintf("args_envs_rp: 0x%lX\n", args_envs_rp);
args_envs_r = (char *)aal_mc_map_virtual(args_envs_rp, args_envs_npages,
PTATTR_WRITABLE);
dkprintf("args_envs_r: 0x%lX\n", args_envs_r);
dkprintf("envs copy, nr: %d\n", *((int*)args_envs_r));
memcpy_long(args_envs + p->args_len, args_envs_r, p->envs_len + 8);
//aal_mc_unmap_virtual(args_envs_r, args_envs_npages);
//aal_mc_unmap_memory(NULL, args_envs_rp, p->envs_len);
// Update variables
argc = *((int*)(args_envs));
dkprintf("argc: %d\n", argc);
argv = (char **)(args_envs + (sizeof(int)));
while (*argv) {
char **_argv = argv;
dkprintf("%s\n", args_envs + (unsigned long)*argv);
*argv = (char *)addr + (unsigned long)*argv; // Process' address space!
argv = ++_argv;
}
argv = (char **)(args_envs + (sizeof(int)));
envc = *((int*)(args_envs + p->args_len));
dkprintf("envc: %d\n", envc);
env = (char **)(args_envs + p->args_len + sizeof(int));
while (*env) {
char **_env = env;
//dkprintf("%s\n", args_envs + p->args_len + (unsigned long)*env);
*env = (char *)addr + p->args_len + (unsigned long)*env;
env = ++_env;
}
env = (char **)(args_envs + p->args_len + sizeof(int));
dkprintf("env OK\n");
aal_mc_unmap_virtual(args_envs, ARGENV_PAGE_COUNT);
p->rprocess = (unsigned long)proc;
init_process_stack(proc);
init_process_stack(proc, argc, argv, envc, env);
dkprintf("new process : %p [%d] / table : %p\n", proc, proc->pid,
proc->vm->page_table);

View File

@ -83,7 +83,8 @@ int add_process_memory_range(struct process *process,
unsigned long phys, unsigned long flag);
int remove_process_region(struct process *proc,
unsigned long start, unsigned long end);
void init_process_stack(struct process *process);
void init_process_stack(struct process *process, int argc, char **argv,
int envc, char **env);
unsigned long extend_process_region(struct process *proc,
unsigned long start, unsigned long end,
unsigned long address);

View File

@ -8,8 +8,9 @@
#define REQUEST_PAGE_COUNT 16
#define RESPONSE_PAGE_COUNT 16
#define DOORBELL_PAGE_COUNT 1
#define ARGENV_PAGE_COUNT 8
#define SCD_RESERVED_COUNT \
(REQUEST_PAGE_COUNT + RESPONSE_PAGE_COUNT + DOORBELL_PAGE_COUNT)
(REQUEST_PAGE_COUNT + RESPONSE_PAGE_COUNT + DOORBELL_PAGE_COUNT + ARGENV_PAGE_COUNT)
#define SCD_MSG_PREPARE_PROCESS 0x1
#define SCD_MSG_PREPARE_PROCESS_ACKED 0x2
@ -89,6 +90,10 @@ struct program_load_desc {
int pid;
unsigned long entry;
unsigned long rprocess;
char *args;
unsigned long args_len;
char *envs;
unsigned long envs_len;
struct program_image_section sections[0];
};

View File

@ -17,7 +17,7 @@
#define USER_STACK_NR_PAGES 4
#define KERNEL_STACK_NR_PAGES 4
#define KERNEL_STACK_NR_PAGES 8
extern long do_arch_prctl(unsigned long code, unsigned long address);
@ -137,8 +137,11 @@ int add_process_memory_range(struct process *process,
void init_process_stack(struct process *process)
void init_process_stack(struct process *process, int argc, char **argv,
int envc, char **env)
{
int s_ind = 0;
int arg_ind;
char *stack = aal_mc_alloc_pages(USER_STACK_NR_PAGES, 0);
unsigned long *p = (unsigned long *)(stack +
(USER_STACK_NR_PAGES * PAGE_SIZE));
@ -150,19 +153,24 @@ void init_process_stack(struct process *process)
USER_END,
virt_to_phys(stack), VR_STACK);
/* TODO: fill with actual value of argc, argv, envp */
p[-1] = 0; /* AT_NULL */
p[-2] = 0;
p[-3] = USER_END - sizeof(unsigned long) * 2;
p[-4] = 0; /* env: "" */
p[-5] = 0x41; /* argv(0): "a" */
p[-6] = 0; /* envp: NULL */
p[-7] = 0; /* argv[1] = NULL */
p[-8] = USER_END - sizeof(unsigned long) * 5; /* argv[0] = END - 16 */
p[-9] = 1; /* argc */
p[-4] = 0; /* envp terminating NULL */
s_ind = -5;
for (arg_ind = envc - 1; arg_ind > -1; --arg_ind) {
p[s_ind--] = (unsigned long)env[arg_ind];
}
p[s_ind--] = 0; /* argv terminating NULL */
for (arg_ind = argc - 1; arg_ind > -1; --arg_ind) {
p[s_ind--] = (unsigned long)argv[arg_ind];
}
/* argc */
p[s_ind] = argc;
aal_mc_modify_user_context(process->uctx, AAL_UCR_STACK_POINTER,
USER_END - sizeof(unsigned long) * 9);
USER_END + sizeof(unsigned long) * s_ind);
process->vm->region.stack_end = USER_END;
process->vm->region.stack_start = USER_END -
(USER_STACK_NR_PAGES * PAGE_SIZE);