mirror of
https://github.com/drasko/codezero.git
synced 2026-04-06 12:09:05 +02:00
VFS updates, readme updates.
Separated vfs file as a specific file. vm file is not always a vfs file. Updated the README sys_open was not returning back to client, added that. Added comments for future vfs additions.
This commit is contained in:
20
README
20
README
@@ -130,15 +130,15 @@ opportunity to incorporate the latest ideas in OS technology.
|
|||||||
Can you summarise all this? Why should I use Codezero, again?
|
Can you summarise all this? Why should I use Codezero, again?
|
||||||
|
|
||||||
Codezero is an operating system that targets embedded systems. It supports the
|
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
|
most fundamental posix calls and it implements modern features such as
|
||||||
virtual filesystem layer. Different from other posix-like systems, it is based
|
demand-paging and virtual filesystem layer. Different from other posix-like
|
||||||
on a microkernel design. It has a cleanly separated set of services, it is small
|
systems, it is based on a microkernel design. It has a cleanly separated set of
|
||||||
and well-focused. It's design is carefully thought out, so it's not just a
|
services, it is small and well-focused. It's design is carefully thought out, so
|
||||||
mock-up implementation of an operating system API. It's source code is also
|
it's not just a mock-up implementation of an operating system API. It's source
|
||||||
freely available. For these reasons it is a good candidate as systems software
|
code is also freely available (See LICENSE heading). For these reasons it is a
|
||||||
to be used on embedded platforms. Currently it has little or no users, therefore
|
good candidate as systems software to be used on embedded platforms. Currently
|
||||||
compared to systems with a saturated user base it is possible to tailor it
|
it has little or no users, therefore compared to systems with a saturated user
|
||||||
rapidly towards the needs of any users who want to be the first to incorporate
|
base it is possible to tailor it rapidly towards the needs of any users who want
|
||||||
it for their needs.
|
to be the first to incorporate it for their needs.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -11,5 +11,5 @@ extern int errno;
|
|||||||
|
|
||||||
void perror(const char *str)
|
void perror(const char *str)
|
||||||
{
|
{
|
||||||
printf("%s: %d\n", errno);
|
printf("%s: %d\n", str, errno);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,10 +92,13 @@ int sys_open(l4id_t sender, const char *pathname, int flags, unsigned int mode)
|
|||||||
/* Get the vnode */
|
/* Get the vnode */
|
||||||
if (IS_ERR(v = vfs_lookup_bypath(task, pathbuf))) {
|
if (IS_ERR(v = vfs_lookup_bypath(task, pathbuf))) {
|
||||||
if (!(flags & O_CREAT)) {
|
if (!(flags & O_CREAT)) {
|
||||||
return (int)v;
|
l4_ipc_return((int)v);
|
||||||
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
if ((err = vfs_create(task, pathname, mode)) < 0)
|
if ((err = vfs_create(task, pathname, mode)) < 0) {
|
||||||
return err;
|
l4_ipc_return(err);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,6 +111,7 @@ int sys_open(l4id_t sender, const char *pathname, int flags, unsigned int mode)
|
|||||||
/* Tell the pager about opened vnode information */
|
/* Tell the pager about opened vnode information */
|
||||||
BUG_ON(pager_sys_open(sender, fd, v->vnum, v->size) < 0);
|
BUG_ON(pager_sys_open(sender, fd, v->vnum, v->size) < 0);
|
||||||
|
|
||||||
|
l4_ipc_return(0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,6 +206,26 @@ int pager_sys_write(l4id_t sender, unsigned long vnum, unsigned long f_offset,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 ..
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reads @count bytes of posix struct dirents into @buf. This implements
|
* Reads @count bytes of posix struct dirents into @buf. This implements
|
||||||
* the raw dirent read syscall upon which readdir() etc. posix calls
|
* the raw dirent read syscall upon which readdir() etc. posix calls
|
||||||
@@ -219,19 +243,25 @@ int sys_readdir(l4id_t sender, int fd, void *buf, int count)
|
|||||||
BUG_ON(!(t = find_task(sender)));
|
BUG_ON(!(t = find_task(sender)));
|
||||||
|
|
||||||
/* Convert fd to vnum. */
|
/* Convert fd to vnum. */
|
||||||
BUG_ON(!(vnum = t->fd[fd]));
|
BUG_ON((vnum = t->fd[fd]) < 0);
|
||||||
|
|
||||||
/* Lookup vnode */
|
/* Lookup vnode */
|
||||||
if (!(v = vfs_lookup_byvnum(vfs_root.pivot->sb, vnum)))
|
if (!(v = vfs_lookup_byvnum(vfs_root.pivot->sb, vnum))) {
|
||||||
return -EINVAL; /* No such vnode */
|
l4_ipc_return(-EINVAL);
|
||||||
|
return 0; /* No such vnode */
|
||||||
|
}
|
||||||
|
|
||||||
/* Ensure vnode is a directory */
|
/* Ensure vnode is a directory */
|
||||||
if (!vfs_isdir(v))
|
if (!vfs_isdir(v)) {
|
||||||
return -ENOTDIR;
|
l4_ipc_return(-ENOTDIR);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Read the whole content from fs, if haven't done so yet */
|
/* Read the whole content from fs, if haven't done so yet */
|
||||||
if ((err = v->ops.readdir(v)) < 0)
|
if ((err = v->ops.readdir(v)) < 0) {
|
||||||
return err;
|
l4_ipc_return(err);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Bytes to read, minimum of vnode size and count requested */
|
/* Bytes to read, minimum of vnode size and count requested */
|
||||||
nbytes = (v->size <= count) ? v->size : count;
|
nbytes = (v->size <= count) ? v->size : count;
|
||||||
@@ -239,7 +269,7 @@ int sys_readdir(l4id_t sender, int fd, void *buf, int count)
|
|||||||
/* Do we have those bytes at hand? */
|
/* Do we have those bytes at hand? */
|
||||||
if (v->dirbuf.buffer && (v->dirbuf.npages * PAGE_SIZE) >= nbytes) {
|
if (v->dirbuf.buffer && (v->dirbuf.npages * PAGE_SIZE) >= nbytes) {
|
||||||
memcpy(buf, v->dirbuf.buffer, nbytes);
|
memcpy(buf, v->dirbuf.buffer, nbytes);
|
||||||
return nbytes;
|
l4_ipc_return(nbytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -141,8 +141,8 @@ int task_utcb_attach(struct tcb *t)
|
|||||||
if ((unsigned long)shmaddr != t->utcb_address)
|
if ((unsigned long)shmaddr != t->utcb_address)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
printf("%s: Mapped utcb of task %d @ 0x%x\n",
|
//printf("%s: Mapped utcb of task %d @ 0x%x\n",
|
||||||
__TASKNAME__, t->tid, shmaddr);
|
// __TASKNAME__, t->tid, shmaddr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -170,9 +170,9 @@ int init_task_structs(struct task_data_head *tdata_head)
|
|||||||
t->curdir = vfs_root.pivot;
|
t->curdir = vfs_root.pivot;
|
||||||
|
|
||||||
/* Print task information */
|
/* Print task information */
|
||||||
printf("%s: Task info received from mm0:\n", __TASKNAME__);
|
//printf("%s: Task info received from mm0:\n", __TASKNAME__);
|
||||||
printf("%s: task id: %d, utcb address: 0x%x\n",
|
//printf("%s: task id: %d, utcb address: 0x%x\n",
|
||||||
__TASKNAME__, t->tid, t->utcb_address);
|
// __TASKNAME__, t->tid, t->utcb_address);
|
||||||
|
|
||||||
/* shm attach to the utcbs for all these tasks except own */
|
/* shm attach to the utcbs for all these tasks except own */
|
||||||
if (t->tid != self_tid())
|
if (t->tid != self_tid())
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#define __MM0_FILE_H__
|
#define __MM0_FILE_H__
|
||||||
|
|
||||||
#include <l4/lib/list.h>
|
#include <l4/lib/list.h>
|
||||||
|
#include <l4lib/types.h>
|
||||||
#include <posix/sys/types.h>
|
#include <posix/sys/types.h>
|
||||||
|
|
||||||
void vmfile_init(void);
|
void vmfile_init(void);
|
||||||
@@ -17,6 +18,15 @@ int sys_read(l4id_t sender, int fd, void *buf, int count);
|
|||||||
int sys_write(l4id_t sender, int fd, void *buf, int count);
|
int sys_write(l4id_t sender, int fd, void *buf, int count);
|
||||||
int sys_lseek(l4id_t sender, int fd, off_t offset, int whence);
|
int sys_lseek(l4id_t sender, int fd, off_t offset, int whence);
|
||||||
|
|
||||||
#define vm_file_to_vnum(f) (*(unsigned long *)((f)->priv_data))
|
struct vfs_file_data {
|
||||||
|
unsigned long vnum;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define vm_file_to_vnum(f) \
|
||||||
|
(((struct vfs_file_data *)((f)->priv_data))->vnum)
|
||||||
|
struct vm_file *vfs_file_create(void);
|
||||||
|
|
||||||
|
|
||||||
extern struct list_head vm_file_list;
|
extern struct list_head vm_file_list;
|
||||||
|
|
||||||
#endif /* __MM0_FILE_H__ */
|
#endif /* __MM0_FILE_H__ */
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
/* Defines the type of file. A device file? Regular file? One used at boot? */
|
/* Defines the type of file. A device file? Regular file? One used at boot? */
|
||||||
enum VM_FILE_TYPE {
|
enum VM_FILE_TYPE {
|
||||||
VM_FILE_DEVZERO = 1,
|
VM_FILE_DEVZERO = 1,
|
||||||
VM_FILE_REGULAR,
|
VM_FILE_VFS,
|
||||||
VM_FILE_BOOTFILE,
|
VM_FILE_BOOTFILE,
|
||||||
VM_FILE_SHM,
|
VM_FILE_SHM,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -93,7 +93,9 @@ int vfs_receive_sys_open(l4id_t sender, l4id_t opener, int fd,
|
|||||||
|
|
||||||
/* Check if that vm_file is already in the list */
|
/* Check if that vm_file is already in the list */
|
||||||
list_for_each_entry(vmfile, &vm_file_list, list) {
|
list_for_each_entry(vmfile, &vm_file_list, list) {
|
||||||
if (vm_file_to_vnum(vmfile) == vnum) {
|
/* Check it is a vfs file and if so vnums match. */
|
||||||
|
if ((vmfile->type & VM_FILE_VFS) &&
|
||||||
|
vm_file_to_vnum(vmfile) == vnum) {
|
||||||
/* Add a reference to it from the task */
|
/* Add a reference to it from the task */
|
||||||
t->fd[fd].vmfile = vmfile;
|
t->fd[fd].vmfile = vmfile;
|
||||||
vmfile->vm_obj.refcnt++;
|
vmfile->vm_obj.refcnt++;
|
||||||
@@ -102,7 +104,7 @@ int vfs_receive_sys_open(l4id_t sender, l4id_t opener, int fd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Otherwise allocate a new one for this vnode */
|
/* Otherwise allocate a new one for this vnode */
|
||||||
if (IS_ERR(vmfile = vm_file_create()))
|
if (IS_ERR(vmfile = vfs_file_create()))
|
||||||
return (int)vmfile;
|
return (int)vmfile;
|
||||||
|
|
||||||
/* Initialise and add it to global list */
|
/* Initialise and add it to global list */
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (C) 2008 Bahadir Balban
|
* Copyright (C) 2008 Bahadir Balban
|
||||||
*/
|
*/
|
||||||
|
#include <file.h>
|
||||||
#include <vm_area.h>
|
#include <vm_area.h>
|
||||||
#include <l4/macros.h>
|
#include <l4/macros.h>
|
||||||
#include <l4/api/errno.h>
|
#include <l4/api/errno.h>
|
||||||
@@ -40,7 +41,7 @@ void vm_object_print(struct vm_object *vmo)
|
|||||||
ftype = "bootfile";
|
ftype = "bootfile";
|
||||||
else if (f->type == VM_FILE_SHM)
|
else if (f->type == VM_FILE_SHM)
|
||||||
ftype = "shm file";
|
ftype = "shm file";
|
||||||
else if (f->type == VM_FILE_REGULAR)
|
else if (f->type == VM_FILE_VFS)
|
||||||
ftype = "regular";
|
ftype = "regular";
|
||||||
else
|
else
|
||||||
BUG();
|
BUG();
|
||||||
@@ -91,6 +92,23 @@ struct vm_file *vm_file_create(void)
|
|||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Populates the priv_data with vfs-file-specific
|
||||||
|
* information.
|
||||||
|
*/
|
||||||
|
struct vm_file *vfs_file_create(void)
|
||||||
|
{
|
||||||
|
struct vm_file *f = vm_file_create();
|
||||||
|
|
||||||
|
if (IS_ERR(f))
|
||||||
|
return f;
|
||||||
|
|
||||||
|
f->priv_data = kzalloc(sizeof(struct vfs_file_data));
|
||||||
|
f->type = VM_FILE_VFS;
|
||||||
|
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
/* Deletes the object via its base, along with all its pages */
|
/* Deletes the object via its base, along with all its pages */
|
||||||
int vm_object_delete(struct vm_object *vmo)
|
int vm_object_delete(struct vm_object *vmo)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -113,14 +113,15 @@ int lsdir(char *path)
|
|||||||
perror("OPEN");
|
perror("OPEN");
|
||||||
return 0;
|
return 0;
|
||||||
} else
|
} else
|
||||||
// printf("OPEN OK.\n");
|
printf("OPEN OK.\n");
|
||||||
|
|
||||||
if ((bytes = os_readdir(fd, dents, sizeof(struct dirent) * DENTS_TOTAL)) < 0) {
|
if ((bytes = os_readdir(fd, dents, sizeof(struct dirent) * DENTS_TOTAL)) < 0) {
|
||||||
perror("GETDENTS");
|
perror("GETDENTS");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
} else {
|
||||||
//printf("GETDENTS OK.\n");
|
printf("GETDENTS OK.\n");
|
||||||
print_dirents(path, dents, bytes);
|
print_dirents(path, dents, bytes);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user