Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 3222 → Rev 3221

/trunk/uspace/srv/loader/include/elf_load.h
File deleted
/trunk/uspace/srv/loader/include/elf.h
File deleted
/trunk/uspace/srv/loader/include/arch.h
File deleted
/trunk/uspace/srv/loader/main.c
File deleted
/trunk/uspace/srv/loader/elf_load.c
File deleted
/trunk/uspace/srv/loader/arch/ppc32/_link.ld.in
File deleted
/trunk/uspace/srv/loader/arch/ppc32/Makefile.inc
File deleted
/trunk/uspace/srv/loader/arch/ppc32/ppc32.s
File deleted
/trunk/uspace/srv/loader/arch/amd64/_link.ld.in
File deleted
/trunk/uspace/srv/loader/arch/amd64/Makefile.inc
File deleted
/trunk/uspace/srv/loader/arch/amd64/amd64.s
File deleted
/trunk/uspace/srv/loader/arch/mips32/mips32.s
File deleted
/trunk/uspace/srv/loader/arch/mips32/_link.ld.in
File deleted
/trunk/uspace/srv/loader/arch/mips32/Makefile.inc
File deleted
/trunk/uspace/srv/loader/arch/ia32/ia32.s
File deleted
/trunk/uspace/srv/loader/arch/ia32/_link.ld.in
File deleted
/trunk/uspace/srv/loader/arch/ia32/Makefile.inc
File deleted
/trunk/uspace/srv/loader/arch/sparc64/_link.ld.in
File deleted
/trunk/uspace/srv/loader/arch/sparc64/sparc64.s
File deleted
/trunk/uspace/srv/loader/arch/sparc64/Makefile.inc
File deleted
/trunk/uspace/srv/loader/arch/ia64/Makefile.inc
File deleted
/trunk/uspace/srv/loader/arch/ia64/_link.ld.in
File deleted
/trunk/uspace/srv/loader/arch/ia64/ia64.s
File deleted
/trunk/uspace/srv/loader/arch/arm32/Makefile.inc
File deleted
/trunk/uspace/srv/loader/arch/arm32/arm32.s
File deleted
/trunk/uspace/srv/loader/arch/arm32/_link.ld.in
File deleted
/trunk/uspace/srv/loader/Makefile
File deleted
/trunk/uspace/srv/loader/interp.s
File deleted
/trunk/uspace/lib/libc/generic/pcb.c
File deleted
/trunk/uspace/lib/libc/generic/smc.c
File deleted
/trunk/uspace/lib/libc/generic/io/stream.c
96,15 → 96,6
}
}
 
void close_console(void)
{
if (console_phone >= 0) {
if (ipc_hangup(console_phone) == 0) {
console_phone = -1;
}
}
}
 
void klog_update(void)
{
(void) __SYSCALL3(SYS_KLOG, 1, NULL, 0);
/trunk/uspace/lib/libc/generic/libc.c
48,10 → 48,8
#include <ipc/ipc.h>
#include <async.h>
#include <as.h>
#include <loader/pcb.h>
 
extern char _heap;
extern int main(int argc, char *argv[]);
 
void _exit(int status)
{
58,11 → 56,9
thread_exit(status);
}
 
void __main(void *pcb_ptr)
void __main(void)
{
fibril_t *f;
int argc;
char **argv;
 
(void) as_area_create(&_heap, 1, AS_AREA_WRITE | AS_AREA_READ);
_async_init();
70,19 → 66,6
__tcb_set(f->tcb);
open_console();
 
/* Save the PCB pointer */
__pcb = (pcb_t *)pcb_ptr;
 
if (__pcb == NULL) {
argc = 0;
argv = NULL;
} else {
argc = __pcb->argc;
argv = __pcb->argv;
}
 
main(argc, argv);
}
 
void __exit(void)
/trunk/uspace/lib/libc/generic/task.c
1,6 → 1,5
/*
* Copyright (c) 2006 Jakub Jermar
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
34,13 → 33,7
*/
 
#include <task.h>
#include <ipc/ipc.h>
#include <ipc/loader.h>
#include <libc.h>
#include <string.h>
#include <stdlib.h>
#include <async.h>
#include <errno.h>
 
task_id_t task_get_id(void)
{
51,124 → 44,10
return task_id;
}
 
static int task_spawn_loader(void)
int task_spawn(void *image, size_t size)
{
int phone_id, rc;
 
rc = __SYSCALL1(SYS_PROGRAM_SPAWN_LOADER, (sysarg_t) &phone_id);
if (rc != 0)
return rc;
 
return phone_id;
return __SYSCALL2(SYS_TASK_SPAWN, (sysarg_t) image, (sysarg_t) size);
}
 
static int loader_set_args(int phone_id, const char *argv[])
{
aid_t req;
ipc_call_t answer;
ipcarg_t rc;
 
const char **ap;
char *dp;
char *arg_buf;
size_t buffer_size;
size_t len;
 
/*
* Serialize the arguments into a single array. First
* compute size of the buffer needed.
*/
ap = argv;
buffer_size = 0;
while (*ap != NULL) {
buffer_size += strlen(*ap) + 1;
++ap;
}
 
arg_buf = malloc(buffer_size);
if (arg_buf == NULL) return ENOMEM;
 
/* Now fill the buffer with null-terminated argument strings */
ap = argv;
dp = arg_buf;
while (*ap != NULL) {
strcpy(dp, *ap);
dp += strlen(*ap) + 1;
 
++ap;
}
 
/* Send serialized arguments to the loader */
 
req = async_send_0(phone_id, LOADER_SET_ARGS, &answer);
rc = ipc_data_write_start(phone_id, (void *)arg_buf, buffer_size);
if (rc != EOK) {
async_wait_for(req, NULL);
return rc;
}
 
async_wait_for(req, &rc);
if (rc != EOK) return rc;
 
/* Free temporary buffer */
free(arg_buf);
 
return EOK;
}
 
/** Create a new task by running an executable from VFS.
*
* @param path pathname of the binary to execute
* @param argv command-line arguments
* @return ID of the newly created task or zero on error.
*/
task_id_t task_spawn(const char *path, const char *argv[])
{
int phone_id;
ipc_call_t answer;
aid_t req;
int rc;
ipcarg_t retval;
 
/* Spawn a program loader */
phone_id = task_spawn_loader();
if (phone_id < 0) return 0;
 
/*
* Say hello so that the loader knows the incoming connection's
* phone hash.
*/
rc = async_req_0_0(phone_id, LOADER_HELLO);
if (rc != EOK) return 0;
 
/* Send program pathname */
req = async_send_0(phone_id, LOADER_SET_PATHNAME, &answer);
rc = ipc_data_write_start(phone_id, (void *)path, strlen(path));
if (rc != EOK) {
async_wait_for(req, NULL);
return 1;
}
 
async_wait_for(req, &retval);
if (retval != EOK) goto error;
 
/* Send arguments */
rc = loader_set_args(phone_id, argv);
if (rc != EOK) goto error;
 
/* Request loader to start the program */
rc = async_req_0_0(phone_id, LOADER_RUN);
if (rc != EOK) goto error;
 
/* Success */
ipc_hangup(phone_id);
return 1;
 
/* Error exit */
error:
ipc_hangup(phone_id);
return 0;
}
 
/** @}
*/
/trunk/uspace/lib/libc/generic/as.c
85,20 → 85,6
return __SYSCALL1(SYS_AS_AREA_DESTROY, (sysarg_t ) address);
}
 
