From 6b5d4b26c2c31868040a54422dfb04c01c374a49 Mon Sep 17 00:00:00 2001 From: Bahadir Balban Date: Mon, 5 Oct 2009 16:40:51 +0300 Subject: [PATCH] Changes to mm0 initialization. mm0 building. Changed mm0 initialization. Removed all cruft about boot-specific task setup and initialization, mm0 now builds with new changes. --- conts/posix/mm0/include/boot.h | 28 ----- conts/posix/mm0/include/file.h | 2 +- conts/posix/mm0/include/linker.h | 24 ++++ conts/posix/mm0/include/linker.lds.in | 48 +++++--- conts/posix/mm0/include/syscalls.h | 19 ---- conts/posix/mm0/main.c | 1 - conts/posix/mm0/mm/boot.c | 122 -------------------- conts/posix/mm0/mm/bootdesc.c | 7 +- conts/posix/mm0/mm/init.c | 156 +++++++++++++++++++------- conts/posix/mm0/mm/memory.c | 8 +- conts/posix/mm0/mm/task.c | 1 - 11 files changed, 182 insertions(+), 234 deletions(-) delete mode 100644 conts/posix/mm0/include/boot.h create mode 100644 conts/posix/mm0/include/linker.h delete mode 100644 conts/posix/mm0/mm/boot.c diff --git a/conts/posix/mm0/include/boot.h b/conts/posix/mm0/include/boot.h deleted file mode 100644 index 62533f7..0000000 --- a/conts/posix/mm0/include/boot.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef __BOOT_H__ -#define __BOOT_H__ - -#include -#include - -/* Structures to use when sending new task information to vfs */ -struct task_data { - unsigned long tid; - unsigned long shpage_address; -}; - -struct task_data_head { - unsigned long total; - struct task_data tdata[]; -}; - -int boottask_setup_regions(struct vm_file *file, struct tcb *task, - unsigned long task_start, unsigned long task_end); - -int boottask_mmap_regions(struct tcb *task, struct vm_file *file); - -struct tcb *boottask_exec(struct vm_file *f, unsigned long task_region_start, - unsigned long task_region_end, struct task_ids *ids); - -int vfs_send_task_data(struct tcb *vfs); - -#endif /* __BOOT_H__ */ diff --git a/conts/posix/mm0/include/file.h b/conts/posix/mm0/include/file.h index f14565f..8d49d3c 100644 --- a/conts/posix/mm0/include/file.h +++ b/conts/posix/mm0/include/file.h @@ -3,7 +3,7 @@ #include #include -#include +#include /* FIXME: Remove this and refer to internal headers */ #include int vfs_read(unsigned long vnum, unsigned long f_offset, unsigned long npages, diff --git a/conts/posix/mm0/include/linker.h b/conts/posix/mm0/include/linker.h new file mode 100644 index 0000000..91da380 --- /dev/null +++ b/conts/posix/mm0/include/linker.h @@ -0,0 +1,24 @@ +#ifndef __LINKER_H__ +#define __LINKER_H__ + +/* + * Linker script-defined memory markers. + */ + +extern unsigned long __start_text[]; +extern unsigned long __end_text[]; +extern unsigned long __start_data[]; +extern unsigned long __end_data[]; +extern unsigned long __start_rodata[]; +extern unsigned long __end_rodata[]; +extern unsigned long __start_bss[]; +extern unsigned long __end_bss[]; + +extern unsigned long __start_stack[]; +extern unsigned long __stack[]; + +extern unsigned long __start_init[]; +extern unsigned long __end_init[]; +extern unsigned long __end[]; + +#endif /* __LINKER_H__ */ diff --git a/conts/posix/mm0/include/linker.lds.in b/conts/posix/mm0/include/linker.lds.in index 542494b..ca01d83 100644 --- a/conts/posix/mm0/include/linker.lds.in +++ b/conts/posix/mm0/include/linker.lds.in @@ -26,29 +26,49 @@ ENTRY(_start) SECTIONS { . = virtual_base; - _start_text = .; - .text : AT (ADDR(.text) - pager_offset) { *(.text.head) *(.text) } - /* 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) } - .bss : AT (ADDR(.bss) - pager_offset) { *(.bss) } + + __start_text = .; + .text : AT (ADDR(.text) - pager_offset) { + *(.text.head) *(.text) + } + __end_text = .; + + __start_rodata = .; + .rodata : AT (ADDR(.rodata) - pager_offset) { + *(.rodata) + } + .rodata1 : AT (ADDR(.rodata1) - pager_offset) { + *(.rodata1) + } + __end_rodata = .; + + __start_data = .; + .data : AT (ADDR(.data) - pager_offset) { + *(.data) + } + __end_data = .; + + __start_bss = .; + .bss : AT (ADDR(.bss) - pager_offset) { + *(.bss) + } . = ALIGN(4K); + __end_bss = .; . += 0x2000; /* BSS doesnt increment link counter??? */ - .stack : AT (ADDR(.stack) - pager_offset) - { + + __start_stack = .; + .stack : AT (ADDR(.stack) - pager_offset) { *(.stack) } . = ALIGN(4K); __stack = .; /* This is the preallocated boot stack */ /* Below part is to be discarded after boot */ - _start_init = .; - .init : AT (ADDR(.init) - pager_offset) - { + __start_init = .; + .init : AT (ADDR(.init) - pager_offset) { *(.init.data) *(.init.bootmem) } - _end_init = .; - _end = .; + __end_init = .; + __end = .; } diff --git a/conts/posix/mm0/include/syscalls.h b/conts/posix/mm0/include/syscalls.h index 6d8a6aa..32763b1 100644 --- a/conts/posix/mm0/include/syscalls.h +++ b/conts/posix/mm0/include/syscalls.h @@ -42,24 +42,5 @@ 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/main.c b/conts/posix/mm0/main.c index 90f4941..9b11b5d 100644 --- a/conts/posix/mm0/main.c +++ b/conts/posix/mm0/main.c @@ -22,7 +22,6 @@ #include #include #include -#include /* Receives all registers and origies back */ diff --git a/conts/posix/mm0/mm/boot.c b/conts/posix/mm0/mm/boot.c deleted file mode 100644 index 97f079a..0000000 --- a/conts/posix/mm0/mm/boot.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Functions used for running initial tasks during boot. - * - * Copyright (C) 2008 Bahadir Balban - */ -#include -#include -#include -#include -#include -#include - -int boottask_setup_regions(struct vm_file *file, struct tcb *task, - unsigned long task_start, unsigned long task_end) -{ - /* - * Set task's main address space boundaries. Not all tasks - * run in the default user boundaries, e.g. mm0 pager. - */ - task->start = task_start; - task->end = task_end; - - /* Task stack starts right after the environment. */ - task->stack_end = task->end; - task->stack_start = task->stack_end - DEFAULT_STACK_SIZE; - - /* Prepare environment boundaries. */ - task->args_end = task->stack_end; - task->args_start = task->stack_start - DEFAULT_ENV_SIZE; - - /* Currently RO text and RW data are one region. TODO: Fix this */ - task->data_start = task->start; - task->data_end = task->start + page_align_up(file->length); - task->text_start = task->data_start; - task->text_end = task->data_end; - task->entry = task->text_start; - - /* Task's region available for mmap */ - task->map_start = task->data_end; - task->map_end = task->stack_start; - - return 0; -} - -/* - * Used for mmapping boot task regions. These are slightly different - * from a vfs executable file. - */ -int boottask_mmap_regions(struct tcb *task, struct vm_file *file) -{ - void *mapped; - - /* - * mmap each task's physical image to task's address space. - * TODO: Map data and text separately when available from bootdesc. - */ - if (IS_ERR(mapped = do_mmap(file, 0, task, task->text_start, - VM_READ | VM_WRITE | VM_EXEC | VMA_PRIVATE, - __pfn(page_align_up(task->text_end) - - task->text_start)))) { - printf("do_mmap: failed with %d.\n", (int)mapped); - return (int)mapped; - } - - /* mmap each task's stack as anonymous memory. */ - if (IS_ERR(mapped = do_mmap(0, 0, task, task->stack_start, - VM_READ | VM_WRITE | - VMA_PRIVATE | VMA_ANONYMOUS, - __pfn(task->stack_end - - task->stack_start)))) { - printf("do_mmap: Mapping stack failed with %d.\n", - (int)mapped); - return (int)mapped; - } - - task_setup_utcb(task); - - return 0; -} - -/* - * Main entry point for the creation, initialisation and - * execution of a new task. - */ -struct tcb *boottask_exec(struct vm_file *f, unsigned long task_region_start, - unsigned long task_region_end, struct task_ids *ids) -{ - struct tcb *task; - int err; - - if (IS_ERR(task = task_create(0, ids, THREAD_NEW_SPACE, - TCB_NO_SHARING))) - return task; - - if ((err = boottask_setup_regions(f, task, task_region_start, - task_region_end)) < 0) - return PTR_ERR(err); - - if ((err = boottask_mmap_regions(task, f)) < 0) - return PTR_ERR(err); - - if ((err = task_setup_registers(task, 0, 0, 0)) < 0) - return PTR_ERR(err); - - /* Add the task to the global task list */ - global_add_task(task); - - /* Add the file to global vm lists */ - global_add_vm_file(f); - - /* Prefault all its regions */ - if (ids->tid == VFS_TID) - task_prefault_regions(task, f); - - /* Start the task */ - if ((err = task_start(task)) < 0) - return PTR_ERR(err); - - return task; -} - - diff --git a/conts/posix/mm0/mm/bootdesc.c b/conts/posix/mm0/mm/bootdesc.c index e62fc57..41c6451 100644 --- a/conts/posix/mm0/mm/bootdesc.c +++ b/conts/posix/mm0/mm/bootdesc.c @@ -7,9 +7,10 @@ #include #include #include +#include + #include -extern unsigned long _end[]; extern unsigned long pager_offset; struct svc_image *bootdesc_get_image_byname(char *name) @@ -28,7 +29,7 @@ void read_boot_params() /* * End of the executable image is where bootdesc resides */ - bootdesc = (struct bootdesc *)_end; + bootdesc = (struct bootdesc *)__end; /* Check if bootdesc is on an unmapped page */ if (is_page_aligned(bootdesc)) @@ -42,5 +43,5 @@ void read_boot_params() bootdesc->desc_size); if (npages > 0) - l4_unmap_helper((void *)page_align_up(_end), npages); + l4_unmap_helper((void *)page_align_up(__end), npages); } diff --git a/conts/posix/mm0/mm/init.c b/conts/posix/mm0/mm/init.c index e9ea5a8..9a380a8 100644 --- a/conts/posix/mm0/mm/init.c +++ b/conts/posix/mm0/mm/init.c @@ -22,17 +22,17 @@ #include #include #include -#include #include #include #include #include #include #include - - -extern unsigned long _start_init[]; -extern unsigned long _end_init[]; +#include +#include +#include +#include +#include /* Kernel data acquired during initialisation */ __initdata struct initdata initdata; @@ -59,38 +59,92 @@ void print_pfn_range(int pfn, int size) } /* - * 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 - * created, registers aren't assigned, and thread not started, since - * these are all already done by the kernel. But we do need a memory - * environment for mm0, hence this function. + * This sets up the mm0 task struct and memory environment but omits + * bits that are already done such as creating a new thread, setting + * registers. */ -int mm0_task_init(struct vm_file *f, unsigned long task_start, - unsigned long task_end, struct task_ids *ids) +int pager_setup_task(void) { - int err; struct tcb *task; + struct task_ids ids; + void *mapped; /* - * The thread itself is already known by the kernel, so we just - * allocate a local task structure. + * The thread itself is already known by the kernel, + * so we just allocate a local task structure. */ - BUG_ON(IS_ERR(task = tcb_alloc_init(TCB_NO_SHARING))); + if (IS_ERR(task = tcb_alloc_init(TCB_NO_SHARING))) { + printf("FATAL: " + "Could not allocate tcb for pager.\n"); + BUG(); + } - task->tid = ids->tid; - task->spid = ids->spid; - task->tgid = ids->tgid; + /* Set up own ids */ + l4_getid(&ids); + task->tid = ids.tid; + 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; + /* Text markers */ + task->text_start = (unsigned long)__start_text; + task->text_end = (unsigned long)__end_rodata; - if ((err = boottask_mmap_regions(task, f)) < 0) - return err; + /* Data markers */ + task->stack_end = (unsigned long)__stack; + task->stack_start = (unsigned long)__start_stack; + + /* Stack markers */ + task->data_start = (unsigned long)__start_data; + task->data_end = (unsigned long)__end_data; + + /* Task's region available for mmap */ + task->map_start = (unsigned long)__stack; + task->map_end = 0xF0000000; /* FIXME: Fix this */ + + /* + * Map all regions as anonymous + * (since no real file could back) + */ + + /* Map text */ + if (IS_ERR(mapped = + do_mmap(0, 0, task, task->text_start, + VMA_ANONYMOUS | VM_READ | + VM_WRITE | VM_EXEC | VMA_PRIVATE, + __pfn(page_align_up(task->text_end) - + task->text_start)))) { + printf("do_mmap: failed with %d.\n", (int)mapped); + return (int)mapped; + } + + /* Map data */ + if (IS_ERR(mapped = + do_mmap(0, 0, task, task->data_start, + VMA_ANONYMOUS | VM_READ | + VM_WRITE | VM_EXEC | VMA_PRIVATE, + __pfn(page_align_up(task->data_end) - + task->data_start)))) { + printf("do_mmap: failed with %d.\n", (int)mapped); + return (int)mapped; + } + + /* Map stack */ + if (IS_ERR(mapped = + do_mmap(0, 0, task, task->stack_start, + VMA_ANONYMOUS | VM_READ | + VM_WRITE | VMA_PRIVATE, + __pfn(task->stack_end - + task->stack_start)))) { + printf("do_mmap: Mapping stack failed with %d.\n", + (int)mapped); + return (int)mapped; + } + + task_setup_utcb(task); /* Set pager as child and parent of itself */ list_insert(&task->child_ref, &task->children); @@ -110,9 +164,6 @@ int mm0_task_init(struct vm_file *f, unsigned long task_start, /* Add the task to the global task list */ global_add_task(task); - /* Add the file to global vm lists */ - global_add_vm_file(f); - return 0; } @@ -141,9 +192,11 @@ int read_pager_capabilities() 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"); + 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; @@ -152,9 +205,11 @@ int read_pager_capabilities() 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"); + 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; } @@ -172,8 +227,10 @@ int read_pager_capabilities() return 0; } } - printf("%s: Error, pager has no physmem capability defined.\n", - __TASKNAME__); + + printf("%s: Error, pager has no physmem " + "capability defined.\n", __TASKNAME__); + goto error; return 0; @@ -201,8 +258,8 @@ void release_initdata() * it remains as if it is a used block */ - l4_unmap(_start_init, - __pfn(page_align_up(_end_init - _start_init)), + l4_unmap(__start_init, + __pfn(page_align_up(__end_init - __start_init)), self_tid()); } @@ -378,11 +435,28 @@ void init_execve(char *path) */ void copy_init_process(void) { - //int fd = sys_open(find_task(self_tid()), "/test0", O_WRITE, 0) + int fd; + struct svc_image *init_img; + unsigned long img_size; + void *init_img_start, *init_img_end; - //sys_write(find_task(self_tid()), fd, __test0_start, __test0_end - __test0_start); + if ((fd = sys_open(find_task(self_tid()), + "/test0", O_TRUNC | O_RDWR, + 0)) < 0) { + printf("FATAL: Could not open file " + "to write initial task.\n"); + BUG(); + } - //sys_close(find_task(self_tid()), fd); + init_img = bootdesc_get_image_byname("test0"); + img_size = init_img->phys_end - init_img->phys_start; + + init_img_start = l4_map_helper((void *)init_img->phys_start, __pfn(img_size)); + init_img_end = init_img_start + img_size; + + sys_write(find_task(self_tid()), fd, init_img_start, img_size); + + sys_close(find_task(self_tid()), fd); } @@ -412,6 +486,8 @@ void init(void) vfs_init(); + pager_setup_task(); + start_init_process(); release_initdata(); diff --git a/conts/posix/mm0/mm/memory.c b/conts/posix/mm0/mm/memory.c index bd1c0bf..02e4859 100644 --- a/conts/posix/mm0/mm/memory.c +++ b/conts/posix/mm0/mm/memory.c @@ -16,7 +16,7 @@ #include #include #include - +#include struct address_pool pager_vaddr_pool; @@ -40,9 +40,6 @@ static struct pager_virtual_address_id_pool { .bitlimit = ADDRESS_POOL_256MB * 32, }; -/* End of pager image */ -extern unsigned char _end[]; - /* For supplying contiguous virtual addresses to pager */ int pager_address_pool_init(void) { @@ -55,7 +52,8 @@ int pager_address_pool_init(void) address_pool_init_with_idpool(&pager_vaddr_pool, (struct id_pool *) &pager_virtual_address_id_pool, - page_align_up((unsigned long)_end + PAGE_SIZE), + page_align_up((unsigned long)__end + PAGE_SIZE), + /* FIXME: Fix this! Same as mm0's map_start and map_end */ (unsigned long)0xF0000000); return 0; } diff --git a/conts/posix/mm0/mm/task.c b/conts/posix/mm0/mm/task.c index ed08bdc..1fce4e5 100644 --- a/conts/posix/mm0/mm/task.c +++ b/conts/posix/mm0/mm/task.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include