Changeset 91001e2 in mainline
- Timestamp:
- 2010-02-26T14:08:39Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 43ed4f3, 7d31f7c
- Parents:
- 137691a
- Location:
- kernel/generic
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/proc/program.h
r137691a r91001e2 45 45 * A program is an abstraction of a freshly created (not yet running) 46 46 * userspace task containing a main thread along with its userspace stack. 47 * 47 48 */ 48 49 typedef struct program { 49 struct task *task; 50 struct thread *main_thread; 50 struct task *task; /**< Program task */ 51 struct thread *main_thread; /**< Program main thread */ 51 52 } program_t; 52 53 53 54 extern void *program_loader; 54 55 55 extern void program_create(as_t *as, uintptr_t entry_addr, char *name, 56 program_t *p); 57 extern int program_create_from_image(void *image_addr, char *name, 58 program_t *p); 59 extern int program_create_loader(program_t *p, char *name); 60 extern void program_ready(program_t *p); 56 extern int program_create(as_t *, uintptr_t, char *, program_t *); 57 extern int program_create_from_image(void *, char *, program_t *); 58 extern int program_create_loader(program_t *, char *); 59 extern void program_ready(program_t *); 61 60 62 extern unative_t sys_program_spawn_loader(char * uspace_name, size_t name_len);61 extern unative_t sys_program_spawn_loader(char *, size_t); 63 62 64 63 #endif -
kernel/generic/src/proc/program.c
r137691a r91001e2 34 34 /** 35 35 * @file 36 * @brief 36 * @brief Running userspace programs. 37 37 */ 38 38 … … 66 66 /** Create a program using an existing address space. 67 67 * 68 * @param as Address space containing a binary program image. 69 * @param entry_addr Program entry-point address in program address space. 70 * @param name Name to set for the program's task. 71 * @param p Buffer for storing program information. 72 */ 73 void program_create(as_t *as, uintptr_t entry_addr, char *name, program_t *p) 74 { 75 as_area_t *a; 68 * @param as Address space containing a binary program image. 69 * @param entry_addr Program entry-point address in program address space. 70 * @param name Name to set for the program's task. 71 * @param prg Buffer for storing program information. 72 * 73 * @return EOK on success or negative error code. 74 * 75 */ 76 int program_create(as_t *as, uintptr_t entry_addr, char *name, program_t *prg) 77 { 76 78 uspace_arg_t *kernel_uarg; 77 79 78 80 kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0); 79 81 kernel_uarg->uspace_entry = (void *) entry_addr; … … 83 85 kernel_uarg->uspace_uarg = NULL; 84 86 85 p->task = task_create(as, name); 86 ASSERT(p->task); 87 87 prg->task = task_create(as, name); 88 if (!prg->task) 89 return ELIMIT; 90 88 91 /* 89 * Create the data a s_area.92 * Create the data address space area. 90 93 */ 91 a = as_area_create(as, AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE, 94 as_area_t *area = as_area_create(as, 95 AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE, 92 96 LOADED_PROG_STACK_PAGES_NO * PAGE_SIZE, USTACK_ADDRESS, 93 97 AS_AREA_ATTR_NONE, &anon_backend, NULL); 94 98 if (!area) 99 return ENOMEM; 100 95 101 /* 96 102 * Create the main thread. 97 103 */ 98 p ->main_thread = thread_create(uinit, kernel_uarg, p->task,104 prg->main_thread = thread_create(uinit, kernel_uarg, prg->task, 99 105 THREAD_FLAG_USPACE, "uinit", false); 100 ASSERT(p->main_thread); 106 if (!prg->main_thread) 107 return ELIMIT; 108 109 return EOK; 101 110 } 102 111 … … 107 116 * executable image. The task is returned in *task. 108 117 * 109 * @param image_addr 110 * @param name 111 * @param p 112 * 113 * 118 * @param image_addr Address of an executable program image. 119 * @param name Name to set for the program's task. 120 * @param prg Buffer for storing program info. If image_addr 121 * points to a loader image, p->task will be set to 122 * NULL and EOK will be returned. 114 123 * 115 124 * @return EOK on success or negative error code. 116 */ 117 int program_create_from_image(void *image_addr, char *name, program_t *p) 118 { 119 as_t *as; 120 unsigned int rc; 121 122 as = as_create(0); 123 ASSERT(as); 124 125 rc = elf_load((elf_header_t *) image_addr, as, 0); 125 * 126 */ 127 int program_create_from_image(void *image_addr, char *name, program_t *prg) 128 { 129 as_t *as = as_create(0); 130 if (!as) 131 return ENOMEM; 132 133 unsigned int rc = elf_load((elf_header_t *) image_addr, as, 0); 126 134 if (rc != EE_OK) { 127 135 as_destroy(as); 128 p->task = NULL; 129 p->main_thread = NULL; 136 prg->task = NULL; 137 prg->main_thread = NULL; 138 130 139 if (rc != EE_LOADER) 131 140 return ENOTSUP; 132 141 133 142 /* Register image as the program loader */ 134 ASSERT(program_loader == NULL); 143 if (program_loader != NULL) 144 return ELIMIT; 145 135 146 program_loader = image_addr; 136 147 LOG("Registered program loader at 0x%" PRIp "\n", 137 148 image_addr); 149 138 150 return EOK; 139 151 } 140 141 program_create(as, ((elf_header_t *) image_addr)->e_entry, name, p); 142 143 return EOK; 152 153 return program_create(as, ((elf_header_t *) image_addr)->e_entry, 154 name, prg); 144 155 } 145 156 146 157 /** Create a task from the program loader image. 147 158 * 148 * @param p 149 * @param name 159 * @param prg Buffer for storing program info. 160 * @param name Name to set for the program's task. 150 161 * 151 162 * @return EOK on success or negative error code. 152 */ 153 int program_create_loader(program_t *p, char *name) 154 { 155 as_t *as; 156 unsigned int rc; 157 void *loader; 158 159 as = as_create(0); 160 ASSERT(as); 161 162 loader = program_loader; 163 * 164 */ 165 int program_create_loader(program_t *prg, char *name) 166 { 167 as_t *as = as_create(0); 168 if (!as) 169 return ENOMEM; 170 171 void *loader = program_loader; 163 172 if (!loader) { 164 173 printf("Cannot spawn loader as none was registered\n"); 165 174 return ENOENT; 166 175 } 167 168 rc = elf_load((elf_header_t *) program_loader, as, ELD_F_LOADER); 176 177 unsigned int rc = elf_load((elf_header_t *) program_loader, as, 178 ELD_F_LOADER); 169 179 if (rc != EE_OK) { 170 180 as_destroy(as); 171 181 return ENOENT; 172 182 } 173 174 program_create(as, ((elf_header_t *) program_loader)->e_entry, 175 name, p); 176 177 return EOK; 183 184 return program_create(as, ((elf_header_t *) program_loader)->e_entry, 185 name, prg); 178 186 } 179 187 … … 182 190 * Switch program's main thread to the ready state. 183 191 * 184 * @param p Program to make ready. 185 */ 186 void program_ready(program_t *p) 187 { 188 thread_ready(p->main_thread); 192 * @param prg Program to make ready. 193 * 194 */ 195 void program_ready(program_t *prg) 196 { 197 thread_ready(prg->main_thread); 189 198 } 190 199 … … 194 203 * the task name. 195 204 * 196 * @param name Name to set on the new task (typically the same 197 * as the command used to execute it). 198 * 199 * @return 0 on success or an error code from @ref errno.h. 205 * @param uspace_name Name to set on the new task (typically the same 206 * as the command used to execute it). 207 * @param name_len Length of the name. 208 * 209 * @return EOK on success or an error code from @ref errno.h. 210 * 200 211 */ 201 212 unative_t sys_program_spawn_loader(char *uspace_name, size_t name_len) 202 213 { 203 program_t p;204 int rc;205 char namebuf[TASK_NAME_BUFLEN];206 207 214 /* Cap length of name and copy it from userspace. */ 208 209 215 if (name_len > TASK_NAME_BUFLEN - 1) 210 216 name_len = TASK_NAME_BUFLEN - 1; 211 212 rc = copy_from_uspace(namebuf, uspace_name, name_len); 217 218 char namebuf[TASK_NAME_BUFLEN]; 219 int rc = copy_from_uspace(namebuf, uspace_name, name_len); 213 220 if (rc != 0) 214 221 return (unative_t) rc; 215 222 216 223 namebuf[name_len] = 0; 217 224 218 225 /* Spawn the new task. */ 219 220 rc = program_create_loader(&p , namebuf);226 program_t prg; 227 rc = program_create_loader(&prg, namebuf); 221 228 if (rc != 0) 222 229 return rc; 223 230 224 231 // FIXME: control the capabilities 225 cap_set(p.task, cap_get(TASK)); 226 227 program_ready(&p); 228 232 cap_set(prg.task, cap_get(TASK)); 233 program_ready(&prg); 234 229 235 return EOK; 230 236 }
Note:
See TracChangeset
for help on using the changeset viewer.