diff --git a/configure.py b/configure.py index abdc94d..31d6ed4 100755 --- a/configure.py +++ b/configure.py @@ -56,6 +56,7 @@ def configure_kernel(cml_file): cml2_update_config_h(CONFIG_H, config) configuration_save(config) + #config.config_print() # Generate bare container files if new ones defined bare_cont_gen = BareContGenerator() diff --git a/conts/posix/SConstruct b/conts/posix/SConstruct index e476f76..4cf07e9 100644 --- a/conts/posix/SConstruct +++ b/conts/posix/SConstruct @@ -70,13 +70,17 @@ mm0 = SConscript('mm0/SConscript', \ exports = { 'config' : config, 'env' : mm0_env, 'contid' : contid }, duplicate = 0, \ variant_dir = join(BUILDDIR, 'cont' + str(contid) + '/posix' + '/mm0')) +rootfs = SConscript('rootfs/SConscript', \ + exports = { 'config' : config, 'environment' : env, 'contid' : contid, 'previmage' : mm0 }, duplicate = 0, \ + variant_dir = join(BUILDDIR, 'cont' + str(contid) + '/posix' + '/rootfs')) + 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' : mm0 }, duplicate = 0, \ + exports = { 'config' : config, 'environment' : test0_env, 'contid' : contid, 'previmage' : rootfs }, duplicate = 0, \ variant_dir = join(BUILDDIR, 'cont' + str(contid) + '/posix' + '/test0')) -images = [mm0, test0] +images = [mm0, rootfs, test0] bootdesc_env = env.Clone() bootdesc_env['bootdesc_dir'] = 'bootdesc' @@ -87,11 +91,13 @@ bootdesc = SConscript('bootdesc/SConscript', \ Depends(mm0, libposix) Depends(test0, libposix) -Depends(bootdesc, [test0, mm0]) +Depends(rootfs, mm0) +Depends(test0, rootfs) +Depends(bootdesc, [test0, mm0, rootfs]) Alias('libposix', libposix) Alias('mm0', mm0) Alias('test0', test0) Alias('bootdesc', bootdesc) - +Alias('rootfs', rootfs) Default([mm0, libposix, test0, bootdesc]) diff --git a/conts/posix/mm0/SConstruct.orig b/conts/posix/mm0/SConstruct.orig deleted file mode 100644 index f6001f0..0000000 --- a/conts/posix/mm0/SConstruct.orig +++ /dev/null @@ -1,97 +0,0 @@ -# -# User space application build script -# -# Copyright (C) 2007 Bahadir Balban -# -import os -import sys -import shutil -from string import split -from os.path import join -from glob import glob - -task_name = "mm0" - -# The root directory of the repository where this file resides: -project_root = "../.." -tools_root = join(project_root, "tools") -prev_image = join(project_root, "build/start.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 - -# libl4 paths: -libl4_path = "../libl4" -libl4_incpath = join(libl4_path, "include") - -# libposix paths: -libposix_path = "../libposix" -libposix_incpath = join(libposix_path, "include") - -#libmem paths: -libmem_path = "../libmem" -libmem_incpath = "../libmem" - -# kernel paths: -kernel_incpath = join(project_root, "include") - -# Kernel config header. -config_h = join(project_root, "include/l4/config.h") - - -# 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" + libposix_path, "-L" + libmem_path], - ASFLAGS = ['-D__ASSEMBLY__'], - PROGSUFFIX = '.axf', # The suffix to use for final executable - ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path - LIBS = [libc_name, 'libl4', 'libmm', 'libmc', 'libkm', 'libposix', \ - 'gcc', libc_name], # libgcc.a - This is required for division routines. - CPPFLAGS = "-D__USERSPACE__", - CPPPATH = ['#include', libl4_incpath, libc_incpath, kernel_incpath, \ - libmem_incpath, libposix_incpath]) - - -def create_symlinks(arch): - arch_path = "include/arch" - arch_path2 ="src/arch" - if os.path.exists(arch_path): - os.system("rm %s" % (arch_path)) - os.system("ln -s %s %s" % ("arch-" + arch, arch_path)) - if os.path.exists(arch_path2): - os.system("rm %s" % (arch_path2)) - os.system("ln -s %s %s" % ("arch-" + arch, arch_path2)) - -arch, subarch, plat = extract_arch_subarch_plat(config_h) - -create_symlinks(arch) # Creates symlinks to architecture specific directories. - -src = [glob("src/*.c"), glob("src/lib/*.c"), glob("src/lib/elf/*.c"), glob("*.c"), glob("src/arch/*.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/mm0/fs/bdev.c b/conts/posix/mm0/fs/bdev.c index 1f69162..6a0e1c0 100644 --- a/conts/posix/mm0/fs/bdev.c +++ b/conts/posix/mm0/fs/bdev.c @@ -1,15 +1,19 @@ /* * This is just to allocate some memory as a block device. */ +#include #include +#include #include - -extern char _start_bdev[]; -extern char _end_bdev[]; - -__attribute__((section(".data.memfs"))) char blockdevice[MEMFS_TOTAL_SIZE]; +#include void *vfs_rootdev_open(void) { - return (void *)_start_bdev; + struct svc_image *rootfs_img = bootdesc_get_image_byname("rootfs"); + unsigned long rootfs_size = rootfs_img->phys_end - rootfs_img->phys_start; + + BUG_ON(rootfs_size < MEMFS_TOTAL_SIZE); + + /* Map filesystem blocks to virtual memory */ + return l4_map_helper((void *)rootfs_img->phys_start, __pfn(rootfs_size)); } diff --git a/conts/posix/mm0/fs/init.c b/conts/posix/mm0/fs/init.c index 7669114..2b33ef8 100644 --- a/conts/posix/mm0/fs/init.c +++ b/conts/posix/mm0/fs/init.c @@ -1,5 +1,5 @@ /* - * FS0 Initialisation. + * Filesystem initialisation. * * Copyright (C) 2007 Bahadir Balban */ @@ -51,7 +51,7 @@ void vfs_register_filesystems(void) /* * Filesystem initialisation. */ -int initialise(void) +int vfs_init(void) { void *rootdev_blocks; struct superblock *root_sb; @@ -79,10 +79,6 @@ int initialise(void) printf("%s: Mounted memfs root filesystem.\n", __TASKNAME__); - /* - * Initialisation is done. From here on, we can start - * serving filesystem requests. - */ return 0; } diff --git a/conts/posix/mm0/include/bootdesc.h b/conts/posix/mm0/include/bootdesc.h index 5c39f79..0da6e5d 100644 --- a/conts/posix/mm0/include/bootdesc.h +++ b/conts/posix/mm0/include/bootdesc.h @@ -15,7 +15,8 @@ struct bootdesc { struct svc_image images[]; } __attribute__((__packed__)); -struct initdata; -void read_bootdesc(struct initdata *initdata); + +void read_boot_params(); +struct svc_image *bootdesc_get_image_byname(char *); #endif /* __BOOTDESC_H__ */ diff --git a/conts/posix/mm0/include/capability.h b/conts/posix/mm0/include/capability.h index 6fe1a59..317a78d 100644 --- a/conts/posix/mm0/include/capability.h +++ b/conts/posix/mm0/include/capability.h @@ -38,7 +38,7 @@ struct capability { extern struct cap_list capability_list; struct initdata; -int read_kernel_capabilities(struct initdata *); -void copy_boot_capabilities(struct initdata *initdata); +int read_pager_capabilities(); +void copy_boot_capabilities(); #endif /* __MM0_CAPABILITY_H__ */ diff --git a/conts/posix/mm0/include/init.h b/conts/posix/mm0/include/init.h index c436575..e1945f8 100644 --- a/conts/posix/mm0/include/init.h +++ b/conts/posix/mm0/include/init.h @@ -29,7 +29,7 @@ struct initdata { extern struct initdata initdata; -void init_pager(void); +void init(void); /* TODO: Remove this stuff from here. */ int init_devzero(void); diff --git a/conts/posix/mm0/include/linker.lds.in b/conts/posix/mm0/include/linker.lds.in index 64bfd47..542494b 100644 --- a/conts/posix/mm0/include/linker.lds.in +++ b/conts/posix/mm0/include/linker.lds.in @@ -31,13 +31,7 @@ SECTIONS /* rodata is needed else your strings will link at physical! */ .rodata : AT (ADDR(.rodata) - pager_offset) { *(.rodata) } .rodata1 : AT (ADDR(.rodata1) - pager_offset) { *(.rodata1) } - .data : AT (ADDR(.data) - pager_offset) - { - *(.data) - _start_bdev = .; - *(.data.memfs) - _end_bdev = .; - } + .data : AT (ADDR(.data) - pager_offset) { *(.data) } .bss : AT (ADDR(.bss) - pager_offset) { *(.bss) } . = ALIGN(4K); . += 0x2000; /* BSS doesnt increment link counter??? */ diff --git a/conts/posix/mm0/include/memory.h b/conts/posix/mm0/include/memory.h index 1db0198..90b7e73 100644 --- a/conts/posix/mm0/include/memory.h +++ b/conts/posix/mm0/include/memory.h @@ -12,7 +12,7 @@ void init_mm_descriptors(struct page_bitmap *page_map, struct bootdesc *bootdesc, struct membank *membank); -void init_physmem(struct initdata *initdata, struct membank *membank); +void init_physmem(void); int pager_address_pool_init(void); void *pager_new_address(int npages); diff --git a/conts/posix/mm0/include/physmem.h b/conts/posix/mm0/include/physmem.h index 698be40..380b714 100644 --- a/conts/posix/mm0/include/physmem.h +++ b/conts/posix/mm0/include/physmem.h @@ -31,15 +31,13 @@ struct membank { extern struct membank membank[]; /* Describes bitmap of used/unused state for all physical pages */ -extern struct page_bitmap page_map; extern struct memdesc physmem; /* Sets the global page map as used/unused. Aligns input when needed. */ int set_page_map(struct page_bitmap *pmap, unsigned long start, int numpages, int val); -struct initdata; -void init_physmem_primary(struct initdata *initdata); -void init_physmem_secondary(struct initdata *initdata, struct membank *membank); +void init_physmem_primary(); +void init_physmem_secondary(struct membank *membank); #endif /* __PAGER_PHYSMEM_H__ */ diff --git a/conts/posix/mm0/include/vfs.h b/conts/posix/mm0/include/vfs.h index 5d9b5a8..a0e8682 100644 --- a/conts/posix/mm0/include/vfs.h +++ b/conts/posix/mm0/include/vfs.h @@ -87,4 +87,6 @@ struct vnode *generic_vnode_lookup(struct vnode *thisnode, struct pathdata *p, struct vnode *vfs_lookup_bypath(struct pathdata *p); struct vnode *vfs_lookup_byvnum(struct superblock *sb, unsigned long vnum); +int vfs_init(void); + #endif /* __VFS_H__ */ diff --git a/conts/posix/mm0/main.c b/conts/posix/mm0/main.c index f05d682..90f4941 100644 --- a/conts/posix/mm0/main.c +++ b/conts/posix/mm0/main.c @@ -153,10 +153,6 @@ void handle_requests(void) else return; /* else we're done */ } - case L4_IPC_TAG_BRK: { -// 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 */ @@ -189,86 +185,11 @@ void handle_requests(void) } } -#if 0 -/* - * Executes the given function in a new thread in the current - * address space but on a brand new stack. - */ -int self_spawn(void) -{ - struct task_ids ids; - struct tcb *self, *self_child; - unsigned long stack, stack_size; - - BUG_ON(!(self = find_task(self_tid()))); - - ids.tid = TASK_ID_INVALID; - ids.spid = self->spid; - ids.tgid = self->tgid; - - /* Create a new L4 thread in current thread's address space. */ - self_child = task_create(self, &ids, THREAD_SAME_SPACE, - TCB_SHARED_VM | TCB_SHARED_FILES); - - if (IS_ERR(self_child = tcb_alloc_init(TCB_SHARED_VM - | TCB_SHARED_FILES))) - BUG(); - - /* - * Create a new utcb. Every pager thread will - * need its own utcb to answer calls. - */ - self_child->utcb = utcb_vaddr_new(); - - /* Map utcb to child */ - task_map_prefault_utcb(self_child, self_child); - - /* - * Set up a child stack by mmapping an anonymous region. - */ - stack_size = self->stack_end - self->stack_start; - if (IS_ERR(stack = do_mmap(0, 0, self, 0, - VM_READ | VM_WRITE | VMA_ANONYMOUS - | VMA_PRIVATE | VMA_GROWSDOWN, - __pfn(stack_size)))) { - printf("%s: Error spawning %s, Error code: %d\n", - __FUNCTION__, __TASKNAME__, (int)stack); - BUG(); - } - - /* Modify stack marker of child tcb */ - self_child->stack_end = stack; - self_child->stack_start = stack - stack_size; - - /* Prefault child stack */ - for (int i = 0; i < __pfn(stack_size); i++) - prefault_page(self_child, - self_child->stack_start + __pfn_to_addr(i), - VM_READ | VM_WRITE); - - /* Copy current stack to child */ - memcpy((void *)self_child->stack_start, - (void *)self->stack_start, stack_size); - - /* TODO: Modify registers ???, it depends on what state is copied in C0 */ - - /* TODO: Notify vfs ??? */ - - task_add_global(self_child); - - if (l4_thread_control(THREAD_CREATE | THREAD_CREATE_SAMESPC, ids) - l4_thread_control(THREAD_RUN, &ids); - - return 0; -} -#endif - void main(void) { printf("\n%s: Started with thread id %d\n", __TASKNAME__, self_tid()); - /* Initialise the memory, server tasks, mmap and start them. */ - init_pager(); + init(); printf("%s: Memory/Process manager initialized. Listening requests.\n", __TASKNAME__); while (1) { diff --git a/conts/posix/mm0/mm/bootdesc.c b/conts/posix/mm0/mm/bootdesc.c index 542f2eb..e62fc57 100644 --- a/conts/posix/mm0/mm/bootdesc.c +++ b/conts/posix/mm0/mm/bootdesc.c @@ -12,7 +12,15 @@ extern unsigned long _end[]; extern unsigned long pager_offset; -void read_bootdesc(struct initdata *initdata) +struct svc_image *bootdesc_get_image_byname(char *name) +{ + for (int i = 0; i < initdata.bootdesc->total_images; i++) + if (!strncmp(initdata.bootdesc->images[i].name, name, strlen(name))) + return &initdata.bootdesc->images[i]; + return 0; +} + +void read_boot_params() { int npages; struct bootdesc *bootdesc; @@ -24,16 +32,15 @@ void read_bootdesc(struct initdata *initdata) /* Check if bootdesc is on an unmapped page */ if (is_page_aligned(bootdesc)) - l4_map_helper(bootdesc - pager_offset, PAGE_SIZE); + l4_map_helper(bootdesc - pager_offset, 1); /* Allocate bootdesc sized structure */ - initdata->bootdesc = alloc_bootmem(bootdesc->desc_size, 0); + initdata.bootdesc = alloc_bootmem(bootdesc->desc_size, 0); /* Copy bootdesc to initdata */ - memcpy(initdata->bootdesc, bootdesc, + memcpy(initdata.bootdesc, bootdesc, bootdesc->desc_size); if (npages > 0) - l4_unmap_helper((void *)page_align_up(_end), - PAGE_SIZE * npages); + l4_unmap_helper((void *)page_align_up(_end), npages); } diff --git a/conts/posix/mm0/mm/capability.c b/conts/posix/mm0/mm/capability.c index b89acb9..f763a3f 100644 --- a/conts/posix/mm0/mm/capability.c +++ b/conts/posix/mm0/mm/capability.c @@ -12,74 +12,3 @@ #include /* TODO: Move this to API */ #include -struct cap_list capability_list; - -__initdata static struct capability *caparray; -__initdata static int total_caps = 0; - -/* Copy all init-memory allocated capabilities */ -void copy_boot_capabilities(struct initdata *initdata) -{ - struct capability *cap; - - for (int i = 0; i < total_caps; i++) { - cap = kzalloc(sizeof(struct capability)); - - /* This copies kernel-allocated unique cap id as well */ - memcpy(cap, &caparray[i], sizeof(struct capability)); - - /* Initialize capability list */ - link_init(&cap->list); - - /* Add capability to global cap list */ - list_insert(&capability_list.caps, &cap->list); - } -} - -int read_kernel_capabilities(struct initdata *initdata) -{ - int ncaps; - int err; - - /* Read number of capabilities */ - if ((err = l4_capability_control(CAP_CONTROL_NCAPS, 0, &ncaps)) < 0) { - printf("l4_capability_control() reading # of capabilities failed.\n" - "Could not complete CAP_CONTROL_NCAPS request.\n"); - goto error; - } - total_caps = ncaps; - - /* Allocate array of caps from boot memory */ - caparray = alloc_bootmem(sizeof(struct capability) * ncaps, 0); - - /* Read all capabilities */ - if ((err = l4_capability_control(CAP_CONTROL_READ_CAPS, 0, caparray)) < 0) { - printf("l4_capability_control() reading of capabilities failed.\n" - "Could not complete CAP_CONTROL_READ_CAPS request.\n"); - goto error; - } - - /* Set up initdata pointer to important capabilities */ - initdata->bootcaps = caparray; - for (int i = 0; i < ncaps; i++) { - /* - * TODO: There may be multiple physmem caps! - * This really needs to be considered as multiple - * membanks!!! - */ - if ((caparray[i].type & CAP_RTYPE_MASK) - == CAP_RTYPE_PHYSMEM) { - initdata->physmem = &caparray[i]; - return 0; - } - } - printf("%s: Error, pager has no physmem capability defined.\n", - __TASKNAME__); - goto error; - - return 0; - -error: - BUG(); -} - diff --git a/conts/posix/mm0/mm/file.c b/conts/posix/mm0/mm/file.c index 6e5f208..a18a5b5 100644 --- a/conts/posix/mm0/mm/file.c +++ b/conts/posix/mm0/mm/file.c @@ -589,8 +589,6 @@ int vfs_write(unsigned long vnum, unsigned long file_offset, return ret; } - - /* Writes updated file stats back to vfs. (e.g. new file size) */ int vfs_update_file_stats(struct vm_file *f) { diff --git a/conts/posix/mm0/mm/init.c b/conts/posix/mm0/mm/init.c index 95c07a6..e9ea5a8 100644 --- a/conts/posix/mm0/mm/init.c +++ b/conts/posix/mm0/mm/init.c @@ -3,15 +3,20 @@ * * Copyright (C) 2007, 2008 Bahadir Balban */ -#include -#include -#include -#include -#include -#include #include #include #include + +#include +#include /* TODO: Move this to API */ +#include + +#include +#include +#include +#include +#include + #include #include #include @@ -21,22 +26,30 @@ #include #include #include +#include +#include +#include -/* A separate list than the generic file list that keeps just the boot files */ -LINK_DECLARE(boot_file_list); + +extern unsigned long _start_init[]; +extern unsigned long _end_init[]; /* Kernel data acquired during initialisation */ __initdata struct initdata initdata; -void print_bootdesc(struct bootdesc *bd) -{ - for (int i = 0; i < bd->total_images; i++) { - printf("Task Image: %d\n", i); - printf("Name: %s\n", bd->images[i].name); - printf("Start: 0x%x\n", bd->images[i].phys_start); - printf("End: 0x%x\n", bd->images[i].phys_end); - } -} + +/* Physical memory descriptors */ +struct memdesc physmem; /* Initial, primitive memory descriptor */ +struct membank membank[1]; /* The memory bank */ +struct page *page_array; /* The physical page array based on mem bank */ + + +/* Capability descriptor list */ +struct cap_list capability_list; + +__initdata static struct capability *caparray; +__initdata static int total_caps = 0; + void print_pfn_range(int pfn, int size) { @@ -45,36 +58,6 @@ void print_pfn_range(int pfn, int size) printf("Used: 0x%x - 0x%x\n", addr, end); } -#if 0 -void print_page_map(struct page_bitmap *map) -{ - unsigned int start_pfn = 0; - unsigned int total_used = 0; - int numpages = 0; - - // printf("Page map: 0x%x-0x%x\n", map->pfn_start << PAGE_BITS, map->pfn_end << PAGE_BITS); - for (int i = 0; i < (PHYSMEM_TOTAL_PAGES >> 5); i++) { - for (int x = 0; x < WORD_BITS; x++) { - if (map->map[i] & (1 << x)) { /* A used page found? */ - if (!start_pfn) /* First such page found? */ - start_pfn = (WORD_BITS * i) + x; - total_used++; - numpages++; /* Increase number of pages */ - } else { /* Either used pages ended or were never found */ - if (start_pfn) { /* We had a used page */ - /* Finished end of used range. - * Print and reset. */ - //print_pfn_range(start_pfn, numpages); - start_pfn = 0; - numpages = 0; - } - } - } - } - printf("%s: Pagemap: Total of %d used physical pages. %d Kbytes used.\n", __TASKNAME__, total_used, total_used << 2); -} -#endif - /* * A specialised function for setting up the task environment of mm0. * Essentially all the memory regions are set up but a new task isn't @@ -133,115 +116,83 @@ int mm0_task_init(struct vm_file *f, unsigned long task_start, return 0; } -struct vm_file *initdata_next_bootfile(struct initdata *initdata) +/* Copy all init-memory allocated capabilities */ +void copy_boot_capabilities() { - struct vm_file *file, *n; - list_foreach_removable_struct(file, n, - &initdata->boot_file_list, - list) { - list_remove_init(&file->list); - return file; + struct capability *cap; + + for (int i = 0; i < total_caps; i++) { + cap = kzalloc(sizeof(struct capability)); + + /* This copies kernel-allocated unique cap id as well */ + memcpy(cap, &caparray[i], sizeof(struct capability)); + + /* Initialize capability list */ + link_init(&cap->list); + + /* Add capability to global cap list */ + list_insert(&capability_list.caps, &cap->list); } - return 0; } -/* - * Reads boot files from init data, determines their task ids if they - * match with particular servers, and starts the tasks. - */ -int start_boot_tasks(struct initdata *initdata) +int read_pager_capabilities() { - struct vm_file *file = 0, *fs0_file = 0, *mm0_file = 0, *n; - struct tcb *fs0_task; - struct svc_image *img; - struct task_ids ids; - struct link other_files; - int total = 0; + int ncaps; + int err; - link_init(&other_files); + /* Read number of capabilities */ + if ((err = l4_capability_control(CAP_CONTROL_NCAPS, 0, &ncaps)) < 0) { + printf("l4_capability_control() reading # of capabilities failed.\n" + "Could not complete CAP_CONTROL_NCAPS request.\n"); + goto error; + } + total_caps = ncaps; - /* Separate out special server tasks and regular files */ - do { - file = initdata_next_bootfile(initdata); + /* Allocate array of caps from boot memory */ + caparray = alloc_bootmem(sizeof(struct capability) * ncaps, 0); - if (file) { - BUG_ON(file->type != VM_FILE_BOOTFILE); - img = file->priv_data; - if (img->name[0] == 'm' && - img->name[1] == 'm' && - img->name[2] == '0') - mm0_file = file; - else if (img->name[0] == 'f' && - img->name[1] == 's' && - img->name[2] == '0') - fs0_file = file; - else - list_insert(&file->list, &other_files); - } else - break; - } while (1); - - if (!mm0_file || !fs0_file) { - printf("%s: FATAL: Could not find images for %s, and/or %s\n", - __PAGERNAME__, __PAGERNAME__, __VFSNAME__); - BUG(); + /* Read all capabilities */ + if ((err = l4_capability_control(CAP_CONTROL_READ_CAPS, 0, caparray)) < 0) { + printf("l4_capability_control() reading of capabilities failed.\n" + "Could not complete CAP_CONTROL_READ_CAPS request.\n"); + goto error; } - /* MM0 needs partial initialisation since it's already running. */ - // printf("%s: Initialising mm0 tcb.\n", __TASKNAME__); - ids.tid = PAGER_TID; - ids.spid = PAGER_TID; - ids.tgid = PAGER_TID; - - if (mm0_task_init(mm0_file, INITTASK_AREA_START, - INITTASK_AREA_END, &ids) < 0) - BUG(); - total++; - - /* Initialise vfs with its predefined id */ - ids.tid = VFS_TID; - ids.spid = VFS_TID; - ids.tgid = VFS_TID; - - // printf("%s: Initialising fs0\n",__TASKNAME__); - BUG_ON((IS_ERR(fs0_task = boottask_exec(fs0_file, USER_AREA_START, - USER_AREA_END, &ids)))); - total++; - - /* Initialise other tasks */ - list_foreach_removable_struct(file, n, &other_files, list) { - ids.tid = TASK_ID_INVALID; - ids.spid = TASK_ID_INVALID; - ids.tgid = TASK_ID_INVALID; - list_remove_init(&file->list); - BUG_ON(IS_ERR(boottask_exec(file, USER_AREA_START, - USER_AREA_END, &ids))); - total++; - } - - if (!total) { - printf("%s: Could not start any tasks.\n", - __TASKNAME__); - BUG(); + /* Set up initdata pointer to important capabilities */ + initdata.bootcaps = caparray; + for (int i = 0; i < ncaps; i++) { + /* + * TODO: There may be multiple physmem caps! + * This really needs to be considered as multiple + * membanks!!! + */ + if ((caparray[i].type & CAP_RTYPE_MASK) + == CAP_RTYPE_PHYSMEM) { + initdata.physmem = &caparray[i]; + return 0; + } } + printf("%s: Error, pager has no physmem capability defined.\n", + __TASKNAME__); + goto error; return 0; -} -extern unsigned long _start_init[]; -extern unsigned long _end_init[]; +error: + BUG(); +} /* * Copy all necessary data from initmem to real memory, * release initdata and any init memory used */ -void copy_release_initdata(struct initdata *initdata) +void release_initdata() { /* * Copy boot capabilities to a list of * real capabilities */ - copy_boot_capabilities(initdata); + copy_boot_capabilities(); /* Free and unmap init memory: * @@ -255,48 +206,215 @@ void copy_release_initdata(struct initdata *initdata) self_tid()); } - -void init_mm(struct initdata *initdata) +static void init_page_map(struct page_bitmap *pmap, unsigned long pfn_start, unsigned long pfn_end) { - /* Initialise the page and bank descriptors */ - init_physmem_primary(initdata); + pmap->pfn_start = pfn_start; + pmap->pfn_end = pfn_end; + set_page_map(pmap, pfn_start, pfn_end - pfn_start, 0); +} - init_physmem_secondary(initdata, membank); +/* + * Marks pages in the global page_map as used or unused. + * + * @start = start page address to set, inclusive. + * @numpages = number of pages to set. + */ +int set_page_map(struct page_bitmap *page_map, unsigned long pfn_start, + int numpages, int val) +{ + unsigned long pfn_end = pfn_start + numpages; + unsigned long pfn_err = 0; - /* Initialise the page allocator on first bank. */ - init_page_allocator(membank[0].free, membank[0].end); - - /* Initialise the zero page */ - init_devzero(); - - /* Initialise in-memory boot files */ - init_boot_files(initdata); - - if (shm_pool_init() < 0) { - printf("SHM initialisation failed.\n"); - BUG(); + if (page_map->pfn_start > pfn_start || page_map->pfn_end < pfn_start) { + pfn_err = pfn_start; + goto error; + } + if (page_map->pfn_end < pfn_end || page_map->pfn_start > pfn_end) { + pfn_err = pfn_end; + goto error; } - if (utcb_pool_init() < 0) { - printf("SHM initialisation failed.\n"); - BUG(); + if (val) + for (int i = pfn_start; i < pfn_end; i++) + page_map->map[BITWISE_GETWORD(i)] |= BITWISE_GETBIT(i); + else + for (int i = pfn_start; i < pfn_end; i++) + page_map->map[BITWISE_GETWORD(i)] &= ~BITWISE_GETBIT(i); + return 0; +error: + BUG_MSG("Given page area is out of system page_map range: 0x%lx\n", + pfn_err << PAGE_BITS); + return -1; +} + +/* Allocates page descriptors and initialises them using page_map information */ +void init_physmem_secondary(struct membank *membank) +{ + struct page_bitmap *pmap = initdata.page_map; + int npages = pmap->pfn_end - pmap->pfn_start; + + /* Allocation marks for the struct page array; npages, start, end */ + int pg_npages, pg_spfn, pg_epfn; + unsigned long ffree_addr; + + /* + * Means the page array won't map one to one to pfns. That's ok, + * but we dont allow it for now. + */ + // BUG_ON(pmap->pfn_start); + + membank[0].start = __pfn_to_addr(pmap->pfn_start); + membank[0].end = __pfn_to_addr(pmap->pfn_end); + + /* First find the first free page after last used page */ + for (int i = 0; i < npages; i++) + if ((pmap->map[BITWISE_GETWORD(i)] & BITWISE_GETBIT(i))) + membank[0].free = (i + 1) * PAGE_SIZE; + BUG_ON(membank[0].free >= membank[0].end); + + /* + * One struct page for every physical page. Calculate how many pages + * needed for page structs, start and end pfn marks. + */ + pg_npages = __pfn(page_align_up((sizeof(struct page) * npages))); + + /* These are relative pfn offsets to the start of the memory bank */ + + /* FIXME: + * 1.) These values were only right when membank started from pfn 0. + * 2.) Use set_page_map to set page map below instead of manually. + */ + pg_spfn = __pfn(membank[0].free); + pg_epfn = pg_spfn + pg_npages; + + /* Use free pages from the bank as the space for struct page array */ + membank[0].page_array = l4_map_helper((void *)membank[0].free, + pg_npages); + /* Update free memory left */ + membank[0].free += pg_npages * PAGE_SIZE; + + /* Update page bitmap for the pages used for the page array */ + for (int i = pg_spfn; i < pg_epfn; i++) + pmap->map[BITWISE_GETWORD(i)] |= BITWISE_GETBIT(i); + + /* Initialise the page array */ + for (int i = 0; i < npages; i++) { + link_init(&membank[0].page_array[i].list); + + /* Set use counts for pages the kernel has already used up */ + if (!(pmap->map[BITWISE_GETWORD(i)] & BITWISE_GETBIT(i))) + membank[0].page_array[i].refcnt = -1; + else /* Last page used +1 is free */ + ffree_addr = (i + 1) * PAGE_SIZE; } + + /* First free address must come up the same for both */ + BUG_ON(ffree_addr != membank[0].free); + + /* Set global page array to this bank's array */ + page_array = membank[0].page_array; + + /* Test that page/phys macros work */ + BUG_ON(phys_to_page(page_to_phys(&page_array[5])) != &page_array[5]) } -void init_pager(void) +/* Fills in the physmem structure with free physical memory information */ +void init_physmem_primary() { + unsigned long pfn_start, pfn_end, pfn_images_end = 0; + struct bootdesc *bootdesc = initdata.bootdesc; + + /* Allocate page map structure */ + initdata.page_map = alloc_bootmem(sizeof(struct page_bitmap) + + ((initdata.physmem->end - + initdata.physmem->start) + >> 5) + 1, 0); + + /* Initialise page map from physmem capability */ + init_page_map(initdata.page_map, + initdata.physmem->start, + initdata.physmem->end); + + /* Mark pager and other boot task areas as used */ + for (int i = 0; i < bootdesc->total_images; i++) { + pfn_start = + __pfn(page_align_up(bootdesc->images[i].phys_start)); + pfn_end = __pfn(page_align_up(bootdesc->images[i].phys_end)); + if (pfn_end > pfn_images_end) + pfn_images_end = pfn_end; + set_page_map(initdata.page_map, pfn_start, + pfn_end - pfn_start, 1); + } + + physmem.start = initdata.physmem->start; + physmem.end = initdata.physmem->end; + + physmem.free_cur = pfn_images_end; + physmem.free_end = physmem.end; + physmem.numpages = __pfn(physmem.end - physmem.start); +} + +void init_physmem(void) +{ + init_physmem_primary(); + + init_physmem_secondary(membank); + + init_page_allocator(membank[0].free, membank[0].end); +} + +void init_execve(char *path) +{ + /* + * Find executable, and execute it by creating a new process + * rather than replacing the current image (which is the pager!) + */ +} + +/* + * To be removed later: This file copies in-memory elf image to the + * initialized and formatted in-memory memfs filesystem. + */ +void copy_init_process(void) +{ + //int fd = sys_open(find_task(self_tid()), "/test0", O_WRITE, 0) + + //sys_write(find_task(self_tid()), fd, __test0_start, __test0_end - __test0_start); + + //sys_close(find_task(self_tid()), fd); + +} + +void start_init_process(void) +{ + /* Copy raw test0 elf image from memory to memfs first */ + copy_init_process(); + + init_execve("/test0"); +} + +void init(void) +{ + read_pager_capabilities(); + pager_address_pool_init(); - read_kernel_capabilities(&initdata); + read_boot_params(); - read_bootdesc(&initdata); + init_physmem(); - init_mm(&initdata); + init_devzero(); - start_boot_tasks(&initdata); + shm_pool_init(); - copy_release_initdata(&initdata); + utcb_pool_init(); + + vfs_init(); + + start_init_process(); + + release_initdata(); mm0_test_global_vm_integrity(); } diff --git a/conts/posix/mm0/mm/physmem.c b/conts/posix/mm0/mm/physmem.c index 88714de..223bf22 100644 --- a/conts/posix/mm0/mm/physmem.c +++ b/conts/posix/mm0/mm/physmem.c @@ -19,157 +19,4 @@ #include #include -struct memdesc physmem; /* Initial, primitive memory descriptor */ -struct membank membank[1]; /* The memory bank */ -struct page *page_array; /* The physical page array based on mem bank */ - - -static void init_page_map(struct page_bitmap *pmap, unsigned long pfn_start, unsigned long pfn_end) -{ - pmap->pfn_start = pfn_start; - pmap->pfn_end = pfn_end; - set_page_map(pmap, pfn_start, pfn_end - pfn_start, 0); -} - -/* - * Marks pages in the global page_map as used or unused. - * - * @start = start page address to set, inclusive. - * @numpages = number of pages to set. - */ -int set_page_map(struct page_bitmap *page_map, unsigned long pfn_start, - int numpages, int val) -{ - unsigned long pfn_end = pfn_start + numpages; - unsigned long pfn_err = 0; - - if (page_map->pfn_start > pfn_start || page_map->pfn_end < pfn_start) { - pfn_err = pfn_start; - goto error; - } - if (page_map->pfn_end < pfn_end || page_map->pfn_start > pfn_end) { - pfn_err = pfn_end; - goto error; - } - - if (val) - for (int i = pfn_start; i < pfn_end; i++) - page_map->map[BITWISE_GETWORD(i)] |= BITWISE_GETBIT(i); - else - for (int i = pfn_start; i < pfn_end; i++) - page_map->map[BITWISE_GETWORD(i)] &= ~BITWISE_GETBIT(i); - return 0; -error: - BUG_MSG("Given page area is out of system page_map range: 0x%lx\n", - pfn_err << PAGE_BITS); - return -1; -} - -/* Allocates page descriptors and initialises them using page_map information */ -void init_physmem_secondary(struct initdata *initdata, struct membank *membank) -{ - struct page_bitmap *pmap = initdata->page_map; - int npages = pmap->pfn_end - pmap->pfn_start; - - /* Allocation marks for the struct page array; npages, start, end */ - int pg_npages, pg_spfn, pg_epfn; - unsigned long ffree_addr; - - /* - * Means the page array won't map one to one to pfns. That's ok, - * but we dont allow it for now. - */ - // BUG_ON(pmap->pfn_start); - - membank[0].start = __pfn_to_addr(pmap->pfn_start); - membank[0].end = __pfn_to_addr(pmap->pfn_end); - - /* First find the first free page after last used page */ - for (int i = 0; i < npages; i++) - if ((pmap->map[BITWISE_GETWORD(i)] & BITWISE_GETBIT(i))) - membank[0].free = (i + 1) * PAGE_SIZE; - BUG_ON(membank[0].free >= membank[0].end); - - /* - * One struct page for every physical page. Calculate how many pages - * needed for page structs, start and end pfn marks. - */ - pg_npages = __pfn(page_align_up((sizeof(struct page) * npages))); - - /* These are relative pfn offsets to the start of the memory bank */ - - /* FIXME: - * 1.) These values were only right when membank started from pfn 0. - * 2.) Use set_page_map to set page map below instead of manually. - */ - pg_spfn = __pfn(membank[0].free); - pg_epfn = pg_spfn + pg_npages; - - /* Use free pages from the bank as the space for struct page array */ - membank[0].page_array = l4_map_helper((void *)membank[0].free, - pg_npages); - /* Update free memory left */ - membank[0].free += pg_npages * PAGE_SIZE; - - /* Update page bitmap for the pages used for the page array */ - for (int i = pg_spfn; i < pg_epfn; i++) - pmap->map[BITWISE_GETWORD(i)] |= BITWISE_GETBIT(i); - - /* Initialise the page array */ - for (int i = 0; i < npages; i++) { - link_init(&membank[0].page_array[i].list); - - /* Set use counts for pages the kernel has already used up */ - if (!(pmap->map[BITWISE_GETWORD(i)] & BITWISE_GETBIT(i))) - membank[0].page_array[i].refcnt = -1; - else /* Last page used +1 is free */ - ffree_addr = (i + 1) * PAGE_SIZE; - } - - /* First free address must come up the same for both */ - BUG_ON(ffree_addr != membank[0].free); - - /* Set global page array to this bank's array */ - page_array = membank[0].page_array; - - /* Test that page/phys macros work */ - BUG_ON(phys_to_page(page_to_phys(&page_array[5])) != &page_array[5]) -} - - -/* Fills in the physmem structure with free physical memory information */ -void init_physmem_primary(struct initdata *initdata) -{ - unsigned long pfn_start, pfn_end, pfn_images_end = 0; - struct bootdesc *bootdesc = initdata->bootdesc; - - /* Allocate page map structure */ - initdata->page_map = alloc_bootmem(sizeof(struct page_bitmap) + - ((initdata->physmem->end - - initdata->physmem->start) - >> 5) + 1, 0); - - /* Initialise page map from physmem capability */ - init_page_map(initdata->page_map, - initdata->physmem->start, - initdata->physmem->end); - - /* Mark pager and other boot task areas as used */ - for (int i = 0; i < bootdesc->total_images; i++) { - pfn_start = - __pfn(page_align_up(bootdesc->images[i].phys_start)); - pfn_end = __pfn(page_align_up(bootdesc->images[i].phys_end)); - if (pfn_end > pfn_images_end) - pfn_images_end = pfn_end; - set_page_map(initdata->page_map, pfn_start, - pfn_end - pfn_start, 1); - } - - physmem.start = initdata->physmem->start; - physmem.end = initdata->physmem->end; - - physmem.free_cur = pfn_images_end; - physmem.free_end = physmem.end; - physmem.numpages = __pfn(physmem.end - physmem.start); -} diff --git a/conts/posix/rootfs/SConscript b/conts/posix/rootfs/SConscript new file mode 100644 index 0000000..fb03ba8 --- /dev/null +++ b/conts/posix/rootfs/SConscript @@ -0,0 +1,46 @@ +# -*- mode: python; coding: utf-8; -*- + +# Codezero -- a microkernel for embedded systems. +# +# Copyright © 2009 B Labs Ltd + +import os.path +import sys, subprocess, shutil +from os.path import * + +Import('config', 'environment', 'previmage') + +e = environment.Clone() + +sys.path.append('../../../') + +from config.projpaths import * +from config.configuration import * +from tools.pyelf.lmanext import * + +rootfs_lds_in = \ +''' +/* + * Linker script that embeds an empty root filesystem. + * This is to be replaced by a real rootfs image later. + */ +SECTIONS +{ + . = %s; + .bss : { *(.bss) } +} +''' + +def generate_rootfs_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)) + +rootfs_lds = e.Command('rootfs.lds', [previmage, 'rootfs.lds.in'], generate_rootfs_lds) + +e.Append(LINKFLAGS = '-T' + rootfs_lds[0].path) +rootfs_img = e.Program('rootfs.elf', 'rootfs.c') +Depends(rootfs_img, rootfs_lds) + +Return('rootfs_img') diff --git a/conts/posix/rootfs/rootfs.c b/conts/posix/rootfs/rootfs.c new file mode 100644 index 0000000..45c1c26 --- /dev/null +++ b/conts/posix/rootfs/rootfs.c @@ -0,0 +1,2 @@ + +SECTION(".bss") char empty_image[SZ_4MB]; diff --git a/conts/posix/rootfs/rootfs.lds.in b/conts/posix/rootfs/rootfs.lds.in new file mode 100644 index 0000000..3e41fe5 --- /dev/null +++ b/conts/posix/rootfs/rootfs.lds.in @@ -0,0 +1,9 @@ +/* + * Linker script that embeds an empty root filesystem. + * This is to be replaced by a real rootfs image later. + */ +SECTIONS +{ + . = %s; + .bss : { *(.bss) } +} diff --git a/loader/main.c b/loader/main.c index da0a296..c1eb0e4 100644 --- a/loader/main.c +++ b/loader/main.c @@ -118,7 +118,7 @@ int main(void) load_container_images((unsigned long)_start_containers, (unsigned long)_end_containers); - printf("elf-loader:\tkernel entry point is %lx\n", *kernel_entry); + printf("elf-loader:\tkernel entry point is 0x%lx\n", *kernel_entry); arch_start_kernel(kernel_entry); printf("elf-loader:\tKernel start failed! Looping endless.\n");