/** Change address-space area flags.
*
* @param address Virtual address pointing into the address space area being
* modified.
* @param flags New flags describing type of the area.
*
* @return Zero on success or a code from @ref errno.h on failure.
*/
int as_area_change_flags(void *address, int flags)
{
return __SYSCALL2(SYS_AS_AREA_CHANGE_FLAGS, (sysarg_t) address,
(sysarg_t) flags);
}
 
static size_t heapsize = 0;
static size_t maxheapsize = (size_t) (-1);
 
/trunk/uspace/lib/libc/arch/arm32/src/entry.s
34,11 → 34,8
 
## User-space task entry point
#
# r1 contains the PCB pointer
#
__entry:
# Pass pcb_ptr to __main as the first argument (in r0)
mov r0, r1
bl __main
 
bl main
bl __exit
/trunk/uspace/lib/libc/arch/ia32/src/entry.s
34,7 → 34,6
 
## User-space task entry point
#
# %ebx contains the PCB pointer
#
__entry:
mov %ss, %ax
42,9 → 41,7
mov %ax, %es
mov %ax, %fs
# Do not set %gs, it contains descriptor that can see TLS
 
# Pass the PCB pointer to __main as the first argument
pushl %ebx
call __main
 
call main
call __exit
/trunk/uspace/lib/libc/arch/amd64/src/entry.s
34,11 → 34,8
 
## User-space task entry point
#
# %rdi contains the PCB pointer
#
__entry:
# %rdi was deliberately chosen as the first argument is also in %rdi
# Pass PCB pointer to __main (no operation)
call __main
 
call main
call __exit
/trunk/uspace/lib/libc/arch/mips32/src/entry.s
35,13 → 35,13
 
## User-space task entry point
#
# $a0 ($4) contains the PCB pointer
#
.ent __entry
__entry:
.frame $sp, 32, $31
.cpload $25
 
# Mips o32 may store its arguments on stack, make space (16 bytes),
# so that it could work with -O0
# Make space additional 16 bytes for the stack frame
48,14 → 48,13
 
addiu $sp, -32
.cprestore 16 # Allow PIC code
 
# Pass pcb_ptr to __main() as the first argument. pcb_ptr is already
# in $a0. As the first argument is passed in $a0, no operation
# is needed.
 
jal __main
nop
jal main
nop
jal __exit
nop
.end
/trunk/uspace/lib/libc/arch/ia64/src/entry.s
34,14 → 34,12
 
## User-space task entry point
#
# r2 contains the PCB pointer
#
__entry:
alloc loc0 = ar.pfs, 0, 1, 2, 0
mov r1 = _gp
 
# Pass PCB pointer as the first argument to __main
mov out0 = r2
mov r1 = _gp
br.call.sptk.many b0 = __main
0:
br.call.sptk.many b0 = main
1:
br.call.sptk.many b0 = __exit
/trunk/uspace/lib/libc/arch/sparc64/src/entry.s
34,15 → 34,12
 
## User-space task entry point
#
# %o0 contains uarg
# %o1 contains pcb_ptr
#
__entry:
# Pass pcb_ptr as the first argument to __main()
mov %o1, %o0
sethi %hi(_gp), %l7
call __main
or %l7, %lo(_gp), %l7
 
call main
nop
call __exit
nop
/trunk/uspace/lib/libc/arch/ppc32/src/entry.s
34,11 → 34,8
 
