diff --git a/README b/README index 58c9abe..c846443 100644 --- a/README +++ b/README @@ -86,38 +86,55 @@ directories for their respective licenses. Why yet another POSIX microkernel? There are many open source POSIX operating systems with advanced features such -as *BSD and Linux. However these were originally not designed for embedded -systems. Unix itself and all the tools built upon weren't meant for using on -small devices. Accordingly, these operating systems contain a lot of historical -code. Linux is well established, and targets a broad range of platforms and -uses, but consequently embedded platforms don't always get enough emphasis. Also -such well established, mature systems tend to oppose major design overhauls, -which limits innovation to a certain extent. In addition, their code base is so -big, that it gets more and more difficult to understand how their internals -work. Usually much of the code is irrelevant to the problem, in case of embedded -systems. Codezero is written from scratch to solely target embedded systems and +as BSD versions and Linux. However, neither of these were originally designed +for embedded systems. Multiple problems arise due to this fact. + +These systems are well established. They target a broad range of platforms and +uses, but consequently their user base has saturated, and embedded platforms +don't get enough emphasis. + +Unix itself and all the tools built upon weren't meant for using on small +devices. Accordingly, these operating systems contain a lot of historical code. +Their code base is so big, that it gets more and more difficult to understand +how their internals work. On these systems usually much of the code is +irrelevant to a new problem, and embedded systems tend to raise new problems +often. Codezero is written from scratch to solely target embedded systems and as such the source code is %100 relevant. It is small and free from legacy code. -Finally monolithic kernels may have issues with dependability due to much of the -code sharing the same address space. Being a microkernel design, Codezero aims -to defeat this problem and increase dependability. -Other than these modern kernels, there is systems software targeting embedded -devices. Most of them are proprietary, with their own users. Some of the open -source ones are structurally too simplistic, and lack modern features such as -paging. There are existing embedded OS'es that are well-designed, but Codezero -provides alternative that will follow the open source development principles -more closely. This will prove useful because many embedded systems still use -older development methods and the right open source methodology would prove -favorable in the fast-paced nature of development. - -Finally, there are new ideas in OS literature that would improve Unix but aren't -implemented either because they have no existing users or may break compatibility -somewhat (e.g. some are presented in Plan 9). As well as practising realistic -development methodologies, Codezero project aims to keep up with the latest OS -literature and provide the opportunity to incorporate the latest ideas in OS -technology. +From a design perspective, due to these kernels having a monolithic design, they +may have issues with dependability due to much of the code sharing the same +address space. This is an important issue on embedded systems since their +operation is more sensitive to disruptions. Being a microkernel design, Codezero +aims to defeat this problem and increase dependability. +Other than these modern kernels, there are existing operating systems targeting +embedded devices. Most of them are proprietary, with their own users. Some of +them are structurally too simplistic, and lack modern features such as paging. +There ones that are well established, but Codezero will contrast them by +providing an alternative that will follow the open source development principles +more closely. Many embedded systems still use older development methods and the +right open source methodology would prove favorable in the fast-paced nature of +development. + +Finally, there are new ideas in literature that would improve systems software +but aren't implemented either because they have no existing users or may break +compatibility (e.g. some are presented in Plan 9). Existing kernels tend to +oppose major design overhauls, which limits their innovation capability for this +kind of experimentation. As well as practising realistic development methods +Codezero project aims to keep up with the latest OS literature and provide the +opportunity to incorporate the latest ideas in OS technology. +Can you summarise all this? Why should I use Codezero, again? + +Codezero is an operating system that targets embedded systems. It supports the +most fundamental posix system calls. Different from other posix-like systems, +it is based on a microkernel design. It supports modern features such as +demand-paging, virtual filesystem support. It has a cleanly separated set of +services, and it is small. Therefore it is a good candidate as systems software +to be used on embedded systems. Currently it has little or no users, and yet it +is about to become usable, therefore compared to systems with a saturated user +base it is possible to tailor it rapidly towards the needs of any users who want +to be the first to use it. diff --git a/libs/c/include/stdio.h b/libs/c/include/stdio.h index 3414333..1bf4ff1 100644 --- a/libs/c/include/stdio.h +++ b/libs/c/include/stdio.h @@ -161,7 +161,7 @@ int setvbuf(FILE *, char *, int, size_t); /* 7.19.6 Format i/o functions */ int fprintf(FILE *, const char *, ...); int fscanf(FILE *, const char *, ...); -int printf(const char *, ...); +int printf(const char *format, ...); __attribute__((format (printf, 1, 2))); int scanf(const char *, ...); int snprintf(char *, size_t , const char *, ...); int sprintf(char *, const char *, ...); diff --git a/src/arch/arm/exception.c b/src/arch/arm/exception.c index 76db52e..1e6cd72 100644 --- a/src/arch/arm/exception.c +++ b/src/arch/arm/exception.c @@ -96,7 +96,7 @@ int check_aborts(u32 faulted_pc, u32 fsr, u32 far) int ret = 0; if (is_prefetch_abort(fsr)) { - dprintk("Prefetch abort @ ", faulted_pc); + dbg_abort("Prefetch abort @ ", faulted_pc); return 0; } diff --git a/tasks/mm0/include/task.h b/tasks/mm0/include/task.h index b8e9ddc..6474ac6 100644 --- a/tasks/mm0/include/task.h +++ b/tasks/mm0/include/task.h @@ -13,6 +13,7 @@ #include #include #include +#include #define __TASKNAME__ __PAGERNAME__ diff --git a/tasks/mm0/src/arch-arm/mm.c b/tasks/mm0/src/arch-arm/mm.c index 444bb22..c0f75ad 100644 --- a/tasks/mm0/src/arch-arm/mm.c +++ b/tasks/mm0/src/arch-arm/mm.c @@ -2,6 +2,7 @@ * Copyright (C) 2007 Bahadir Balban */ #include +#include /* Extracts generic protection flags from architecture-specific pte */ unsigned int vm_prot_flags(pte_t pte) @@ -51,11 +52,9 @@ void set_generic_fault_params(struct fault_data *fault) else BUG(); } - /* printf("%s: Handling %s fault (%s abort) from %d. fault @ 0x%x\n", __TASKNAME__, (fault->reason & VM_READ) ? "read" : "write", is_prefetch_abort(fault->kdata->fsr) ? "prefetch" : "data", fault->task->tid, fault->address); - */ } diff --git a/tasks/mm0/src/fault.c b/tasks/mm0/src/fault.c index b17c827..7e38a99 100644 --- a/tasks/mm0/src/fault.c +++ b/tasks/mm0/src/fault.c @@ -271,10 +271,10 @@ int copy_on_write(struct fault_data *fault) * when there are shadows one is created because a fork had just * happened, in which case all shadows are rendered read-only. */ - if (!(vmo->flags & VM_WRITE)) { + if (!(vmo_link->obj->flags & VM_WRITE)) { if (!(shadow_link = vma_create_shadow())) return -ENOMEM; - + printf("%s: Created a shadow.\n", __TASKNAME__); /* Initialise the shadow */ shadow = shadow_link->obj; shadow->refcnt = 1; @@ -328,7 +328,7 @@ int copy_on_write(struct fault_data *fault) /* Update page details */ spin_lock(&new_page->lock); - new_page->refcnt = 1; + new_page->refcnt = 0; new_page->owner = copier_link->obj; new_page->offset = file_offset; new_page->virtual = 0; @@ -343,6 +343,8 @@ int copy_on_write(struct fault_data *fault) (void *)page_align(fault->address), 1, (reason & VM_READ) ? MAP_USR_RO_FLAGS : MAP_USR_RW_FLAGS, fault->task->tid); + printf("%s: Mapped 0x%x as writable to tid %d.\n", __TASKNAME__, + page_align(fault->address), fault->task->tid); /* * Finished handling the actual fault, now check for possible @@ -403,11 +405,14 @@ int __do_page_fault(struct fault_data *fault) __TASKNAME__); BUG(); } + /* Map it to faulty task */ l4_map((void *)page_to_phys(page), (void *)page_align(fault->address), 1, (reason & VM_READ) ? MAP_USR_RO_FLAGS : MAP_USR_RW_FLAGS, fault->task->tid); + printf("%s: Mapped 0x%x as readable to tid %d.\n", __TASKNAME__, + page_align(fault->address), fault->task->tid); } /* Handle write */ @@ -435,6 +440,8 @@ int __do_page_fault(struct fault_data *fault) (void *)page_align(fault->address), 1, (reason & VM_READ) ? MAP_USR_RO_FLAGS : MAP_USR_RW_FLAGS, fault->task->tid); + printf("%s: Mapped 0x%x as writable to tid %d.\n", __TASKNAME__, + page_align(fault->address), fault->task->tid); } /* FIXME: Just do fs files for now, anon shm objects later. */ BUG_ON((vma_flags & VMA_SHARED) && (vma_flags & VMA_ANONYMOUS)); diff --git a/tasks/mm0/src/mmap.c b/tasks/mm0/src/mmap.c index 07e2362..1c00a1f 100644 --- a/tasks/mm0/src/mmap.c +++ b/tasks/mm0/src/mmap.c @@ -546,6 +546,7 @@ int do_mmap(struct vm_file *mapfile, unsigned long file_offset, return -ENOMEM; } vmo_link->obj = &mapfile->vm_obj; + mapfile->vm_obj.refcnt++; list_add_tail(&vmo_link->list, &new->vm_obj_list); /* Finished initialising the vma, add it to task */ diff --git a/tasks/mm0/src/pagers.c b/tasks/mm0/src/pagers.c index 931f87c..778ec11 100644 --- a/tasks/mm0/src/pagers.c +++ b/tasks/mm0/src/pagers.c @@ -181,21 +181,33 @@ struct page *bootfile_page_in(struct vm_object *vm_obj, { struct vm_file *boot_file = vm_object_to_file(vm_obj); struct svc_image *img = boot_file->priv_data; - struct page *page = phys_to_page(img->phys_start + - __pfn_to_addr(offset)); + struct page *page; - /* TODO: Check file length against page offset! */ + /* Check first if the file has such a page at all */ + if (__pfn(page_align_up(boot_file->length) <= offset)) { + printf("%s: %s: Trying to look up page %d, but file length " + "is %d bytes.\n", __TASKNAME__, __FUNCTION__, + offset, boot_file->length); + BUG(); + } - /* Update page */ - page_init(page); - page->refcnt++; + /* The page is not resident in page cache. */ + if (!(page = find_page(vm_obj, offset))) { + page = phys_to_page(img->phys_start + __pfn_to_addr(offset)); - /* Update object */ - vm_obj->npages++; + /* Update page */ + page_init(page); + page->refcnt++; + page->owner = vm_obj; + page->offset = offset; - /* Add the page to owner's list of in-memory pages */ - BUG_ON(!list_empty(&page->list)); - insert_page_olist(page, vm_obj); + /* Update object */ + vm_obj->npages++; + + /* Add the page to owner's list of in-memory pages */ + BUG_ON(!list_empty(&page->list)); + insert_page_olist(page, vm_obj); + } return page; }