static void init_mem(unsigned long start_mem, unsigned long end_mem, unsigned long virt_start_addr){ int reservedpages = 0; unsigned long tmp; end_mem &= PAGE_MASK; g_max_mapnr = MAP_NR(end_mem); INIT_LOG(" first page : %x :%x :%x\n",MAP_NR(start_mem),MAP_NR(start_mem+PAGE_SIZE),MAP_NR(virt_start_addr)); start_mem = PAGE_ALIGN(start_mem); g_stat_mem_size = end_mem -start_mem; while (start_mem < end_mem) { clear_bit(PG_reserved, &g_mem_map[MAP_NR(start_mem)].flags); start_mem += PAGE_SIZE; } for (tmp = virt_start_addr ; tmp < (end_mem - 0x2000) ; tmp += PAGE_SIZE) { /*if (tmp >= MAX_DMA_ADDRESS) clear_bit(PG_DMA, &g_mem_map[MAP_NR(tmp)].flags);*/ if (PageReserved(g_mem_map+MAP_NR(tmp))) { reservedpages++; continue; } atomic_set(&g_mem_map[MAP_NR(tmp)].count, 1); PageSetReferenced(g_mem_map+MAP_NR(tmp)); mm_putFreePages(tmp,0); } stat_allocs=0; stat_frees =0; INIT_LOG(" Reserved pages : %x(%d) \n",reservedpages,reservedpages); init_done=1; INIT_LOG(" Release to FREEMEM : %x \n",(end_mem - 0x2000)); return; }
static unsigned long setup_userstack(unsigned char **argv, unsigned char **env, unsigned long *stack_len, unsigned long *t_argc, unsigned long *t_argv, unsigned long *p_aux, unsigned char *elf_interp) { int i, len, total_args = 0; int total_envs =0; unsigned char *p, *stack; unsigned long real_stack, addr; unsigned char **target_argv; unsigned char **target_env; int max_stack_len=MAX_USERSPACE_STACK_TEMPLEN; int max_list_len=(PAGE_SIZE/sizeof(void *))-1; unsigned long ret=0; if (argv == 0 && env == 0) { ut_printf(" ERROR in setuo_userstack argv:0\n"); return 0; } target_argv = (unsigned char **) alloc_page(MEM_CLEAR); target_env = (unsigned char **) alloc_page(MEM_CLEAR); if (target_argv==0 || target_env==0){ BUG(); } stack = (unsigned char *) vmalloc(MAX_USERSPACE_STACK_TEMPLEN,MEM_CLEAR); if (stack ==0){ goto error; } ret = stack; p = stack + max_stack_len; len = 0; real_stack = USERSTACK_ADDR + USERSTACK_LEN; if (elf_interp != 0){ //BUG(); len = ut_strlen(elf_interp); p = p - len - 1; real_stack = real_stack - len - 1; ut_strcpy(p, elf_interp); target_argv[total_args] = (unsigned char *)real_stack; total_args++; } for (i = 0; argv[i] != 0 && i < max_list_len; i++) { len = ut_strlen(argv[i]); if ((p - len - 1) > stack) { p = p - len - 1; real_stack = real_stack - len - 1; DEBUG(" argument :%d address:%x \n",i,real_stack); ut_strcpy(p, argv[i]); target_argv[total_args] = (unsigned char *)real_stack; total_args++; } else { ret=0 ; goto error; } } target_argv[total_args] = 0; for (i = 0; env[i] != 0 && i < max_list_len; i++) { total_envs++; len = ut_strlen(env[i]); if ((p - len - 1) > stack) { p = p - len - 1; real_stack = real_stack - len - 1; DEBUG(" envs :%d address:%x \n",i,real_stack); ut_strcpy(p, env[i]); target_env[i] = (unsigned char *)real_stack; } else { ret=0 ; goto error; } } target_env[i] = 0; addr = (unsigned long)p; addr = (unsigned long)((addr / 8) * 8); p = (unsigned char *)addr; p = p - (MAX_AUX_VEC_ENTRIES * 16); real_stack = USERSTACK_ADDR + USERSTACK_LEN + p - (stack + max_stack_len); *p_aux = (unsigned long)p; len = (1+total_args + 1 + total_envs+1) * 8; /* total_args+args+0+envs+0 */ if ((p - len - 1) > stack) { unsigned long *t; p = p - (total_envs+1)*8; ut_memcpy(p, (unsigned char *)target_env, (total_envs+1)*8); p = p - (1+total_args+1)*8; ut_memcpy(p+8, (unsigned char *)target_argv, (total_args+1)*8); t = (unsigned long *)p; *t = total_args; /* store argc at the top of stack */ DEBUG("Target ARG arg0:%x arg1:%x arg2:%x len:%d \n",target_argv[0],target_argv[1],target_argv[2],len); DEBUG("Target ENV arg0:%x arg1:%x arg2:%x len:%d \n",target_env[0],target_env[1],target_env[2],len); real_stack = real_stack - len; } else { ret=0; goto error; } *stack_len = max_stack_len - (p - stack); *t_argc = total_args; *t_argv = real_stack; error: if (ret ==0 ){ ut_log(" Error: user stack creation failed :%s:\n",g_current_task->name); vfree((unsigned long)stack); } mm_putFreePages((unsigned long)target_argv, 0); mm_putFreePages((unsigned long)target_env, 0); return ret; }