/branches/dynload/kernel/generic/include/proc/task.h |
---|
120,7 → 120,7 |
extern void task_destroy(task_t *t); |
extern task_t *task_create_from_as(as_t *as, uintptr_t entry_addr, char *name); |
extern int task_parse_initial(void *program_addr, char *name, task_t **task); |
extern task_t *task_create_from_loader(char *name); |
extern int task_create_from_loader(char *name, task_t **task); |
extern void task_ready(task_t *t); |
extern task_t *task_find_by_id(task_id_t id); |
extern int task_kill(task_id_t id); |
139,7 → 139,7 |
#endif |
extern unative_t sys_task_get_id(task_id_t *uspace_task_id); |
extern unative_t sys_task_spawn(task_id_t *uspace_task_id); |
extern unative_t sys_task_spawn(int *uspace_phone_id); |
#endif |
/branches/dynload/kernel/generic/src/proc/task.c |
---|
50,6 → 50,7 |
#include <adt/btree.h> |
#include <adt/list.h> |
#include <ipc/ipc.h> |
#include <ipc/ipcrsc.h> |
#include <security/cap.h> |
#include <memstr.h> |
#include <print.h> |
323,27 → 324,33 |
/** Create a task from the program loader image. |
* |
* @param program_addr Address of program executable image. |
* @param name Program name. |
* @param t Buffer for storing pointer to the newly created task. |
* |
* @return Task of the running program or NULL on error. |
*/ |
task_t *task_create_from_loader(char *name) |
int task_create_from_loader(char *name, task_t **t) |
{ |
as_t *as; |
unsigned int rc; |
void *loader; |
as = as_create(0); |
ASSERT(as); |
loader = program_loader; |
if (!loader) return ENOENT; |
rc = elf_load((elf_header_t *) program_loader, as, ELD_F_LOADER); |
if (rc != EE_OK) { |
as_destroy(as); |
return NULL; |
return ENOENT; |
} |
return task_create_from_as( |
*t = task_create_from_as( |
as, ((elf_header_t *) program_loader)->e_entry, name); |
return EOK; |
} |
/** Make task ready. |
379,33 → 386,44 |
/** Syscall for creating a new task from userspace. |
* |
* Creates a new task from the program loader image and stores its |
* task id into the provided buffer. |
* Creates a new task from the program loader image, connects a phone |
* to it and stores the phone id into the provided buffer. |
* |
* @param uspace_task_id Userspace address of 8-byte buffer where to store |
* current task ID. |
* @param uspace_phone_id Userspace address where to store the phone id. |
* |
* @return 0 on success or an error code from @ref errno.h. |
*/ |
unative_t sys_task_spawn(task_id_t *uspace_task_id) |
unative_t sys_task_spawn(int *uspace_phone_id) |
{ |
task_t *t; |
task_id_t fake_id; |
int fake_id; |
int rc; |
int phone_id; |
fake_id = 0; |
/* Before we even try creating the task, see if we can write the id */ |
rc = (unative_t) copy_to_uspace(uspace_task_id, &fake_id, |
rc = (unative_t) copy_to_uspace(uspace_phone_id, &fake_id, |
sizeof(fake_id)); |
if (rc != 0) |
return rc; |
t = task_create_from_loader("loader"); |
phone_id = phone_alloc(); |
if (phone_id < 0) |
return ELIMIT; |
rc = task_create_from_loader("loader", &t); |
if (rc != 0) |
return rc; |
phone_connect(phone_id, &t->answerbox); |
/* No need to aquire lock before task_ready() */ |
rc = (unative_t) copy_to_uspace(uspace_task_id, &t->taskid, |
sizeof(t->taskid)); |
rc = (unative_t) copy_to_uspace(uspace_phone_id, &phone_id, |
sizeof(phone_id)); |
if (rc != 0) { |
/* Ooops */ |
ipc_phone_hangup(&TASK->phones[phone_id]); |
task_kill(t->taskid); |
return rc; |
} |
/branches/dynload/uspace/app/dltest/arch/ia32/_link.ld.in |
---|
2,11 → 2,16 |
ENTRY(__entry) |
PHDRS { |
interp PT_INTERP; |
text PT_LOAD FLAGS(5); |
data PT_LOAD FLAGS(6); |
} |
SECTIONS { |
.interp : { |
*(.interp); |
} :interp |
. = 0x1000; |
.init ALIGN(0x1000) : SUBALIGN(0x1000) { |
33,9 → 38,6 |
*(.plt); |
} :text |
.interp : { |
*(.interp); |
} :text |
.dynamic ALIGN(0x1000) : { |
*(.dynamic); |
/branches/dynload/uspace/app/iloader/interp.s |
---|
0,0 → 1,7 |
# |
# Provide a string to be included in a special DT_INTERP header, even though |
# this is a statically-linked executable. This will mark te binary as |
# the program loader. |
# |
.section .interp , "" |
.string "kernel" |
/branches/dynload/uspace/app/iloader/include/elf_load.h |
---|
48,8 → 48,11 |
/** Entry point */ |
entry_point_t entry; |
/** ELF interpreter name or NULL if statically-linked */ |
char *interp; |
/** Pointer to the dynamic section */ |
void *dynamic; |
void *dynamic; |
} elf_info_t; |
/** |
/branches/dynload/uspace/app/iloader/main.c |
---|
35,9 → 35,12 |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <unistd.h> |
#include <fcntl.h> |
#include <sys/types.h> |
#include <ipc/ipc.h> |
#include <errno.h> |
#include <as.h> |
#include <elf.h> |
46,21 → 49,54 |
#define RTLD_BIAS 0x80000 |
int main(int argc, char *argv[]) |
static char *pathname = NULL; |
void iloader_set_pathname(ipc_callid_t rid, ipc_call_t *request) |
{ |
// ipc_callid_t callid; |
size_t len; |
char *name_buf; |
/* printf("iloader_set_pathname\n"); |
if (!ipc_data_write_receive(&callid, &len)) { |
ipc_answer_0(callid, EINVAL); |
ipc_answer_0(rid, EINVAL); |
return; |
} |
*/ |
len = IPC_GET_ARG2(*request); |
printf("alloc %d bytes\n", len+1); |
name_buf = malloc(len + 1); |
if (!name_buf) { |
// ipc_answer_0(callid, ENOMEM); |
ipc_answer_0(rid, ENOMEM); |
return; |
} |
printf("write_finalize\n"); |
ipc_data_write_finalize(rid, name_buf, len); |
// ipc_answer_0(rid, EOK); |
if (pathname != NULL) { |
free(pathname); |
pathname = NULL; |
} |
pathname = name_buf; |
} |
int iloader_run(ipc_callid_t rid, ipc_call_t *request) |
{ |
int rc; |
pcb_t *pcb; |
elf_info_t prog_info; |
elf_info_t interp_info; |
char *file_name; |
pcb_t *pcb; |
int rc; |
printf("This is loader\n"); |
getchar(); |
printf("Load program '%s'\n", pathname); |
printf("Load program\n"); |
rc = elf_load_file("/dltest", 0, &prog_info); |
// rc = elf_load_file("/tetris", 0, &prog_info); |
rc = elf_load_file(pathname, 0, &prog_info); |
if (rc < 0) { |
printf("failed to load program\n"); |
return 1; |
69,14 → 105,15 |
printf("Create PCB\n"); |
if (elf_create_pcb(&prog_info) < 0) return 1; |
// elf_run(&prog_info); |
if (prog_info.interp == NULL) { |
/* Statically linked program */ |
printf("Run statically linked program\n"); |
elf_run(&prog_info); |
return 0; |
} |
// getchar(); |
printf("Load dynamic linker\n"); |
file_name = "/rtld.so"; |
printf("open and read '%s'...\n", file_name); |
rc = elf_load_file(file_name, RTLD_BIAS, &interp_info); |
printf("Load dynamic linker '%s'\n", prog_info.interp); |
rc = elf_load_file("/rtld.so", RTLD_BIAS, &interp_info); |
if (rc < 0) { |
printf("failed to load dynamic linker\n"); |
return 1; |
83,7 → 120,7 |
} |
/* |
* Provide rtld with some useful data |
* Provide dynamic linker with some useful data |
*/ |
pcb = (pcb_t *)PCB_ADDRESS; |
pcb->rtld_dynamic = interp_info.dynamic; |
92,6 → 129,35 |
printf("run dynamic linker\n"); |
elf_run(&interp_info); |
return 0; |
} |
int main(int argc, char *argv[]) |
{ |
ipc_callid_t callid; |
ipc_call_t call; |
int retval; |
int len; |
while (1) { |
callid = ipc_wait_for_call(&call); |
printf("received call, method=%d\n", IPC_GET_METHOD(call)); |
switch (IPC_GET_METHOD(call)) { |
case IPC_M_DATA_WRITE: |
iloader_set_pathname(callid, &call); |
iloader_run(callid, &call); |
exit(0); |
continue; |
default: |
retval = ENOENT; |
break; |
} |
if ((callid & IPC_CALLID_NOTIFICATION) == 0) { |
printf("responding EINVAL to method %d\n", IPC_GET_METHOD(call)); |
ipc_answer_0(callid, EINVAL); |
} |
} |
/* not reached */ |
return 0; |
} |
/branches/dynload/uspace/app/iloader/elf_load.c |
---|
181,6 → 181,8 |
elf->bias = 0; |
printf("Bias set to 0x%x\n", elf->bias); |
elf->info->interp = NULL; |
elf->info->dynamic = NULL; |
printf("parse segments\n"); |
201,7 → 203,6 |
} |
printf("parse sections\n"); |
elf->info->dynamic = NULL; |
/* Inspect all section headers and proccess them. */ |
for (i = 0; i < header->e_shnum; i++) { |
256,8 → 257,11 |
case PT_LOAD: |
return load_segment(elf, entry); |
break; |
case PT_INTERP: |
/* Assume silently interp == "/rtld.so" */ |
elf->info->interp = "/rtld.so"; |
break; |
case PT_DYNAMIC: |
case PT_INTERP: |
case PT_SHLIB: |
case PT_NOTE: |
case PT_LOPROC: |
/branches/dynload/uspace/app/iloader/Makefile |
---|
40,7 → 40,7 |
CFLAGS += -Iinclude -D__32_BITS__ |
LIBS = $(LIBC_PREFIX)/libc.a |
LIBS = $(LIBC_PREFIX)/libc.a $(SOFTINT_PREFIX)/libsoftint.a |
DEFS += -DRELEASE=\"$(RELEASE)\" |
ifdef REVISION |
57,7 → 57,8 |
OUTPUT = iloader |
SOURCES = \ |
main.c \ |
elf_load.c |
elf_load.c \ |
interp.s |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
78,7 → 79,7 |
$(OUTPUT): $(OBJECTS) $(LIBS) arch/$(ARCH)/_link.ld |
# $(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
$(LD) -T arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
$(LD) -T arch/$(ARCH)/_link.ld $(LFLAGS) $(OBJECTS) $(LIBS) -o $@ -Map $(OUTPUT).map |
disasm: |
$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm |
/branches/dynload/uspace/app/iloader/arch/ia32/_link.ld.in |
---|
1,16 → 1,21 |
/* |
* The only difference from _link.ld.in for regular statically-linked apps |
* is the base address. |
* The difference from _link.ld.in for regular statically-linked apps |
* is the base address and the special interp section. |
*/ |
STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o) |
ENTRY(__entry) |
PHDRS { |
text PT_LOAD FLAGS(5); |
interp PT_INTERP; |
text PT_LOAD FILEHDR PHDRS FLAGS(5); |
data PT_LOAD FLAGS(6); |
} |
SECTIONS { |
.interp : { |
*(.interp); |
} : interp |
. = 0x70001000; |
.init ALIGN(0x1000) : SUBALIGN(0x1000) { |
/branches/dynload/uspace/app/iramfs/data.h |
---|
49,6 → 49,10 |
extern const size_t libc_size; |
extern const char libc_filename[]; |
extern const uint8_t tetris[]; |
extern const size_t tetris_size; |
extern const char tetris_filename[]; |
#endif |
/** @} |
/branches/dynload/uspace/app/iramfs/main.c |
---|
89,6 → 89,7 |
if (write_file(rtld, rtld_size, rtld_filename) < 0) return 1; |
if (write_file(dltest, dltest_size, dltest_filename) < 0) return 1; |
if (write_file(libc, libc_size, libc_filename) < 0) return 1; |
if (write_file(tetris, tetris_size, tetris_filename) < 0) return 1; |
printf("done\n"); |
getchar(); |
/branches/dynload/uspace/app/iramfs/Makefile |
---|
87,7 → 87,8 |
%.o: %.c |
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@ |
data.c: ../../lib/rtld/rtld.so ../dltest/dltest ../../lib/libc-shared/libc.so.0 |
data.c: ../../lib/rtld/rtld.so ../dltest/dltest ../../lib/libc-shared/libc.so.0 ../tetris/tetris |
../../../tools/bin2c.py ../../lib/rtld/rtld.so rtld.so rtld >$@ |
../../../tools/bin2c.py ../dltest/dltest dltest dltest >>$@ |
../../../tools/bin2c.py ../../lib/libc-shared/libc.so.0 libc.so.0 libc >>$@ |
../../../tools/bin2c.py ../tetris/tetris tetris tetris >>$@ |
/branches/dynload/uspace/app/cli/cli.c |
---|
0,0 → 1,93 |
/* |
* Copyright (c) 2008 Jiri Svoboda |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup cli cli |
* @brief Trivial command-line interface for running programs. |
* @{ |
*/ |
/** |
* @file |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <task.h> |
#define LINE_BUFFER_SIZE 128 |
static char line_buffer[LINE_BUFFER_SIZE]; |
void read_line(char *buffer, int n) |
{ |
char c; |
int chars; |
printf("> "); |
chars = 0; |
while (chars < n - 1) { |
c = getchar(); |
if (c == '\n') break; |
if (c == '\b') { |
if (chars > 0) { |
putchar('\b'); |
--chars; |
} |
continue; |
} |
putchar(c); |
buffer[chars++] = c; |
} |
putchar('\n'); |
buffer[chars] = '\0'; |
} |
int main(int argc, char *argv[]) |
{ |
printf("This is CLI\n"); |
while (1) { |
read_line(line_buffer, LINE_BUFFER_SIZE); |
printf("'%s'\n", line_buffer); |
if (strcmp(line_buffer, "exit") == 0) |
break; |
printf("spawn task\n"); |
if (line_buffer[0] != '\0') |
task_spawn(line_buffer, NULL); |
} |
printf("Bye\n"); |
return 0; |
} |
/** @} |
*/ |
/branches/dynload/uspace/app/cli/Makefile |
---|
0,0 → 1,86 |
# |
# Copyright (c) 2005 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
include ../../../version |
include ../../Makefile.config |
## Setup toolchain |
# |
LIBC_PREFIX = ../../lib/libc |
SOFTINT_PREFIX = ../../lib/softint |
include $(LIBC_PREFIX)/Makefile.toolchain |
CFLAGS += -I../../srv/kbd/include |
LIBS = $(LIBC_PREFIX)/libc.a |
DEFS += -DRELEASE=\"$(RELEASE)\" |
ifdef REVISION |
DEFS += "-DREVISION=\"$(REVISION)\"" |
endif |
ifdef TIMESTAMP |
DEFS += "-DTIMESTAMP=\"$(TIMESTAMP)\"" |
endif |
## Sources |
# |
OUTPUT = cli |
SOURCES = \ |
cli.c |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
.PHONY: all clean depend disasm |
all: $(OUTPUT) disasm |
-include Makefile.depend |
clean: |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend |
depend: |
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend |
$(OUTPUT): $(OBJECTS) $(LIBS) |
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
disasm: |
$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
%.o: %.s |
$(AS) $(AFLAGS) $< -o $@ |
%.o: %.c |
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@ |
/branches/dynload/uspace/lib/rtld/arch/ppc32/src/runtime.c |
---|
42,7 → 42,7 |
{ |
asm volatile ( |
"mr %%r3, %0\n" |
"li %%r9, 30\n" |
"li %%r9, 31\n" |
"sc\n" |
: |
: "r" (i) |
/branches/dynload/uspace/lib/rtld/arch/ppc32/src/bootstrap.c |
---|
49,7 → 49,7 |
{ |
asm volatile ( |
"mr %%r3, %0\n" |
"li %%r9, 30\n" |
"li %%r9, 31\n" |
"sc\n" |
: |
: "r" (i) |
/branches/dynload/uspace/lib/rtld/arch/ia32/src/runtime.c |
---|
42,7 → 42,7 |
{ |
unsigned dummy; |
asm volatile ( |
"movl $30, %%eax;" |
"movl $31, %%eax;" |
"int $0x30" |
: "=d" (dummy) /* output - %edx clobbered */ |
: "d" (i) /* input */ |
/branches/dynload/uspace/lib/rtld/arch/ia32/src/bootstrap.c |
---|
46,7 → 46,7 |
{ |
unsigned dummy; |
asm volatile ( |
"movl $30, %%eax;" |
"movl $31, %%eax;" |
"int $0x30" |
: "=d" (dummy) /* output - %edx clobbered */ |
: "d" (i) /* input */ |
/branches/dynload/uspace/lib/libc/include/task.h |
---|
40,6 → 40,7 |
typedef uint64_t task_id_t; |
extern task_id_t task_get_id(void); |
task_id_t task_spawn(const char *path, const char *argv[]); |
#endif |
/branches/dynload/uspace/lib/libc/generic/task.c |
---|
33,7 → 33,9 |
*/ |
#include <task.h> |
#include <libc.h> |
#include <ipc/ipc.h> |
#include <async.h> |
#include <errno.h> |
task_id_t task_get_id(void) |
{ |
44,5 → 46,50 |
return task_id; |
} |
static int task_spawn_loader(void) |
{ |
int phone_id, rc; |
rc = __SYSCALL1(SYS_TASK_SPAWN, (sysarg_t) &phone_id); |
if (rc != 0) |
return rc; |
return phone_id; |
} |
#include <stdio.h> |
#include <unistd.h> |
task_id_t task_spawn(const char *path, const char *argv[]) |
{ |
int phone_id; |
ipc_call_t answer; |
aid_t req; |
int rc; |
phone_id = task_spawn_loader(); |
if (phone_id < 0) return 0; |
printf("phone_id:%d\n", phone_id); |
// getchar(); |
// req = async_send_0(phone_id, 1024, &answer); |
rc = ipc_data_write_start(phone_id, (void *)path, strlen(path)); |
printf("->%d\n", rc); |
if (rc != EOK) { |
// async_wait_for(req, NULL); |
return 1; |
} |
// async_wait_for(req, &rc); |
if (rc != EOK) return 0; |
// rc = async_req_0_0(phone_id, 1025); |
// printf("->%d\n", rc); |
// if (rc != EOK) return 0; |
// ipc_hangup(phone_id); |
return 1; |
} |
/** @} |
*/ |
/branches/dynload/uspace/Makefile |
---|
53,6 → 53,7 |
app/tester \ |
app/dltest \ |
app/iramfs \ |
app/cli \ |
app/klog \ |
app/init |
/branches/dynload/boot/arch/ia32/grub/menu.lst |
---|
15,7 → 15,8 |
# module /boot/fat |
module /boot/devmap |
# module /boot/tetris |
# module /boot/tester |
module /boot/tester |
module /boot/iramfs |
module /boot/iloader |
module /boot/cli |
module /boot/klog |
/branches/dynload/boot/arch/ia32/Makefile.inc |
---|
41,6 → 41,7 |
$(USPACEDIR)/app/tester/tester \ |
$(USPACEDIR)/app/iramfs/iramfs \ |
$(USPACEDIR)/app/iloader/iloader \ |
$(USPACEDIR)/app/cli/cli \ |
$(USPACEDIR)/app/klog/klog |
build: $(BASE)/image.iso |