From 05e9028e906ff80ac41734ea5700cf96d8ed718f Mon Sep 17 00:00:00 2001 From: Bahadir Balban Date: Tue, 22 Jan 2008 13:26:19 +0000 Subject: [PATCH] Some more minor changes. --- include/l4/macros.h | 1 + tasks/blkdev0/include/linker.lds | 10 +- tasks/blkdev0/include/ramdisk.h | 2 +- tasks/blkdev0/src/arch | 1 - tasks/blkdev0/src/ramdisk.c | 39 +++++-- tasks/fs0/include/bdev.h | 8 -- tasks/fs0/include/lib/bit.h | 43 +++++++ tasks/fs0/include/lib/idpool.h | 17 +++ tasks/fs0/include/lib/spinlock.h | 17 +++ tasks/fs0/include/lib/vaddr.h | 17 +++ tasks/fs0/include/linker.lds | 9 +- tasks/fs0/src/init.c | 107 +----------------- tasks/fs0/src/lib/bit.c | 98 ++++++++++++++++ tasks/fs0/src/lib/idpool.c | 63 +++++++++++ tasks/fs0/src/lib/vaddr.c | 39 +++++++ tasks/fs0/src/simplefs/inode.c | 31 ----- tasks/fs0/src/simplefs/sfs.c | 17 +++ tasks/fs0/src/simplefs/{sfslayout.h => sfs.h} | 29 ++--- 18 files changed, 375 insertions(+), 173 deletions(-) delete mode 120000 tasks/blkdev0/src/arch delete mode 100644 tasks/fs0/include/bdev.h create mode 100644 tasks/fs0/include/lib/bit.h create mode 100644 tasks/fs0/include/lib/idpool.h create mode 100644 tasks/fs0/include/lib/spinlock.h create mode 100644 tasks/fs0/include/lib/vaddr.h create mode 100644 tasks/fs0/src/lib/bit.c create mode 100644 tasks/fs0/src/lib/idpool.c create mode 100644 tasks/fs0/src/lib/vaddr.c delete mode 100644 tasks/fs0/src/simplefs/inode.c create mode 100644 tasks/fs0/src/simplefs/sfs.c rename tasks/fs0/src/simplefs/{sfslayout.h => sfs.h} (79%) diff --git a/include/l4/macros.h b/include/l4/macros.h index 0943ab1..e578ef9 100644 --- a/include/l4/macros.h +++ b/include/l4/macros.h @@ -52,6 +52,7 @@ #define SZ_16K 0x4000 #define SZ_64K 0x10000 #define SZ_1MB 0x100000 +#define SZ_8MB (8*SZ_1MB) #define SZ_16MB (16*SZ_1MB) #define SZ_1K_BITS 10 #define SZ_4K_BITS 12 diff --git a/tasks/blkdev0/include/linker.lds b/tasks/blkdev0/include/linker.lds index 15c5b3c..c8d5734 100644 --- a/tasks/blkdev0/include/linker.lds +++ b/tasks/blkdev0/include/linker.lds @@ -33,9 +33,13 @@ SECTIONS .data : AT (ADDR(.data) - offset) { . = ALIGN(4K); - _start_ramdisk = .; - *(.data.fs) - _end_ramdisk = .; + _start_ramdisk0 = .; + *(.data.romfs) + _end_ramdisk0 = .; + . = ALIGN(4K); + _start_ramdisk1 = .; + *(.data.sfs) + _end_ramdisk1 = .; *(.data) } .bss : AT (ADDR(.bss) - offset) { *(.bss) } diff --git a/tasks/blkdev0/include/ramdisk.h b/tasks/blkdev0/include/ramdisk.h index 5ccfefa..b41421e 100644 --- a/tasks/blkdev0/include/ramdisk.h +++ b/tasks/blkdev0/include/ramdisk.h @@ -1,6 +1,6 @@ #ifndef __RAMDISK_H__ #define __RAMDISK_H__ -extern struct block_device ramdisk; +extern struct block_device ramdisk[]; #endif diff --git a/tasks/blkdev0/src/arch b/tasks/blkdev0/src/arch deleted file mode 120000 index 85405c2..0000000 --- a/tasks/blkdev0/src/arch +++ /dev/null @@ -1 +0,0 @@ -arch-arm \ No newline at end of file diff --git a/tasks/blkdev0/src/ramdisk.c b/tasks/blkdev0/src/ramdisk.c index b0c420b..aee8aaf 100644 --- a/tasks/blkdev0/src/ramdisk.c +++ b/tasks/blkdev0/src/ramdisk.c @@ -17,9 +17,14 @@ #include INC_GLUE(memory.h) /* Ramdisk section markers for ramdisk inside this executable image */ -extern char _start_ramdisk[]; -extern char _end_ramdisk[]; -static unsigned long ramdisk_base; +extern char _start_ramdisk0[]; +extern char _end_ramdisk0[]; +extern char _start_ramdisk1[]; +extern char _end_ramdisk1[]; + +__attribute__((section(".data.sfs"))) char sfsdisk[SZ_16MB]; + +static unsigned long ramdisk_base[2]; void ramdisk_open(struct block_device *ramdisk) { @@ -52,14 +57,26 @@ void ramdisk_writepage(unsigned long pfn, void *buf) ramdisk_write(__pfn_to_addr(pfn), PAGE_SIZE, buf); } -struct block_device ramdisk = { - .name = "ramdisk", - .ops = { - .open = ramdisk_open, - .read = ramdisk_read, - .write = ramdisk_write, - .read_page = ramdisk_readpage, - .write_page = ramdisk_writepage, +struct block_device ramdisk[2] = { + [0] = { + .name = "ramdisk0", + .ops = { + .open = ramdisk_open, + .read = ramdisk_read, + .write = ramdisk_write, + .read_page = ramdisk_readpage, + .write_page = ramdisk_writepage, + }, }, + [1] = { + .name = "ramdisk1", + .ops = { + .open = ramdisk_open, + .read = ramdisk_read, + .write = ramdisk_write, + .read_page = ramdisk_readpage, + .write_page = ramdisk_writepage, + }, + } }; diff --git a/tasks/fs0/include/bdev.h b/tasks/fs0/include/bdev.h deleted file mode 100644 index 347c42b..0000000 --- a/tasks/fs0/include/bdev.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __BLOCK_DEV_H__ -#define __BLOCK_DEV_H__ - -void bdev_open(void); -void bdev_readpage(unsigned long offset, void *buf); -void bdev_writepage(unsigned long offset, void *buf); - -#endif /* __BLOCK_DEV_H__ */ diff --git a/tasks/fs0/include/lib/bit.h b/tasks/fs0/include/lib/bit.h new file mode 100644 index 0000000..bccc5df --- /dev/null +++ b/tasks/fs0/include/lib/bit.h @@ -0,0 +1,43 @@ +#ifndef __LIB_BIT_H__ +#define __LIB_BIT_H__ + +#include + +unsigned int __clz(unsigned int bitvector); +int find_and_set_first_free_bit(u32 *word, unsigned int lastbit); +int find_and_set_first_free_contig_bits(u32 *word, unsigned int limit, + int nbits); +int check_and_clear_bit(u32 *word, int bit); +int check_and_clear_contig_bits(u32 *word, int first, int nbits); + + +/* Set */ +static inline void setbit(unsigned int *w, unsigned int flags) +{ + *w |= flags; +} + + +/* Clear */ +static inline void clrbit(unsigned int *w, unsigned int flags) +{ + *w &= ~flags; +} + +/* Test */ +static inline int tstbit(unsigned int *w, unsigned int flags) +{ + return *w & flags; +} + +/* Test and clear */ +static inline int tstclr(unsigned int *w, unsigned int flags) +{ + int res = tstbit(w, flags); + + clrbit(w, flags); + + return res; +} + +#endif /* __LIB_BIT_H__ */ diff --git a/tasks/fs0/include/lib/idpool.h b/tasks/fs0/include/lib/idpool.h new file mode 100644 index 0000000..3400849 --- /dev/null +++ b/tasks/fs0/include/lib/idpool.h @@ -0,0 +1,17 @@ +#ifndef __MM0_IDPOOL_H__ +#define __MM0_IDPOOL_H__ + +#include + +struct id_pool { + int nwords; + u32 bitmap[]; +}; + +struct id_pool *id_pool_new_init(int mapsize); +int id_new(struct id_pool *pool); +int id_del(struct id_pool *pool, int id); +int ids_new_contiguous(struct id_pool *pool, int numids); +int ids_del_contiguous(struct id_pool *pool, int first, int numids); + +#endif /* __MM0_IDPOOL_H__ */ diff --git a/tasks/fs0/include/lib/spinlock.h b/tasks/fs0/include/lib/spinlock.h new file mode 100644 index 0000000..7a61930 --- /dev/null +++ b/tasks/fs0/include/lib/spinlock.h @@ -0,0 +1,17 @@ +/* + * Fake spinlock for future multi-threaded mm0 + */ +#ifndef __MM0_SPINLOCK_H__ +#define __MM0_SPINLOCK_H__ + + + +struct spinlock { + int lock; +}; + +static inline void spin_lock_init(struct spinlock *s) { } +static inline void spin_lock(struct spinlock *s) { } +static inline void spin_unlock(struct spinlock *s) { } + +#endif /* __MM0_SPINLOCK_H__ */ diff --git a/tasks/fs0/include/lib/vaddr.h b/tasks/fs0/include/lib/vaddr.h new file mode 100644 index 0000000..d26d8af --- /dev/null +++ b/tasks/fs0/include/lib/vaddr.h @@ -0,0 +1,17 @@ +/* + * Virtual address allocation pool (for shm) + * + * Copyright (C) 2007 Bahadir Balban + */ +#ifndef __VADDR_H__ +#define __VADDR_H__ + +#include + +void vaddr_pool_init(struct id_pool *pool, unsigned long start, + unsigned long end); +void *vaddr_new(struct id_pool *pool, int npages); +int vaddr_del(struct id_pool *, void *vaddr, int npages); + +#endif /* __VADDR_H__ */ + diff --git a/tasks/fs0/include/linker.lds b/tasks/fs0/include/linker.lds index 163e367..54a31ae 100644 --- a/tasks/fs0/include/linker.lds +++ b/tasks/fs0/include/linker.lds @@ -30,7 +30,14 @@ SECTIONS /* rodata is needed else your strings will link at physical! */ .rodata : AT (ADDR(.rodata) - offset) { *(.rodata) } .rodata1 : AT (ADDR(.rodata1) - offset) { *(.rodata1) } - .data : AT (ADDR(.data) - offset) { *(.data) } + .data : AT (ADDR(.data) - offset) + { + . = ALIGN(4K); + _start_ramdisk = .; + *(.data.diskspace) + _end_ramdisk = .; + *(.data) + } .bss : AT (ADDR(.bss) - offset) { *(.bss) } _end = .; } diff --git a/tasks/fs0/src/init.c b/tasks/fs0/src/init.c index 207fc95..62d0624 100644 --- a/tasks/fs0/src/init.c +++ b/tasks/fs0/src/init.c @@ -9,112 +9,13 @@ #include #include #include - -struct filesystem bootfs = { - .magic = 0, - .name = "Tempfs for boot images", -}; - -struct superblock bootfs_sb; - -#define BOOTFS_IMG_MAX 10 -struct vnode bootfs_vnode[BOOTFS_IMG_MAX]; -struct dentry bootfs_dentry[BOOTFS_IMG_MAX]; -struct file bootfs_file[BOOTFS_IMG_MAX]; - -struct rootdir { - struct dentry *d; - struct filesystem *fs; -}; -struct rootdir bootfs_root; - -void init_root(struct vnode *root_vn, struct dentry *root_d) -{ - /* Initialise dentry for rootdir */ - root_d->refcnt = 0; - strcpy(root_d->name, ""); - INIT_LIST_HEAD(&root_d->child); - INIT_LIST_HEAD(&root_d->children); - INIT_LIST_HEAD(&root_d->dref_list); - root_d->vnode = root_vn; - - /* Initialise vnode for rootdir */ - root_vn->id = 0; - root_vn->refcnt = 0; - INIT_LIST_HEAD(&root_vn->dirents); - INIT_LIST_HEAD(&root_vn->state_list); - list_add(&root_d->vnlist, &root_vn->dirents); - root_vn->size = 0; - - /* Initialise global struct rootdir ptr */ - bootfs_root.d = root_d; - bootfs_root.fs = &bootfs; -} - -#define PATH_SEP "/" -#define PATH_CURDIR "." -#define PATH_OUTDIR ".." - -void fs_debug_list_all(struct dentry *root) -{ - struct dentry *d; - int stotal = 0; - - /* List paths first */ - printf("%s%s\n", root->name, PATH_SEP); - list_for_each_entry(d, &root->children, child) { - printf("%s%s%s, size: 0x%x\n", d->parent->name, PATH_SEP, d->name, d->vnode->size); - stotal += d->vnode->size; - } -} - -void init_bootfs(struct initdata *initdata) -{ - struct bootdesc *bd = initdata->bootdesc; - struct dentry *img_d = &bootfs_dentry[1]; - struct vnode *img_vn = &bootfs_vnode[1]; - struct file *img_f = &bootfs_file[1]; - struct svc_image *img; - - /* The first vfs object slot is for the root */ - init_root(&bootfs_vnode[0], &bootfs_dentry[0]); - - BUG_ON(bd->total_images >= BOOTFS_IMG_MAX); - for (int i = 0; i < bd->total_images; i++) { - img = &bd->images[i]; - - /* Initialise dentry for image */ - img_d->refcnt = 0; - strncpy(img_d->name, img->name, VFS_DENTRY_NAME_MAX); - INIT_LIST_HEAD(&img_d->child); - INIT_LIST_HEAD(&img_d->children); - img_d->vnode = img_vn; - img_d->parent = bootfs_root.d; - list_add(&img_d->child, &bootfs_root.d->children); - - /* Initialise vnode for image */ - img_vn->id = img->phys_start; - img_vn->refcnt = 0; - INIT_LIST_HEAD(&img_vn->dirents); - list_add(&img_d->dref_list, &img_vn->dirents); - img_vn->size = img->phys_end - img->phys_start; - - /* Initialise file struct for image */ - img_f->refcnt = 0; - img_f->dentry = img_d; - - img_d++; - img_vn++; - img_f++; - } -} +#include void initialise(void) { - request_initdata(&initdata); - init_bootfs(&initdata); + struct block_device *bdev; - /* A debug call that lists all vfs structures */ - fs_debug_list_all(bootfs_root.d); + request_initdata(&initdata); + vfs_probe_fs(bdev); } diff --git a/tasks/fs0/src/lib/bit.c b/tasks/fs0/src/lib/bit.c new file mode 100644 index 0000000..7190e5b --- /dev/null +++ b/tasks/fs0/src/lib/bit.c @@ -0,0 +1,98 @@ +/* + * Bit manipulation functions. + * + * Copyright (C) 2007 Bahadir Balban + */ +#include +#include +#include +#include +#include INC_GLUE(memory.h) + +/* Emulation of ARM's CLZ (count leading zeroes) instruction */ +unsigned int __clz(unsigned int bitvector) +{ + unsigned int x = 0; + while((!(bitvector & ((unsigned)1 << 31))) && (x < 32)) { + bitvector <<= 1; + x++; + } + return x; +} + +int find_and_set_first_free_bit(u32 *word, unsigned int limit) +{ + int success = 0; + int i; + + for(i = 0; i < limit; i++) { + /* Find first unset bit */ + if (!(word[BITWISE_GETWORD(i)] & BITWISE_GETBIT(i))) { + /* Set it */ + word[BITWISE_GETWORD(i)] |= BITWISE_GETBIT(i); + success = 1; + break; + } + } + /* Return bit just set */ + if (success) + return i; + else + return -1; +} + +int find_and_set_first_free_contig_bits(u32 *word, unsigned int limit, + int nbits) +{ + int i = 0, first = 0, last = 0, found = 0; + + /* Can't allocate more than the limit */ + if (nbits > limit) + return -1; + + /* This is a state machine that checks n contiguous free bits. */ + while (i + nbits < limit) { + first = i; + last = i; + while (!(word[BITWISE_GETWORD(last)] & BITWISE_GETBIT(last))) { + last++; + i++; + if (last == first + nbits) { + found = 1; + break; + } + } + if (found) + break; + i++; + } + + /* If found, set the bits */ + if (found) { + for (int x = first; x < first + nbits; x++) + word[BITWISE_GETWORD(x)] |= BITWISE_GETBIT(x); + return first; + } else + return -1; +} + +int check_and_clear_bit(u32 *word, int bit) +{ + /* Check that bit was set */ + if (word[BITWISE_GETWORD(bit)] & BITWISE_GETBIT(bit)) { + word[BITWISE_GETWORD(bit)] &= ~BITWISE_GETBIT(bit); + return 0; + } else { + printf("Trying to clear already clear bit\n"); + return -1; + } +} + +int check_and_clear_contig_bits(u32 *word, int first, int nbits) +{ + for (int i = first; i < first + nbits; i++) + if (check_and_clear_bit(word, i) < 0) + return -1; + return 0; +} + diff --git a/tasks/fs0/src/lib/idpool.c b/tasks/fs0/src/lib/idpool.c new file mode 100644 index 0000000..136ad56 --- /dev/null +++ b/tasks/fs0/src/lib/idpool.c @@ -0,0 +1,63 @@ +/* + * Used for thread and space ids. + * + * Copyright (C) 2007 Bahadir Balban + */ +#include +#include +#include INC_GLUE(memory.h) +#include + +struct id_pool *id_pool_new_init(int totalbits) +{ + int nwords = BITWISE_GETWORD(totalbits); + struct id_pool *new = kzalloc((nwords * SZ_WORD) + + sizeof(struct id_pool)); + new->nwords = nwords; + return new; +} + +int id_new(struct id_pool *pool) +{ + int id = find_and_set_first_free_bit(pool->bitmap, + pool->nwords * WORD_BITS); + if (id < 0) + printf("%s: Warning! New id alloc failed\n", __FUNCTION__); + return id; +} + +/* This finds n contiguous free ids, allocates and returns the first one */ +int ids_new_contiguous(struct id_pool *pool, int numids) +{ + int id = find_and_set_first_free_contig_bits(pool->bitmap, + pool->nwords *WORD_BITS, + numids); + if (id < 0) + printf("%s: Warning! New id alloc failed\n", __FUNCTION__); + return id; +} + +/* This deletes a list of contiguous ids given the first one and number of ids */ +int ids_del_contiguous(struct id_pool *pool, int first, int numids) +{ + int ret; + + if (pool->nwords * WORD_BITS < first + numids) + return -1; + if ((ret = check_and_clear_contig_bits(pool->bitmap, first, numids))) + printf("%s: Error: Invalid argument range.\n", __FUNCTION__); + return ret; +} + +int id_del(struct id_pool *pool, int id) +{ + int ret; + + if (pool->nwords * WORD_BITS < id) + return -1; + + if ((ret = check_and_clear_bit(pool->bitmap, id) < 0)) + printf("%s: Error: Could not delete id.\n", __FUNCTION__); + return ret; +} + diff --git a/tasks/fs0/src/lib/vaddr.c b/tasks/fs0/src/lib/vaddr.c new file mode 100644 index 0000000..8a847a7 --- /dev/null +++ b/tasks/fs0/src/lib/vaddr.c @@ -0,0 +1,39 @@ +/* + * This module allocates an unused virtual address range for shm segments. + * + * Copyright (C) 2007 Bahadir Balban + */ +#include +#include +#include +#include INC_GLUE(memory.h) +#include +#include + +void vaddr_pool_init(struct id_pool *pool, unsigned long start, unsigned long end) +{ + pool = id_pool_new_init(__pfn(end - start)); +} + +void *vaddr_new(struct id_pool *pool, int npages) +{ + unsigned int shm_vpfn; + + if ((int)(shm_vpfn = ids_new_contiguous(pool, npages)) < 0) + return 0; + + return (void *)__pfn_to_addr(shm_vpfn + SHM_AREA_START); +} + +int vaddr_del(struct id_pool *pool, void *vaddr, int npages) +{ + unsigned long idpfn = __pfn(page_align(vaddr) - SHM_AREA_START); + + if (ids_del_contiguous(pool, idpfn, npages) < 0) { + printf("%s: Invalid address range returned to " + "virtual address pool.\n", __FUNCTION__); + return -1; + } + return 0; +} + diff --git a/tasks/fs0/src/simplefs/inode.c b/tasks/fs0/src/simplefs/inode.c deleted file mode 100644 index efc292f..0000000 --- a/tasks/fs0/src/simplefs/inode.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * A basic unix-like read/writeable filesystem. - * - * Copyright (C) 2007 Bahadir Balban - */ - -#define SIMPLEFS_BLOCK_SIZE 1024 -/* - * Simplefs superblock - */ -struct simplefs_sb { - unsigned long magic; /* Filesystem magic */ - unsigned long ioffset; /* Offset of first inode */ - unsigned long bsize; /* Fs block size */ -}; - -struct simplefs_sb *sb; - -static void simplefs_fill_super(struct superblock *sb) -{ - char buf[SIMPLEFS_BLOCK_SIZE]; - - bdev_read(0, SIMPLEFS_BLOCK_SIZE, buf); - -} - -static void simplefs_read_vnode(struct vnode *) -{ -} - - diff --git a/tasks/fs0/src/simplefs/sfs.c b/tasks/fs0/src/simplefs/sfs.c new file mode 100644 index 0000000..704f7a4 --- /dev/null +++ b/tasks/fs0/src/simplefs/sfs.c @@ -0,0 +1,17 @@ +/* + * A basic unix-like read/writeable filesystem. + * + * Copyright (C) 2007, 2008 Bahadir Balban + */ + +void sfs_read_sb(struct superblock *sb) +{ + +} + +static void simplefs_alloc_vnode(struct vnode *) +{ + +} + + diff --git a/tasks/fs0/src/simplefs/sfslayout.h b/tasks/fs0/src/simplefs/sfs.h similarity index 79% rename from tasks/fs0/src/simplefs/sfslayout.h rename to tasks/fs0/src/simplefs/sfs.h index c5d9f25..f21a8a5 100644 --- a/tasks/fs0/src/simplefs/sfslayout.h +++ b/tasks/fs0/src/simplefs/sfs.h @@ -8,23 +8,26 @@ #define __SFS_LAYOUT_H__ #include +#include +#include +#include INC_GLUE(memory.h) /* * * Filesystem layout: * * |---------------| - * | Unit 0 | + * | Group 0 | * |---------------| - * | Unit 1 | + * | Group 1 | * |---------------| * | ... | * |---------------| - * | Unit n | + * | Group n | * |---------------| * * - * Unit layout: + * Group layout: * * |---------------| * | Superblock | @@ -42,24 +45,23 @@ * */ -#define SZ_8MB (0x100000 * 8) -#define SZ_4KB 0x1000 -#define SZ_4KB_BITS 12 +#define BLOCK_SIZE PAGE_SIZE +#define BLOCK_BITS PAGE_BITS +#define GROUP_SIZE SZ_8MB +#define INODE_TABLE_SIZE ((GROUP_SIZE / BLOCK_SIZE) / 2) +#define INODE_BITMAP_SIZE (INODE_TABLE_SIZE >> 5) -#define UNIT_SIZE (SZ_8MB) -#define INODE_TABLE_SIZE ((UNIT_SIZE >> SZ_4KB_BITS) >> 1) -#define INODE_BITMAP_SZIDX (INODE_TABLE_SIZE >> 5) struct sfs_superblock { u32 magic; /* Filesystem magic number */ u32 fssize; /* Total size of filesystem */ u32 szidx; /* Bitmap index size */ - u32 unitmap[] /* Bitmap of all fs units */ + u32 groupmap[]; /* Bitmap of all fs groups */ }; struct sfs_inode_table { u32 szidx; - u32 inodemap[INODE_BITMAP_SZIDX]; + u32 inodemap[INODE_BITMAP_SIZE]; struct sfs_inode inode[INODE_TABLE_SIZE]; }; @@ -70,7 +72,7 @@ struct sfs_inode_table { * 2) Keep file/directory metadata. * 3) Provide access means to file blocks/directory contents. */ - +#define INODE_DIRECT_BLOCKS 5 struct sfs_inode_blocks { u32 szidx; /* Direct array index size */ unsigned long indirect; @@ -97,5 +99,4 @@ struct sfs_dentry { u8 name[]; /* Name string */ } __attribute__ ((__packed__)); - #endif /* __SFS_LAYOUT_H__ */