From f8bcd7a5469c03e585b515f61f7a29c41ea2c552 Mon Sep 17 00:00:00 2001 From: Bahadir Balban Date: Sun, 4 Oct 2009 17:34:19 +0300 Subject: [PATCH] Merged fs0 to mm0 for simpler progress on posix api. mm0 and all other posix dependents are building ok. --- conts/posix/SConstruct | 17 +- conts/posix/fs0/SConscript | 30 - conts/posix/fs0/SConstruct | 75 --- conts/posix/fs0/container.c | 23 - conts/posix/fs0/include/file.h | 6 - conts/posix/fs0/include/globals.h | 13 - conts/posix/fs0/include/init.h | 7 - conts/posix/fs0/include/lib/bit.h | 44 -- conts/posix/fs0/include/lib/idpool.h | 29 - conts/posix/fs0/include/lib/malloc.h | 19 - conts/posix/fs0/include/lib/spinlock.h | 15 - conts/posix/fs0/include/linker.lds.in | 41 -- conts/posix/fs0/include/syscalls.h | 35 -- conts/posix/fs0/include/task.h | 55 -- conts/posix/fs0/main.c | 148 ----- conts/posix/fs0/src/bootfs/bootfs.c | 147 ----- conts/posix/fs0/src/c0fs/c0fs.c | 29 - conts/posix/fs0/src/lib/bit.c | 111 ---- conts/posix/fs0/src/lib/idpool.c | 81 --- conts/posix/fs0/src/lib/malloc.c | 417 ------------- conts/posix/fs0/src/syscalls.c | 528 ----------------- conts/posix/fs0/src/task.c | 315 ---------- conts/posix/fs0/tools/generate_bootdesc.py | 27 - conts/posix/mm0/SConscript | 3 +- conts/posix/{fs0/src => mm0/fs}/bdev.c | 0 conts/posix/{fs0/src => mm0/fs}/c0fs/c0fs.h | 0 conts/posix/{fs0/src => mm0/fs}/file.c | 0 conts/posix/{fs0/src => mm0/fs}/init.c | 3 - conts/posix/{fs0/src => mm0/fs}/lookup.c | 0 conts/posix/{fs0/src => mm0/fs}/memfs/file.c | 0 conts/posix/{fs0/src => mm0/fs}/memfs/memfs.c | 0 conts/posix/{fs0/src => mm0/fs}/memfs/vnode.c | 0 conts/posix/{fs0/src => mm0/fs}/path.c | 0 conts/posix/{fs0/src => mm0/fs}/romfs/romfs.c | 0 conts/posix/{fs0/src => mm0/fs}/romfs/romfs.h | 0 .../{fs0/src => mm0/fs}/romfs/romfs_fs.h | 0 conts/posix/{fs0/src => mm0/fs}/vfs.c | 8 - conts/posix/{fs0 => mm0}/include/bdev.h | 0 conts/posix/{fs0 => mm0}/include/fs.h | 0 conts/posix/mm0/include/lib/bit.h | 2 +- conts/posix/mm0/include/lib/idpool.h | 10 + conts/posix/mm0/include/lib/malloc.h | 1 - .../posix/{fs0 => mm0}/include/lib/pathstr.h | 0 conts/posix/mm0/include/lib/spinlock.h | 4 +- conts/posix/{fs0 => mm0}/include/lib/vaddr.h | 0 conts/posix/mm0/include/linker.lds.in | 3 + conts/posix/{fs0 => mm0}/include/memfs/file.h | 0 .../posix/{fs0 => mm0}/include/memfs/memfs.h | 0 .../posix/{fs0 => mm0}/include/memfs/vnode.h | 0 conts/posix/{fs0 => mm0}/include/path.h | 0 conts/posix/{fs0 => mm0}/include/stat.h | 0 conts/posix/mm0/include/syscalls.h | 25 + conts/posix/mm0/include/task.h | 18 +- conts/posix/{fs0 => mm0}/include/vfs.h | 0 conts/posix/mm0/{src => }/lib/addr.c | 0 conts/posix/mm0/{src => }/lib/bit.c | 0 conts/posix/mm0/{src => }/lib/elf/elf.c | 0 conts/posix/mm0/{src => }/lib/idpool.c | 0 conts/posix/mm0/{src => }/lib/malloc.c | 0 conts/posix/{fs0/src => mm0}/lib/pathstr.c | 0 conts/posix/{fs0/src => mm0}/lib/vaddr.c | 0 conts/posix/mm0/main.c | 25 +- conts/posix/mm0/{src => mm}/arch | 0 .../posix/{fs0/src => mm0/mm/arch-arm}/crt0.S | 0 conts/posix/mm0/{src => mm}/arch-arm/mm.c | 0 conts/posix/mm0/{src => mm}/boot.c | 9 - conts/posix/mm0/{src => mm}/bootdesc.c | 0 conts/posix/mm0/{src => mm}/bootm.c | 0 conts/posix/mm0/{src => mm}/capability.c | 0 conts/posix/mm0/{src => mm}/clone.c | 55 +- conts/posix/mm0/{src => mm}/dev.c | 0 conts/posix/mm0/{src => mm}/execve.c | 0 conts/posix/mm0/{src => mm}/exit.c | 44 +- conts/posix/mm0/{src => mm}/fault.c | 0 conts/posix/mm0/{src => mm}/file.c | 548 +++++++++++++----- conts/posix/mm0/{src => mm}/init.c | 5 + conts/posix/mm0/{src => mm}/memory.c | 0 conts/posix/mm0/{src => mm}/mmap.c | 0 conts/posix/mm0/{src => mm}/munmap.c | 0 conts/posix/mm0/{src => mm}/pagers.c | 12 +- conts/posix/mm0/{src => mm}/physmem.c | 0 conts/posix/mm0/{src => mm}/shm.c | 47 +- conts/posix/mm0/{src => mm}/task.c | 103 ++-- conts/posix/mm0/{src => mm}/test.c | 0 conts/posix/mm0/{src => mm}/user.c | 0 conts/posix/mm0/{src => mm}/utcb.c | 0 conts/posix/mm0/{src => mm}/vm_object.c | 0 conts/posix/mm0/src/arch-arm/crt0.S | 94 --- 88 files changed, 593 insertions(+), 2638 deletions(-) delete mode 100644 conts/posix/fs0/SConscript delete mode 100644 conts/posix/fs0/SConstruct delete mode 100644 conts/posix/fs0/container.c delete mode 100644 conts/posix/fs0/include/file.h delete mode 100644 conts/posix/fs0/include/globals.h delete mode 100644 conts/posix/fs0/include/init.h delete mode 100644 conts/posix/fs0/include/lib/bit.h delete mode 100644 conts/posix/fs0/include/lib/idpool.h delete mode 100644 conts/posix/fs0/include/lib/malloc.h delete mode 100644 conts/posix/fs0/include/lib/spinlock.h delete mode 100644 conts/posix/fs0/include/linker.lds.in delete mode 100644 conts/posix/fs0/include/syscalls.h delete mode 100644 conts/posix/fs0/include/task.h delete mode 100644 conts/posix/fs0/main.c delete mode 100644 conts/posix/fs0/src/bootfs/bootfs.c delete mode 100644 conts/posix/fs0/src/c0fs/c0fs.c delete mode 100644 conts/posix/fs0/src/lib/bit.c delete mode 100644 conts/posix/fs0/src/lib/idpool.c delete mode 100644 conts/posix/fs0/src/lib/malloc.c delete mode 100644 conts/posix/fs0/src/syscalls.c delete mode 100644 conts/posix/fs0/src/task.c delete mode 100755 conts/posix/fs0/tools/generate_bootdesc.py rename conts/posix/{fs0/src => mm0/fs}/bdev.c (100%) rename conts/posix/{fs0/src => mm0/fs}/c0fs/c0fs.h (100%) rename conts/posix/{fs0/src => mm0/fs}/file.c (100%) rename conts/posix/{fs0/src => mm0/fs}/init.c (96%) rename conts/posix/{fs0/src => mm0/fs}/lookup.c (100%) rename conts/posix/{fs0/src => mm0/fs}/memfs/file.c (100%) rename conts/posix/{fs0/src => mm0/fs}/memfs/memfs.c (100%) rename conts/posix/{fs0/src => mm0/fs}/memfs/vnode.c (100%) rename conts/posix/{fs0/src => mm0/fs}/path.c (100%) rename conts/posix/{fs0/src => mm0/fs}/romfs/romfs.c (100%) rename conts/posix/{fs0/src => mm0/fs}/romfs/romfs.h (100%) rename conts/posix/{fs0/src => mm0/fs}/romfs/romfs_fs.h (100%) rename conts/posix/{fs0/src => mm0/fs}/vfs.c (94%) rename conts/posix/{fs0 => mm0}/include/bdev.h (100%) rename conts/posix/{fs0 => mm0}/include/fs.h (100%) rename conts/posix/{fs0 => mm0}/include/lib/pathstr.h (100%) rename conts/posix/{fs0 => mm0}/include/lib/vaddr.h (100%) rename conts/posix/{fs0 => mm0}/include/memfs/file.h (100%) rename conts/posix/{fs0 => mm0}/include/memfs/memfs.h (100%) rename conts/posix/{fs0 => mm0}/include/memfs/vnode.h (100%) rename conts/posix/{fs0 => mm0}/include/path.h (100%) rename conts/posix/{fs0 => mm0}/include/stat.h (100%) rename conts/posix/{fs0 => mm0}/include/vfs.h (100%) rename conts/posix/mm0/{src => }/lib/addr.c (100%) rename conts/posix/mm0/{src => }/lib/bit.c (100%) rename conts/posix/mm0/{src => }/lib/elf/elf.c (100%) rename conts/posix/mm0/{src => }/lib/idpool.c (100%) rename conts/posix/mm0/{src => }/lib/malloc.c (100%) rename conts/posix/{fs0/src => mm0}/lib/pathstr.c (100%) rename conts/posix/{fs0/src => mm0}/lib/vaddr.c (100%) rename conts/posix/mm0/{src => mm}/arch (100%) rename conts/posix/{fs0/src => mm0/mm/arch-arm}/crt0.S (100%) rename conts/posix/mm0/{src => mm}/arch-arm/mm.c (100%) rename conts/posix/mm0/{src => mm}/boot.c (91%) rename conts/posix/mm0/{src => mm}/bootdesc.c (100%) rename conts/posix/mm0/{src => mm}/bootm.c (100%) rename conts/posix/mm0/{src => mm}/capability.c (100%) rename conts/posix/mm0/{src => mm}/clone.c (74%) rename conts/posix/mm0/{src => mm}/dev.c (100%) rename conts/posix/mm0/{src => mm}/execve.c (100%) rename conts/posix/mm0/{src => mm}/exit.c (76%) rename conts/posix/mm0/{src => mm}/fault.c (100%) rename conts/posix/mm0/{src => mm}/file.c (69%) rename conts/posix/mm0/{src => mm}/init.c (98%) rename conts/posix/mm0/{src => mm}/memory.c (100%) rename conts/posix/mm0/{src => mm}/mmap.c (100%) rename conts/posix/mm0/{src => mm}/munmap.c (100%) rename conts/posix/mm0/{src => mm}/pagers.c (96%) rename conts/posix/mm0/{src => mm}/physmem.c (100%) rename conts/posix/mm0/{src => mm}/shm.c (99%) rename conts/posix/mm0/{src => mm}/task.c (91%) rename conts/posix/mm0/{src => mm}/test.c (100%) rename conts/posix/mm0/{src => mm}/user.c (100%) rename conts/posix/mm0/{src => mm}/utcb.c (100%) rename conts/posix/mm0/{src => mm}/vm_object.c (100%) delete mode 100644 conts/posix/mm0/src/arch-arm/crt0.S diff --git a/conts/posix/SConstruct b/conts/posix/SConstruct index 22f9ec8..e476f76 100644 --- a/conts/posix/SConstruct +++ b/conts/posix/SConstruct @@ -70,19 +70,13 @@ mm0 = SConscript('mm0/SConscript', \ exports = { 'config' : config, 'env' : mm0_env, 'contid' : contid }, duplicate = 0, \ variant_dir = join(BUILDDIR, 'cont' + str(contid) + '/posix' + '/mm0')) -fs0_env = env.Clone() -fs0_env.Append(CPPPATH = LIBPOSIX_INCLUDE_SERVER) -fs0 = SConscript('fs0/SConscript', \ - exports = { 'config' : config, 'env' : fs0_env, 'contid' : contid, 'previmage' : mm0 }, duplicate = 0, \ - variant_dir = join(BUILDDIR, 'cont' + str(contid) + '/posix' + '/fs0')) - test0_env = env.Clone() test0_env.Replace(CPPPATH = ['include', KERNEL_INCLUDE, LIBL4_INCLUDE, LIBMEM_INCLUDE]) test0 = SConscript('test0/SConscript', \ - exports = { 'config' : config, 'environment' : test0_env, 'contid' : contid, 'previmage' : fs0 }, duplicate = 0, \ + exports = { 'config' : config, 'environment' : test0_env, 'contid' : contid, 'previmage' : mm0 }, duplicate = 0, \ variant_dir = join(BUILDDIR, 'cont' + str(contid) + '/posix' + '/test0')) -images = [mm0, fs0, test0] +images = [mm0, test0] bootdesc_env = env.Clone() bootdesc_env['bootdesc_dir'] = 'bootdesc' @@ -91,14 +85,13 @@ bootdesc = SConscript('bootdesc/SConscript', \ 'contid' : contid, 'images' : images }, duplicate = 0, \ variant_dir = join(BUILDDIR, 'cont' + str(contid) + '/posix' + '/bootdesc')) -Depends(fs0, libposix) +Depends(mm0, libposix) Depends(test0, libposix) -Depends(bootdesc, [fs0, test0, mm0]) +Depends(bootdesc, [test0, mm0]) Alias('libposix', libposix) Alias('mm0', mm0) -Alias('fs0', fs0) Alias('test0', test0) Alias('bootdesc', bootdesc) -Default([mm0, fs0, libposix, test0, bootdesc]) +Default([mm0, libposix, test0, bootdesc]) diff --git a/conts/posix/fs0/SConscript b/conts/posix/fs0/SConscript deleted file mode 100644 index 73da02b..0000000 --- a/conts/posix/fs0/SConscript +++ /dev/null @@ -1,30 +0,0 @@ - -Import('config', 'env', 'previmage', 'contid') - -import os, sys - -arch = config.arch - -sys.path.append('../../../') - -from config.lib import * -from tools.pyelf.lmanext import * - -src = [Glob('*.c') + Glob('src/*.c') + Glob('src/arch/arm/*.c') + Glob('src/memfs/*.c') + Glob('src/lib/*.c')] - -def generate_lma_lds(target, source, env): - with open(source[1].path, 'r') as lds_in: - with open(target[0].path, 'w+') as lds_out: - linker_script = lds_in.read() - lds_out.write(linker_script % next_available_lma(source[0].path)) - -lma_lds = Command('include/linker.lds', [previmage, 'include/linker.lds.in'], generate_lma_lds) - -e = env.Clone() -e.Append(LIBS = 'posix') -e.Append(LINKFLAGS = ['-T' + lma_lds[0].path, '-u_start']) - -objs = e.Object(src) -fs0 = e.Program('fs0.elf', objs) -Depends(fs0, lma_lds) -Return('fs0') diff --git a/conts/posix/fs0/SConstruct b/conts/posix/fs0/SConstruct deleted file mode 100644 index 6c6b1e3..0000000 --- a/conts/posix/fs0/SConstruct +++ /dev/null @@ -1,75 +0,0 @@ -# -# User space application build script -# -# Copyright (C) 2007 Bahadir Balban -# -import os -import sys -import shutil -from os.path import join -from glob import glob - -task_name = "fs0" - -# The root directory of the repository where this file resides: -project_root = "../.." -tools_root = join(project_root, "tools") -prev_image = join(project_root, "tasks/mm0/mm0.axf") -libs_path = join(project_root, "libs") -ld_script = "include/linker.lds" -physical_base_ld_script = "include/physical_base.lds" - -# libc paths: -libc_variant = "userspace" -libc_libpath = join(libs_path, "c/build/%s" % libc_variant) -libc_incpath = join(libc_libpath, "include") -libc_crt0 = join(libs_path, "c/build/crt/sys-userspace/arch-arm/crt0.o") -libc_name = "c-%s" % libc_variant - -#libmem paths: -libmem_path = "../libmem" -libmem_incpath = "../libmem" - -# libl4 paths: -libl4_path = "../libl4" -libl4_incpath1 = join(libl4_path, "include") - -# libposix paths: -libposix_path = "../libposix" -libposix_incpath = join(libposix_path, "include") - -# kernel paths: -kernel_incpath = join(project_root, "include") - -# If crt0 is in its library path, it becomes hard to link with it. -# For instance the linker script must use an absolute path for it. -def copy_crt0(source, target, env): - os.system("cp " + str(source[0]) + " " + str(target[0])) - -def get_physical_base(source, target, env): - os.system(join(tools_root, "pyelf/readelf.py --first-free-page " + \ - prev_image + " >> " + physical_base_ld_script)) - -# The kernel build environment: -env = Environment(CC = 'arm-none-linux-gnueabi-gcc', - # We don't use -nostdinc because sometimes we need standard headers, - # such as stdarg.h e.g. for variable args, as in printk(). - CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', '-Werror'], - LINKFLAGS = ['-nostdlib', '-T' + ld_script, "-L" + libc_libpath, "-L" + libl4_path,\ - "-L" + libmem_path, "-L" + libposix_path], - ASFLAGS = ['-D__ASSEMBLY__'], - PROGSUFFIX = '.axf', # The suffix to use for final executable - ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path - LIBS = [libc_name, 'gcc', 'libmc', 'libl4', 'gcc', libc_name, "posix"], - CPPFLAGS = "-D__USERSPACE__", - CPPPATH = ['#include', libl4_incpath1, kernel_incpath, libc_incpath, \ - libposix_incpath, libmem_incpath]) - -src = [glob("src/*.c"), glob("*.c"), glob("src/arch/arm/*.c"), glob("src/memfs/*.c"), glob("src/lib/*.c")] -objs = env.Object(src) -physical_base = env.Command(physical_base_ld_script, prev_image, get_physical_base) -crt0_copied = env.Command("crt0.o", libc_crt0, copy_crt0) - -task = env.Program(task_name, objs + [crt0_copied]) -env.Alias(task_name, task) -env.Depends(task, physical_base) diff --git a/conts/posix/fs0/container.c b/conts/posix/fs0/container.c deleted file mode 100644 index 8b3311f..0000000 --- a/conts/posix/fs0/container.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Container entry point for this task - * - * Copyright (C) 2007-2009 Bahadir Bilgehan Balban - */ -#include -#include -#include - -void main(void); - -void __container_init(void) -{ - /* Generic L4 thread initialisation */ - __l4_init(); - - /* FS0 posix-service initialisation */ - posix_service_init(); - - /* Entry to main */ - main(); -} - diff --git a/conts/posix/fs0/include/file.h b/conts/posix/fs0/include/file.h deleted file mode 100644 index a553e4b..0000000 --- a/conts/posix/fs0/include/file.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __FS0_MM_H__ -#define __FS0_MM_H__ - - - -#endif /* __FS0_MM_H__ */ diff --git a/conts/posix/fs0/include/globals.h b/conts/posix/fs0/include/globals.h deleted file mode 100644 index 50f588d..0000000 --- a/conts/posix/fs0/include/globals.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef __GLOBALS_H__ -#define __GLOBALS_H__ - -struct global_list { - int total; - struct link list; -}; - -extern struct global_list global_vm_files; -extern struct global_list global_vm_objects; -extern struct global_list global_tasks; - -#endif /* __GLOBALS_H__ */ diff --git a/conts/posix/fs0/include/init.h b/conts/posix/fs0/include/init.h deleted file mode 100644 index 30b4104..0000000 --- a/conts/posix/fs0/include/init.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __INIT_H__ -#define __INIT_H__ - -/* FS0 initialisation */ -int initialise(void); - -#endif /* __INIT_H__ */ diff --git a/conts/posix/fs0/include/lib/bit.h b/conts/posix/fs0/include/lib/bit.h deleted file mode 100644 index 7d6f8a7..0000000 --- a/conts/posix/fs0/include/lib/bit.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef __LIB_BIT_H__ -#define __LIB_BIT_H__ - -#include - -unsigned int __clz(unsigned int bitvector); -int find_and_set_first_free_bit(u32 *word, unsigned int lastbit); -int find_and_set_first_free_contig_bits(u32 *word, unsigned int limit, - int nbits); -int check_and_clear_bit(u32 *word, int bit); -int check_and_clear_contig_bits(u32 *word, int first, int nbits); - -int check_and_set_bit(u32 *word, int bit); - -/* Set */ -static inline void setbit(unsigned int *w, unsigned int flags) -{ - *w |= flags; -} - - -/* Clear */ -static inline void clrbit(unsigned int *w, unsigned int flags) -{ - *w &= ~flags; -} - -/* Test */ -static inline int tstbit(unsigned int *w, unsigned int flags) -{ - return *w & flags; -} - -/* Test and clear */ -static inline int tstclr(unsigned int *w, unsigned int flags) -{ - int res = tstbit(w, flags); - - clrbit(w, flags); - - return res; -} - -#endif /* __LIB_BIT_H__ */ diff --git a/conts/posix/fs0/include/lib/idpool.h b/conts/posix/fs0/include/lib/idpool.h deleted file mode 100644 index 2650e75..0000000 --- a/conts/posix/fs0/include/lib/idpool.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef __MM0_IDPOOL_H__ -#define __MM0_IDPOOL_H__ - -#include -#include -#include INC_GLUE(memory.h) -#include - -struct id_pool { - int nwords; - u32 bitmap[]; -}; - -/* Copy one id pool to another by calculating its size */ -static inline void id_pool_copy(struct id_pool *to, struct id_pool *from, int totalbits) -{ - int nwords = BITWISE_GETWORD(totalbits); - - memcpy(to, from, nwords * SZ_WORD + sizeof(struct id_pool)); -} - -struct id_pool *id_pool_new_init(int mapsize); -int id_new(struct id_pool *pool); -int id_del(struct id_pool *pool, int id); -int id_get(struct id_pool *pool, int id); -int ids_new_contiguous(struct id_pool *pool, int numids); -int ids_del_contiguous(struct id_pool *pool, int first, int numids); - -#endif /* __MM0_IDPOOL_H__ */ diff --git a/conts/posix/fs0/include/lib/malloc.h b/conts/posix/fs0/include/lib/malloc.h deleted file mode 100644 index 37479ff..0000000 --- a/conts/posix/fs0/include/lib/malloc.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef __PRIVATE_MALLOC_H__ -#define __PRIVATE_MALLOC_H__ - -#include -#include - -void *kmalloc(size_t size); -void kfree(void *blk); - -static inline void *kzalloc(size_t size) -{ - void *buf = kmalloc(size); - - memset(buf, 0, size); - return buf; -} - - -#endif /*__PRIVATE_MALLOC_H__ */ diff --git a/conts/posix/fs0/include/lib/spinlock.h b/conts/posix/fs0/include/lib/spinlock.h deleted file mode 100644 index b3cc39c..0000000 --- a/conts/posix/fs0/include/lib/spinlock.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Fake spinlock for future multi-threaded mm0 - */ -#ifndef __MM0_SPINLOCK_H__ -#define __MM0_SPINLOCK_H__ - -struct spinlock { - int lock; -}; - -static inline void spin_lock_init(struct spinlock *s) { } -static inline void spin_lock(struct spinlock *s) { } -static inline void spin_unlock(struct spinlock *s) { } - -#endif /* __MM0_SPINLOCK_H__ */ diff --git a/conts/posix/fs0/include/linker.lds.in b/conts/posix/fs0/include/linker.lds.in deleted file mode 100644 index 3fb6458..0000000 --- a/conts/posix/fs0/include/linker.lds.in +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Simple linker script for userspace or svc tasks. - * - * Copyright (C) 2007 Bahadir Balban - */ - -/* USER_AREA_START, see memlayout.h */ -virtual_base = 0x10000000; -physical_base = %s; -__stack = (0x20000000 - 0x1000 - 8); /* First page before env/args page */ -/* INCLUDE "include/physical_base.lds" */ - -/* physical_base = 0x228000; */ -offset = virtual_base - physical_base; - -ENTRY(_start) - -SECTIONS -{ - . = virtual_base; - _start_text = .; - .text : AT (ADDR(.text) - offset) { *(.text.head) *(.text) } - /* rodata is needed else your strings will link at physical! */ - .rodata : AT (ADDR(.rodata) - offset) { *(.rodata) } - .rodata1 : AT (ADDR(.rodata1) - offset) { *(.rodata1) } - .data : AT (ADDR(.data) - offset) - { - . = ALIGN(4K); /* Align UTCB to page boundary */ - _start_utcb = .; - *(.utcb) - _end_utcb = .; - . = ALIGN(4K); - _start_bdev = .; - *(.data.memfs) - _end_bdev = .; - *(.data) - } - .bss : AT (ADDR(.bss) - offset) { *(.bss) } - - _end = .; -} diff --git a/conts/posix/fs0/include/syscalls.h b/conts/posix/fs0/include/syscalls.h deleted file mode 100644 index b10b892..0000000 --- a/conts/posix/fs0/include/syscalls.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * System call function signatures. - * - * Copyright (C) 2007, 2008 Bahadir Balban - */ -#ifndef __FS0_SYSCALLS_H__ -#define __FS0_SYSCALLS_H__ - -#include - -/* Posix calls */ -int sys_open(struct tcb *sender, const char *pathname, int flags, u32 mode); -int sys_readdir(struct tcb *sender, int fd, void *buf, int count); -int sys_mkdir(struct tcb *sender, const char *pathname, unsigned int mode); -int sys_chdir(struct tcb *sender, const char *pathname); - -/* Calls from pager that completes a posix call */ -int pager_open_bypath(struct tcb *pager, char *pathname); -int pager_sys_open(struct tcb *sender, l4id_t opener, int fd); -int pager_sys_read(struct tcb *sender, unsigned long vnum, unsigned long f_offset, - unsigned long npages, void *pagebuf); - -int pager_sys_write(struct tcb *sender, unsigned long vnum, unsigned long f_offset, - unsigned long npages, void *pagebuf); - -int pager_sys_close(struct tcb *sender, l4id_t closer, int fd); -int pager_update_stats(struct tcb *sender, unsigned long vnum, - unsigned long newsize); - -int pager_notify_fork(struct tcb *sender, l4id_t parentid, - l4id_t childid, unsigned long utcb_address, - unsigned int flags); - -int pager_notify_exit(struct tcb *sender, l4id_t tid); -#endif /* __FS0_SYSCALLS_H__ */ diff --git a/conts/posix/fs0/include/task.h b/conts/posix/fs0/include/task.h deleted file mode 100644 index 7908755..0000000 --- a/conts/posix/fs0/include/task.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2008 Bahadir Balban - */ -#ifndef __FS0_TASK_H__ -#define __FS0_TASK_H__ - -#include -#include -#include - -#define __TASKNAME__ __VFSNAME__ - -#define TCB_NO_SHARING 0 -#define TCB_SHARED_VM (1 << 0) -#define TCB_SHARED_FILES (1 << 1) -#define TCB_SHARED_FS (1 << 2) - -#define TASK_FILES_MAX 32 - -struct task_fd_head { - int fd[TASK_FILES_MAX]; - struct id_pool *fdpool; - int tcb_refs; -}; - -struct task_fs_data { - struct vnode *curdir; - struct vnode *rootdir; - int tcb_refs; -}; - -/* Thread control block, fs0 portion */ -struct tcb { - l4id_t tid; - struct link list; - unsigned long shpage_address; - struct task_fd_head *files; - struct task_fs_data *fs_data; -}; - -/* Structures used when receiving new task info from pager */ -struct task_data { - unsigned long tid; - unsigned long shpage_address; -}; - -struct task_data_head { - unsigned long total; - struct task_data tdata[]; -}; - -struct tcb *find_task(int tid); -int init_task_data(void); - -#endif /* __FS0_TASK_H__ */ diff --git a/conts/posix/fs0/main.c b/conts/posix/fs0/main.c deleted file mode 100644 index b5b672b..0000000 --- a/conts/posix/fs0/main.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * FS0. Filesystem implementation - * - * Copyright (C) 2007 Bahadir Balban - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * TODO: - * - Have a dentry cache searchable by name - * - Have a vnode cache searchable by vnum (and name?) - * - fs-specific readdir would read contents by page range, and add vnodes/dentries - * to their caches, while populating the directory vnode being read. - * - Have 2 vfs_lookup() flavors, one that searches a path, one that searches a vnum. - * - dirbuf is either allocated by low-level readdir, or else by a higher level, i.e. - * either high-level vfs code, or the mm0 page cache. - * - readdir provides a posix-compliant dirent structure list in dirbuf. - * - memfs dentries should be identical to posix struct dirents. - * - * ALL DONE!!! But untested. - * - * - Add mkdir - * - Add create - * - Add read/write -> This will need page cache and mm0 involvement. - * - * Done those, too. but untested. - */ - -/* Synchronise with pager via a `wait' tagged ipc with destination as pager */ -void wait_pager(l4id_t partner) -{ - l4_send(partner, L4_IPC_TAG_SYNC); - // printf("%s: Pager synced with us.\n", __TASKNAME__); -} - -void handle_fs_requests(void) -{ - u32 mr[MR_UNUSED_TOTAL]; - l4id_t senderid; - struct tcb *sender; - int ret; - u32 tag; - - if ((ret = l4_receive(L4_ANYTHREAD)) < 0) { - printf("%s: %s: IPC Error: %d. Quitting...\n", __TASKNAME__, - __FUNCTION__, ret); - BUG(); - } - - /* Read conventional ipc data */ - tag = l4_get_tag(); - senderid = l4_get_sender(); - - if (!(sender = find_task(senderid))) { - l4_ipc_return(-ESRCH); - return; - } - - /* Read mrs not used by syslib */ - for (int i = 0; i < MR_UNUSED_TOTAL; i++) - mr[i] = read_mr(MR_UNUSED_START + i); - - /* FIXME: Fix all these syscalls to read any buffer data from the caller task's utcb. - * Make sure to return -EINVAL if data is not valid. */ - switch(tag) { - case L4_IPC_TAG_SYNC: - printf("%s: Synced with waiting thread.\n", __TASKNAME__); - return; /* No origy for this tag */ - case L4_IPC_TAG_OPEN: - ret = sys_open(sender, (void *)mr[0], (int)mr[1], (unsigned int)mr[2]); - break; - case L4_IPC_TAG_MKDIR: - ret = sys_mkdir(sender, (const char *)mr[0], (unsigned int)mr[1]); - break; - case L4_IPC_TAG_CHDIR: - ret = sys_chdir(sender, (const char *)mr[0]); - break; - case L4_IPC_TAG_READDIR: - ret = sys_readdir(sender, (int)mr[0], (void *)mr[1], (int)mr[2]); - break; - case L4_IPC_TAG_PAGER_READ: - ret = pager_sys_read(sender, (unsigned long)mr[0], (unsigned long)mr[1], - (unsigned long)mr[2], (void *)mr[3]); - break; - case L4_IPC_TAG_PAGER_OPEN: - ret = pager_sys_open(sender, (l4id_t)mr[0], (int)mr[1]); - break; - case L4_IPC_TAG_PAGER_OPEN_BYPATH: - ret = pager_open_bypath(sender, (char *)mr[0]); - break; - case L4_IPC_TAG_PAGER_WRITE: - ret = pager_sys_write(sender, (unsigned long)mr[0], (unsigned long)mr[1], - (unsigned long)mr[2], (void *)mr[3]); - break; - case L4_IPC_TAG_PAGER_CLOSE: - ret = pager_sys_close(sender, (l4id_t)mr[0], (int)mr[1]); - break; - case L4_IPC_TAG_PAGER_UPDATE_STATS: - ret = pager_update_stats(sender, (unsigned long)mr[0], - (unsigned long)mr[1]); - break; - case L4_IPC_TAG_NOTIFY_FORK: - ret = pager_notify_fork(sender, (l4id_t)mr[0], (l4id_t)mr[1], - (unsigned long)mr[2], (unsigned int)mr[3]); - break; - case L4_IPC_TAG_NOTIFY_EXIT: - ret = pager_notify_exit(sender, (l4id_t)mr[0]); - break; - - default: - printf("%s: Unrecognised ipc tag (%d) " - "received from tid: %d. Ignoring.\n", __TASKNAME__, - mr[MR_TAG], senderid); - } - - /* Reply */ - if ((ret = l4_ipc_return(ret)) < 0) { - printf("%s: L4 IPC Error: %d.\n", __FUNCTION__, ret); - BUG(); - } -} - -void main(void) -{ - printf("\n%s: Started with thread id %d\n", __TASKNAME__, self_tid()); - - initialise(); - - wait_pager(PAGER_TID); - - printf("%s: VFS service initialized. Listening requests.\n", __TASKNAME__); - while (1) { - handle_fs_requests(); - } -} - diff --git a/conts/posix/fs0/src/bootfs/bootfs.c b/conts/posix/fs0/src/bootfs/bootfs.c deleted file mode 100644 index 1b3fdcb..0000000 --- a/conts/posix/fs0/src/bootfs/bootfs.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * A pseudo-filesystem for reading the in-memory - * server tasks loaded from the initial elf executable. - * - * Copyright (C) 2007, 2008 Bahadir Balban - */ -#include -#include -#include - -struct dentry *bootfs_dentry_lookup(struct dentry *d, char *dname) -{ - struct dentry *this; - - list_foreach_struct(this, child, &d->children) { - if (this->compare(this, dname)) - return this; - } - return 0; -} - -struct dentry *path_lookup(struct superblock *sb, char *pathstr) -{ - char *dname; - char *splitpath; - struct dentry *this, *next; - - /* First dentry is root */ - this = sb->root; - - /* Get next path component from path string */ - dname = path_next_dentry_name(pathstr); - - if (!this->compare(dname)) - return; - - while(!(dname = path_next_dentry_name(pathstr))) { - if ((d = this->lookup(this, dname))) - return 0; - } -} - -/* - * This creates a pseudo-filesystem tree from the loaded - * server elf images whose information is available from - * initdata. - */ -void bootfs_populate(struct initdata *initdata, struct superblock *sb) -{ - struct bootdesc *bd = initdata->bootdesc; - struct svc_image *img; - struct dentry *d; - struct vnode *v; - struct file *f; - - for (int i = 0; i < bd->total_images; i++) { - img = &bd->images[i]; - - d = malloc(sizeof(struct dentry)); - v = malloc(sizeof(struct vnode)); - f = malloc(sizeof(struct file)); - - /* Initialise dentry for image */ - d->refcnt = 0; - d->vnode = v; - d->parent = sb->root; - strncpy(d->name, img->name, VFS_DENTRY_NAME_MAX); - link_init(&d->child); - link_init(&d->children); - list_insert(&d->child, &sb->root->children); - - /* Initialise vnode for image */ - v->refcnt = 0; - v->id = img->phys_start; - v->size = img->phys_end - img->phys_start; - link_init(&v->dirents); - list_insert(&d->v_ref, &v->dirents); - - /* Initialise file struct for image */ - f->refcnt = 0; - f->dentry = d; - - img_d++; - img_vn++; - img_f++; - } -} - -void bootfs_init_root(struct dentry *r) -{ - struct vnode *v = r->vnode; - - /* Initialise dentry for rootdir */ - r->refcnt = 0; - strcpy(r->name, ""); - link_init(&r->child); - link_init(&r->children); - link_init(&r->vref); - r->parent = r; - - /* Initialise vnode for rootdir */ - v->id = 0; - v->refcnt = 0; - link_init(&v->dirents); - link_init(&v->state_list); - list_insert(&r->vref, &v->dirents); - v->size = 0; -} - -struct superblock *bootfs_init_sb(struct superblock *sb) -{ - sb->root = malloc(sizeof(struct dentry)); - sb->root->vnode = malloc(sizeof(struct vnode)); - - bootfs_init_root(&sb->root); - - return sb; -} - -struct superblock bootfs_sb = { - .fs = bootfs_type, - .ops = { - .read_sb = bootfs_read_sb, - .write_sb = bootfs_write_sb, - .read_vnode = bootfs_read_vnode, - .write_vnode = bootfs_write_vnode, - }, -}; - -struct superblock *bootfs_get_sb(void) -{ - bootfs_init_sb(&bootfs_sb); - return &bootfs_sb; -} - -struct file_system_type bootfs_type = { - .name = "bootfs", - .magic = 0, - .get_sb = bootfs_get_sb, -}; - -void init_bootfs() -{ - bootfs_init_sb(&bootfs_sb); - - bootfs_populate(&bootfs_sb); -} diff --git a/conts/posix/fs0/src/c0fs/c0fs.c b/conts/posix/fs0/src/c0fs/c0fs.c deleted file mode 100644 index d1146b2..0000000 --- a/conts/posix/fs0/src/c0fs/c0fs.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * A basic unix-like read/writeable filesystem for Codezero. - * - * Copyright (C) 2007, 2008 Bahadir Balban - */ -#include -#include - -void sfs_read_sb(struct superblock *sb) -{ - -} - -static void simplefs_alloc_vnode(struct vnode *) -{ - -} - -struct file_system_type sfs_type = { - .name = "c0fs", - .magic = 1, - .flags = 0, -}; - -/* Registers sfs as an available filesystem type */ -void sfs_register_fstype(struct link *fslist) -{ - list_insert(&sfs_type.list, fslist); -} diff --git a/conts/posix/fs0/src/lib/bit.c b/conts/posix/fs0/src/lib/bit.c deleted file mode 100644 index 7b1dee4..0000000 --- a/conts/posix/fs0/src/lib/bit.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Bit manipulation functions. - * - * Copyright (C) 2007 Bahadir Balban - */ -#include -#include -#include -#include -#include INC_GLUE(memory.h) - -/* Emulation of ARM's CLZ (count leading zeroes) instruction */ -unsigned int __clz(unsigned int bitvector) -{ - unsigned int x = 0; - while((!(bitvector & ((unsigned)1 << 31))) && (x < 32)) { - bitvector <<= 1; - x++; - } - return x; -} - -int find_and_set_first_free_bit(u32 *word, unsigned int limit) -{ - int success = 0; - int i; - - for(i = 0; i < limit; i++) { - /* Find first unset bit */ - if (!(word[BITWISE_GETWORD(i)] & BITWISE_GETBIT(i))) { - /* Set it */ - word[BITWISE_GETWORD(i)] |= BITWISE_GETBIT(i); - success = 1; - break; - } - } - /* Return bit just set */ - if (success) - return i; - else - return -1; -} - -int find_and_set_first_free_contig_bits(u32 *word, unsigned int limit, - int nbits) -{ - int i = 0, first = 0, last = 0, found = 0; - - /* Can't allocate more than the limit */ - if (nbits > limit) - return -1; - - /* This is a state machine that checks n contiguous free bits. */ - while (i + nbits < limit) { - first = i; - last = i; - while (!(word[BITWISE_GETWORD(last)] & BITWISE_GETBIT(last))) { - last++; - i++; - if (last == first + nbits) { - found = 1; - break; - } - } - if (found) - break; - i++; - } - - /* If found, set the bits */ - if (found) { - for (int x = first; x < first + nbits; x++) - word[BITWISE_GETWORD(x)] |= BITWISE_GETBIT(x); - return first; - } else - return -1; -} - -int check_and_clear_bit(u32 *word, int bit) -{ - /* Check that bit was set */ - if (word[BITWISE_GETWORD(bit)] & BITWISE_GETBIT(bit)) { - word[BITWISE_GETWORD(bit)] &= ~BITWISE_GETBIT(bit); - return 0; - } else { - printf("Trying to clear already clear bit\n"); - return -1; - } -} - -int check_and_clear_contig_bits(u32 *word, int first, int nbits) -{ - for (int i = first; i < first + nbits; i++) - if (check_and_clear_bit(word, i) < 0) - return -1; - return 0; -} - -int check_and_set_bit(u32 *word, int bit) -{ - /* Check that bit was clear */ - if (!(word[BITWISE_GETWORD(bit)] & BITWISE_GETBIT(bit))) { - word[BITWISE_GETWORD(bit)] |= BITWISE_GETBIT(bit); - return 0; - } else { - //printf("Trying to set already set bit\n"); - return -1; - } -} - - diff --git a/conts/posix/fs0/src/lib/idpool.c b/conts/posix/fs0/src/lib/idpool.c deleted file mode 100644 index 0cb826e..0000000 --- a/conts/posix/fs0/src/lib/idpool.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Used for thread and space ids. - * - * Copyright (C) 2007 Bahadir Balban - */ -#include -// #include --> This requires page allocation to grow/shrink. -#include // --> This is a local library that statically allocates its heap. -#include -#include INC_GLUE(memory.h) -#include -#include - -struct id_pool *id_pool_new_init(int totalbits) -{ - int nwords = BITWISE_GETWORD(totalbits); - struct id_pool *new = kzalloc((nwords * SZ_WORD) - + sizeof(struct id_pool)); - if (!new) - return PTR_ERR(-ENOMEM); - new->nwords = nwords; - return new; -} - -int id_new(struct id_pool *pool) -{ - int id = find_and_set_first_free_bit(pool->bitmap, - pool->nwords * WORD_BITS); - if (id < 0) - printf("%s: Warning! New id alloc failed\n", __FUNCTION__); - return id; -} - -/* This finds n contiguous free ids, allocates and returns the first one */ -int ids_new_contiguous(struct id_pool *pool, int numids) -{ - int id = find_and_set_first_free_contig_bits(pool->bitmap, - pool->nwords *WORD_BITS, - numids); - if (id < 0) - printf("%s: Warning! New id alloc failed\n", __FUNCTION__); - return id; -} - -/* This deletes a list of contiguous ids given the first one and number of ids */ -int ids_del_contiguous(struct id_pool *pool, int first, int numids) -{ - int ret; - - if (pool->nwords * WORD_BITS < first + numids) - return -1; - if ((ret = check_and_clear_contig_bits(pool->bitmap, first, numids))) - printf("%s: Error: Invalid argument range.\n", __FUNCTION__); - return ret; -} - -int id_del(struct id_pool *pool, int id) -{ - int ret; - - if (pool->nwords * WORD_BITS < id) - return -1; - - if ((ret = check_and_clear_bit(pool->bitmap, id) < 0)) - printf("%s: Error: Could not delete id.\n", __FUNCTION__); - return ret; -} - -/* Return a specific id, if available */ -int id_get(struct id_pool *pool, int id) -{ - int ret; - - ret = check_and_set_bit(pool->bitmap, id); - - if (ret < 0) - return ret; - else - return id; -} - diff --git a/conts/posix/fs0/src/lib/malloc.c b/conts/posix/fs0/src/lib/malloc.c deleted file mode 100644 index 27c3829..0000000 --- a/conts/posix/fs0/src/lib/malloc.c +++ /dev/null @@ -1,417 +0,0 @@ -/***************************************************************************** -Simple malloc -Chris Giese http://www.execpc.com/~geezer -Release date: Oct 30, 2002 -This code is public domain (no copyright). -You can do whatever you want with it. - -Features: -- First-fit -- free() coalesces adjacent free blocks -- Uses variable-sized heap, enlarged with kbrk()/sbrk() function -- Does not use mmap() -- Can be easily modified to use fixed-size heap -- Works with 16- or 32-bit compilers - -Build this program with either of the two main() functions, then run it. -Messages that indicate a software error will contain three asterisks (***). -*****************************************************************************/ -#include /* memcpy(), memset() */ -#include /* printf() */ - -#define _32BIT 1 - -/* use small (32K) heap for 16-bit compilers, -large (500K) heap for 32-bit compilers */ -#if defined(_32BIT) -#define HEAP_SIZE 500000uL -#else -#define HEAP_SIZE 32768u -#endif - -#define MALLOC_MAGIC 0x6D92 /* must be < 0x8000 */ - -typedef struct _malloc /* Turbo C DJGPP */ -{ - size_t size; /* 2 bytes 4 bytes */ - struct _malloc *next; /* 2 bytes 4 bytes */ - unsigned magic : 15; /* 2 bytes total 4 bytes total */ - unsigned used : 1; -} malloc_t; /* total 6 bytes 12 bytes */ - -static char *g_heap_bot, *g_kbrk, *g_heap_top; -/***************************************************************************** -*****************************************************************************/ -void dump_heap(void) -{ - unsigned blks_used = 0, blks_free = 0; - size_t bytes_used = 0, bytes_free = 0; - malloc_t *m; - int total; - - printf("===============================================\n"); - for(m = (malloc_t *)g_heap_bot; m != NULL; m = m->next) - { - printf("blk %5p: %6u bytes %s\n", m, - m->size, m->used ? "used" : "free"); - if(m->used) - { - blks_used++; - bytes_used += m->size; - } - else - { - blks_free++; - bytes_free += m->size; - } - } - printf("blks: %6u used, %6u free, %6u total\n", blks_used, - blks_free, blks_used + blks_free); - printf("bytes: %6u used, %6u free, %6u total\n", bytes_used, - bytes_free, bytes_used + bytes_free); - printf("g_heap_bot=0x%p, g_kbrk=0x%p, g_heap_top=0x%p\n", - g_heap_bot, g_kbrk, g_heap_top); - total = (bytes_used + bytes_free) + - (blks_used + blks_free) * sizeof(malloc_t); - if(total != g_kbrk - g_heap_bot) - printf("*** some heap memory is not accounted for\n"); - printf("===============================================\n"); -} -/***************************************************************************** -POSIX sbrk() looks like this - void *sbrk(int incr); -Mine is a bit different so I can signal the calling function -if more memory than desired was allocated (e.g. in a system with paging) -If your kbrk()/sbrk() always allocates the amount of memory you ask for, -this code can be easily changed. - - int brk( void *sbrk( void *kbrk( -function void *adr); int delta); int *delta); ----------------------- ------------ ------------ ------------- -POSIX? yes yes NO -return value if error -1 -1 NULL -get break value . sbrk(0) int x=0; kbrk(&x); -set break value to X brk(X) sbrk(X - sbrk(0)) int x=X, y=0; kbrk(&x) - kbrk(&y); -enlarge heap by N bytes . sbrk(+N) int x=N; kbrk(&x); -shrink heap by N bytes . sbrk(-N) int x=-N; kbrk(&x); -can you tell if you're - given more memory - than you wanted? no no yes -*****************************************************************************/ -static void *kbrk(int *delta) -{ - static char heap[HEAP_SIZE]; -/**/ - char *new_brk, *old_brk; - -/* heap doesn't exist yet */ - if(g_heap_bot == NULL) - { - g_heap_bot = g_kbrk = heap; - g_heap_top = g_heap_bot + HEAP_SIZE; - } - new_brk = g_kbrk + (*delta); -/* too low: return NULL */ - if(new_brk < g_heap_bot) - return NULL; -/* too high: return NULL */ - if(new_brk >= g_heap_top) - return NULL; -/* success: adjust brk value... */ - old_brk = g_kbrk; - g_kbrk = new_brk; -/* ...return actual delta... (for this sbrk(), they are the same) - (*delta) = (*delta); */ -/* ...return old brk value */ - return old_brk; -} -/***************************************************************************** -kmalloc() and kfree() use g_heap_bot, but not g_kbrk nor g_heap_top -*****************************************************************************/ -void *kmalloc(size_t size) -{ - unsigned total_size; - malloc_t *m, *n; - int delta; - - if(size == 0) - return NULL; - total_size = size + sizeof(malloc_t); -/* search heap for free block (FIRST FIT) */ - m = (malloc_t *)g_heap_bot; -/* g_heap_bot == 0 == NULL if heap does not yet exist */ - if(m != NULL) - { - if(m->magic != MALLOC_MAGIC) -// panic("kernel heap is corrupt in kmalloc()"); - { - printf("*** kernel heap is corrupt in kmalloc()\n"); - return NULL; - } - for(; m->next != NULL; m = m->next) - { - if(m->used) - continue; -/* size == m->size is a perfect fit */ - if(size == m->size) - m->used = 1; - else - { -/* otherwise, we need an extra sizeof(malloc_t) bytes for the header -of a second, free block */ - if(total_size > m->size) - continue; -/* create a new, smaller free block after this one */ - n = (malloc_t *)((char *)m + total_size); - n->size = m->size - total_size; - n->next = m->next; - n->magic = MALLOC_MAGIC; - n->used = 0; -/* reduce the size of this block and mark it used */ - m->size = size; - m->next = n; - m->used = 1; - } - return (char *)m + sizeof(malloc_t); - } - } -/* use kbrk() to enlarge (or create!) heap */ - delta = total_size; - n = kbrk(&delta); -/* uh-oh */ - if(n == NULL) - return NULL; - if(m != NULL) - m->next = n; - n->size = size; - n->magic = MALLOC_MAGIC; - n->used = 1; -/* did kbrk() return the exact amount of memory we wanted? -cast to make "gcc -Wall -W ..." shut the hell up */ - if((int)total_size == delta) - n->next = NULL; - else - { -/* it returned more than we wanted (it will never return less): -create a new, free block */ - m = (malloc_t *)((char *)n + total_size); - m->size = delta - total_size - sizeof(malloc_t); - m->next = NULL; - m->magic = MALLOC_MAGIC; - m->used = 0; - - n->next = m; - } - return (char *)n + sizeof(malloc_t); -} - -static inline void *kzalloc(size_t size) -{ - void *buf = kmalloc(size); - - memset(buf, 0, size); - return buf; -} - -/***************************************************************************** -*****************************************************************************/ -void kfree(void *blk) -{ - malloc_t *m, *n; - -/* get address of header */ - m = (malloc_t *)((char *)blk - sizeof(malloc_t)); - if(m->magic != MALLOC_MAGIC) -// panic("attempt to kfree() block at 0x%p " -// "with bad magic value", blk); - { - printf("*** attempt to kfree() block at 0x%p " - "with bad magic value\n", blk); - return; - } -/* find this block in the heap */ - n = (malloc_t *)g_heap_bot; - if(n->magic != MALLOC_MAGIC) -// panic("kernel heap is corrupt in kfree()"); - { - printf("*** kernel heap is corrupt in kfree()\n"); - return; - } - for(; n != NULL; n = n->next) - { - if(n == m) - break; - } -/* not found? bad pointer or no heap or something else? */ - if(n == NULL) -// panic("attempt to kfree() block at 0x%p " -// "that is not in the heap", blk); - { - printf("*** attempt to kfree() block at 0x%p " - "that is not in the heap\n", blk); - return; - } -/* free the block */ - m->used = 0; -/* coalesce adjacent free blocks -Hard to spell, hard to do */ - for(m = (malloc_t *)g_heap_bot; m != NULL; m = m->next) - { - while(!m->used && m->next != NULL && !m->next->used) - { -/* resize this block */ - m->size += sizeof(malloc_t) + m->next->size; -/* merge with next block */ - m->next = m->next->next; - } - } -} -/***************************************************************************** -*****************************************************************************/ -void *krealloc(void *blk, size_t size) -{ - void *new_blk; - malloc_t *m; - -/* size == 0: free block */ - if(size == 0) - { - if(blk != NULL) - kfree(blk); - new_blk = NULL; - } - else - { -/* allocate new block */ - new_blk = kmalloc(size); -/* if allocation OK, and if old block exists, copy old block to new */ - if(new_blk != NULL && blk != NULL) - { - m = (malloc_t *)((char *)blk - sizeof(malloc_t)); - if(m->magic != MALLOC_MAGIC) -// panic("attempt to krealloc() block at " -// "0x%p with bad magic value", blk); - { - printf("*** attempt to krealloc() block at " - "0x%p with bad magic value\n", blk); - return NULL; - } -/* copy minimum of old and new block sizes */ - if(size > m->size) - size = m->size; - memcpy(new_blk, blk, size); -/* free the old block */ - kfree(blk); - } - } - return new_blk; -} -/***************************************************************************** -*****************************************************************************/ - -#if 0 - -#include /* rand() */ - - -#define SLOTS 17 - -int main(void) -{ - unsigned lifetime[SLOTS]; - void *blk[SLOTS]; - int i, j, k; - - dump_heap(); - memset(lifetime, 0, sizeof(lifetime)); - memset(blk, 0, sizeof(blk)); - for(i = 0; i < 1000; i++) - { - printf("Pass %6u\n", i); - for(j = 0; j < SLOTS; j++) - { -/* age the block */ - if(lifetime[j] != 0) - { - (lifetime[j])--; - continue; - } -/* too old; free it */ - if(blk[j] != NULL) - { - kfree(blk[j]); - blk[j] = NULL; - } -/* alloc new block of random size -Note that size_t==unsigned, but kmalloc() uses integer math, -so block size must be positive integer */ -#if defined(_32BIT) - k = rand() % 40960 + 1; -#else - k = rand() % 4096 + 1; -#endif - blk[j] = kmalloc(k); - if(blk[j] == NULL) - printf("failed to alloc %u bytes\n", k); - else -/* give it a random lifetime 0-20 */ - lifetime[j] = rand() % 21; - } - } -/* let's see what we've wrought */ - printf("\n\n"); - dump_heap(); -/* free everything */ - for(j = 0; j < SLOTS; j++) - { - if(blk[j] != NULL) - { - kfree(blk[j]); - blk[j] = NULL; - } - (lifetime[j]) = 0; - } -/* after all that, we should have a single, unused block */ - dump_heap(); - return 0; -} -/***************************************************************************** -*****************************************************************************/ - -int main(void) -{ - void *b1, *b2, *b3; - - dump_heap(); - - b1 = kmalloc(42); - dump_heap(); - - b2 = kmalloc(23); - dump_heap(); - - b3 = kmalloc(7); - dump_heap(); - - b2 = krealloc(b2, 24); - dump_heap(); - - kfree(b1); - dump_heap(); - - b1 = kmalloc(5); - dump_heap(); - - kfree(b2); - dump_heap(); - - kfree(b3); - dump_heap(); - - kfree(b1); - dump_heap(); - - return 0; -} -#endif - diff --git a/conts/posix/fs0/src/syscalls.c b/conts/posix/fs0/src/syscalls.c deleted file mode 100644 index 9943c44..0000000 --- a/conts/posix/fs0/src/syscalls.c +++ /dev/null @@ -1,528 +0,0 @@ -/* - * Some syscall stubs - * - * Copyright (C) 2008 Bahadir Balban - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define NILFD -1 - -/* - * This informs mm0 about an opened file descriptors. - * - * MM0 *also* keeps track of fd's because mm0 is a better candidate - * for handling syscalls that access file content (i.e. read/write) since - * it maintains the page cache. MM0 is not notified about opened files - * but is rather informed when it asks to be. This avoids deadlocks by - * keeping the request flow in one way. - */ - -int pager_sys_open(struct tcb *pager, l4id_t opener, int fd) -{ - struct tcb *task; - struct vnode *v; - - //printf("%s/%s\n", __TASKNAME__, __FUNCTION__); - if (pager->tid != PAGER_TID) - return -EINVAL; - - /* Check if such task exists */ - if (!(task = find_task(opener))) - return -ESRCH; - - /* Check if that fd has been opened */ - if (task->files->fd[fd] == NILFD) - return -EBADF; - - /* Search the vnode by that vnum */ - if (IS_ERR(v = vfs_lookup_byvnum(vfs_root.pivot->sb, - task->files->fd[fd]))) - return (int)v; - - /* - * Write file information, they will - * be sent via the return origy. - */ - write_mr(L4SYS_ARG0, v->vnum); - write_mr(L4SYS_ARG1, v->size); - - return 0; -} - -/* This is called when the pager needs to open a vfs file via its path */ -int pager_open_bypath(struct tcb *pager, char *pathname) -{ - struct pathdata *pdata; - struct tcb *task; - struct vnode *v; - int retval; - - //printf("%s/%s\n", __TASKNAME__, __FUNCTION__); - if (pager->tid != PAGER_TID) - return -EINVAL; - - /* Parse path data */ - if (IS_ERR(pdata = pathdata_parse(pathname, - alloca(strlen(pathname) + 1), - task))) - return (int)pdata; - - /* Search the vnode by that path */ - if (IS_ERR(v = vfs_lookup_bypath(pdata))) { - retval = (int)v; - goto out; - } - - /* - * Write file information, they will - * be sent via the return origy. - */ - write_mr(L4SYS_ARG0, v->vnum); - write_mr(L4SYS_ARG1, v->size); - - return 0; - -out: - pathdata_destroy(pdata); - return retval; - -} - - -/* Directories only for now */ -void print_vnode(struct vnode *v) -{ - struct dentry *d, *c; - - printf("Vnode names:\n"); - list_foreach_struct(d, &v->dentries, vref) { - printf("%s\n", d->name); - printf("Children dentries:\n"); - list_foreach_struct(c, &d->children, child) - printf("%s\n", c->name); - } -} - -/* Creates a node under a directory, e.g. a file, directory. */ -struct vnode *vfs_create(struct tcb *task, struct pathdata *pdata, - unsigned int mode) -{ - struct vnode *vparent, *newnode; - const char *nodename; - - /* The last component is to be created */ - nodename = pathdata_last_component(pdata); - - /* Check that the parent directory exists. */ - if (IS_ERR(vparent = vfs_lookup_bypath(pdata))) - return vparent; - - /* The parent vnode must be a directory. */ - if (!vfs_isdir(vparent)) - return PTR_ERR(-ENOENT); - - /* Create new directory under the parent */ - if (IS_ERR(newnode = vparent->ops.mknod(vparent, nodename, mode))) - return newnode; - - // print_vnode(vparent); - return newnode; -} - -/* - * Pager notifies vfs about a closed file descriptor. - * - * FIXME: fsync + close could be done under a single "close" ipc - * from pager. Currently there are 2 ipcs: 1 fsync + 1 fd close. - */ -int pager_sys_close(struct tcb *sender, l4id_t closer, int fd) -{ - struct tcb *task; - int err; - - // printf("%s/%s\n", __TASKNAME__, __FUNCTION__); - - BUG_ON(!(task = find_task(closer))); - - if ((err = id_del(task->files->fdpool, fd)) < 0) { - printf("%s: Error releasing fd identifier.\n", - __FUNCTION__); - return err; - } - task->files->fd[fd] = NILFD; - - return 0; -} - -/* FIXME: - * - Is it already open? - * - Allocate a copy of path string since lookup destroys it - * - Check flags and mode. - */ -int sys_open(struct tcb *task, const char *pathname, int flags, unsigned int mode) -{ - struct pathdata *pdata; - struct vnode *v; - int fd; - int retval; - - // printf("%s/%s\n", __TASKNAME__, __FUNCTION__); - - /* Parse path data */ - if (IS_ERR(pdata = pathdata_parse(pathname, - alloca(strlen(pathname) + 1), - task))) - return (int)pdata; - - /* Creating new file */ - if (flags & O_CREAT) { - /* Make sure mode identifies a file */ - mode |= S_IFREG; - if (IS_ERR(v = vfs_create(task, pdata, mode))) { - retval = (int)v; - goto out; - } - } else { - /* Not creating, just opening, get the vnode */ - if (IS_ERR(v = vfs_lookup_bypath(pdata))) { - retval = (int)v; - goto out; - } - } - - /* Get a new fd */ - BUG_ON((fd = id_new(task->files->fdpool)) < 0); - retval = fd; - - /* Assign the new fd with the vnode's number */ - task->files->fd[fd] = v->vnum; - -out: - pathdata_destroy(pdata); - return retval; -} - -int sys_mkdir(struct tcb *task, const char *pathname, unsigned int mode) -{ - struct pathdata *pdata; - struct vnode *v; - int ret = 0; - - /* Parse path data */ - if (IS_ERR(pdata = pathdata_parse(pathname, - alloca(strlen(pathname) + 1), - task))) - return (int)pdata; - - /* Make sure we create a directory */ - mode |= S_IFDIR; - - /* Create the directory or fail */ - if (IS_ERR(v = vfs_create(task, pdata, mode))) - ret = (int)v; - - /* Destroy extracted path data */ - pathdata_destroy(pdata); - return ret; -} - -int sys_chdir(struct tcb *task, const char *pathname) -{ - struct vnode *v; - struct pathdata *pdata; - int ret = 0; - - /* Parse path data */ - if (IS_ERR(pdata = pathdata_parse(pathname, - alloca(strlen(pathname) + 1), - task))) - return (int)pdata; - - /* Get the vnode */ - if (IS_ERR(v = vfs_lookup_bypath(pdata))) { - ret = (int)v; - goto out; - } - - /* Ensure it's a directory */ - if (!vfs_isdir(v)) { - ret = -ENOTDIR; - goto out; - } - - /* Assign the current directory pointer */ - task->fs_data->curdir = v; - -out: - /* Destroy extracted path data */ - pathdata_destroy(pdata); - return ret; -} - -void fill_kstat(struct vnode *v, struct kstat *ks) -{ - ks->vnum = (u64)v->vnum; - ks->mode = v->mode; - ks->links = v->links; - ks->uid = v->owner & 0xFFFF; - ks->gid = (v->owner >> 16) & 0xFFFF; - ks->size = v->size; - ks->blksize = v->sb->blocksize; - ks->atime = v->atime; - ks->mtime = v->mtime; - ks->ctime = v->ctime; -} - -int sys_fstat(struct tcb *task, int fd, void *statbuf) -{ - struct vnode *v; - unsigned long vnum; - - /* Get the vnum */ - if (fd < 0 || fd > TASK_FILES_MAX || task->files->fd[fd] == NILFD) - return -EBADF; - - vnum = task->files->fd[fd]; - - /* Lookup vnode */ - if (!(v = vfs_lookup_byvnum(vfs_root.pivot->sb, vnum))) - return -EINVAL; - - /* Fill in the c0-style stat structure */ - fill_kstat(v, statbuf); - - return 0; -} - -/* - * Returns codezero-style stat structure which in turn is - * converted to posix style stat structure via the libposix - * library in userspace. - */ -int sys_stat(struct tcb *task, const char *pathname, void *statbuf) -{ - struct vnode *v; - struct pathdata *pdata; - int ret = 0; - - /* Parse path data */ - if (IS_ERR(pdata = pathdata_parse(pathname, - alloca(strlen(pathname) + 1), - task))) - return (int)pdata; - - /* Get the vnode */ - if (IS_ERR(v = vfs_lookup_bypath(pdata))) { - ret = (int)v; - goto out; - } - - /* Fill in the c0-style stat structure */ - fill_kstat(v, statbuf); - -out: - /* Destroy extracted path data */ - pathdata_destroy(pdata); - return ret; -} - -/* - * Note this can be solely called by the pager and is not the posix read call. - * That call is in the pager. This merely supplies the pages the pager needs - * if they're not in the page cache. - */ -int pager_sys_read(struct tcb *pager, unsigned long vnum, unsigned long f_offset, - unsigned long npages, void *pagebuf) -{ - struct vnode *v; - - // printf("%s/%s\n", __TASKNAME__, __FUNCTION__); - - if (pager->tid != PAGER_TID) - return -EINVAL; - - /* Lookup vnode */ - if (!(v = vfs_lookup_byvnum(vfs_root.pivot->sb, vnum))) - return -EINVAL; - - /* Ensure vnode is not a directory */ - if (vfs_isdir(v)) - return -EISDIR; - - return v->fops.read(v, f_offset, npages, pagebuf); -} - -int pager_update_stats(struct tcb *pager, unsigned long vnum, - unsigned long newsize) -{ - struct vnode *v; - - // printf("%s/%s\n", __TASKNAME__, __FUNCTION__); - - if (pager->tid != PAGER_TID) - return -EINVAL; - - /* Lookup vnode */ - if (!(v = vfs_lookup_byvnum(vfs_root.pivot->sb, vnum))) - return -EINVAL; - - v->size = newsize; - v->sb->ops->write_vnode(v->sb, v); - - return 0; -} - -/* - * This can be solely called by the pager and is not the posix write call. - * That call is in the pager. This writes the dirty pages of a file - * back to disk via vfs. - * - * The buffer must be contiguous by page, if npages > 1. - */ -int pager_sys_write(struct tcb *pager, unsigned long vnum, unsigned long f_offset, - unsigned long npages, void *pagebuf) -{ - struct vnode *v; - int ret; - int fwrite_end; - - // printf("%s/%s\n", __TASKNAME__, __FUNCTION__); - - if (pager->tid != PAGER_TID) - return -EINVAL; - - /* Lookup vnode */ - if (!(v = vfs_lookup_byvnum(vfs_root.pivot->sb, vnum))) - return -EINVAL; - - /* Ensure vnode is not a directory */ - if (vfs_isdir(v)) - return -EISDIR; - - //printf("%s/%s: Writing to vnode %lu, at pgoff 0x%x, %d pages, buf at 0x%x\n", - // __TASKNAME__, __FUNCTION__, vnum, f_offset, npages, pagebuf); - - if ((ret = v->fops.write(v, f_offset, npages, pagebuf)) < 0) - return ret; - - /* - * If the file is extended, write silently extends it. - * We update the extended size here. Otherwise subsequent write's - * may fail by relying on wrong file size. - */ - fwrite_end = __pfn_to_addr(f_offset) + ret; - if (v->size < fwrite_end) { - v->size = fwrite_end; - v->sb->ops->write_vnode(v->sb, v); - } - - return ret; -} - -/* - * FIXME: Here's how this should have been: - * v->ops.readdir() -> Reads fs-specific directory contents. i.e. reads - * the directory buffer, doesn't care however contained vnode details are - * stored. - * - * After reading, it converts the fs-spceific contents into generic vfs - * dentries and populates the dentries of those vnodes. - * - * If vfs_readdir() is issued, those generic dentries are converted into - * the posix-defined directory record structure. During this on-the-fly - * generation, pseudo-entries such as . and .. are also added. - * - * If this layering is not done, i.e. the low-level dentry buffer already - * keeps this record structure and we try to return that, then we wont - * have a chance to add the pseudo-entries . and .. These record entries - * are essentially created from parent vnode and current vnode but using - * the names . and .. - */ - -int fill_dirent(void *buf, unsigned long vnum, int offset, char *name) -{ - struct dirent *d = buf; - - d->inum = (unsigned int)vnum; - d->offset = offset; - d->rlength = sizeof(struct dirent); - strncpy((char *)d->name, name, DIRENT_NAME_MAX); - - return d->rlength; -} - -/* - * Reads @count bytes of posix struct dirents into @buf. This implements - * the raw dirent read syscall upon which readdir() etc. posix calls - * can be built in userspace. - * - * FIXME: Ensure buf is in shared utcb, and count does not exceed it. - */ -int sys_readdir(struct tcb *t, int fd, void *buf, int count) -{ - int dirent_size = sizeof(struct dirent); - int total = 0, nbytes = 0; - unsigned long vnum; - struct vnode *v; - struct dentry *d; - - // printf("%s/%s\n", __TASKNAME__, __FUNCTION__); - - /* Check address is in task's utcb */ - 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) - return -EBADF; - - vnum = t->files->fd[fd]; - - /* Lookup vnode */ - if (!(v = vfs_lookup_byvnum(vfs_root.pivot->sb, vnum))) - return -EINVAL; - - d = link_to_struct(v->dentries.next, struct dentry, vref); - - /* Ensure vnode is a directory */ - if (!vfs_isdir(v)) - return -ENOTDIR; - - /* Write pseudo-entries . and .. to user buffer */ - if (count < dirent_size) - return 0; - - fill_dirent(buf, v->vnum, nbytes, VFS_STR_CURDIR); - nbytes += dirent_size; - buf += dirent_size; - count -= dirent_size; - - if (count < dirent_size) - return 0; - - fill_dirent(buf, d->parent->vnode->vnum, nbytes, VFS_STR_PARDIR); - nbytes += dirent_size; - buf += dirent_size; - count -= dirent_size; - - /* Copy fs-specific dir to buf in struct dirent format */ - if ((total = v->ops.filldir(buf, v, count)) < 0) - return total; - - return nbytes + total; -} - diff --git a/conts/posix/fs0/src/task.c b/conts/posix/fs0/src/task.c deleted file mode 100644 index c0b7bb2..0000000 --- a/conts/posix/fs0/src/task.c +++ /dev/null @@ -1,315 +0,0 @@ -/* - * FS0 task data initialisation. - * - * Copyright (C) 2008 Bahadir Balban - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -extern void *shared_page; - -struct global_list global_tasks = { - .list = { &global_tasks.list, &global_tasks.list }, - .total = 0, -}; - -void global_add_task(struct tcb *task) -{ - BUG_ON(!list_empty(&task->list)); - list_insert_tail(&task->list, &global_tasks.list); - global_tasks.total++; -} - -void global_remove_task(struct tcb *task) -{ - BUG_ON(list_empty(&task->list)); - list_remove_init(&task->list); - BUG_ON(--global_tasks.total < 0); -} - -struct tcb *find_task(int tid) -{ - struct tcb *t; - - list_foreach_struct(t, &global_tasks.list, list) - if (t->tid == tid) - return t; - return 0; -} - -/* Allocate a vfs task structure according to given flags */ -struct tcb *tcb_alloc_init(unsigned int flags) -{ - struct tcb *task; - - if (!(task = kzalloc(sizeof(struct tcb)))) - return PTR_ERR(-ENOMEM); - - /* Allocate new fs data struct if its not shared */ - if (!(flags & TCB_SHARED_FS)) { - if (!(task->fs_data = - kzalloc(sizeof(*task->fs_data)))) { - kfree(task); - return PTR_ERR(-ENOMEM); - } - task->fs_data->tcb_refs = 1; - } - - /* Allocate file structures if not shared */ - if (!(flags & TCB_SHARED_FILES)) { - if (!(task->files = - kzalloc(sizeof(*task->files)))) { - kfree(task->fs_data); - kfree(task); - return PTR_ERR(-ENOMEM); - } - if (IS_ERR(task->files->fdpool = - id_pool_new_init(TASK_FILES_MAX))) { - void *err = task->files->fdpool; - - kfree(task->files); - kfree(task->fs_data); - kfree(task); - return err; - } - task->files->tcb_refs = 1; - } - - /* Ids will be set up later */ - task->tid = TASK_ID_INVALID; - - /* Initialise list structure */ - link_init(&task->list); - - return task; -} - -void copy_tcb(struct tcb *to, struct tcb *from, unsigned int share_flags) -{ - if (share_flags & TCB_SHARED_FILES) { - to->files = from->files; - to->files->tcb_refs++; - } else { - /* Copy all file descriptors */ - memcpy(to->files->fd, from->files->fd, - TASK_FILES_MAX * sizeof(to->files->fd[0])); - - /* Copy the idpool */ - id_pool_copy(to->files->fdpool, from->files->fdpool, TASK_FILES_MAX); - } - - if (share_flags & TCB_SHARED_FS) { - to->fs_data = from->fs_data; - to->fs_data->tcb_refs++; - } else - memcpy(to->fs_data, from->fs_data, sizeof(*to->fs_data)); -} - -/* Allocate a task struct and initialise it */ -struct tcb *tcb_create(struct tcb *orig, l4id_t tid, unsigned long shpage, - unsigned int share_flags) -{ - struct tcb *task; - - /* Can't have some share flags with no original task */ - BUG_ON(!orig && share_flags); - - /* Create a task and use given space and thread ids. */ - if (IS_ERR(task = tcb_alloc_init(share_flags))) - return task; - - task->tid = tid; - task->shpage_address = shpage; - - /* - * If there's an original task that means this will be a full - * or partial copy of it. We copy depending on share_flags. - */ - if (orig) - copy_tcb(task, orig, share_flags); - - return task; -} - -/* Free shared structures if no references left */ -void tcb_free_resources(struct tcb *task) -{ - - if (--task->fs_data->tcb_refs == 0) - kfree(task->fs_data); - - if (--task->files->tcb_refs == 0) { - kfree(task->files->fdpool); - kfree(task->files); - } - -} - -void tcb_destroy(struct tcb *task) -{ - global_remove_task(task); - - tcb_free_resources(task); - - kfree(task); -} - -/* - * Attaches to task's utcb. TODO: Add SHM_RDONLY and test it. - * FIXME: This calls the pager and is a potential for deadlock - * it only doesn't lock because it is called during initialisation. - */ -int task_utcb_attach(struct tcb *t) -{ - int shmid; - void *shmaddr; - - /* Use it as a key to create a shared memory region */ - 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->shpage_address, 0)) == -1) - goto out_err; - - /* Ensure address is right */ - if ((unsigned long)shmaddr != t->shpage_address) - return -EINVAL; - - // printf("%s: Mapped shared page of task %d @ 0x%x\n", - // __TASKNAME__, t->tid, shmaddr); - - return 0; - -out_err: - printf("%s: Mapping utcb of task %d failed with err: %d.\n", - __TASKNAME__, t->tid, errno); - return -EINVAL; -} - -/* - * Receives ipc from pager about a new fork event and - * the information on the resulting child task. - */ -int pager_notify_fork(struct tcb *sender, l4id_t parentid, - l4id_t childid, unsigned long shpage_address, - unsigned int flags) -{ - struct tcb *child, *parent; - - // printf("%s/%s\n", __TASKNAME__, __FUNCTION__); - 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, shpage_address, flags))) - return (int)child; - - global_add_task(child); - - // printf("%s/%s: Exiting...\n", __TASKNAME__, __FUNCTION__); - return 0; -} - - -/* - * Pager tells us that a task is exiting by this call. - */ -int pager_notify_exit(struct tcb *sender, l4id_t tid) -{ - struct tcb *task; - - // printf("%s/%s\n", __TASKNAME__, __FUNCTION__); - BUG_ON(!(task = find_task(tid))); - - tcb_destroy(task); - - // printf("%s/%s: Exiting...\n", __TASKNAME__, __FUNCTION__); - - return 0; -} - - -/* Read task information into the utcb page, since it won't fit into mrs. */ -struct task_data_head *receive_pager_taskdata(void) -{ - int err; - - /* Make the actual ipc call */ - if ((err = l4_sendrecv(PAGER_TID, PAGER_TID, - L4_IPC_TAG_TASKDATA)) < 0) { - printf("%s: L4 IPC Error: %d.\n", __FUNCTION__, err); - return PTR_ERR(err); - } - - /* Check if call itself was successful */ - if ((err = l4_get_retval()) < 0) { - printf("%s: Error: %d.\n", __FUNCTION__, err); - return PTR_ERR(err); - } - - /* Data is expected in the utcb page */ - // printf("%s: %d Total tasks.\n", __FUNCTION__, - // ((struct task_data_head *)shared_page)->total); - - return (struct task_data_head *)shared_page; -} - - -int init_task_structs(struct task_data_head *tdata_head) -{ - struct tcb *t; - - 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].shpage_address, - 0))) - return (int)t; - - /* Initialise vfs specific fields. */ - t->fs_data->rootdir = vfs_root.pivot; - t->fs_data->curdir = vfs_root.pivot; - - /* Print task information */ - //printf("%s: Task info received from mm0:\n", __TASKNAME__); - //printf("%s: task id: %d, utcb address: 0x%x\n", - // __TASKNAME__, t->tid, t->utcb_address); - - /* shm attach to the utcbs for all these tasks except own */ - if (t->tid != self_tid()) - task_utcb_attach(t); - global_add_task(t); - } - - return 0; -} - -int init_task_data(void) -{ - struct task_data_head *tdata_head; - - /* Read how many tasks and tids of each */ - BUG_ON((tdata_head = receive_pager_taskdata()) < 0); - - /* Initialise local task structs using this info */ - BUG_ON(init_task_structs(tdata_head) < 0); - - return 0; -} - diff --git a/conts/posix/fs0/tools/generate_bootdesc.py b/conts/posix/fs0/tools/generate_bootdesc.py deleted file mode 100755 index 9761a6d..0000000 --- a/conts/posix/fs0/tools/generate_bootdesc.py +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/python -import os -import sys - -compiler_prefix = "arm-linux-" -objdump = "objdump" -command = "-t" -image_name = "roottask.axf" -linkoutput_file_suffix = "-linkinfo.txt" -linkoutput_file = image_name + linkoutput_file_suffix -def generate_bootdesc(): - command = compiler_prefix + objdump + " -t " + image_name + " > " + linkoutput_file - print command - os.system(command) - f = open(linkoutput_file, "r") - - while True: - line = f.readline() - if len(line) is 0: - break - if "_start" in line or "_end" in line: - print line - f.close() - -if __name__ == "__main__": - generate_bootdesc() - diff --git a/conts/posix/mm0/SConscript b/conts/posix/mm0/SConscript index b8c3fc2..4800ef5 100644 --- a/conts/posix/mm0/SConscript +++ b/conts/posix/mm0/SConscript @@ -29,11 +29,12 @@ def generate_lma_lds(target, source, env): lma_lds = Command('include/linker.lds', 'include/linker.lds.in', generate_lma_lds) -src = [Glob('*.c') + Glob('src/*.c') + Glob('src/lib/*.c') + Glob('src/lib/elf/*.c') + Glob('src/arch/*.c')] +src = [Glob('*.c') + Glob('mm/*.c') + Glob('lib/*.c') + Glob('fs/*.c') + Glob('fs/memfs/*.c') + Glob('lib/elf/*.c') + Glob('mm/arch/*.c')] e = env.Clone() e.Append(LINKFLAGS = ['-T' + lma_lds[0].path, '-u_start']) +e.Append(LIBS = 'posix') objs = e.Object(src) mm0 = e.Program('mm0.elf', objs) diff --git a/conts/posix/fs0/src/bdev.c b/conts/posix/mm0/fs/bdev.c similarity index 100% rename from conts/posix/fs0/src/bdev.c rename to conts/posix/mm0/fs/bdev.c diff --git a/conts/posix/fs0/src/c0fs/c0fs.h b/conts/posix/mm0/fs/c0fs/c0fs.h similarity index 100% rename from conts/posix/fs0/src/c0fs/c0fs.h rename to conts/posix/mm0/fs/c0fs/c0fs.h diff --git a/conts/posix/fs0/src/file.c b/conts/posix/mm0/fs/file.c similarity index 100% rename from conts/posix/fs0/src/file.c rename to conts/posix/mm0/fs/file.c diff --git a/conts/posix/fs0/src/init.c b/conts/posix/mm0/fs/init.c similarity index 96% rename from conts/posix/fs0/src/init.c rename to conts/posix/mm0/fs/init.c index 84ff20c..7669114 100644 --- a/conts/posix/fs0/src/init.c +++ b/conts/posix/mm0/fs/init.c @@ -79,9 +79,6 @@ int initialise(void) printf("%s: Mounted memfs root filesystem.\n", __TASKNAME__); - /* Learn about what tasks are running */ - init_task_data(); - /* * Initialisation is done. From here on, we can start * serving filesystem requests. diff --git a/conts/posix/fs0/src/lookup.c b/conts/posix/mm0/fs/lookup.c similarity index 100% rename from conts/posix/fs0/src/lookup.c rename to conts/posix/mm0/fs/lookup.c diff --git a/conts/posix/fs0/src/memfs/file.c b/conts/posix/mm0/fs/memfs/file.c similarity index 100% rename from conts/posix/fs0/src/memfs/file.c rename to conts/posix/mm0/fs/memfs/file.c diff --git a/conts/posix/fs0/src/memfs/memfs.c b/conts/posix/mm0/fs/memfs/memfs.c similarity index 100% rename from conts/posix/fs0/src/memfs/memfs.c rename to conts/posix/mm0/fs/memfs/memfs.c diff --git a/conts/posix/fs0/src/memfs/vnode.c b/conts/posix/mm0/fs/memfs/vnode.c similarity index 100% rename from conts/posix/fs0/src/memfs/vnode.c rename to conts/posix/mm0/fs/memfs/vnode.c diff --git a/conts/posix/fs0/src/path.c b/conts/posix/mm0/fs/path.c similarity index 100% rename from conts/posix/fs0/src/path.c rename to conts/posix/mm0/fs/path.c diff --git a/conts/posix/fs0/src/romfs/romfs.c b/conts/posix/mm0/fs/romfs/romfs.c similarity index 100% rename from conts/posix/fs0/src/romfs/romfs.c rename to conts/posix/mm0/fs/romfs/romfs.c diff --git a/conts/posix/fs0/src/romfs/romfs.h b/conts/posix/mm0/fs/romfs/romfs.h similarity index 100% rename from conts/posix/fs0/src/romfs/romfs.h rename to conts/posix/mm0/fs/romfs/romfs.h diff --git a/conts/posix/fs0/src/romfs/romfs_fs.h b/conts/posix/mm0/fs/romfs/romfs_fs.h similarity index 100% rename from conts/posix/fs0/src/romfs/romfs_fs.h rename to conts/posix/mm0/fs/romfs/romfs_fs.h diff --git a/conts/posix/fs0/src/vfs.c b/conts/posix/mm0/fs/vfs.c similarity index 94% rename from conts/posix/fs0/src/vfs.c rename to conts/posix/mm0/fs/vfs.c index 3752fa3..488b785 100644 --- a/conts/posix/fs0/src/vfs.c +++ b/conts/posix/mm0/fs/vfs.c @@ -11,14 +11,6 @@ LINK_DECLARE(vnode_cache); LINK_DECLARE(dentry_cache); -/* - * / - * /boot - * /boot/images/mm0.axf - * /boot/images/fs0.axf - * /boot/images/test0.axf - * /file.txt - */ struct vfs_mountpoint vfs_root; /* diff --git a/conts/posix/fs0/include/bdev.h b/conts/posix/mm0/include/bdev.h similarity index 100% rename from conts/posix/fs0/include/bdev.h rename to conts/posix/mm0/include/bdev.h diff --git a/conts/posix/fs0/include/fs.h b/conts/posix/mm0/include/fs.h similarity index 100% rename from conts/posix/fs0/include/fs.h rename to conts/posix/mm0/include/fs.h diff --git a/conts/posix/mm0/include/lib/bit.h b/conts/posix/mm0/include/lib/bit.h index ab58671..7d6f8a7 100644 --- a/conts/posix/mm0/include/lib/bit.h +++ b/conts/posix/mm0/include/lib/bit.h @@ -9,8 +9,8 @@ int find_and_set_first_free_contig_bits(u32 *word, unsigned int limit, int nbits); int check_and_clear_bit(u32 *word, int bit); int check_and_clear_contig_bits(u32 *word, int first, int nbits); -int check_and_set_bit(u32 *word, int bit); +int check_and_set_bit(u32 *word, int bit); /* Set */ static inline void setbit(unsigned int *w, unsigned int flags) diff --git a/conts/posix/mm0/include/lib/idpool.h b/conts/posix/mm0/include/lib/idpool.h index b66424f..24249aa 100644 --- a/conts/posix/mm0/include/lib/idpool.h +++ b/conts/posix/mm0/include/lib/idpool.h @@ -3,6 +3,8 @@ #include #include +#include +#include INC_GLUE(memory.h) struct id_pool { int nwords; @@ -10,6 +12,14 @@ struct id_pool { u32 bitmap[]; }; +/* Copy one id pool to another by calculating its size */ +static inline void id_pool_copy(struct id_pool *to, struct id_pool *from, int totalbits) +{ + int nwords = BITWISE_GETWORD(totalbits); + + memcpy(to, from, nwords * SZ_WORD + sizeof(struct id_pool)); +} + struct id_pool *id_pool_new_init(int mapsize); int id_new(struct id_pool *pool); int id_del(struct id_pool *pool, int id); diff --git a/conts/posix/mm0/include/lib/malloc.h b/conts/posix/mm0/include/lib/malloc.h index 7def53a..37479ff 100644 --- a/conts/posix/mm0/include/lib/malloc.h +++ b/conts/posix/mm0/include/lib/malloc.h @@ -3,7 +3,6 @@ #include #include -#include void *kmalloc(size_t size); void kfree(void *blk); diff --git a/conts/posix/fs0/include/lib/pathstr.h b/conts/posix/mm0/include/lib/pathstr.h similarity index 100% rename from conts/posix/fs0/include/lib/pathstr.h rename to conts/posix/mm0/include/lib/pathstr.h diff --git a/conts/posix/mm0/include/lib/spinlock.h b/conts/posix/mm0/include/lib/spinlock.h index 7a61930..b3cc39c 100644 --- a/conts/posix/mm0/include/lib/spinlock.h +++ b/conts/posix/mm0/include/lib/spinlock.h @@ -4,13 +4,11 @@ #ifndef __MM0_SPINLOCK_H__ #define __MM0_SPINLOCK_H__ - - struct spinlock { int lock; }; -static inline void spin_lock_init(struct spinlock *s) { } +static inline void spin_lock_init(struct spinlock *s) { } static inline void spin_lock(struct spinlock *s) { } static inline void spin_unlock(struct spinlock *s) { } diff --git a/conts/posix/fs0/include/lib/vaddr.h b/conts/posix/mm0/include/lib/vaddr.h similarity index 100% rename from conts/posix/fs0/include/lib/vaddr.h rename to conts/posix/mm0/include/lib/vaddr.h diff --git a/conts/posix/mm0/include/linker.lds.in b/conts/posix/mm0/include/linker.lds.in index f91dd53..64bfd47 100644 --- a/conts/posix/mm0/include/linker.lds.in +++ b/conts/posix/mm0/include/linker.lds.in @@ -34,6 +34,9 @@ SECTIONS .data : AT (ADDR(.data) - pager_offset) { *(.data) + _start_bdev = .; + *(.data.memfs) + _end_bdev = .; } .bss : AT (ADDR(.bss) - pager_offset) { *(.bss) } . = ALIGN(4K); diff --git a/conts/posix/fs0/include/memfs/file.h b/conts/posix/mm0/include/memfs/file.h similarity index 100% rename from conts/posix/fs0/include/memfs/file.h rename to conts/posix/mm0/include/memfs/file.h diff --git a/conts/posix/fs0/include/memfs/memfs.h b/conts/posix/mm0/include/memfs/memfs.h similarity index 100% rename from conts/posix/fs0/include/memfs/memfs.h rename to conts/posix/mm0/include/memfs/memfs.h diff --git a/conts/posix/fs0/include/memfs/vnode.h b/conts/posix/mm0/include/memfs/vnode.h similarity index 100% rename from conts/posix/fs0/include/memfs/vnode.h rename to conts/posix/mm0/include/memfs/vnode.h diff --git a/conts/posix/fs0/include/path.h b/conts/posix/mm0/include/path.h similarity index 100% rename from conts/posix/fs0/include/path.h rename to conts/posix/mm0/include/path.h diff --git a/conts/posix/fs0/include/stat.h b/conts/posix/mm0/include/stat.h similarity index 100% rename from conts/posix/fs0/include/stat.h rename to conts/posix/mm0/include/stat.h diff --git a/conts/posix/mm0/include/syscalls.h b/conts/posix/mm0/include/syscalls.h index e2610cb..6d8a6aa 100644 --- a/conts/posix/mm0/include/syscalls.h +++ b/conts/posix/mm0/include/syscalls.h @@ -36,5 +36,30 @@ int sys_fork(struct tcb *parent); int sys_clone(struct tcb *parent, void *child_stack, unsigned int clone_flags); void sys_exit(struct tcb *task, int status); +/* Posix calls */ +int sys_open(struct tcb *sender, const char *pathname, int flags, u32 mode); +int sys_readdir(struct tcb *sender, int fd, void *buf, int count); +int sys_mkdir(struct tcb *sender, const char *pathname, unsigned int mode); +int sys_chdir(struct tcb *sender, const char *pathname); + +/* Calls from pager that completes a posix call */ +int pager_open_bypath(struct tcb *pager, char *pathname); +int pager_sys_open(struct tcb *sender, l4id_t opener, int fd); +int pager_sys_read(struct tcb *sender, unsigned long vnum, unsigned long f_offset, + unsigned long npages, void *pagebuf); + +int pager_sys_write(struct tcb *sender, unsigned long vnum, unsigned long f_offset, + unsigned long npages, void *pagebuf); + +int pager_sys_close(struct tcb *sender, l4id_t closer, int fd); +int pager_update_stats(struct tcb *sender, unsigned long vnum, + unsigned long newsize); + +int pager_notify_fork(struct tcb *sender, l4id_t parentid, + l4id_t childid, unsigned long utcb_address, + unsigned int flags); + +int pager_notify_exit(struct tcb *sender, l4id_t tid); + #endif /* __MM0_SYSARGS_H__ */ diff --git a/conts/posix/mm0/include/task.h b/conts/posix/mm0/include/task.h index 5e420c2..9482f26 100644 --- a/conts/posix/mm0/include/task.h +++ b/conts/posix/mm0/include/task.h @@ -47,6 +47,7 @@ struct file_descriptor { struct task_fd_head { struct file_descriptor fd[TASK_FILES_MAX]; + struct id_pool *fdpool; int tcb_refs; }; @@ -55,6 +56,18 @@ struct task_vma_head { int tcb_refs; }; +#define TCB_NO_SHARING 0 +#define TCB_SHARED_VM (1 << 0) +#define TCB_SHARED_FILES (1 << 1) +#define TCB_SHARED_FS (1 << 2) +#define TASK_FILES_MAX 32 + +struct task_fs_data { + struct vnode *curdir; + struct vnode *rootdir; + int tcb_refs; +}; + struct utcb_desc { struct link list; unsigned long utcb_base; @@ -114,9 +127,6 @@ struct tcb { unsigned long map_start; unsigned long map_end; - /* Default ipc-shared-page information */ - void *shared_page; - /* Chain of utcb descriptors */ struct utcb_head *utcb_head; @@ -128,6 +138,8 @@ struct tcb { /* File descriptors for this task */ struct task_fd_head *files; + struct task_fs_data *fs_data; + }; struct tcb_head { diff --git a/conts/posix/fs0/include/vfs.h b/conts/posix/mm0/include/vfs.h similarity index 100% rename from conts/posix/fs0/include/vfs.h rename to conts/posix/mm0/include/vfs.h diff --git a/conts/posix/mm0/src/lib/addr.c b/conts/posix/mm0/lib/addr.c similarity index 100% rename from conts/posix/mm0/src/lib/addr.c rename to conts/posix/mm0/lib/addr.c diff --git a/conts/posix/mm0/src/lib/bit.c b/conts/posix/mm0/lib/bit.c similarity index 100% rename from conts/posix/mm0/src/lib/bit.c rename to conts/posix/mm0/lib/bit.c diff --git a/conts/posix/mm0/src/lib/elf/elf.c b/conts/posix/mm0/lib/elf/elf.c similarity index 100% rename from conts/posix/mm0/src/lib/elf/elf.c rename to conts/posix/mm0/lib/elf/elf.c diff --git a/conts/posix/mm0/src/lib/idpool.c b/conts/posix/mm0/lib/idpool.c similarity index 100% rename from conts/posix/mm0/src/lib/idpool.c rename to conts/posix/mm0/lib/idpool.c diff --git a/conts/posix/mm0/src/lib/malloc.c b/conts/posix/mm0/lib/malloc.c similarity index 100% rename from conts/posix/mm0/src/lib/malloc.c rename to conts/posix/mm0/lib/malloc.c diff --git a/conts/posix/fs0/src/lib/pathstr.c b/conts/posix/mm0/lib/pathstr.c similarity index 100% rename from conts/posix/fs0/src/lib/pathstr.c rename to conts/posix/mm0/lib/pathstr.c diff --git a/conts/posix/fs0/src/lib/vaddr.c b/conts/posix/mm0/lib/vaddr.c similarity index 100% rename from conts/posix/fs0/src/lib/vaddr.c rename to conts/posix/mm0/lib/vaddr.c diff --git a/conts/posix/mm0/main.c b/conts/posix/mm0/main.c index 1e29ab9..f05d682 100644 --- a/conts/posix/mm0/main.c +++ b/conts/posix/mm0/main.c @@ -84,11 +84,6 @@ void handle_requests(void) ret = page_fault_handler(sender, (fault_kdata_t *)&mr[0]); break; - case L4_IPC_TAG_TASKDATA: - /* Send runnable task information to fs0 */ - ret = vfs_send_task_data(sender); - break; - case L4_IPC_TAG_SHMGET: { ret = sys_shmget((key_t)mr[0], (int)mr[1], (int)mr[2]); break; @@ -103,10 +98,6 @@ void handle_requests(void) ret = sys_shmdt(sender, (void *)mr[0]); break; - case L4_IPC_TAG_SHPAGE: - ret = (int)task_send_shpage_address(sender, (l4id_t)mr[0]); - break; - case L4_IPC_TAG_READ: ret = sys_read(sender, (int)mr[0], (void *)mr[1], (int)mr[2]); break; @@ -166,6 +157,22 @@ void handle_requests(void) // ret = sys_brk(sender, (void *)mr[0]); // break; } + + /* FIXME: Fix all these syscalls to read any buffer data from the caller task's utcb. */ + /* FS0 System calls */ + case L4_IPC_TAG_OPEN: + ret = sys_open(sender, (void *)mr[0], (int)mr[1], (unsigned int)mr[2]); + break; + case L4_IPC_TAG_MKDIR: + ret = sys_mkdir(sender, (const char *)mr[0], (unsigned int)mr[1]); + break; + case L4_IPC_TAG_CHDIR: + ret = sys_chdir(sender, (const char *)mr[0]); + break; + case L4_IPC_TAG_READDIR: + ret = sys_readdir(sender, (int)mr[0], (void *)mr[1], (int)mr[2]); + break; + default: printf("%s: Unrecognised ipc tag (%d) " "received from (%d). Full mr reading: " diff --git a/conts/posix/mm0/src/arch b/conts/posix/mm0/mm/arch similarity index 100% rename from conts/posix/mm0/src/arch rename to conts/posix/mm0/mm/arch diff --git a/conts/posix/fs0/src/crt0.S b/conts/posix/mm0/mm/arch-arm/crt0.S similarity index 100% rename from conts/posix/fs0/src/crt0.S rename to conts/posix/mm0/mm/arch-arm/crt0.S diff --git a/conts/posix/mm0/src/arch-arm/mm.c b/conts/posix/mm0/mm/arch-arm/mm.c similarity index 100% rename from conts/posix/mm0/src/arch-arm/mm.c rename to conts/posix/mm0/mm/arch-arm/mm.c diff --git a/conts/posix/mm0/src/boot.c b/conts/posix/mm0/mm/boot.c similarity index 91% rename from conts/posix/mm0/src/boot.c rename to conts/posix/mm0/mm/boot.c index 422376b..97f079a 100644 --- a/conts/posix/mm0/src/boot.c +++ b/conts/posix/mm0/mm/boot.c @@ -49,7 +49,6 @@ int boottask_setup_regions(struct vm_file *file, struct tcb *task, int boottask_mmap_regions(struct tcb *task, struct vm_file *file) { void *mapped; - struct vm_file *shm; /* * mmap each task's physical image to task's address space. @@ -74,14 +73,6 @@ int boottask_mmap_regions(struct tcb *task, struct vm_file *file) return (int)mapped; } - /* Task's default shared page */ - task->shared_page = shm_new_address(DEFAULT_SHPAGE_SIZE/PAGE_SIZE); - - /* Create a shared memory segment available for shmat() */ - if (IS_ERR(shm = shm_new((key_t)task->shared_page, - __pfn(DEFAULT_SHPAGE_SIZE)))) - return (int)shm; - task_setup_utcb(task); return 0; diff --git a/conts/posix/mm0/src/bootdesc.c b/conts/posix/mm0/mm/bootdesc.c similarity index 100% rename from conts/posix/mm0/src/bootdesc.c rename to conts/posix/mm0/mm/bootdesc.c diff --git a/conts/posix/mm0/src/bootm.c b/conts/posix/mm0/mm/bootm.c similarity index 100% rename from conts/posix/mm0/src/bootm.c rename to conts/posix/mm0/mm/bootm.c diff --git a/conts/posix/mm0/src/capability.c b/conts/posix/mm0/mm/capability.c similarity index 100% rename from conts/posix/mm0/src/capability.c rename to conts/posix/mm0/mm/capability.c diff --git a/conts/posix/mm0/src/clone.c b/conts/posix/mm0/mm/clone.c similarity index 74% rename from conts/posix/mm0/src/clone.c rename to conts/posix/mm0/mm/clone.c index 7fa7446..312c88d 100644 --- a/conts/posix/mm0/src/clone.c +++ b/conts/posix/mm0/mm/clone.c @@ -16,42 +16,6 @@ #include #include -/* - * Sends vfs task information about forked child, and its utcb - */ -int vfs_notify_fork(struct tcb *child, struct tcb *parent, unsigned int flags) -{ - int err = 0; - - // printf("%s/%s\n", __TASKNAME__, __FUNCTION__); - - l4_save_ipcregs(); - - /* Write parent and child information */ - write_mr(L4SYS_ARG0, parent->tid); - write_mr(L4SYS_ARG1, child->tid); - write_mr(L4SYS_ARG2, (unsigned int)child->shared_page); - write_mr(L4SYS_ARG3, flags); - - if ((err = l4_sendrecv(VFS_TID, VFS_TID, - L4_IPC_TAG_NOTIFY_FORK)) < 0) { - printf("%s: L4 IPC Error: %d.\n", __FUNCTION__, err); - goto out; - } - - /* Check if syscall was successful */ - if ((err = l4_get_retval()) < 0) { - printf("%s: Pager from VFS read error: %d.\n", - __FUNCTION__, err); - goto out; - } - -out: - l4_restore_ipcregs(); - return err; -} - - int sys_fork(struct tcb *parent) { int err; @@ -88,15 +52,13 @@ int sys_fork(struct tcb *parent) BUG(); /* Create and prefault a shared page for child and map it to vfs task */ - shpage_map_to_task(child, find_task(VFS_TID), - SHPAGE_NEW_ADDRESS | SHPAGE_NEW_SHM | - SHPAGE_PREFAULT); + BUG(); + //shpage_map_to_task(child, find_task(VFS_TID), + // SHPAGE_NEW_ADDRESS | SHPAGE_NEW_SHM | + // SHPAGE_PREFAULT); // printf("Mapped 0x%p to vfs as utcb of %d\n", child->utcb, child->tid); - /* We can now notify vfs about forked process */ - vfs_notify_fork(child, parent, TCB_NO_SHARING); - /* Add child to global task list */ global_add_task(child); @@ -146,12 +108,13 @@ int do_clone(struct tcb *parent, unsigned long child_stack, unsigned int flags) BUG(); /* Create and prefault a shared page for child and map it to vfs task */ - shpage_map_to_task(child, find_task(VFS_TID), - SHPAGE_NEW_ADDRESS | SHPAGE_NEW_SHM | - SHPAGE_PREFAULT); + BUG(); + //shpage_map_to_task(child, find_task(VFS_TID), + // SHPAGE_NEW_ADDRESS | SHPAGE_NEW_SHM | + // SHPAGE_PREFAULT); /* We can now notify vfs about forked process */ - vfs_notify_fork(child, parent, flags); + BUG(); /* Add child to global task list */ global_add_task(child); diff --git a/conts/posix/mm0/src/dev.c b/conts/posix/mm0/mm/dev.c similarity index 100% rename from conts/posix/mm0/src/dev.c rename to conts/posix/mm0/mm/dev.c diff --git a/conts/posix/mm0/src/execve.c b/conts/posix/mm0/mm/execve.c similarity index 100% rename from conts/posix/mm0/src/execve.c rename to conts/posix/mm0/mm/execve.c diff --git a/conts/posix/mm0/src/exit.c b/conts/posix/mm0/mm/exit.c similarity index 76% rename from conts/posix/mm0/src/exit.c rename to conts/posix/mm0/mm/exit.c index 1f8f17d..a06394a 100644 --- a/conts/posix/mm0/src/exit.c +++ b/conts/posix/mm0/mm/exit.c @@ -18,39 +18,6 @@ #include #include -/* - * Sends vfs task information about forked child, and its utcb - */ -int vfs_notify_exit(struct tcb *task, int status) -{ - int err = 0; - - // printf("%s/%s\n", __TASKNAME__, __FUNCTION__); - - l4_save_ipcregs(); - - /* Write parent and child information */ - write_mr(L4SYS_ARG0, task->tid); - write_mr(L4SYS_ARG1, status); - - if ((err = l4_sendrecv(VFS_TID, VFS_TID, - L4_IPC_TAG_NOTIFY_EXIT)) < 0) { - printf("%s: L4 IPC Error: %d.\n", __FUNCTION__, err); - goto out; - } - - /* Check if syscall was successful */ - if ((err = l4_get_retval()) < 0) { - printf("%s: VFS returned ipc error: %d.\n", - __FUNCTION__, err); - goto out; - } - -out: - l4_restore_ipcregs(); - return err; -} - /* Closes all file descriptors of a task */ int task_close_files(struct tcb *task) @@ -91,7 +58,10 @@ int execve_recycle_task(struct tcb *new, struct tcb *orig) new->pagerid = orig->pagerid; /* Copy shared page */ - new->shared_page = orig->shared_page; + /* + * FIXME: Make sure to take care of this. + */ + //new->shared_page = orig->shared_page; /* Copy parent relationship */ BUG_ON(new->parent); @@ -135,12 +105,10 @@ void do_exit(struct tcb *task, int status) /* Destroy task's utcb slot */ task_destroy_utcb(task); - /* Tell vfs that task is exiting */ - vfs_notify_exit(task, status); - /* Remove default shared page shm areas from vfs */ + BUG(); // printf("Unmapping 0x%p from vfs as shared-page of %d\n", task->shared_page, task->tid); - shpage_unmap_from_task(task, find_task(VFS_TID)); + //shpage_unmap_from_task(task, find_task(VFS_TID)); /* Free task's local tcb */ tcb_destroy(task); diff --git a/conts/posix/mm0/src/fault.c b/conts/posix/mm0/mm/fault.c similarity index 100% rename from conts/posix/mm0/src/fault.c rename to conts/posix/mm0/mm/fault.c diff --git a/conts/posix/mm0/src/file.c b/conts/posix/mm0/mm/file.c similarity index 69% rename from conts/posix/mm0/src/file.c rename to conts/posix/mm0/mm/file.c index 5e5b91d..6e5f208 100644 --- a/conts/posix/mm0/src/file.c +++ b/conts/posix/mm0/mm/file.c @@ -21,6 +21,15 @@ #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* Copy from one page's buffer into another page */ int page_copy(struct page *dst, struct page *src, @@ -56,34 +65,35 @@ int page_copy(struct page *dst, struct page *src, int vfs_read(unsigned long vnum, unsigned long file_offset, unsigned long npages, void *pagebuf) { - int err = 0; + struct vnode *v; - // printf("%s/%s\n", __TASKNAME__, __FUNCTION__); + /* Lookup vnode */ + if (!(v = vfs_lookup_byvnum(vfs_root.pivot->sb, vnum))) + return -EINVAL; - l4_save_ipcregs(); + /* Ensure vnode is not a directory */ + if (vfs_isdir(v)) + return -EISDIR; - write_mr(L4SYS_ARG0, vnum); - write_mr(L4SYS_ARG1, file_offset); - write_mr(L4SYS_ARG2, npages); - write_mr(L4SYS_ARG3, (u32)pagebuf); - - if ((err = l4_sendrecv(VFS_TID, VFS_TID, L4_IPC_TAG_PAGER_READ)) < 0) { - printf("%s: L4 IPC Error: %d.\n", __FUNCTION__, err); - goto out; - } - - /* Check if syscall was successful */ - if ((err = l4_get_retval()) < 0) { - printf("%s: Error: %d.\n", - __FUNCTION__, err); - goto out; - } - -out: - l4_restore_ipcregs(); - return err; + return v->fops.read(v, file_offset, npages, pagebuf); } +/* Directories only for now */ +void print_vnode(struct vnode *v) +{ + struct dentry *d, *c; + + printf("Vnode names:\n"); + list_foreach_struct(d, &v->dentries, vref) { + printf("%s\n", d->name); + printf("Children dentries:\n"); + list_foreach_struct(c, &d->children, child) + printf("%s\n", c->name); + } +} + + + /* * Different from vfs_open(), which validates an already opened * file descriptor, this call opens a new vfs file by the pager @@ -92,46 +102,31 @@ out: */ int vfs_open_bypath(const char *pathname, unsigned long *vnum, unsigned long *length) { - int err = 0; - struct tcb *vfs; + struct pathdata *pdata; + struct tcb *task; + struct vnode *v; + int retval; - // printf("%s/%s\n", __TASKNAME__, __FUNCTION__); + /* Parse path data */ + if (IS_ERR(pdata = pathdata_parse(pathname, + alloca(strlen(pathname) + 1), + task))) + return (int)pdata; - if (!(vfs = find_task(VFS_TID))) - return -ESRCH; - - /* - * Copy string to vfs shared page. - * - * FIXME: There's a chance we're overwriting other tasks' - * ipc information that is on the vfs shared page. - */ - strcpy(vfs->shared_page + 0x200, pathname); - - l4_save_ipcregs(); - - write_mr(L4SYS_ARG0, (unsigned long)vfs->shared_page + 0x200); - - if ((err = l4_sendrecv(VFS_TID, VFS_TID, - L4_IPC_TAG_PAGER_OPEN_BYPATH)) < 0) { - printf("%s: L4 IPC Error: %d.\n", __FUNCTION__, err); + /* Search the vnode by that path */ + if (IS_ERR(v = vfs_lookup_bypath(pdata))) { + retval = (int)v; goto out; } - /* Check if syscall was successful */ - if ((err = l4_get_retval()) < 0) { - printf("%s: VFS open error: %d.\n", - __FUNCTION__, err); - goto out; - } + *vnum = v->vnum; + *length = v->size; - /* Read file information */ - *vnum = read_mr(L4SYS_ARG0); - *length = read_mr(L4SYS_ARG1); + return 0; out: - l4_restore_ipcregs(); - return err; + pathdata_destroy(pdata); + return retval; } /* @@ -142,32 +137,229 @@ out: */ int vfs_open(l4id_t opener, int fd, unsigned long *vnum, unsigned long *length) { - int err = 0; + struct tcb *task; + struct vnode *v; - l4_save_ipcregs(); + /* Check if such task exists */ + if (!(task = find_task(opener))) + return -ESRCH; - write_mr(L4SYS_ARG0, opener); - write_mr(L4SYS_ARG1, fd); + /* Check if that fd has been opened */ + if (!task->files->fd[fd].vnum) + return -EBADF; - if ((err = l4_sendrecv(VFS_TID, VFS_TID, L4_IPC_TAG_PAGER_OPEN)) < 0) { - printf("%s: L4 IPC Error: %d.\n", __FUNCTION__, err); - goto out; - } - - /* Check if syscall was successful */ - if ((err = l4_get_retval()) < 0) { - printf("%s: VFS open error: %d.\n", - __FUNCTION__, err); - goto out; - } + /* Search the vnode by that vnum */ + if (IS_ERR(v = vfs_lookup_byvnum(vfs_root.pivot->sb, + task->files->fd[fd].vnum))) + return (int)v; /* Read file information */ - *vnum = read_mr(L4SYS_ARG0); - *length = read_mr(L4SYS_ARG1); + *vnum = v->vnum; + *length = v->size; + + return 0; +} + +/* Creates a node under a directory, e.g. a file, directory. */ +struct vnode *vfs_create(struct tcb *task, struct pathdata *pdata, + unsigned int mode) +{ + struct vnode *vparent, *newnode; + const char *nodename; + + /* The last component is to be created */ + nodename = pathdata_last_component(pdata); + + /* Check that the parent directory exists. */ + if (IS_ERR(vparent = vfs_lookup_bypath(pdata))) + return vparent; + + /* The parent vnode must be a directory. */ + if (!vfs_isdir(vparent)) + return PTR_ERR(-ENOENT); + + /* Create new directory under the parent */ + if (IS_ERR(newnode = vparent->ops.mknod(vparent, nodename, mode))) + return newnode; + + // print_vnode(vparent); + return newnode; +} + +/* FIXME: + * - Is it already open? + * - Allocate a copy of path string since lookup destroys it + * - Check flags and mode. + */ +int sys_open(struct tcb *task, const char *pathname, int flags, unsigned int mode) +{ + struct pathdata *pdata; + struct vnode *v; + int fd; + int retval; + + // printf("%s/%s\n", __TASKNAME__, __FUNCTION__); + + /* Parse path data */ + if (IS_ERR(pdata = pathdata_parse(pathname, + alloca(strlen(pathname) + 1), + task))) + return (int)pdata; + + /* Creating new file */ + if (flags & O_CREAT) { + /* Make sure mode identifies a file */ + mode |= S_IFREG; + if (IS_ERR(v = vfs_create(task, pdata, mode))) { + retval = (int)v; + goto out; + } + } else { + /* Not creating, just opening, get the vnode */ + if (IS_ERR(v = vfs_lookup_bypath(pdata))) { + retval = (int)v; + goto out; + } + } + + /* Get a new fd */ + BUG_ON((fd = id_new(task->files->fdpool)) < 0); + retval = fd; + + /* Why assign just vnum? Why not vmfile, vnode etc? */ + BUG(); + + /* Assign the new fd with the vnode's number */ + task->files->fd[fd].vnum = v->vnum; out: - l4_restore_ipcregs(); - return err; + pathdata_destroy(pdata); + return retval; +} + +int sys_mkdir(struct tcb *task, const char *pathname, unsigned int mode) +{ + struct pathdata *pdata; + struct vnode *v; + int ret = 0; + + /* Parse path data */ + if (IS_ERR(pdata = pathdata_parse(pathname, + alloca(strlen(pathname) + 1), + task))) + return (int)pdata; + + /* Make sure we create a directory */ + mode |= S_IFDIR; + + /* Create the directory or fail */ + if (IS_ERR(v = vfs_create(task, pdata, mode))) + ret = (int)v; + + /* Destroy extracted path data */ + pathdata_destroy(pdata); + return ret; +} + +int sys_chdir(struct tcb *task, const char *pathname) +{ + struct vnode *v; + struct pathdata *pdata; + int ret = 0; + + /* Parse path data */ + if (IS_ERR(pdata = pathdata_parse(pathname, + alloca(strlen(pathname) + 1), + task))) + return (int)pdata; + + /* Get the vnode */ + if (IS_ERR(v = vfs_lookup_bypath(pdata))) { + ret = (int)v; + goto out; + } + + /* Ensure it's a directory */ + if (!vfs_isdir(v)) { + ret = -ENOTDIR; + goto out; + } + + /* Assign the current directory pointer */ + task->fs_data->curdir = v; + +out: + /* Destroy extracted path data */ + pathdata_destroy(pdata); + return ret; +} + +void fill_kstat(struct vnode *v, struct kstat *ks) +{ + ks->vnum = (u64)v->vnum; + ks->mode = v->mode; + ks->links = v->links; + ks->uid = v->owner & 0xFFFF; + ks->gid = (v->owner >> 16) & 0xFFFF; + ks->size = v->size; + ks->blksize = v->sb->blocksize; + ks->atime = v->atime; + ks->mtime = v->mtime; + ks->ctime = v->ctime; +} + +int sys_fstat(struct tcb *task, int fd, void *statbuf) +{ + struct vnode *v; + unsigned long vnum; + + /* Get the vnum */ + if (fd < 0 || fd > TASK_FILES_MAX || !task->files->fd[fd].vnum) + return -EBADF; + + BUG(); /* Could just return vmfile->vnode here. */ + vnum = task->files->fd[fd].vnum; + + /* Lookup vnode */ + if (!(v = vfs_lookup_byvnum(vfs_root.pivot->sb, vnum))) + return -EINVAL; + + /* Fill in the c0-style stat structure */ + fill_kstat(v, statbuf); + + return 0; +} + +/* + * Returns codezero-style stat structure which in turn is + * converted to posix style stat structure via the libposix + * library in userspace. + */ +int sys_stat(struct tcb *task, const char *pathname, void *statbuf) +{ + struct vnode *v; + struct pathdata *pdata; + int ret = 0; + + /* Parse path data */ + if (IS_ERR(pdata = pathdata_parse(pathname, + alloca(strlen(pathname) + 1), + task))) + return (int)pdata; + + /* Get the vnode */ + if (IS_ERR(v = vfs_lookup_bypath(pdata))) { + ret = (int)v; + goto out; + } + + /* Fill in the c0-style stat structure */ + fill_kstat(v, statbuf); + +out: + /* Destroy extracted path data */ + pathdata_destroy(pdata); + return ret; } /* @@ -357,89 +549,62 @@ int read_file_pages(struct vm_file *vmfile, unsigned long pfn_start, return 0; } +/* + * The buffer must be contiguous by page, if npages > 1. + */ int vfs_write(unsigned long vnum, unsigned long file_offset, unsigned long npages, void *pagebuf) { - int err = 0; + struct vnode *v; + int fwrite_end; + int ret; // printf("%s/%s\n", __TASKNAME__, __FUNCTION__); - l4_save_ipcregs(); - write_mr(L4SYS_ARG0, vnum); - write_mr(L4SYS_ARG1, file_offset); - write_mr(L4SYS_ARG2, npages); - write_mr(L4SYS_ARG3, (u32)pagebuf); + /* Lookup vnode */ + if (!(v = vfs_lookup_byvnum(vfs_root.pivot->sb, vnum))) + return -EINVAL; - if ((err = l4_sendrecv(VFS_TID, VFS_TID, L4_IPC_TAG_PAGER_WRITE)) < 0) { - printf("%s: L4 IPC Error: %d.\n", __FUNCTION__, err); - goto out; + /* Ensure vnode is not a directory */ + if (vfs_isdir(v)) + return -EISDIR; + + //printf("%s/%s: Writing to vnode %lu, at pgoff 0x%x, %d pages, buf at 0x%x\n", + // __TASKNAME__, __FUNCTION__, vnum, f_offset, npages, pagebuf); + + if ((ret = v->fops.write(v, file_offset, npages, pagebuf)) < 0) + return ret; + + /* + * If the file is extended, write silently extends it. + * We update the extended size here. Otherwise subsequent write's + * may fail by relying on wrong file size. + */ + fwrite_end = __pfn_to_addr(file_offset) + ret; + if (v->size < fwrite_end) { + v->size = fwrite_end; + v->sb->ops->write_vnode(v->sb, v); } - /* Check if syscall was successful */ - if ((err = l4_get_retval()) < 0) { - printf("%s: Pager to VFS write error: %d.\n", __FUNCTION__, err); - goto out; - } - -out: - l4_restore_ipcregs(); - return err; + return ret; } -int vfs_close(l4id_t sender, int fd) -{ - int err = 0; - // printf("%s/%s Sending to %d\n", __TASKNAME__, __FUNCTION__, VFS_TID); - l4_save_ipcregs(); - - write_mr(L4SYS_ARG0, sender); - write_mr(L4SYS_ARG1, fd); - - if ((err = l4_sendrecv(VFS_TID, VFS_TID, L4_IPC_TAG_PAGER_CLOSE)) < 0) { - printf("%s: L4 IPC Error: %d.\n", __FUNCTION__, err); - goto out; - } - // printf("%s/%s Received from %d\n", __TASKNAME__, __FUNCTION__, VFS_TID); - - /* Check if syscall was successful */ - if ((err = l4_get_retval()) < 0) { - printf("%s: Pager to VFS write error: %d.\n", __FUNCTION__, err); - goto out; - } - -out: - l4_restore_ipcregs(); - return err; -} /* Writes updated file stats back to vfs. (e.g. new file size) */ int vfs_update_file_stats(struct vm_file *f) { - int err = 0; + unsigned long vnum = vm_file_to_vnum(f); + struct vnode *v; - // printf("%s/%s\n", __TASKNAME__, __FUNCTION__); - l4_save_ipcregs(); + /* Lookup vnode */ + if (!(v = vfs_lookup_byvnum(vfs_root.pivot->sb, vnum))) + return -EINVAL; - write_mr(L4SYS_ARG0, vm_file_to_vnum(f)); - write_mr(L4SYS_ARG1, f->length); + v->size = f->length; + v->sb->ops->write_vnode(v->sb, v); - if ((err = l4_sendrecv(VFS_TID, VFS_TID, - L4_IPC_TAG_PAGER_UPDATE_STATS)) < 0) { - printf("%s: L4 IPC Error: %d.\n", __FUNCTION__, err); - goto out; - } - - /* Check if syscall was successful */ - if ((err = l4_get_retval()) < 0) { - printf("%s: Pager to VFS write error: %d.\n", - __FUNCTION__, err); - goto out; - } - -out: - l4_restore_ipcregs(); - return err; + return 0; } /* Writes pages in cache back to their file */ @@ -518,15 +683,24 @@ void vm_file_put(struct vm_file *file) } +/* + * FIXME: fsync + close could be done under a single "close" ipc + * from pager. Currently there are 2 ipcs: 1 fsync + 1 fd close. + */ + /* Closes the file descriptor and notifies vfs */ int do_close(struct tcb *task, int fd) { int err; - // printf("%s: Closing fd: %d on task %d\n", __FUNCTION__, - // fd, task->tid); - if ((err = vfs_close(task->tid, fd)) < 0) + printf("%s: Closing fd: %d on task %d\n", __FUNCTION__, + fd, task->tid); + + if ((err = id_del(task->files->fdpool, fd)) < 0) { + printf("%s: Error releasing fd identifier.\n", + __FUNCTION__); return err; + } /* * If there was no IO on it, we may not know the file, @@ -991,3 +1165,95 @@ int sys_lseek(struct tcb *task, int fd, off_t offset, int whence) return retval; } +/* + * FIXME: Here's how this should have been: + * v->ops.readdir() -> Reads fs-specific directory contents. i.e. reads + * the directory buffer, doesn't care however contained vnode details are + * stored. + * + * After reading, it converts the fs-spceific contents into generic vfs + * dentries and populates the dentries of those vnodes. + * + * If vfs_readdir() is issued, those generic dentries are converted into + * the posix-defined directory record structure. During this on-the-fly + * generation, pseudo-entries such as . and .. are also added. + * + * If this layering is not done, i.e. the low-level dentry buffer already + * keeps this record structure and we try to return that, then we wont + * have a chance to add the pseudo-entries . and .. These record entries + * are essentially created from parent vnode and current vnode but using + * the names . and .. + */ + +int fill_dirent(void *buf, unsigned long vnum, int offset, char *name) +{ + struct dirent *d = buf; + + d->inum = (unsigned int)vnum; + d->offset = offset; + d->rlength = sizeof(struct dirent); + strncpy((char *)d->name, name, DIRENT_NAME_MAX); + + return d->rlength; +} + + +/* + * Reads @count bytes of posix struct dirents into @buf. This implements + * the raw dirent read syscall upon which readdir() etc. posix calls + * can be built in userspace. + * + * FIXME: Ensure buf is in shared utcb, and count does not exceed it. + */ +int sys_readdir(struct tcb *t, int fd, void *buf, int count) +{ + int dirent_size = sizeof(struct dirent); + int total = 0, nbytes = 0; + unsigned long vnum; + struct vnode *v; + struct dentry *d; + + // printf("%s/%s\n", __TASKNAME__, __FUNCTION__); + + BUG(); /* Do this by extended ipc !!! */ + /* Check address is in task's utcb */ + + if (fd < 0 || fd > TASK_FILES_MAX || !t->files->fd[fd].vnum) + return -EBADF; + + vnum = t->files->fd[fd].vnum; + + /* Lookup vnode */ + if (!(v = vfs_lookup_byvnum(vfs_root.pivot->sb, vnum))) + return -EINVAL; + + d = link_to_struct(v->dentries.next, struct dentry, vref); + + /* Ensure vnode is a directory */ + if (!vfs_isdir(v)) + return -ENOTDIR; + + /* Write pseudo-entries . and .. to user buffer */ + if (count < dirent_size) + return 0; + + fill_dirent(buf, v->vnum, nbytes, VFS_STR_CURDIR); + nbytes += dirent_size; + buf += dirent_size; + count -= dirent_size; + + if (count < dirent_size) + return 0; + + fill_dirent(buf, d->parent->vnode->vnum, nbytes, VFS_STR_PARDIR); + nbytes += dirent_size; + buf += dirent_size; + count -= dirent_size; + + /* Copy fs-specific dir to buf in struct dirent format */ + if ((total = v->ops.filldir(buf, v, count)) < 0) + return total; + + return nbytes + total; +} + diff --git a/conts/posix/mm0/src/init.c b/conts/posix/mm0/mm/init.c similarity index 98% rename from conts/posix/mm0/src/init.c rename to conts/posix/mm0/mm/init.c index 6c62d9d..95c07a6 100644 --- a/conts/posix/mm0/src/init.c +++ b/conts/posix/mm0/mm/init.c @@ -20,6 +20,7 @@ #include #include #include +#include /* A separate list than the generic file list that keeps just the boot files */ LINK_DECLARE(boot_file_list); @@ -97,6 +98,10 @@ int mm0_task_init(struct vm_file *f, unsigned long task_start, task->spid = ids->spid; task->tgid = ids->tgid; + /* Initialise vfs specific fields. */ + task->fs_data->rootdir = vfs_root.pivot; + task->fs_data->curdir = vfs_root.pivot; + if ((err = boottask_setup_regions(f, task, task_start, task_end)) < 0) return err; diff --git a/conts/posix/mm0/src/memory.c b/conts/posix/mm0/mm/memory.c similarity index 100% rename from conts/posix/mm0/src/memory.c rename to conts/posix/mm0/mm/memory.c diff --git a/conts/posix/mm0/src/mmap.c b/conts/posix/mm0/mm/mmap.c similarity index 100% rename from conts/posix/mm0/src/mmap.c rename to conts/posix/mm0/mm/mmap.c diff --git a/conts/posix/mm0/src/munmap.c b/conts/posix/mm0/mm/munmap.c similarity index 100% rename from conts/posix/mm0/src/munmap.c rename to conts/posix/mm0/mm/munmap.c diff --git a/conts/posix/mm0/src/pagers.c b/conts/posix/mm0/mm/pagers.c similarity index 96% rename from conts/posix/mm0/src/pagers.c rename to conts/posix/mm0/mm/pagers.c index fd46d59..b096c0e 100644 --- a/conts/posix/mm0/src/pagers.c +++ b/conts/posix/mm0/mm/pagers.c @@ -61,7 +61,6 @@ int default_release_pages(struct vm_object *vm_obj) return 0; } - int file_page_out(struct vm_object *vm_obj, unsigned long page_offset) { struct vm_file *f = vm_object_to_file(vm_obj); @@ -88,11 +87,14 @@ int file_page_out(struct vm_object *vm_obj, unsigned long page_offset) paddr = (void *)page_to_phys(page); vaddr = l4_new_virtual(1); - /* Map the page to vfs task */ - l4_map(paddr, vaddr, 1, MAP_USR_RW_FLAGS, VFS_TID); + /* FIXME: Are we sure that pages need to be mapped to self one-by-one? */ + BUG(); - // printf("%s/%s: Writing to vnode %d, at pgoff 0x%x, %d pages, buf at 0x%x\n", - // __TASKNAME__, __FUNCTION__, vm_file_to_vnum(f), page_offset, 1, vaddr); + /* Map the page to self */ + l4_map(paddr, vaddr, 1, MAP_USR_RW_FLAGS, self_tid()); + + printf("%s/%s: Writing to vnode %lu, at pgoff 0x%lu, %d pages, buf at %p\n", + __TASKNAME__, __FUNCTION__, vm_file_to_vnum(f), page_offset, 1, vaddr); /* Syscall to vfs to write page back to file. */ if ((err = vfs_write(vm_file_to_vnum(f), page_offset, 1, vaddr)) < 0) diff --git a/conts/posix/mm0/src/physmem.c b/conts/posix/mm0/mm/physmem.c similarity index 100% rename from conts/posix/mm0/src/physmem.c rename to conts/posix/mm0/mm/physmem.c diff --git a/conts/posix/mm0/src/shm.c b/conts/posix/mm0/mm/shm.c similarity index 99% rename from conts/posix/mm0/src/shm.c rename to conts/posix/mm0/mm/shm.c index 38fcf64..055d2d6 100644 --- a/conts/posix/mm0/src/shm.c +++ b/conts/posix/mm0/mm/shm.c @@ -226,28 +226,6 @@ struct vm_file *shm_new(key_t key, unsigned long npages) return shm_file; } -/* - * Fast internal path to do shmget/shmat() together for mm0's - * convenience. Works for existing areas. - */ -void *shmat_shmget_internal(struct tcb *task, key_t key, void *shmaddr) -{ - struct vm_file *shm_file; - struct shm_descriptor *shm_desc; - - list_foreach_struct(shm_file, &global_vm_files.list, list) { - if(shm_file->type == VM_FILE_SHM) { - shm_desc = shm_file_to_desc(shm_file); - /* Found the key, shmat that area */ - if (shm_desc->key == key) - return do_shmat(shm_file, shmaddr, - 0, task); - } - } - - return PTR_ERR(-EEXIST); -} - /* * FIXME: Make sure hostile tasks don't subvert other tasks' shared pages * by early-registring their shared page address here. @@ -308,6 +286,30 @@ int sys_shmget(key_t key, int size, int shmflg) +#if 0 + +/* + * Fast internal path to do shmget/shmat() together for mm0's + * convenience. Works for existing areas. + */ +void *shmat_shmget_internal(struct tcb *task, key_t key, void *shmaddr) +{ + struct vm_file *shm_file; + struct shm_descriptor *shm_desc; + + list_foreach_struct(shm_file, &global_vm_files.list, list) { + if(shm_file->type == VM_FILE_SHM) { + shm_desc = shm_file_to_desc(shm_file); + /* Found the key, shmat that area */ + if (shm_desc->key == key) + return do_shmat(shm_file, shmaddr, + 0, task); + } + } + + return PTR_ERR(-EEXIST); +} + /* * Currently, a default shm page is allocated to every thread in the system * for efficient ipc communication. This part below provides the allocation @@ -379,3 +381,4 @@ int shpage_unmap_from_task(struct tcb *owner, struct tcb *mapper) { return sys_shmdt(mapper, owner->shared_page); } +#endif diff --git a/conts/posix/mm0/src/task.c b/conts/posix/mm0/mm/task.c similarity index 91% rename from conts/posix/mm0/src/task.c rename to conts/posix/mm0/mm/task.c index 00c1b15..ed08bdc 100644 --- a/conts/posix/mm0/src/task.c +++ b/conts/posix/mm0/mm/task.c @@ -35,6 +35,7 @@ #include #include #include +#include struct global_list global_tasks = { .list = { &global_tasks.list, &global_tasks.list }, @@ -74,6 +75,7 @@ struct tcb *find_task(int tid) return 0; } + struct tcb *tcb_alloc_init(unsigned int flags) { struct tcb *task; @@ -102,15 +104,40 @@ struct tcb *tcb_alloc_init(unsigned int flags) link_init(&task->utcb_head->list); } + /* Allocate new fs data struct if its not shared */ + if (!(flags & TCB_SHARED_FS)) { + if (!(task->fs_data = + kzalloc(sizeof(*task->fs_data)))) { + kfree(task->vm_area_head); + kfree(task->utcb_head); + kfree(task); + return PTR_ERR(-ENOMEM); + } + task->fs_data->tcb_refs = 1; + } + /* Allocate file structures if not shared */ if (!(flags & TCB_SHARED_FILES)) { if (!(task->files = kzalloc(sizeof(*task->files)))) { kfree(task->vm_area_head); kfree(task->utcb_head); + kfree(task->fs_data); kfree(task); + return PTR_ERR(-ENOMEM); } + if (IS_ERR(task->files->fdpool = + id_pool_new_init(TASK_FILES_MAX))) { + void *err = task->files->fdpool; + kfree(task->vm_area_head); + kfree(task->utcb_head); + kfree(task->fs_data); + kfree(task->files); + kfree(task); + + return err; + } task->files->tcb_refs = 1; } @@ -137,8 +164,14 @@ int task_free_resources(struct tcb *task) * Threads may share file descriptor structure * if no users left, free it. */ - if (!(--task->files->tcb_refs)) + if (--task->files->tcb_refs == 0) { + kfree(task->files->fdpool); kfree(task->files); + } + + /* Similarly free filesystem view structure */ + if (--task->fs_data->tcb_refs == 0) + kfree(task->fs_data); /* * Threads may share the virtual space. @@ -246,7 +279,7 @@ int task_release_vmas(struct task_vma_head *vma_head) return 0; } -int copy_tcb(struct tcb *to, struct tcb *from, unsigned int flags) +int copy_tcb(struct tcb *to, struct tcb *from, unsigned int share_flags) { /* Copy program segment boundary information */ to->start = from->start; @@ -267,7 +300,7 @@ int copy_tcb(struct tcb *to, struct tcb *from, unsigned int flags) to->map_end = from->map_end; /* Sharing the list of vmas and utcbs */ - if (flags & TCB_SHARED_VM) { + if (share_flags & TCB_SHARED_VM) { to->vm_area_head = from->vm_area_head; to->vm_area_head->tcb_refs++; to->utcb_head = from->utcb_head; @@ -283,13 +316,16 @@ int copy_tcb(struct tcb *to, struct tcb *from, unsigned int flags) */ } - /* Copy all file descriptors */ - if (flags & TCB_SHARED_FILES) { + if (share_flags & TCB_SHARED_FILES) { to->files = from->files; to->files->tcb_refs++; } else { - /* Bulk copy all file descriptors */ - memcpy(to->files, from->files, sizeof(*to->files)); + /* Copy all file descriptors */ + memcpy(to->files->fd, from->files->fd, + TASK_FILES_MAX * sizeof(to->files->fd[0])); + + /* Copy the idpool */ + id_pool_copy(to->files->fdpool, from->files->fdpool, TASK_FILES_MAX); /* Increase refcount for all open files */ for (int i = 0; i < TASK_FILES_MAX; i++) @@ -297,6 +333,12 @@ int copy_tcb(struct tcb *to, struct tcb *from, unsigned int flags) to->files->fd[i].vmfile->openers++; } + if (share_flags & TCB_SHARED_FS) { + to->fs_data = from->fs_data; + to->fs_data->tcb_refs++; + } else + memcpy(to->fs_data, from->fs_data, sizeof(*to->fs_data)); + return 0; } @@ -306,6 +348,9 @@ struct tcb *task_create(struct tcb *parent, struct task_ids *ids, struct tcb *task; int err; + /* Can't have some share flags with no parent task */ + BUG_ON(!parent && share_flags); + /* Set task ids if a parent is supplied */ if (parent) { ids->tid = parent->tid; @@ -369,6 +414,10 @@ struct tcb *task_create(struct tcb *parent, struct task_ids *ids, } else { struct tcb *pager = find_task(PAGER_TID); + /* Initialise vfs specific fields. */ + task->fs_data->rootdir = vfs_root.pivot; + task->fs_data->curdir = vfs_root.pivot; + /* All parentless tasks are children of the pager */ list_insert_tail(&task->child_ref, &pager->children); task->parent = pager; @@ -643,46 +692,6 @@ int task_start(struct tcb *task) return 0; } -/* - * During its initialisation FS0 wants to learn how many boot tasks - * are running, and their tids, which includes itself. This function - * provides that information. - */ -int vfs_send_task_data(struct tcb *vfs) -{ - int li = 0; - struct tcb *t, *self; - struct task_data_head *tdata_head; - - if (vfs->tid != VFS_TID) { - printf("%s: Task data requested by %d, which is not " - "FS0 id %d, ignoring.\n", __TASKNAME__, vfs->tid, - VFS_TID); - return 0; - } - - BUG_ON(!(self = find_task(self_tid()))); - BUG_ON(!vfs->shared_page); - - /* Attach mm0 to vfs's utcb segment just like a normal task */ - shpage_map_to_task(vfs, self, SHPAGE_PREFAULT); - - /* Write all requested task information to shared pages's user buffer area */ - tdata_head = (struct task_data_head *)vfs->shared_page; - - /* First word is total number of tcbs */ - tdata_head->total = global_tasks.total; - - /* Write per-task data for all tasks */ - list_foreach_struct(t, &global_tasks.list, list) { - tdata_head->tdata[li].tid = t->tid; - tdata_head->tdata[li].shpage_address = (unsigned long)t->shared_page; - li++; - } - - return 0; -} - /* * Prefaults all mapped regions of a task. The reason we have this is * some servers are in the page fault handling path (e.g. fs0), and we diff --git a/conts/posix/mm0/src/test.c b/conts/posix/mm0/mm/test.c similarity index 100% rename from conts/posix/mm0/src/test.c rename to conts/posix/mm0/mm/test.c diff --git a/conts/posix/mm0/src/user.c b/conts/posix/mm0/mm/user.c similarity index 100% rename from conts/posix/mm0/src/user.c rename to conts/posix/mm0/mm/user.c diff --git a/conts/posix/mm0/src/utcb.c b/conts/posix/mm0/mm/utcb.c similarity index 100% rename from conts/posix/mm0/src/utcb.c rename to conts/posix/mm0/mm/utcb.c diff --git a/conts/posix/mm0/src/vm_object.c b/conts/posix/mm0/mm/vm_object.c similarity index 100% rename from conts/posix/mm0/src/vm_object.c rename to conts/posix/mm0/mm/vm_object.c diff --git a/conts/posix/mm0/src/arch-arm/crt0.S b/conts/posix/mm0/src/arch-arm/crt0.S deleted file mode 100644 index 9bcb3a8..0000000 --- a/conts/posix/mm0/src/arch-arm/crt0.S +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Australian Public Licence B (OZPLB) - * - * Version 1-0 - * - * Copyright (c) 2004 National ICT Australia - * - * All rights reserved. - * - * Developed by: Embedded, Real-time and Operating Systems Program (ERTOS) - * National ICT Australia - * http://www.ertos.nicta.com.au - * - * Permission is granted by National ICT Australia, free of charge, to - * any person obtaining a copy of this software and any associated - * documentation files (the "Software") to deal with the Software without - * restriction, including (without limitation) the rights to use, copy, - * modify, adapt, merge, publish, distribute, communicate to the public, - * sublicense, and/or sell, lend or rent out copies of the Software, and - * to permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimers. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimers in the documentation and/or other materials provided - * with the distribution. - * - * * Neither the name of National ICT Australia, nor the names of its - * contributors, may be used to endorse or promote products derived - * from this Software without specific prior written permission. - * - * EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT - * PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND - * NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS, - * WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS - * REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE, - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, - * THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF - * ERRORS, WHETHER OR NOT DISCOVERABLE. - * - * TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL - * NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL - * THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER - * LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR - * OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS - * OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR - * OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT, - * CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN - * CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER - * DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS - * CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS, - * DAMAGES OR OTHER LIABILITY. - * - * If applicable legislation implies representations, warranties, or - * conditions, or imposes obligations or liability on National ICT - * Australia or one of its contributors in respect of the Software that - * cannot be wholly or partly excluded, restricted or modified, the - * liability of National ICT Australia or the contributor is limited, to - * the full extent permitted by the applicable legislation, at its - * option, to: - * a. in the case of goods, any one or more of the following: - * i. the replacement of the goods or the supply of equivalent goods; - * ii. the repair of the goods; - * iii. the payment of the cost of replacing the goods or of acquiring - * equivalent goods; - * iv. the payment of the cost of having the goods repaired; or - * b. in the case of services: - * i. the supplying of the services again; or - * ii. the payment of the cost of having the services supplied again. - * - * The construction, validity and performance of this licence is governed - * by the laws in force in New South Wales, Australia. - */ - -#ifdef __thumb__ -#define bl blx -#endif - - .section .text.head - .code 32 - .global _start; - .align; -_start: - ldr sp, =__stack - bl platform_init - bl __container_init -1: - b 1b -