mirror of
https://github.com/drasko/codezero.git
synced 2026-01-12 02:43:15 +01:00
Various minor fixes.
Removed some commented out code. Removed excessive printfs. Fixed spid not initialising for mm0 Fixed some faults with fs0. TODO: - Need to store vfs files in a separate list. - Need to define vnum as a vfs-file-specific data, i.e. in priv_data field of vm_file. - Need to then fix vfs_receive_sys_open.
This commit is contained in:
4
README
4
README
@@ -133,8 +133,8 @@ Codezero is an operating system that targets embedded systems. It supports the
|
||||
most fundamental posix calls and modern features such as demand-paging and has a
|
||||
virtual filesystem layer. Different from other posix-like systems, it is based
|
||||
on a microkernel design. It has a cleanly separated set of services, it is small
|
||||
and well-focused. Its design is carefully thought out, so it's not just a
|
||||
mock-up implementation of an operating system API. Its source code is also
|
||||
and well-focused. It's design is carefully thought out, so it's not just a
|
||||
mock-up implementation of an operating system API. It's source code is also
|
||||
freely available. For these reasons it is a good candidate as systems software
|
||||
to be used on embedded platforms. Currently it has little or no users, therefore
|
||||
compared to systems with a saturated user base it is possible to tailor it
|
||||
|
||||
@@ -23,19 +23,19 @@ int __sys_kread(int rd, void *dest)
|
||||
|
||||
switch(rd) {
|
||||
case KDATA_PAGE_MAP:
|
||||
printk("Handling KDATA_PAGE_MAP request.\n");
|
||||
// printk("Handling KDATA_PAGE_MAP request.\n");
|
||||
if (check_access(vaddr, sizeof(page_map), MAP_USR_RW_FLAGS) < 0)
|
||||
return -EINVAL;
|
||||
memcpy(dest, &page_map, sizeof(page_map));
|
||||
break;
|
||||
case KDATA_BOOTDESC:
|
||||
printk("Handling KDATA_BOOTDESC request.\n");
|
||||
// printk("Handling KDATA_BOOTDESC request.\n");
|
||||
if (check_access(vaddr, bootdesc->desc_size, MAP_USR_RW_FLAGS) < 0)
|
||||
return -EINVAL;
|
||||
memcpy(dest, bootdesc, bootdesc->desc_size);
|
||||
break;
|
||||
case KDATA_BOOTDESC_SIZE:
|
||||
printk("Handling KDATA_BOOTDESC_SIZE request.\n");
|
||||
// printk("Handling KDATA_BOOTDESC_SIZE request.\n");
|
||||
if (check_access(vaddr, sizeof(unsigned int), MAP_USR_RW_FLAGS) < 0)
|
||||
return -EINVAL;
|
||||
*(unsigned int *)dest = bootdesc->desc_size;
|
||||
|
||||
@@ -49,75 +49,6 @@ int sys_schedule(struct syscall_args *regs)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* THIS CODE IS TO BE USED WHEN MODIFYING PAGE TABLES FOR SHARED MEMORY!!!
|
||||
*/
|
||||
int do_shm_setup(struct shm_kdata *kdata)
|
||||
{
|
||||
struct ktcb *sender, *receiver;
|
||||
unsigned long sndphys, sndvirt, rcvvirt;
|
||||
|
||||
if (!(sender = find_task(kdata->sender)))
|
||||
return -1;
|
||||
if (!(receiver = find_task(kdata->receiver)))
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* There's no guarantee that shared pages are contiguous in physical,
|
||||
* therefore every virtual page in the sharer shall be converted for
|
||||
* its physical address, and each of those addresses are mapped.
|
||||
*/
|
||||
for (int i = 0; i < kdata->npages; i++) {
|
||||
/* The sender virtual address for each shared page */
|
||||
sndvirt = __pfn_to_addr(kdata->send_pfn) + (i * PAGE_SIZE);
|
||||
|
||||
/* The corresponding receiver virtual address */
|
||||
rcvvirt = __pfn_to_addr(kdata->recv_pfn) + (i * PAGE_SIZE);
|
||||
|
||||
/* Converted to physical, through the sharer's page table. */
|
||||
sndphys = __pte_to_addr(virt_to_pte_from_pgd(sndvirt,
|
||||
sender->pgd));
|
||||
/*
|
||||
* Mapped to virtual in the sharee's address space. Note this
|
||||
* is mapped as uncached, in order to avoid cache aliasing
|
||||
* issues in ARM v5, which is VIVT. A possible optimisation for
|
||||
* the future is to make it cached and restrict the shm
|
||||
* address range.
|
||||
*/
|
||||
add_mapping_pgd(sndphys, rcvvirt, PAGE_SIZE, MAP_SVC_IO_FLAGS,
|
||||
receiver->pgd);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Modifies an address space */
|
||||
int sys_space_control(struct syscall_args *regs)
|
||||
{
|
||||
unsigned int operation = regs->r0;
|
||||
int err = 0;
|
||||
|
||||
if (current->tid != PAGER_TID) {
|
||||
printk("%s: Priveledged call, only task id %d can call it. (Current id: %d)\n",
|
||||
__FUNCTION__, current->tid, PAGER_TID);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
switch (operation) {
|
||||
case SPCCTRL_SHM:
|
||||
/* FIXME: Add an access check for user space structure */
|
||||
if ((err = do_shm_setup((struct shm_kdata *)®s->r1) < 0))
|
||||
printk("%s: Error setting up the shm area.\n", __FUNCTION__);
|
||||
break;
|
||||
default:
|
||||
printk("%s: Unsupported operation: %d\n", __FUNCTION__, operation);
|
||||
err = -ENOSYS;
|
||||
}
|
||||
printk("%s called. Tid (%d)\n", __FUNCTION__, current->tid);
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
int sys_space_control(struct syscall_args *regs)
|
||||
{
|
||||
return -ENOSYS;
|
||||
|
||||
@@ -65,8 +65,10 @@ void handle_fs_requests(void)
|
||||
|
||||
/* Read mrs not used by syslib */
|
||||
for (int i = 0; i < MR_UNUSED_TOTAL; i++)
|
||||
mr[i] = read_mr(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_WAIT:
|
||||
printf("%s: Synced with waiting thread.\n", __TASKNAME__);
|
||||
|
||||
@@ -91,7 +91,7 @@ int sys_open(l4id_t sender, const char *pathname, int flags, unsigned int mode)
|
||||
|
||||
/* Get the vnode */
|
||||
if (IS_ERR(v = vfs_lookup_bypath(task, pathbuf))) {
|
||||
if (!flags & O_CREAT) {
|
||||
if (!(flags & O_CREAT)) {
|
||||
return (int)v;
|
||||
} else {
|
||||
if ((err = vfs_create(task, pathname, mode)) < 0)
|
||||
@@ -100,7 +100,7 @@ int sys_open(l4id_t sender, const char *pathname, int flags, unsigned int mode)
|
||||
}
|
||||
|
||||
/* Get a new fd */
|
||||
BUG_ON(!(fd = id_new(task->fdpool)));
|
||||
BUG_ON((fd = id_new(task->fdpool)) < 0);
|
||||
|
||||
/* Assign the new fd with the vnode's number */
|
||||
task->fd[fd] = v->vnum;
|
||||
|
||||
@@ -115,6 +115,7 @@ struct tcb *create_tcb(void)
|
||||
if (!(t = kmalloc(sizeof(*t))))
|
||||
return PTR_ERR(-ENOMEM);
|
||||
|
||||
t->fdpool = id_pool_new_init(TASK_OFILES_MAX);
|
||||
INIT_LIST_HEAD(&t->list);
|
||||
list_add_tail(&t->list, &tcb_head.list);
|
||||
tcb_head.total++;
|
||||
|
||||
@@ -90,8 +90,8 @@ int utcb_init(void)
|
||||
|
||||
/* Obtain our utcb page address */
|
||||
utcb_page = l4_utcb_page();
|
||||
printf("%s: UTCB Read from mm0 as: 0x%x\n", __FUNCTION__,
|
||||
(unsigned long)utcb_page);
|
||||
//printf("%s: UTCB Read from mm0 as: 0x%x\n", __FUNCTION__,
|
||||
// (unsigned long)utcb_page);
|
||||
|
||||
/* Use it as a key to create a shared memory region */
|
||||
BUG_ON((shmid = shmget((key_t)utcb_page,
|
||||
|
||||
@@ -35,6 +35,7 @@ static inline int l4_open(const char *pathname, int flags, mode_t mode)
|
||||
|
||||
// write_mr(L4SYS_ARG0, (unsigned long)pathname);
|
||||
copy_to_utcb((void *)pathname, strlen(pathname));
|
||||
write_mr(L4SYS_ARG0, (unsigned long)utcb_page);
|
||||
write_mr(L4SYS_ARG1, flags);
|
||||
write_mr(L4SYS_ARG2, (u32)mode);
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include <arch/mm.h>
|
||||
#include <lib/spinlock.h>
|
||||
|
||||
#define DEBUG_FAULT_HANDLING
|
||||
// #define DEBUG_FAULT_HANDLING
|
||||
#ifdef DEBUG_FAULT_HANDLING
|
||||
#define dprintf(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
|
||||
@@ -22,32 +22,32 @@ void init_mm(struct initdata *initdata)
|
||||
{
|
||||
/* Initialise the page and bank descriptors */
|
||||
init_physmem(initdata, membank);
|
||||
printf("%s: Initialised physmem.\n", __TASKNAME__);
|
||||
// printf("%s: Initialised physmem.\n", __TASKNAME__);
|
||||
|
||||
/* Initialise the page allocator on first bank. */
|
||||
init_page_allocator(membank[0].free, membank[0].end);
|
||||
printf("%s: Initialised page allocator.\n", __TASKNAME__);
|
||||
// printf("%s: Initialised page allocator.\n", __TASKNAME__);
|
||||
|
||||
/* Initialise the pager's memory allocator */
|
||||
kmalloc_init();
|
||||
printf("%s: Initialised kmalloc.\n", __TASKNAME__);
|
||||
// printf("%s: Initialised kmalloc.\n", __TASKNAME__);
|
||||
|
||||
/* Initialise the zero page */
|
||||
init_devzero();
|
||||
printf("%s: Initialised devzero.\n", __TASKNAME__);
|
||||
// printf("%s: Initialised devzero.\n", __TASKNAME__);
|
||||
|
||||
/* Initialise in-memory boot files */
|
||||
init_boot_files(initdata);
|
||||
printf("%s: Initialised in-memory boot files.\n", __TASKNAME__);
|
||||
// printf("%s: Initialised in-memory boot files.\n", __TASKNAME__);
|
||||
|
||||
shm_init();
|
||||
printf("%s: Initialised shm structures.\n", __TASKNAME__);
|
||||
// printf("%s: Initialised shm structures.\n", __TASKNAME__);
|
||||
|
||||
if (utcb_pool_init() < 0) {
|
||||
printf("UTCB initialisation failed.\n");
|
||||
BUG();
|
||||
}
|
||||
printf("%s: Initialised utcb address pool.\n", __TASKNAME__);
|
||||
// printf("%s: Initialised utcb address pool.\n", __TASKNAME__);
|
||||
|
||||
/* Give the kernel some memory to use for its allocators */
|
||||
l4_kmem_grant(__pfn(alloc_page(__pfn(SZ_1MB))), __pfn(SZ_1MB));
|
||||
|
||||
@@ -564,8 +564,8 @@ int do_mmap(struct vm_file *mapfile, unsigned long file_offset,
|
||||
}
|
||||
|
||||
/* Finished initialising the vma, add it to task */
|
||||
printf("%s: Mapping 0x%x - 0x%x\n", __FUNCTION__,
|
||||
map_address, map_address + npages * PAGE_SIZE);
|
||||
dprintf("%s: Mapping 0x%x - 0x%x\n", __FUNCTION__,
|
||||
map_address, map_address + npages * PAGE_SIZE);
|
||||
list_add(&new->list, &task->vm_area_list);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -34,6 +34,15 @@ struct tcb_head {
|
||||
int total; /* Total threads */
|
||||
} tcb_head;
|
||||
|
||||
void print_tasks(void)
|
||||
{
|
||||
struct tcb *task;
|
||||
printf("Tasks:\n========\n");
|
||||
list_for_each_entry(task, &tcb_head.list, list) {
|
||||
printf("Task tid: %d, spid: %d\n", task->tid, task->spid);
|
||||
}
|
||||
}
|
||||
|
||||
struct tcb *find_task(int tid)
|
||||
{
|
||||
struct tcb *t;
|
||||
@@ -73,14 +82,12 @@ struct tcb *task_create(struct task_ids *ids)
|
||||
int err;
|
||||
|
||||
/* Create the thread structures and address space */
|
||||
printf("Creating new thread with ids: %d, %d.\n", ids->tid, ids->spid);
|
||||
if ((err = l4_thread_control(THREAD_CREATE, ids)) < 0) {
|
||||
printf("l4_thread_control failed with %d.\n", err);
|
||||
return PTR_ERR(err);
|
||||
}
|
||||
|
||||
/* Create a task and use given space and thread ids. */
|
||||
printf("New task with id: %d, space id: %d\n", ids->tid, ids->spid);
|
||||
if (IS_ERR(task = tcb_alloc_init()))
|
||||
return PTR_ERR(task);
|
||||
|
||||
@@ -195,7 +202,7 @@ int task_start(struct tcb *task, struct task_ids *ids)
|
||||
int err;
|
||||
|
||||
/* Start the thread */
|
||||
printf("Starting task with id %d\n", task->tid);
|
||||
printf("Starting task with id %d, spid: %d\n", task->tid, task->spid);
|
||||
if ((err = l4_thread_control(THREAD_RUN, ids)) < 0) {
|
||||
printf("l4_thread_control failed with %d\n", err);
|
||||
return err;
|
||||
@@ -409,7 +416,7 @@ struct vm_file *initdata_next_bootfile(struct initdata *initdata)
|
||||
*/
|
||||
int start_boot_tasks(struct initdata *initdata)
|
||||
{
|
||||
struct vm_file *file, *fs0, *mm0, *n;
|
||||
struct vm_file *file = 0, *fs0 = 0, *mm0 = 0, *n;
|
||||
struct svc_image *img;
|
||||
struct task_ids ids;
|
||||
struct list_head files;
|
||||
@@ -438,7 +445,7 @@ int start_boot_tasks(struct initdata *initdata)
|
||||
/* MM0 needs partial initialisation, since its already running. */
|
||||
printf("%s: Initialising mm0 tcb.\n", __TASKNAME__);
|
||||
ids.tid = PAGER_TID;
|
||||
ids.tid = PAGER_TID;
|
||||
ids.spid = PAGER_TID;
|
||||
if (mm0_task_init(mm0, INITTASK_AREA_START, INITTASK_AREA_END, &ids) < 0)
|
||||
BUG();
|
||||
total++;
|
||||
@@ -460,14 +467,6 @@ int start_boot_tasks(struct initdata *initdata)
|
||||
BUG();
|
||||
total++;
|
||||
}
|
||||
{
|
||||
struct tcb *t;
|
||||
printf("Tasks:\n========\n");
|
||||
list_for_each_entry(t, &tcb_head.list, list) {
|
||||
printf("Task tid: %d, spid: %d\n", t->tid, t->spid);
|
||||
BUG_ON(t->tid != t->spid);
|
||||
}
|
||||
}
|
||||
|
||||
if (!total) {
|
||||
printf("%s: Could not start any tasks.\n", __TASKNAME__);
|
||||
|
||||
Reference in New Issue
Block a user