passing argc, argv and envp to main()
This commit is contained in:
@@ -49,7 +49,7 @@ int __kprintf(const char *format, ...)
|
|||||||
|
|
||||||
/* Copy into the local buf */
|
/* Copy into the local buf */
|
||||||
va_start(va, format);
|
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);
|
va_end(va);
|
||||||
|
|
||||||
/* Append to kmsg buffer */
|
/* Append to kmsg buffer */
|
||||||
@@ -74,7 +74,7 @@ int kprintf(const char *format, ...)
|
|||||||
|
|
||||||
/* Copy into the local buf */
|
/* Copy into the local buf */
|
||||||
va_start(va, format);
|
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);
|
va_end(va);
|
||||||
|
|
||||||
/* Append to kmsg buffer */
|
/* Append to kmsg buffer */
|
||||||
|
|||||||
@@ -28,6 +28,11 @@ static void process_msg_prepare_process(unsigned long rphys)
|
|||||||
int i, npages, n;
|
int i, npages, n;
|
||||||
struct process *proc;
|
struct process *proc;
|
||||||
unsigned long addr;
|
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)
|
sz = sizeof(struct program_load_desc)
|
||||||
+ sizeof(struct program_image_section) * 16;
|
+ 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,
|
cpu_local_var(scp).response_pa,
|
||||||
VR_RESERVED);
|
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;
|
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,
|
dkprintf("new process : %p [%d] / table : %p\n", proc, proc->pid,
|
||||||
proc->vm->page_table);
|
proc->vm->page_table);
|
||||||
|
|||||||
@@ -83,7 +83,8 @@ int add_process_memory_range(struct process *process,
|
|||||||
unsigned long phys, unsigned long flag);
|
unsigned long phys, unsigned long flag);
|
||||||
int remove_process_region(struct process *proc,
|
int remove_process_region(struct process *proc,
|
||||||
unsigned long start, unsigned long end);
|
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 extend_process_region(struct process *proc,
|
||||||
unsigned long start, unsigned long end,
|
unsigned long start, unsigned long end,
|
||||||
unsigned long address);
|
unsigned long address);
|
||||||
|
|||||||
@@ -8,8 +8,9 @@
|
|||||||
#define REQUEST_PAGE_COUNT 16
|
#define REQUEST_PAGE_COUNT 16
|
||||||
#define RESPONSE_PAGE_COUNT 16
|
#define RESPONSE_PAGE_COUNT 16
|
||||||
#define DOORBELL_PAGE_COUNT 1
|
#define DOORBELL_PAGE_COUNT 1
|
||||||
|
#define ARGENV_PAGE_COUNT 8
|
||||||
#define SCD_RESERVED_COUNT \
|
#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 0x1
|
||||||
#define SCD_MSG_PREPARE_PROCESS_ACKED 0x2
|
#define SCD_MSG_PREPARE_PROCESS_ACKED 0x2
|
||||||
@@ -89,6 +90,10 @@ struct program_load_desc {
|
|||||||
int pid;
|
int pid;
|
||||||
unsigned long entry;
|
unsigned long entry;
|
||||||
unsigned long rprocess;
|
unsigned long rprocess;
|
||||||
|
char *args;
|
||||||
|
unsigned long args_len;
|
||||||
|
char *envs;
|
||||||
|
unsigned long envs_len;
|
||||||
struct program_image_section sections[0];
|
struct program_image_section sections[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#define USER_STACK_NR_PAGES 4
|
#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);
|
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);
|
char *stack = aal_mc_alloc_pages(USER_STACK_NR_PAGES, 0);
|
||||||
unsigned long *p = (unsigned long *)(stack +
|
unsigned long *p = (unsigned long *)(stack +
|
||||||
(USER_STACK_NR_PAGES * PAGE_SIZE));
|
(USER_STACK_NR_PAGES * PAGE_SIZE));
|
||||||
@@ -150,19 +153,24 @@ void init_process_stack(struct process *process)
|
|||||||
USER_END,
|
USER_END,
|
||||||
virt_to_phys(stack), VR_STACK);
|
virt_to_phys(stack), VR_STACK);
|
||||||
|
|
||||||
/* TODO: fill with actual value of argc, argv, envp */
|
|
||||||
p[-1] = 0; /* AT_NULL */
|
p[-1] = 0; /* AT_NULL */
|
||||||
p[-2] = 0;
|
p[-2] = 0;
|
||||||
p[-3] = USER_END - sizeof(unsigned long) * 2;
|
p[-3] = USER_END - sizeof(unsigned long) * 2;
|
||||||
p[-4] = 0; /* env: "" */
|
p[-4] = 0; /* envp terminating NULL */
|
||||||
p[-5] = 0x41; /* argv(0): "a" */
|
s_ind = -5;
|
||||||
p[-6] = 0; /* envp: NULL */
|
for (arg_ind = envc - 1; arg_ind > -1; --arg_ind) {
|
||||||
p[-7] = 0; /* argv[1] = NULL */
|
p[s_ind--] = (unsigned long)env[arg_ind];
|
||||||
p[-8] = USER_END - sizeof(unsigned long) * 5; /* argv[0] = END - 16 */
|
}
|
||||||
p[-9] = 1; /* argc */
|
|
||||||
|
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,
|
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_end = USER_END;
|
||||||
process->vm->region.stack_start = USER_END -
|
process->vm->region.stack_start = USER_END -
|
||||||
(USER_STACK_NR_PAGES * PAGE_SIZE);
|
(USER_STACK_NR_PAGES * PAGE_SIZE);
|
||||||
|
|||||||
@@ -191,12 +191,88 @@ void print_desc(struct program_load_desc *desc)
|
|||||||
|
|
||||||
unsigned long dma_buf_pa;
|
unsigned long dma_buf_pa;
|
||||||
|
|
||||||
|
|
||||||
|
void print_flat(char *flat)
|
||||||
|
{
|
||||||
|
char **string;
|
||||||
|
|
||||||
|
printf("counter: %d\n", *((int *)flat));
|
||||||
|
|
||||||
|
string = (char **)(flat + sizeof(int));
|
||||||
|
while (*string) {
|
||||||
|
|
||||||
|
printf("%s\n", (flat + (unsigned long)(*string)));
|
||||||
|
|
||||||
|
++string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flatten out a (char **) string array into the following format:
|
||||||
|
* [nr_strings][char *offset of string_0]...[char *offset of string_n-1][NULL][string0]...[stringn_1]
|
||||||
|
* if nr_strings == -1, we assume the last item is NULL
|
||||||
|
*
|
||||||
|
* NOTE: copy this string somewhere, add the address of the string to each offset
|
||||||
|
* and we get back a valid argv or envp array.
|
||||||
|
*
|
||||||
|
* returns the total length of the flat string and updates flat to
|
||||||
|
* point to the beginning.
|
||||||
|
*/
|
||||||
|
int flatten_strings(int nr_strings, char **strings, char **flat)
|
||||||
|
{
|
||||||
|
int full_len, string_i;
|
||||||
|
unsigned int flat_offset;
|
||||||
|
char *string;
|
||||||
|
char *_flat;
|
||||||
|
|
||||||
|
/* How many strings do we have? */
|
||||||
|
if (nr_strings == -1) {
|
||||||
|
for (nr_strings = 0; strings[nr_strings]; ++nr_strings);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Count full length */
|
||||||
|
full_len = sizeof(int) + sizeof(char *); // Counter and terminating NULL
|
||||||
|
for (string_i = 0; string_i < nr_strings; ++string_i) {
|
||||||
|
// Pointer + actual value
|
||||||
|
full_len += sizeof(char *) + strlen(strings[string_i]) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
_flat = (char *)malloc(full_len);
|
||||||
|
if (!_flat) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(_flat, 0, full_len);
|
||||||
|
|
||||||
|
/* Number of strings */
|
||||||
|
*((int*)_flat) = nr_strings;
|
||||||
|
|
||||||
|
// Actual offset
|
||||||
|
flat_offset = sizeof(int) + sizeof(char *) * (nr_strings + 1);
|
||||||
|
|
||||||
|
for (string_i = 0; string_i < nr_strings; ++string_i) {
|
||||||
|
|
||||||
|
/* Fabricate the string */
|
||||||
|
*((char **)(_flat + sizeof(int) + string_i * sizeof(char *))) = (void *)flat_offset;
|
||||||
|
memcpy(_flat + flat_offset, strings[string_i], strlen(strings[string_i]) + 1);
|
||||||
|
flat_offset += strlen(strings[string_i]) + 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
*flat = _flat;
|
||||||
|
return full_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int fd, fdm;
|
int fd, fdm;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
struct program_load_desc *desc;
|
struct program_load_desc *desc;
|
||||||
long r;
|
long r;
|
||||||
|
char *envs;
|
||||||
|
char *args;
|
||||||
|
int len;
|
||||||
|
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
fprintf(stderr, "Usage: %s (program) [args...]\n",
|
fprintf(stderr, "Usage: %s (program) [args...]\n",
|
||||||
@@ -217,6 +293,14 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
__dprintf("# of sections: %d\n", desc->num_sections);
|
__dprintf("# of sections: %d\n", desc->num_sections);
|
||||||
|
|
||||||
|
desc->envs_len = flatten_strings(-1, environ, &envs);
|
||||||
|
desc->envs = envs;
|
||||||
|
//print_flat(envs);
|
||||||
|
|
||||||
|
desc->args_len = flatten_strings(-1, argv + 1, &args);
|
||||||
|
desc->args = args;
|
||||||
|
//print_flat(args);
|
||||||
|
|
||||||
fd = open("/dev/mcos0", O_RDWR);
|
fd = open("/dev/mcos0", O_RDWR);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
|
|||||||
@@ -31,6 +31,10 @@ struct program_load_desc {
|
|||||||
int pid;
|
int pid;
|
||||||
unsigned long entry;
|
unsigned long entry;
|
||||||
unsigned long rprocess;
|
unsigned long rprocess;
|
||||||
|
char *args;
|
||||||
|
unsigned long args_len;
|
||||||
|
char *envs;
|
||||||
|
unsigned long envs_len;
|
||||||
struct program_image_section sections[0];
|
struct program_image_section sections[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ static long mcexec_prepare_image(aal_os_t os,
|
|||||||
{
|
{
|
||||||
struct program_load_desc desc, *pdesc;
|
struct program_load_desc desc, *pdesc;
|
||||||
struct ikc_scd_packet isp;
|
struct ikc_scd_packet isp;
|
||||||
|
void *args, *envs;
|
||||||
|
|
||||||
if (copy_from_user(&desc, udesc,
|
if (copy_from_user(&desc, udesc,
|
||||||
sizeof(struct program_load_desc))) {
|
sizeof(struct program_load_desc))) {
|
||||||
@@ -46,6 +47,28 @@ static long mcexec_prepare_image(aal_os_t os,
|
|||||||
|
|
||||||
pdesc->pid = task_tgid_vnr(current);
|
pdesc->pid = task_tgid_vnr(current);
|
||||||
|
|
||||||
|
args = kmalloc(pdesc->args_len, GFP_KERNEL);
|
||||||
|
if (copy_from_user(args, pdesc->args, pdesc->args_len)) {
|
||||||
|
kfree(args);
|
||||||
|
kfree(pdesc);
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
envs = kmalloc(pdesc->envs_len, GFP_KERNEL);
|
||||||
|
if (copy_from_user(envs, pdesc->envs, pdesc->envs_len)) {
|
||||||
|
kfree(envs);
|
||||||
|
kfree(args);
|
||||||
|
kfree(pdesc);
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
pdesc->args = virt_to_phys(args);
|
||||||
|
printk("args: 0x%lX\n", pdesc->args);
|
||||||
|
printk("argc: %d\n", *(int*)args);
|
||||||
|
pdesc->envs = virt_to_phys(envs);
|
||||||
|
printk("envs: 0x%lX\n", pdesc->envs);
|
||||||
|
printk("envc: %d\n", *(int*)envs);
|
||||||
|
|
||||||
isp.msg = SCD_MSG_PREPARE_PROCESS;
|
isp.msg = SCD_MSG_PREPARE_PROCESS;
|
||||||
isp.ref = pdesc->cpu;
|
isp.ref = pdesc->cpu;
|
||||||
isp.arg = virt_to_phys(pdesc);
|
isp.arg = virt_to_phys(pdesc);
|
||||||
@@ -62,6 +85,8 @@ static long mcexec_prepare_image(aal_os_t os,
|
|||||||
sizeof(struct program_image_section) * desc.num_sections);
|
sizeof(struct program_image_section) * desc.num_sections);
|
||||||
|
|
||||||
kfree(pdesc);
|
kfree(pdesc);
|
||||||
|
kfree(envs);
|
||||||
|
kfree(args);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user