## User-space task entry point
#
# r3 contains the PCB pointer
#
__entry:
# Pass the PCB pointer to __main() as the first argument.
# Since the first argument is passed in r3, no operation is needed.
bl __main
 
bl main
bl __exit
/trunk/uspace/lib/libc/arch/ppc64/src/entry.s
31,6 → 31,7
.org 0
 
.globl __entry
.globl __entry_driver
 
## User-space task entry point
#
37,4 → 38,11
#
__entry:
bl __main
bl __io_init
bl main
bl __exit
 
__entry_driver:
bl __main
bl main
bl __exit
/trunk/uspace/lib/libc/include/smc.h
File deleted
/trunk/uspace/lib/libc/include/loader/pcb.h
File deleted
/trunk/uspace/lib/libc/include/io/stream.h
40,7 → 40,6
#define EMFILE -17
 
extern void open_console(void);
extern void close_console(void);
extern void klog_update(void);
 
extern ssize_t read_stdin(void *, size_t);
/trunk/uspace/lib/libc/include/ipc/loader.h
File deleted
/trunk/uspace/lib/libc/include/task.h
40,7 → 40,7
typedef uint64_t task_id_t;
 
extern task_id_t task_get_id(void);
extern task_id_t task_spawn(const char *path, const char *argv[]);
extern int task_spawn(void *image, size_t size);
 
#endif
 
/trunk/uspace/lib/libc/include/libc.h
48,7 → 48,7
#define __SYSCALL6(id, p1, p2, p3, p4, p5, p6) \
__syscall(p1, p2, p3, p4, p5, p6,id)
 
extern void __main(void *pcb_ptr);
extern void __main(void);
extern void __exit(void);
 
#endif
/trunk/uspace/lib/libc/include/as.h
42,7 → 42,6
 
extern void *as_area_create(void *address, size_t size, int flags);
extern int as_area_resize(void *address, size_t size, int flags);
extern int as_area_change_flags(void *address, int flags);
extern int as_area_destroy(void *address);
extern void *set_maxheapsize(size_t mhs);
extern void * as_get_mappable_page(size_t sz);
/trunk/uspace/lib/libc/Makefile
51,8 → 51,6
generic/cap.c \
generic/string.c \
generic/fibril.c \
generic/pcb.c \
generic/smc.c \
generic/thread.c \
generic/tls.c \
generic/task.c \
/trunk/uspace/app/cli/cli.c
File deleted
/trunk/uspace/app/cli/Makefile
File deleted
/trunk/uspace/app/init/init.c
45,6 → 45,10
#include "init.h"
#include "version.h"
 
#define BUF_SIZE 150000
 
static char *buf;
 
static void console_wait(void)
{
while (get_cons_phone() < 0)
78,16 → 82,28
 
static void spawn(char *fname)
{
char *argv[2];
 
printf(NAME ": Spawning %s\n", fname);
 
argv[0] = fname;
argv[1] = NULL;
 
if (task_spawn(fname, argv) != 0) {
/* Success */
sleep(1);
int fd = open(fname, O_RDONLY);
if (fd >= 0) {
ssize_t rd;
size_t len = 0;
// FIXME: cannot do long reads yet
do {
rd = read(fd, buf + len, 1024);
if (rd > 0)
len += rd;
} while (rd > 0);
if (len > 0) {
task_spawn(buf, len);
sleep(1); // FIXME
}
close(fd);
}
}
 
101,6 → 117,8
return -1;
}
buf = malloc(BUF_SIZE);
// FIXME: spawn("/sbin/pci");
spawn("/sbin/fb");
spawn("/sbin/kbd");
111,10 → 129,10
spawn("/sbin/fat");
spawn("/sbin/tetris");
spawn("/sbin/cli");
// FIXME: spawn("/sbin/tester");
spawn("/sbin/klog");
free(buf);
return 0;
}
 
/trunk/uspace/app/tester/tester.c
107,17 → 107,8
printf("*\t\t\tRun all safe tests\n");
}
 
