diff --git a/libs/c/crt/sys-userspace/arch-arm/crt0.S b/libs/c/crt/sys-userspace/arch-arm/crt0.S index 561c7c4..a5de7c1 100644 --- a/libs/c/crt/sys-userspace/arch-arm/crt0.S +++ b/libs/c/crt/sys-userspace/arch-arm/crt0.S @@ -88,7 +88,7 @@ _start: ldr sp, =__stack bl platform_init bl __l4_init - bl main + bl __container_init 1: b 1b diff --git a/tasks/fs0/include/task.h b/tasks/fs0/include/task.h index e58b4f1..4be6566 100644 --- a/tasks/fs0/include/task.h +++ b/tasks/fs0/include/task.h @@ -33,7 +33,7 @@ struct task_fs_data { struct tcb { l4id_t tid; struct list_head list; - unsigned long utcb_address; + unsigned long shpage_address; struct task_fd_head *files; struct task_fs_data *fs_data; }; @@ -41,7 +41,7 @@ struct tcb { /* Structures used when receiving new task info from pager */ struct task_data { unsigned long tid; - unsigned long utcb_address; + unsigned long shpage_address; }; struct task_data_head { diff --git a/tasks/fs0/src/syscalls.c b/tasks/fs0/src/syscalls.c index e935a79..ec6438c 100644 --- a/tasks/fs0/src/syscalls.c +++ b/tasks/fs0/src/syscalls.c @@ -486,8 +486,8 @@ int sys_readdir(struct tcb *t, int fd, void *buf, int count) // printf("%s/%s\n", __TASKNAME__, __FUNCTION__); /* Check address is in task's utcb */ - if ((unsigned long)buf < t->utcb_address || - (unsigned long)buf > t->utcb_address + PAGE_SIZE) + if ((unsigned long)buf < t->shpage_address || + (unsigned long)buf > t->shpage_address + PAGE_SIZE) return -EINVAL; if (fd < 0 || fd > TASK_FILES_MAX || t->files->fd[fd] == NILFD) diff --git a/tasks/fs0/src/task.c b/tasks/fs0/src/task.c index e172c43..63bddf2 100644 --- a/tasks/fs0/src/task.c +++ b/tasks/fs0/src/task.c @@ -20,6 +20,8 @@ #include #include +extern void *shared_page; + struct global_list global_tasks = { .list = { &global_tasks.list, &global_tasks.list }, .total = 0, @@ -118,7 +120,7 @@ void copy_tcb(struct tcb *to, struct tcb *from, unsigned int share_flags) } /* Allocate a task struct and initialise it */ -struct tcb *tcb_create(struct tcb *orig, l4id_t tid, unsigned long utcb, +struct tcb *tcb_create(struct tcb *orig, l4id_t tid, unsigned long shpage, unsigned int share_flags) { struct tcb *task; @@ -131,7 +133,7 @@ struct tcb *tcb_create(struct tcb *orig, l4id_t tid, unsigned long utcb, return task; task->tid = tid; - task->utcb_address = utcb; + task->shpage_address = shpage; /* * If there's an original task that means this will be a full @@ -177,18 +179,18 @@ int task_utcb_attach(struct tcb *t) void *shmaddr; /* Use it as a key to create a shared memory region */ - if ((shmid = shmget((key_t)t->utcb_address, PAGE_SIZE, 0)) == -1) + if ((shmid = shmget((key_t)t->shpage_address, PAGE_SIZE, 0)) == -1) goto out_err; /* Attach to the region */ - if ((int)(shmaddr = shmat(shmid, (void *)t->utcb_address, 0)) == -1) + if ((int)(shmaddr = shmat(shmid, (void *)t->shpage_address, 0)) == -1) goto out_err; /* Ensure address is right */ - if ((unsigned long)shmaddr != t->utcb_address) + if ((unsigned long)shmaddr != t->shpage_address) return -EINVAL; - // printf("%s: Mapped utcb of task %d @ 0x%x\n", + // printf("%s: Mapped shared page of task %d @ 0x%x\n", // __TASKNAME__, t->tid, shmaddr); return 0; @@ -204,7 +206,7 @@ out_err: * the information on the resulting child task. */ int pager_notify_fork(struct tcb *sender, l4id_t parentid, - l4id_t childid, unsigned long utcb_address, + l4id_t childid, unsigned long shpage_address, unsigned int flags) { struct tcb *child, *parent; @@ -213,7 +215,7 @@ int pager_notify_fork(struct tcb *sender, l4id_t parentid, BUG_ON(!(parent = find_task(parentid))); /* Create a child vfs tcb using given parent and copy flags */ - if (IS_ERR(child = tcb_create(parent, childid, utcb_address, flags))) + if (IS_ERR(child = tcb_create(parent, childid, shpage_address, flags))) return (int)child; global_add_task(child); @@ -261,9 +263,9 @@ struct task_data_head *receive_pager_taskdata(void) /* Data is expected in the utcb page */ // printf("%s: %d Total tasks.\n", __FUNCTION__, - // ((struct task_data_head *)utcb_page)->total); + // ((struct task_data_head *)shared_page)->total); - return (struct task_data_head *)utcb_page; + return (struct task_data_head *)shared_page; } @@ -274,7 +276,7 @@ int init_task_structs(struct task_data_head *tdata_head) for (int i = 0; i < tdata_head->total; i++) { /* New tcb with fields sent by pager */ if (IS_ERR(t = tcb_create(0, tdata_head->tdata[i].tid, - tdata_head->tdata[i].utcb_address, + tdata_head->tdata[i].shpage_address, 0))) return (int)t; diff --git a/tasks/libl4/include/l4lib/arch-arm/utcb.h b/tasks/libl4/include/l4lib/arch-arm/utcb.h index 8e8c112..5b6991e 100644 --- a/tasks/libl4/include/l4lib/arch-arm/utcb.h +++ b/tasks/libl4/include/l4lib/arch-arm/utcb.h @@ -30,7 +30,6 @@ struct utcb { } __attribute__((__packed__)); extern struct utcb utcb; -extern void *utcb_page; static inline struct utcb *l4_get_utcb() { @@ -48,30 +47,6 @@ static inline void write_mr(unsigned int offset, unsigned int val) l4_get_utcb()->mr[offset] = val; } -/* - * Arguments that are too large to fit in message registers are - * copied onto another area that is still on the utcb, and the servers - * map-in the task utcb and read those arguments from there. - */ - -static inline int copy_to_utcb(void *arg, int offset, int size) -{ - if (offset + size > PAGE_SIZE) - return -1; - - memcpy(utcb_page + offset, arg, size); - return 0; -} - -static inline int copy_from_utcb(void *buf, int offset, int size) -{ - if (offset + size > PAGE_SIZE) - return -1; - - memcpy(buf, utcb_page + offset, size); - return 0; -} - #endif /* !__ASSEMBLY__ */ #endif /* __ARM_UTCB_H__ */ diff --git a/tasks/libl4/src/init.c b/tasks/libl4/src/init.c index 15f79c7..0ddb8c0 100644 --- a/tasks/libl4/src/init.c +++ b/tasks/libl4/src/init.c @@ -10,8 +10,6 @@ #include #include INC_GLUE(memlayout.h) #include -#include -#include __l4_ipc_t __l4_ipc = 0; __l4_map_t __l4_map = 0; diff --git a/tasks/libposix/chdir.c b/tasks/libposix/chdir.c index c25e76b..c069382 100644 --- a/tasks/libposix/chdir.c +++ b/tasks/libposix/chdir.c @@ -3,6 +3,7 @@ * * Copyright (C) 2008 Bahadir Balban */ +#include #include #include #include @@ -21,8 +22,8 @@ static inline int l4_chdir(const char *pathname) int fd; // write_mr(L4SYS_ARG0, (unsigned long)pathname); - copy_to_utcb((void *)pathname, 0, strlen(pathname) + 1); - write_mr(L4SYS_ARG0, (unsigned long)utcb_page); + copy_to_shpage((void *)pathname, 0, strlen(pathname) + 1); + write_mr(L4SYS_ARG0, (unsigned long)shared_page); /* Call pager with shmget() request. Check ipc error. */ if ((fd = l4_sendrecv(VFS_TID, VFS_TID, L4_IPC_TAG_CHDIR)) < 0) { diff --git a/tasks/libposix/fork.c b/tasks/libposix/fork.c index d4319e9..b604e96 100644 --- a/tasks/libposix/fork.c +++ b/tasks/libposix/fork.c @@ -12,6 +12,7 @@ #include #include #include INC_GLUE(memory.h) +#include static inline int l4_fork(void) { @@ -40,9 +41,12 @@ int fork(void) return -1; } - /* If we're a child, we need to initialise the utcb page */ + /* + * If we're a child, we need to initialise the default + * shared page via posix_init() + */ if (ret == 0) - utcb_init(); + posix_init(); return ret; } diff --git a/tasks/libposix/include/posix/posix_init.h b/tasks/libposix/include/posix/posix_init.h new file mode 100644 index 0000000..7abdffe --- /dev/null +++ b/tasks/libposix/include/posix/posix_init.h @@ -0,0 +1,6 @@ +#ifndef __POSIX_INIT_H__ +#define __POSIX_INIT_H__ + +void posix_init(void); + +#endif /* __POSIX_INIT_H__ */ diff --git a/tasks/libposix/include/posix/shpage.h b/tasks/libposix/include/posix/shpage.h new file mode 100644 index 0000000..1d12790 --- /dev/null +++ b/tasks/libposix/include/posix/shpage.h @@ -0,0 +1,45 @@ +/* + * A default shared page is used by every thread + * to pass large data for system calls. + * + * This file contains relevant shpage definitions. + */ +#ifndef __LIBPOSIX_SHPAGE_H__ +#define __LIBPOSIX_SHPAGE_H__ + +#include +#include +#include +#include +#include +#include INC_GLUE(memory.h) + +extern void *shared_page; + +int shared_page_init(void); + +/* + * Arguments that are too large to fit in message registers are + * copied onto another area that is still on the utcb, and the servers + * map-in the task utcb and read those arguments from there. + */ + +static inline int copy_to_shpage(void *arg, int offset, int size) +{ + if (offset + size > PAGE_SIZE) + return -1; + + memcpy(shared_page + offset, arg, size); + return 0; +} + +static inline int copy_from_shpage(void *buf, int offset, int size) +{ + if (offset + size > PAGE_SIZE) + return -1; + + memcpy(buf, shared_page + offset, size); + return 0; +} + +#endif /* __LIBPOSIX_SHPAGE_H__ */ diff --git a/tasks/libposix/init.c b/tasks/libposix/init.c index b6db019..273eb5b 100644 --- a/tasks/libposix/init.c +++ b/tasks/libposix/init.c @@ -1,79 +1,30 @@ /* - * Shared page initialisation of posix-like tasks. + * Main entry point for posix services and applications. * - * POSIX tasks currently use a default shared page for communciation. - * This could have been also done by long ipc calls. + * Copyright (C) 2007-2009 Bahadir Balban */ -/* - * Shared page for this task. Used for passing data among ipc - * parties when message registers are not big enough. Every thread - * has right to own one, and it has an address unique to every - * thread. It must be explicitly mapped by both parties of the ipc - * in order to be useful. - */ -void *shared_page; +#include +#include -/* - * Obtains a unique address for the task's shared page. Note this - * just returns the address. This address is used as an shm key - * to map it via shmget()/shmat() later on. - */ -static void *shared_page_address(void) +void posix_init(void) { - void *addr; - int err; - - /* We're asking it for ourself. */ - write_mr(L4SYS_ARG0, self_tid()); - - /* Call pager with utcb address request. Check ipc error. */ - if ((err = l4_sendrecv(PAGER_TID, PAGER_TID, - L4_IPC_TAG_DEFAULT_SHPAGE)) < 0) { - printf("%s: L4 IPC Error: %d.\n", __FUNCTION__, err); - return PTR_ERR(err); - } - - /* Check if syscall itself was successful */ - if (IS_ERR(addr = (void *)l4_get_retval())) { - printf("%s: Request UTCB Address Error: %d.\n", - __FUNCTION__, (int)addr); - return addr; - } - - return addr; + /* Non-pager tasks initialise their shared communication page */ + if (self_tid() != PAGER_TID) + shared_page_init(); } +int main(void); + /* - * Initialises a non-pager task's default shared memory page - * using posix semantics. Used during task initialisation - * and by child tasks after a fork. + * Entry point for posix services container. + * + * This is executed by all posix system services and tasks + * that run in this container. */ -int shared_page_init(void) +void __container_init(void) { - int shmid; - void *shmaddr; - - /* - * Initialise shared page only if we're not the pager. - * The pager does it differently for itself. - */ - BUG_ON(self_tid() == PAGER_TID); - - /* Obtain our utcb page address */ - utcb_page = l4_utcb_page(); - //printf("%s: UTCB Read from mm0 as: 0x%x\n", __FUNCTION__, - // (unsigned long)utcb_page); - - /* Use it as a key to create a shared memory region */ - BUG_ON((shmid = shmget((key_t)utcb_page, - PAGE_SIZE, IPC_CREAT)) < 0); - - /* Attach to the region */ - BUG_ON((shmaddr = shmat(shmid, utcb_page, 0)) < 0); - BUG_ON(shmaddr != utcb_page); - - return 0; + posix_init(); + main(); } - diff --git a/tasks/libposix/mkdir.c b/tasks/libposix/mkdir.c index 2b86824..2ea78e4 100644 --- a/tasks/libposix/mkdir.c +++ b/tasks/libposix/mkdir.c @@ -3,6 +3,7 @@ * * Copyright (C) 2008 Bahadir Balban */ +#include #include #include #include @@ -23,8 +24,8 @@ static inline int l4_mkdir(const char *pathname, mode_t mode) int fd; // write_mr(L4SYS_ARG0, (unsigned long)pathname); - copy_to_utcb((void *)pathname, 0, strlen(pathname) + 1); - write_mr(L4SYS_ARG0, (unsigned long)utcb_page); + copy_to_shpage((void *)pathname, 0, strlen(pathname) + 1); + write_mr(L4SYS_ARG0, (unsigned long)shared_page); write_mr(L4SYS_ARG1, (u32)mode); /* Call pager with shmget() request. Check ipc error. */ diff --git a/tasks/libposix/open.c b/tasks/libposix/open.c index 575a57a..1147628 100644 --- a/tasks/libposix/open.c +++ b/tasks/libposix/open.c @@ -3,6 +3,7 @@ * * Copyright (C) 2007 Bahadir Balban */ + #include #include #include @@ -17,13 +18,14 @@ #include #include #include INC_GLUE(memory.h) +#include static inline int l4_open(const char *pathname, int flags, mode_t mode) { int fd; - copy_to_utcb((void *)pathname, 0, strlen(pathname) + 1); - write_mr(L4SYS_ARG0, (unsigned long)utcb_page); + copy_to_shpage((void *)pathname, 0, strlen(pathname) + 1); + write_mr(L4SYS_ARG0, (unsigned long)shared_page); write_mr(L4SYS_ARG1, flags); write_mr(L4SYS_ARG2, (u32)mode); diff --git a/tasks/libposix/read.c b/tasks/libposix/read.c index 7f64eb3..283c25c 100644 --- a/tasks/libposix/read.c +++ b/tasks/libposix/read.c @@ -3,6 +3,7 @@ * * Copyright (C) 2007 Bahadir Balban */ + #include #include #include @@ -14,14 +15,14 @@ #include #include #include INC_GLUE(memory.h) - +#include static inline int l4_readdir(int fd, void *buf, size_t count) { int cnt; write_mr(L4SYS_ARG0, fd); - write_mr(L4SYS_ARG1, (unsigned long)utcb_page); + write_mr(L4SYS_ARG1, (unsigned long)shared_page); write_mr(L4SYS_ARG2, count); /* Call pager with readdir() request. Check ipc error. */ @@ -36,7 +37,7 @@ static inline int l4_readdir(int fd, void *buf, size_t count) } - copy_from_utcb(buf, 0, cnt); + copy_from_shpage(buf, 0, cnt); return cnt; } diff --git a/tasks/libposix/shpage.c b/tasks/libposix/shpage.c new file mode 100644 index 0000000..fc931a7 --- /dev/null +++ b/tasks/libposix/shpage.c @@ -0,0 +1,96 @@ +/* + * Initialise posix-related structures. + * + * Copyright (C) 2007-2009 Bahadir Balban + */ +#include +#include +#include +#include +#include +#include INC_GLUE(memlayout.h) +#include +#include +#include +#include +#include + +/* + * Shared page initialisation of posix-like tasks. + * + * POSIX tasks currently use a default shared page for communciation. + * This could have been also done by long ipc calls. + */ + +/* + * Shared page for this task. Used for passing data among ipc + * parties when message registers are not big enough. Every thread + * has right to own one, and it has an address unique to every + * thread. It must be explicitly mapped by both parties of the ipc + * in order to be useful. + */ +void *shared_page; + +/* + * Obtains a unique address for the task's shared page. Note this + * just returns the address. This address is used as an shm key + * to map it via shmget()/shmat() later on. + */ +static void *shared_page_address(void) +{ + void *addr; + int err; + + /* We're asking it for ourself. */ + write_mr(L4SYS_ARG0, self_tid()); + + /* Call pager with utcb address request. Check ipc error. */ + if ((err = l4_sendrecv(PAGER_TID, PAGER_TID, + L4_IPC_TAG_SHPAGE)) < 0) { + printf("%s: L4 IPC Error: %d.\n", __FUNCTION__, err); + return PTR_ERR(err); + } + + /* Check if syscall itself was successful */ + if (IS_ERR(addr = (void *)l4_get_retval())) { + printf("%s: Request UTCB Address Error: %d.\n", + __FUNCTION__, (int)addr); + return addr; + } + + return addr; +} + +/* + * Initialises a non-pager task's default shared memory page + * using posix semantics. Used during task initialisation + * and by child tasks after a fork. + */ +int shared_page_init(void) +{ + int shmid; + void *shmaddr; + + /* + * Initialise shared page only if we're not the pager. + * The pager does it differently for itself. + */ + BUG_ON(self_tid() == PAGER_TID); + + /* Obtain our shared page address */ + shared_page = shared_page_address(); + + //printf("%s: UTCB Read from mm0 as: 0x%x\n", __FUNCTION__, + // (unsigned long)shared_page); + + /* Use it as a key to create a shared memory region */ + BUG_ON((shmid = shmget((key_t)shared_page, + PAGE_SIZE, IPC_CREAT)) < 0); + + /* Attach to the region */ + BUG_ON((shmaddr = shmat(shmid, shared_page, 0)) < 0); + BUG_ON(shmaddr != shared_page); + + return 0; +} + diff --git a/tasks/libposix/stat.c b/tasks/libposix/stat.c index defb442..bafe519 100644 --- a/tasks/libposix/stat.c +++ b/tasks/libposix/stat.c @@ -18,6 +18,7 @@ #include #include #include INC_GLUE(memory.h) +#include static inline int l4_fstat(int fd, void *buffer) { @@ -62,10 +63,10 @@ static inline int l4_stat(const char *pathname, void *buffer) int err; struct kstat ks; - copy_to_utcb((void *)pathname, 0, strlen(pathname) + 1); + copy_to_shpage((void *)pathname, 0, strlen(pathname) + 1); /* Pathname address on utcb page */ - write_mr(L4SYS_ARG0, (unsigned long)utcb_page); + write_mr(L4SYS_ARG0, (unsigned long)shared_page); /* Pass on buffer that should receive stat */ write_mr(L4SYS_ARG1, (unsigned long)&ks); diff --git a/tasks/mm0/include/boot.h b/tasks/mm0/include/boot.h index d19de97..62533f7 100644 --- a/tasks/mm0/include/boot.h +++ b/tasks/mm0/include/boot.h @@ -7,7 +7,7 @@ /* Structures to use when sending new task information to vfs */ struct task_data { unsigned long tid; - unsigned long utcb_address; + unsigned long shpage_address; }; struct task_data_head { diff --git a/tasks/mm0/src/task.c b/tasks/mm0/src/task.c index ecc7ac2..201e42a 100644 --- a/tasks/mm0/src/task.c +++ b/tasks/mm0/src/task.c @@ -624,7 +624,7 @@ int vfs_send_task_data(struct tcb *vfs) /* Write per-task data for all tasks */ list_for_each_entry(t, &global_tasks.list, list) { tdata_head->tdata[li].tid = t->tid; - tdata_head->tdata[li].utcb_address = (unsigned long)t->shared_page; + tdata_head->tdata[li].shpage_address = (unsigned long)t->shared_page; li++; }