int main(int argc, char **argv)
int main(void)
{
printf("Number of arguments: %d\n", argc);
if (argv) {
printf("Arguments:");
while (*argv) {
printf(" '%s'", *argv++);
}
printf("\n");
}
 
while (1) {
char c;
test_t *test;
/trunk/uspace/Makefile
37,7 → 37,6
lib/softint \
lib/softfloat \
srv/ns \
srv/loader \
srv/fb \
srv/kbd \
srv/console \
48,7 → 47,6
srv/devmap \
app/tetris \
app/tester \
app/cli \
app/klog \
app/init
 
/trunk/kernel/arch/ia32/src/userspace.c
70,10 → 70,6
"pushl %3\n"
"pushl %4\n"
"movl %5, %%eax\n"
 
/* %ebx is defined to hold pcb_ptr - set it to 0 */
"xorl %%ebx, %%ebx\n"
 
"iret\n"
:
: "i" (selector(UDATA_DES) | PL_USER),
/trunk/kernel/arch/ppc32/src/asm.S
65,10 → 65,6
# set stack
mr sp, r4
 
# %r3 is defined to hold pcb_ptr - set it to 0
 
xor r3, r3, r3
# jump to userspace
/trunk/kernel/arch/amd64/src/userspace.c
61,8 → 61,6
"pushq %3\n"
"pushq %4\n"
"movq %5, %%rax\n"
/* %rdi is defined to hold pcb_ptr - set it to 0 */
"xorq %%rdi, %%rdi\n"
"iretq\n"
: :
"i" (gdtselector(UDATA_DES) | PL_USER),
/trunk/kernel/arch/mips32/src/start.S
349,7 → 349,5
userspace_asm:
add $sp, $a0, 0
add $v0, $a1, 0
add $t9, $a2, 0 # Set up correct entry into PIC code
xor $a0, $a0, $a0 # $a0 is defined to hold pcb_ptr
# set it to 0
add $t9, $a2, 0 # Set up correct entry into PIC code
eret
/trunk/kernel/arch/sparc64/src/asm.S
274,8 → 274,6
wrpr %g0, 0, %cleanwin ! avoid information leak
 
mov %i2, %o0 ! uarg
xor %o1, %o1, %o1 ! %o1 is defined to hold pcb_ptr
! set it to 0
 
clr %i2
clr %i3
/trunk/kernel/arch/ia64/src/asm.S
163,9 → 163,6
 
xor r1 = r1, r1
/* r2 is defined to hold pcb_ptr - set it to 0 */
xor r2 = r2, r2
mov loc1 = cr.ifs
movl loc2 = PFM_MASK ;;
and loc1 = loc2, loc1 ;;
/trunk/kernel/arch/arm32/src/userspace.c
70,11 → 70,8
/* set first parameter */
ustate.r0 = (uintptr_t) kernel_uarg->uspace_uarg;
 
/* %r1 is defined to hold pcb_ptr - set it to 0 */
ustate.r1 = 0;
 
/* clear other registers */
ustate.r2 = ustate.r3 = ustate.r4 = ustate.r5 =
ustate.r1 = ustate.r2 = ustate.r3 = ustate.r4 = ustate.r5 =
ustate.r6 = ustate.r7 = ustate.r8 = ustate.r9 = ustate.r10 =
ustate.r11 = ustate.r12 = ustate.lr = 0;
 
/trunk/kernel/arch/ppc64/src/asm.S
66,10 → 66,6
mr sp, r4
# %r3 is defined to hold pcb_ptr - set it to 0
 
xor r3, r3, r3
 
# jump to userspace
rfi
/trunk/kernel/arch/ia32xen/src/userspace.c
68,10 → 68,6
"pushl %3\n"
"pushl %4\n"
"movl %5, %%eax\n"
 
/* %ebx is defined to hold pcb_ptr - set it to 0 */
"xorl %%ebx, %%ebx\n"
 
"iret\n"
:
: "i" (selector(UDATA_DES) | PL_USER),
/trunk/kernel/generic/include/mm/as.h
269,7 → 269,6
extern int as_area_resize(as_t *as, uintptr_t address, size_t size, int flags);
int as_area_share(as_t *src_as, uintptr_t src_base, size_t acc_size,
as_t *dst_as, uintptr_t dst_base, int dst_flags_mask);
extern int as_area_change_flags(as_t *as, int flags, uintptr_t address);
 
extern int as_area_get_flags(as_area_t *area);
extern bool as_area_check_access(as_area_t *area, pf_access_t access);
300,19 → 299,11
extern mem_backend_t elf_backend;
extern mem_backend_t phys_backend;
 
/**
* This flags is passed when running the loader, otherwise elf_load()
* would return with a EE_LOADER error code.
*/
#define ELD_F_NONE 0
#define ELD_F_LOADER 1
extern unsigned int elf_load(elf_header_t *header, as_t *as);
 
extern unsigned int elf_load(elf_header_t *header, as_t *as, int flags);
 
/* Address space area related syscalls. */
extern unative_t sys_as_area_create(uintptr_t address, size_t size, int flags);
extern unative_t sys_as_area_resize(uintptr_t address, size_t size, int flags);
extern unative_t sys_as_area_change_flags(uintptr_t address, int flags);
extern unative_t sys_as_area_destroy(uintptr_t address);
 
/* Introspection functions. */
/trunk/kernel/generic/include/synch/smc.h
File deleted
/trunk/kernel/generic/include/syscall/syscall.h
44,15 → 44,13
SYS_THREAD_GET_ID,
SYS_TASK_GET_ID,
SYS_PROGRAM_SPAWN_LOADER,
SYS_TASK_SPAWN,
SYS_FUTEX_SLEEP,
SYS_FUTEX_WAKEUP,
SYS_SMC_COHERENCE,
SYS_AS_AREA_CREATE,
SYS_AS_AREA_RESIZE,
SYS_AS_AREA_CHANGE_FLAGS,
SYS_AS_AREA_DESTROY,
SYS_IPC_CALL_SYNC_FAST,
/trunk/kernel/generic/include/proc/program.h
File deleted
/trunk/kernel/generic/include/proc/task.h
132,6 → 132,7
#endif
 
extern unative_t sys_task_get_id(task_id_t *uspace_task_id);
extern unative_t sys_task_spawn(void *image, size_t size);
 
#endif
 
/trunk/kernel/generic/include/proc/thread.h
248,6 → 248,8
extern void thread_update_accounting(void);
extern bool thread_exists(thread_t *t);
 
extern thread_t *thread_create_program(void *program_addr, char *name);
 
/** Fpu context slab cache. */
extern slab_cache_t *fpu_context_slab;
 
/trunk/kernel/generic/include/lib/elf.h
114,8 → 114,7
#define EE_MEMORY 2 /* Cannot allocate address space */
#define EE_INCOMPATIBLE 3 /* ELF image is not compatible with current architecture */
#define EE_UNSUPPORTED 4 /* Non-supported ELF (e.g. dynamic ELFs) */
#define EE_LOADER 5 /* The image is actually a program loader */
#define EE_IRRECOVERABLE 6
#define EE_IRRECOVERABLE 5
 
/**
* ELF section types
339,10 → 338,6
 
extern char *elf_error(unsigned int rc);
 
/* Interpreter string used to recognize the program loader */
#define ELF_INTERP_ZSTR "kernel"
#define ELF_INTERP_ZLEN sizeof(ELF_INTERP_ZSTR)
 
#endif
 
/** @}
/trunk/kernel/generic/src/mm/as.c
771,160 → 771,6
return true;
}
 
/** Change adress area flags.
*
* The idea is to have the same data, but with a different access mode.
* This is needed e.g. for writing code into memory and then executing it.
* In order for this to work properly, this may copy the data
* into private anonymous memory (unless it's already there).
*
* @param as Address space.
* @param flags Flags of the area memory.
* @param address Address withing the area to be changed.
*
* @return Zero on success or a value from @ref errno.h on failure.
*/
int as_area_change_flags(as_t *as, int flags, uintptr_t address)
{
as_area_t *area;
uintptr_t base;
link_t *cur;
ipl_t ipl;
int page_flags;
uintptr_t *old_frame;
index_t frame_idx;
count_t used_pages;
 
/* Flags for the new memory mapping */
page_flags = area_flags_to_page_flags(flags);
 
ipl = interrupts_disable();
mutex_lock(&as->lock);
 
area = find_area_and_lock(as, address);
if (!area) {
mutex_unlock(&as->lock);
interrupts_restore(ipl);
return ENOENT;
}
 
if (area->sh_info || area->backend != &anon_backend) {
/* Copying shared areas not supported yet */
/* Copying non-anonymous memory not supported yet */
mutex_unlock(&area->lock);
mutex_unlock(&as->lock);
interrupts_restore(ipl);
return ENOTSUP;
}
 
base = area->base;
 
/*
* Compute total number of used pages in the used_space B+tree
*/
used_pages = 0;
 
for (cur = area->used_space.leaf_head.next;
cur != &area->used_space.leaf_head; cur = cur->next) {
btree_node_t *node;
unsigned int i;
node = list_get_instance(cur, btree_node_t, leaf_link);
for (i = 0; i < node->keys; i++) {
used_pages += (count_t) node->value[i];
}
}
 
/* An array for storing frame numbers */
old_frame = malloc(used_pages * sizeof(uintptr_t), 0);
 
/*
* Start TLB shootdown sequence.
*/
tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base, area->pages);
 
/*
* Remove used pages from page tables and remember their frame
* numbers.
*/
frame_idx = 0;
 
for (cur = area->used_space.leaf_head.next;
cur != &area->used_space.leaf_head; cur = cur->next) {
btree_node_t *node;
unsigned int i;
node = list_get_instance(cur, btree_node_t, leaf_link);
for (i = 0; i < node->keys; i++) {
uintptr_t b = node->key[i];
count_t j;
pte_t *pte;
for (j = 0; j < (count_t) node->value[i]; j++) {
page_table_lock(as, false);
pte = page_mapping_find(as, b + j * PAGE_SIZE);
ASSERT(pte && PTE_VALID(pte) &&
PTE_PRESENT(pte));
old_frame[frame_idx++] = PTE_GET_FRAME(pte);
 
/* Remove old mapping */
page_mapping_remove(as, b + j * PAGE_SIZE);
page_table_unlock(as, false);
}
}
}
 
/*
* Finish TLB shootdown sequence.
*/
 
tlb_invalidate_pages(as->asid, area->base, area->pages);
/*
* Invalidate potential software translation caches (e.g. TSB on
* sparc64).
*/
as_invalidate_translation_cache(as, area->base, area->pages);
tlb_shootdown_finalize();
 
/*
* Map pages back in with new flags. This step is kept separate
* so that there's no instant when the memory area could be
* accesed with both the old and the new flags at once.
*/
frame_idx = 0;
 
for (cur = area->used_space.leaf_head.next;
cur != &area->used_space.leaf_head; cur = cur->next) {
btree_node_t *node;
unsigned int i;
node = list_get_instance(cur, btree_node_t, leaf_link);
for (i = 0; i < node->keys; i++) {
uintptr_t b = node->key[i];
count_t j;
for (j = 0; j < (count_t) node->value[i]; j++) {
page_table_lock(as, false);
 
/* Insert the new mapping */
page_mapping_insert(as, b + j * PAGE_SIZE,
old_frame[frame_idx++], page_flags);
 
page_table_unlock(as, false);
}
}
}
 
free(old_frame);
 
mutex_unlock(&area->lock);
mutex_unlock(&as->lock);
interrupts_restore(ipl);
 
return 0;
}
 
 
/** Handle page fault within the current address space.
*
* This is the high-level page fault handler. It decides
1920,12 → 1766,6
return (unative_t) as_area_resize(AS, address, size, 0);
}
 
/** Wrapper for as_area_change_flags(). */
unative_t sys_as_area_change_flags(uintptr_t address, int flags)
{
return (unative_t) as_area_change_flags(AS, flags, address);
}
 
/** Wrapper for as_area_destroy(). */
unative_t sys_as_area_destroy(uintptr_t address)
{
/trunk/kernel/generic/src/main/kinit.c
47,7 → 47,6
#include <proc/scheduler.h>
#include <proc/task.h>
#include <proc/thread.h>
#include <proc/program.h>
#include <panic.h>
#include <func.h>
#include <cpu.h>
160,7 → 159,7
* Create user tasks, load RAM disk images.
*/
count_t i;
program_t programs[CONFIG_INIT_TASKS];
thread_t *threads[CONFIG_INIT_TASKS];
for (i = 0; i < init.cnt; i++) {
if (init.tasks[i].addr % FRAME_SIZE) {
168,23 → 167,19
continue;
}
 
int rc = program_create_from_image((void *) init.tasks[i].addr,
&programs[i]);
 
if (rc == 0 && programs[i].task != NULL) {
threads[i] = thread_create_program((void *) init.tasks[i].addr,
"uspace");
if (threads[i] != NULL) {
/*
* Set capabilities to init userspace tasks.
*/
cap_set(programs[i].task, CAP_CAP | CAP_MEM_MANAGER |
cap_set(threads[i]->task, CAP_CAP | CAP_MEM_MANAGER |
CAP_IO_MANAGER | CAP_PREEMPT_CONTROL | CAP_IRQ_REG);
 
if (!ipc_phone_0)
ipc_phone_0 = &programs[i].task->answerbox;
} else if (rc == 0) {
/* It was the program loader and was registered */
ipc_phone_0 = &threads[i]->task->answerbox;
} else {
/* RAM disk image */
int rd = init_rd((rd_header_t *) init.tasks[i].addr,
init.tasks[i].size);
198,9 → 193,9
* Run user tasks with reasonable delays
*/
for (i = 0; i < init.cnt; i++) {
if (programs[i].task != NULL) {
if (threads[i] != NULL) {
thread_usleep(50000);
program_ready(&programs[i]);
thread_ready(threads[i]);
}
}
 
/trunk/kernel/generic/src/synch/smc.c
File deleted
/trunk/kernel/generic/src/proc/program.c
File deleted
/trunk/kernel/generic/src/proc/task.c
35,8 → 35,10
* @brief Task management.
*/
 
#include <main/uinit.h>
#include <proc/thread.h>
#include <proc/task.h>
#include <proc/uarg.h>
#include <mm/as.h>
#include <mm/slab.h>
#include <atomic.h>
44,16 → 46,23
#include <synch/waitq.h>
#include <arch.h>
#include <arch/barrier.h>
#include <panic.h>
#include <adt/avl.h>
#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>
#include <lib/elf.h>
#include <errno.h>
#include <func.h>
#include <syscall/copy.h>
 
#ifndef LOADED_PROG_STACK_PAGES_NO
#define LOADED_PROG_STACK_PAGES_NO 1
#endif
 
/** Spinlock protecting the tasks_tree AVL tree. */
SPINLOCK_INITIALIZE(tasks_lock);
 
242,6 → 251,89
sizeof(TASK->taskid));
}
 
unative_t sys_task_spawn(void *image, size_t size)
{
void *kimage = malloc(size, 0);
if (kimage == NULL)
return ENOMEM;
int rc = copy_from_uspace(kimage, image, size);
if (rc != EOK)
return rc;
 
/*
* Not very efficient and it would be better to call it on code only,
* but this whole function is a temporary hack anyway and one day it
* will go in favor of the userspace dynamic loader.
*/
smc_coherence_block(kimage, size);
uspace_arg_t *kernel_uarg;
kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0);
if (kernel_uarg == NULL) {
free(kimage);
return ENOMEM;
}
kernel_uarg->uspace_entry =
(void *) ((elf_header_t *) kimage)->e_entry;
kernel_uarg->uspace_stack = (void *) USTACK_ADDRESS;
kernel_uarg->uspace_thread_function = NULL;
kernel_uarg->uspace_thread_arg = NULL;
kernel_uarg->uspace_uarg = NULL;
as_t *as = as_create(0);
if (as == NULL) {
free(kernel_uarg);
free(kimage);
return ENOMEM;
}
unsigned int erc = elf_load((elf_header_t *) kimage, as);
if (erc != EE_OK) {
as_destroy(as);
free(kernel_uarg);
free(kimage);
return ENOENT;
}
as_area_t *area = as_area_create(as,
AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE,
LOADED_PROG_STACK_PAGES_NO * PAGE_SIZE, USTACK_ADDRESS,
AS_AREA_ATTR_NONE, &anon_backend, NULL);
if (area == NULL) {
as_destroy(as);
free(kernel_uarg);
free(kimage);
return ENOMEM;
}
task_t *task = task_create(as, "app");
if (task == NULL) {
as_destroy(as);
free(kernel_uarg);
free(kimage);
return ENOENT;
}
// FIXME: control the capabilities
cap_set(task, cap_get(TASK));
thread_t *thread = thread_create(uinit, kernel_uarg, task,
THREAD_FLAG_USPACE, "user", false);
if (thread == NULL) {
task_destroy(task);
as_destroy(as);
free(kernel_uarg);
free(kimage);
return ENOENT;
}
thread_ready(thread);
return EOK;
}
 
/** Find task structure corresponding to task ID.
*
* The tasks_lock must be already held by the caller of this function
/trunk/kernel/generic/src/proc/thread.c
672,6 → 672,74
return node != NULL;
}
 
 
/** Create new user task with 1 thread from image
*
* @param program_addr Address of program executable image.
* @param name Program name.
*
* @return Initialized main thread of the task or NULL on error.
*/
thread_t *thread_create_program(void *program_addr, char *name)
{
as_t *as;
as_area_t *area;
unsigned int rc;
task_t *task;
uspace_arg_t *kernel_uarg;
kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0);
if (kernel_uarg == NULL)
return NULL;
kernel_uarg->uspace_entry =
(void *) ((elf_header_t *) program_addr)->e_entry;
kernel_uarg->uspace_stack = (void *) USTACK_ADDRESS;
kernel_uarg->uspace_thread_function = NULL;
kernel_uarg->uspace_thread_arg = NULL;
kernel_uarg->uspace_uarg = NULL;
 
as = as_create(0);
if (as == NULL) {
free(kernel_uarg);
return NULL;
}
 
rc = elf_load((elf_header_t *) program_addr, as);
if (rc != EE_OK) {
free(kernel_uarg);
as_destroy(as);
return NULL;
}
/*
* Create the data as_area.
*/
area = as_area_create(as,
AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE,
LOADED_PROG_STACK_PAGES_NO * PAGE_SIZE, USTACK_ADDRESS,
AS_AREA_ATTR_NONE, &anon_backend, NULL);
if (area == NULL) {
free(kernel_uarg);
as_destroy(as);
return NULL;
}
task = task_create(as, name);
if (task == NULL) {
free(kernel_uarg);
as_destroy(as);
return NULL;
}
/*
* Create the main thread.
*/
return thread_create(uinit, kernel_uarg, task, THREAD_FLAG_USPACE,
"uinit", false);
}
 
 
/** Update accounting of current thread.
*
* Note that thread_lock on THREAD must be already held and
/trunk/kernel/generic/src/syscall/syscall.c
38,7 → 38,6
#include <syscall/syscall.h>
#include <proc/thread.h>
#include <proc/task.h>
#include <proc/program.h>
#include <mm/as.h>
#include <print.h>
#include <putchar.h>
47,7 → 46,6
#include <debug.h>
#include <ipc/sysipc.h>
#include <synch/futex.h>
#include <synch/smc.h>
#include <ddi/ddi.h>
#include <security/cap.h>
#include <syscall/copy.h>
125,17 → 123,15
(syshandler_t) sys_thread_get_id,
(syshandler_t) sys_task_get_id,
(syshandler_t) sys_program_spawn_loader,
(syshandler_t) sys_task_spawn,
/* Synchronization related syscalls. */
(syshandler_t) sys_futex_sleep_timeout,
(syshandler_t) sys_futex_wakeup,
(syshandler_t) sys_smc_coherence,
/* Address space related syscalls. */
(syshandler_t) sys_as_area_create,
(syshandler_t) sys_as_area_resize,
(syshandler_t) sys_as_area_change_flags,
(syshandler_t) sys_as_area_destroy,
/* IPC related syscalls. */
/trunk/kernel/generic/src/lib/elf.c
57,7 → 57,7
};
 
static int segment_header(elf_segment_header_t *entry, elf_header_t *elf,
as_t *as, int flags);
as_t *as);
static int section_header(elf_section_header_t *entry, elf_header_t *elf,
as_t *as);
static int load_segment(elf_segment_header_t *entry, elf_header_t *elf,
67,10 → 67,9
*
* @param header Pointer to ELF header in memory
* @param as Created and properly mapped address space
* @param flags A combination of ELD_F_*
* @return EE_OK on success
*/
unsigned int elf_load(elf_header_t *header, as_t * as, int flags)
unsigned int elf_load(elf_header_t *header, as_t * as)
{
int i, rc;
 
111,7 → 110,7
 
seghdr = &((elf_segment_header_t *)(((uint8_t *) header) +
header->e_phoff))[i];
rc = segment_header(seghdr, header, as, flags);
rc = segment_header(seghdr, header, as);
if (rc != EE_OK)
return rc;
}
152,10 → 151,8
* @return EE_OK on success, error code otherwise.
*/
static int segment_header(elf_segment_header_t *entry, elf_header_t *elf,
as_t *as, int flags)
as_t *as)
{
char *interp;
 
switch (entry->p_type) {
case PT_NULL:
case PT_PHDR:
165,16 → 162,6
break;
case PT_DYNAMIC:
case PT_INTERP:
interp = (char *)elf + entry->p_offset;
/* FIXME */
/*if (memcmp((uintptr_t)interp, (uintptr_t)ELF_INTERP_ZSTR,
ELF_INTERP_ZLEN) != 0) {
return EE_UNSUPPORTED;
}*/
if ((flags & ELD_F_LOADER) == 0) {
return EE_LOADER;
}
break;
case PT_SHLIB:
case PT_NOTE:
case PT_LOPROC:
/trunk/kernel/Makefile
232,7 → 232,6
generic/src/main/uinit.c \
generic/src/main/version.c \
generic/src/main/shutdown.c \
generic/src/proc/program.c \
generic/src/proc/scheduler.c \
generic/src/proc/thread.c \
generic/src/proc/task.c \
271,7 → 270,6
generic/src/synch/rwlock.c \
generic/src/synch/mutex.c \
generic/src/synch/semaphore.c \
generic/src/synch/smc.c \
generic/src/synch/waitq.c \
generic/src/synch/futex.c \
generic/src/smp/ipi.c \
/trunk/boot/arch/mips32/loader/Makefile
80,7 → 80,6
COMPONENTS = \
$(KERNELDIR)/kernel.bin \
$(USPACEDIR)/srv/ns/ns \
$(USPACEDIR)/srv/loader/loader \
$(USPACEDIR)/app/init/init \
$(USPACEDIR)/srv/devmap/devmap \
$(USPACEDIR)/srv/rd/rd \
94,10 → 93,8
$(USPACEDIR)/srv/fs/fat/fat \
$(USPACEDIR)/app/tetris/tetris \
$(USPACEDIR)/app/tester/tester \
$(USPACEDIR)/app/cli/cli \
$(USPACEDIR)/app/klog/klog
 
 
OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
COMPONENT_OBJECTS := $(addsuffix .o,$(basename $(notdir $(COMPONENTS))))
 
/trunk/boot/arch/arm32/loader/Makefile
80,7 → 80,6
COMPONENTS = \
$(KERNELDIR)/kernel.bin \
$(USPACEDIR)/srv/ns/ns \
$(USPACEDIR)/srv/loader/loader \
$(USPACEDIR)/app/init/init \
$(USPACEDIR)/srv/devmap/devmap \
$(USPACEDIR)/srv/rd/rd \
94,8 → 93,7
$(USPACEDIR)/srv/fs/fat/fat \
$(USPACEDIR)/app/tetris/tetris \
$(USPACEDIR)/app/tester/tester \
$(USPACEDIR)/app/klog/klog \
$(USPACEDIR)/app/cli/cli
$(USPACEDIR)/app/klog/klog
 
OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
COMPONENT_OBJECTS := $(addsuffix .o,$(basename $(notdir $(COMPONENTS))))
/trunk/boot/arch/ia64/loader/Makefile
86,7 → 86,6
COMPONENTS = \
$(KERNELDIR)/kernel.bin \
$(USPACEDIR)/srv/ns/ns \
$(USPACEDIR)/srv/loader/loader \
$(USPACEDIR)/srv/fb/fb \
$(USPACEDIR)/srv/kbd/kbd \
$(USPACEDIR)/srv/console/console \
/trunk/boot/arch/sparc64/loader/Makefile
79,7 → 79,6
$(KERNELDIR)/kernel.bin \
$(USPACEDIR)/srv/ns/ns \
$(USPACEDIR)/app/init/init \
$(USPACEDIR)/srv/loader/loader \
$(USPACEDIR)/srv/devmap/devmap \
$(USPACEDIR)/srv/rd/rd \
$(USPACEDIR)/srv/vfs/vfs \
92,7 → 91,6
$(USPACEDIR)/srv/fs/fat/fat \
$(USPACEDIR)/app/tetris/tetris \
$(USPACEDIR)/app/tester/tester \
$(USPACEDIR)/app/cli/cli \
$(USPACEDIR)/app/klog/klog
 
OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
/trunk/boot/arch/ppc32/loader/Makefile
75,7 → 75,6
COMPONENTS = \
$(KERNELDIR)/kernel.bin \
$(USPACEDIR)/srv/ns/ns \
$(USPACEDIR)/srv/loader/loader \
$(USPACEDIR)/app/init/init \
$(USPACEDIR)/srv/devmap/devmap \
$(USPACEDIR)/srv/rd/rd \
89,8 → 88,7
$(USPACEDIR)/srv/fs/fat/fat \
$(USPACEDIR)/app/tetris/tetris \
$(USPACEDIR)/app/tester/tester \
$(USPACEDIR)/app/klog/klog \
$(USPACEDIR)/app/cli/cli
$(USPACEDIR)/app/klog/klog
 
OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
COMPONENT_OBJECTS := $(addsuffix .o,$(basename $(notdir $(COMPONENTS))))
/trunk/boot/arch/amd64/grub/menu.lst
10,5 → 10,4
module /boot/rd
module /boot/vfs
module /boot/tmpfs
module /boot/loader
module /boot/initrd.img
/trunk/boot/arch/amd64/Makefile.inc
28,12 → 28,11
 
INIT_TASKS = \
$(USPACEDIR)/srv/ns/ns \
$(USPACEDIR)/srv/loader/loader \
$(USPACEDIR)/app/init/init \
$(USPACEDIR)/srv/devmap/devmap \
$(USPACEDIR)/srv/rd/rd \
$(USPACEDIR)/srv/vfs/vfs \
$(USPACEDIR)/srv/fs/tmpfs/tmpfs \
$(USPACEDIR)/srv/fs/tmpfs/tmpfs
 
RD_TASKS = \
$(USPACEDIR)/srv/pci/pci \
43,8 → 42,7
$(USPACEDIR)/srv/fs/fat/fat \
$(USPACEDIR)/app/tetris/tetris \
$(USPACEDIR)/app/tester/tester \
$(USPACEDIR)/app/klog/klog \
$(USPACEDIR)/app/cli/cli
$(USPACEDIR)/app/klog/klog
 
build: $(BASE)/image.iso
 
/trunk/boot/arch/ia32/grub/menu.lst
10,5 → 10,4
module /boot/rd
module /boot/vfs
module /boot/tmpfs
module /boot/loader
module /boot/initrd.img
/trunk/boot/arch/ia32/Makefile.inc
28,7 → 28,6
 
INIT_TASKS = \
$(USPACEDIR)/srv/ns/ns \
$(USPACEDIR)/srv/loader/loader \
$(USPACEDIR)/app/init/init \
$(USPACEDIR)/srv/devmap/devmap \
$(USPACEDIR)/srv/rd/rd \
43,7 → 42,6
$(USPACEDIR)/srv/fs/fat/fat \
$(USPACEDIR)/app/tetris/tetris \
$(USPACEDIR)/app/tester/tester \
$(USPACEDIR)/app/cli/cli \
$(USPACEDIR)/app/klog/klog
 
build: $(BASE)/image.iso