diff --git a/Makefile b/Makefile index 91b1486..073663f 100644 --- a/Makefile +++ b/Makefile @@ -62,6 +62,7 @@ initrd: mke2fs -Fv -m0 -r0 -i1024 $(INITRD) -mkdir $(INITRD_MOUNT) mount -t ext2 -o loop $(INITRD) $(INITRD_MOUNT) + touch $(INITRD_MOUNT)/hi\ there mkdir $(INITRD_MOUNT)/txt cp Makefile $(INITRD_MOUNT)/txt umount $(INITRD_MOUNT) diff --git a/kernel/Makefile b/kernel/Makefile index 644dde6..f8d3e3a 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -17,13 +17,13 @@ LD_FLAGS=-nodefaultlibs -nostdlib --no-demangle -T link.ld all: Asm_Kernel C_Kernel $(LD) $(LD_FLAGS) -Map kernel.map \ - boot.o kernel.o asmfuncs.o mm.o vmm.o parallel.o conv.o kout.o \ + boot.o kernel.o lang_a.o mm.o vmm.o parallel.o conv.o kout.o \ vconsole.o display.o devices.o pic.o keyboard.o ramdisk.o vfs.o \ - devfs.o ext2.o -o kernel.bin + devfs.o ext2.o lang_c.o -o kernel.bin Asm_Kernel: $(NASM) $(NASM_FLAGS) -l boot.lst boot.asm -o boot.o - $(NASM) $(NASM_FLAGS) -l asmfuncs.lst lang/asmfuncs.asm -o asmfuncs.o + $(NASM) $(NASM_FLAGS) -l lang.lst lang/lang.asm -o lang_a.o C_Kernel: $(CC) $(CC_FLAGS) -c kernel.c -o kernel.o @@ -41,6 +41,7 @@ C_Kernel: $(CC) $(CC_FLAGS) -c fs/devfs.c -o devfs.o $(CC) $(CC_FLAGS) -c fs/vfs.c -o vfs.o $(CC) $(CC_FLAGS) -c fs/ext2.c -o ext2.o + $(CC) $(CC_FLAGS) -c lang/lang.c -o lang_c.o ################################################# # Clean up the source directory of any binaries # diff --git a/kernel/block/ramdisk.c b/kernel/block/ramdisk.c index 73b2da3..5f8f11c 100644 --- a/kernel/block/ramdisk.c +++ b/kernel/block/ramdisk.c @@ -7,7 +7,7 @@ #include "fs/devices.h" #include "functions.h" #include "mm/vmm.h" -#include "lang/asmfuncs.h" +#include "lang/lang.h" ramdisk_t *ramdisks[256]; diff --git a/kernel/char/vconsole.c b/kernel/char/vconsole.c index edbfafb..a39e008 100644 --- a/kernel/char/vconsole.c +++ b/kernel/char/vconsole.c @@ -7,7 +7,7 @@ #include "hos_defines.h" #include "fs/devices.h" #include "mm/vmm.h" -#include "lang/asmfuncs.h" +#include "lang/lang.h" #include "display.h" #include "functions.h" diff --git a/kernel/display.c b/kernel/display.c index f36d6df..fb1cf4a 100644 --- a/kernel/display.c +++ b/kernel/display.c @@ -6,7 +6,7 @@ #include "fs/devices.h" #include "char/vconsole.h" #include "display.h" -#include "lang/asmfuncs.h" +#include "lang/lang.h" int display_activeConsole = -1; // start with no active console display_t myDisplays[12]; // f1-f12 change displays diff --git a/kernel/fs/ext2.c b/kernel/fs/ext2.c index a48ae55..165fb86 100644 --- a/kernel/fs/ext2.c +++ b/kernel/fs/ext2.c @@ -9,7 +9,7 @@ #include "ext2.h" #include "mm/vmm.h" #include "fs/vfs.h" -#include "lang/asmfuncs.h" +#include "lang/lang.h" #include "functions.h" /* Turning an inode number into a (group, inode_index) pair: @@ -26,8 +26,10 @@ int ext2_init(int fsID) { fs->mount_super = ext2_mount_super; fs->umount_super = ext2_umount_super; - fs->mkfs = ext2_mkfs; fs->stat = ext2_stat; + fs->open_dir = ext2__open_dir; + fs->read_dir = ext2__read_dir; + fs->close_dir = ext2__close_dir; vfs_register_fs(fsID, fs); return 0; } @@ -35,13 +37,6 @@ int ext2_init(int fsID) } -// create an ext2 filesystem on the given device -int ext2_mkfs(major_t major, minor_t minor) -{ - return 0; -} - - // mount the superblock of the filesystem and return a pointer to it, if valid void *ext2_mount_super(major_t major, minor_t minor) { @@ -55,6 +50,14 @@ void *ext2_mount_super(major_t major, minor_t minor) return super; } + +// called when we are unmounting this filesystem mount +int ext2_umount_super(vfs_mount_t *mount) +{ + return kfree(mount->super); // free memory that the superblock was taking +} + + // stat a file, return a structure of info about it int ext2_stat(vfs_mount_t *mount, char *file, vfs_stat_t *stat) { @@ -65,14 +68,14 @@ int ext2_stat(vfs_mount_t *mount, char *file, vfs_stat_t *stat) switch(inode.i_mode & EXT2_I_MODE_TYPE_MASK) { - case EXT2_I_MODE_FIFO: stat->type = VFS_FT_FIFO; - case EXT2_I_MODE_CHAR: stat->type = VFS_FT_CHAR; - case EXT2_I_MODE_DIR: stat->type = VFS_FT_DIR; - case EXT2_I_MODE_BLOCK: stat->type = VFS_FT_BLOCK; - case EXT2_I_MODE_FILE: stat->type = VFS_FT_FILE; - case EXT2_I_MODE_SYM: stat->type = VFS_FT_SYMLINK; - case EXT2_I_MODE_SOCK: stat->type = VFS_FT_SOCK; - default: stat->type = VFS_FT_UNKNOWN; + case EXT2_I_MODE_FIFO: stat->type = VFS_FT_FIFO; break; + case EXT2_I_MODE_CHAR: stat->type = VFS_FT_CHAR; break; + case EXT2_I_MODE_DIR: stat->type = VFS_FT_DIR; break; + case EXT2_I_MODE_BLOCK: stat->type = VFS_FT_BLOCK; break; + case EXT2_I_MODE_FILE: stat->type = VFS_FT_FILE; break; + case EXT2_I_MODE_SYM: stat->type = VFS_FT_SYMLINK; break; + case EXT2_I_MODE_SOCK: stat->type = VFS_FT_SOCK; break; + default: stat->type = VFS_FT_UNKNOWN; break; } stat->size = inode.i_size; stat->inode = inode_number; @@ -92,34 +95,51 @@ u32_t ext2_get_inode_number(vfs_mount_t *mount, char *file) { if (file[0] != '/') return 0; - int length = strlen(file); - if (length == 1) - return 2; - char *fil = kmalloc(length + 1); - strcpy(fil, file); - if (fil[length-1] == '/') + if (strlen(file) == 1) + return 2; // root inode number + char *fil = kmalloc(strlen(file)); + strcpy(fil, file + 1); + int subs = str_split(fil, '/'); // how many levels are there to do lookups on? + u32_t on_dir = 2; // start on the root directory + char *lookupName = fil; + ext2_dir_entry_t dentry; + while (subs--) { - length--; - fil[length] = 0; - } - u32_t inode_number = 0; - // TODO: get inode number - + if (ext2_dir_lookup(mount, on_dir, lookupName, &dentry)) + { + kfree(fil); + return 0; // entry not found + } + on_dir = dentry.inode; + lookupName = str_advance(lookupName); + } kfree(fil); - return inode_number; + return on_dir; } -// DEBUG -void ext2_dump_root(vfs_mount_t *mount) + +// lookup a file name in a directory and store the directory entry for it +int ext2_dir_lookup(vfs_mount_t *mount, u32_t dir_inode, char *fileName, ext2_dir_entry_t *direntry) { - ext2_open_dir_t *root_dir = ext2_open_dir(mount, 2); + ext2_open_dir_t *dir = ext2_open_dir(mount, dir_inode); + if (!dir) + return -1; // bad directory inode number ext2_dir_entry_t dentry; - while (!ext2_dir_read_entry(mount, root_dir, &dentry)) + while (!ext2_dir_read_entry(mount, dir, &dentry)) { - kprintf("Directory Entry: inode %d, length %d, name_length %d, file_type 0x%x, name '%s'\n", - dentry.inode, dentry.length, dentry.name_length, dentry.file_type, dentry.name); + char *dentryName = kcalloc(1, dentry.name_length + 1); + memcpy(dentryName, dentry.name, dentry.name_length); + int res = strcmp(fileName, dentryName); + kfree(dentryName); + if (!res) + { + *direntry = dentry; + ext2_close_dir(mount, dir); + return 0; + } } - ext2_close_dir(mount, root_dir); + ext2_close_dir(mount, dir); + return -2; } // open a directory by inode number for reading @@ -127,7 +147,7 @@ ext2_open_dir_t *ext2_open_dir(vfs_mount_t *mount, u32_t inode_number) { ext2_open_dir_t *open_dir = New(ext2_open_dir_t); ext2_open_inode_t *open_inode = ext2_open_inode(mount, inode_number); - if (!open_inode) + if (!open_inode || ((open_inode->inode.i_mode & EXT2_I_MODE_TYPE_MASK) != EXT2_I_MODE_DIR)) { kfree(open_dir); return NULL; @@ -153,7 +173,6 @@ int ext2_dir_read_entry(vfs_mount_t *mount, ext2_open_dir_t *open_dir, ext2_dir_ kfree(block); return -2; // EOF } - memcpy(dentry, dir_entry, min(dir_entry->length, sizeof(ext2_dir_entry_t))); open_dir->position += dir_entry->length; kfree(block); @@ -167,6 +186,7 @@ int ext2_close_dir(vfs_mount_t *mount, ext2_open_dir_t *open_dir) return 0; } + // open an inode for reading ext2_open_inode_t *ext2_open_inode(vfs_mount_t *mount, u32_t inode_number) { @@ -182,49 +202,6 @@ ext2_open_inode_t *ext2_open_inode(vfs_mount_t *mount, u32_t inode_number) return open_inode; } -// check the status of an inode -// -1: invalid inode number -// 0: free inode -// 1: allocated inode -int ext2_inode_status(vfs_mount_t *mount, u32_t inode_number) -{ - ext2_super_block_t *super = mount->super; - if (inode_number < 1 || inode_number > super->s_inodes_count) // inode number invalid - return -1; - inode_number--; // turn inode_number into a 0-based index - u32_t group = inode_number / super->s_inodes_per_group; - u32_t index = inode_number % super->s_inodes_per_group; - u32_t inode_bitmap_block = ext2_get_group_desc(mount, group).bg_inode_bitmap + (index >> (13 + super->s_log_block_size)); - u32_t bitmap_index = index % (8192 << super->s_log_block_size); - u8_t *inode_bitmap = kmalloc(1024 << super->s_log_block_size); - block_read(mount->major, mount->minor, - ext2_FSToDiskBlock(inode_bitmap_block, super), 2 << super->s_log_block_size, inode_bitmap); - int inode_status = (inode_bitmap[bitmap_index >> 3] >> (bitmap_index & 0x7)) & 1; - kfree(inode_bitmap); - return inode_status; -} - -// check the status of a block -// -1: invalid block number -// 0: free block -// 1: allocated block -int ext2_block_status(vfs_mount_t *mount, u32_t block_number) -{ - ext2_super_block_t *super = mount->super; - if (block_number < super->s_first_data_block || block_number > super->s_blocks_count) // block number invalid - return -1; - block_number -= super->s_first_data_block; - u32_t group = block_number / super->s_blocks_per_group; - u32_t index = block_number % super->s_blocks_per_group; - u32_t block_bitmap_block = ext2_get_group_desc(mount, group).bg_block_bitmap + (index >> (13 + super->s_log_block_size)); - u32_t bitmap_index = index % (8192 << super->s_log_block_size); - u8_t *block_bitmap = kmalloc(1024 << super->s_log_block_size); - block_read(mount->major, mount->minor, - ext2_FSToDiskBlock(block_bitmap_block, super), 2 << super->s_log_block_size, block_bitmap); - int block_status = (block_bitmap[bitmap_index >> 3] >> (bitmap_index & 0x7)) & 1; - kfree(block_bitmap); - return block_status; -} // seek to a certain block of an open inode int ext2_inode_seek(vfs_mount_t *mount, ext2_open_inode_t *open_inode, u32_t block_number) @@ -250,6 +227,64 @@ int ext2_read_inode_block(vfs_mount_t *mount, ext2_open_inode_t *open_inode, voi return min(leftover_bytes, 1024 << super->s_log_block_size); } + +// close an open inode +int ext2_close_inode(vfs_mount_t *mount, ext2_open_inode_t *open_inode) +{ + mount->refs--; + if (open_inode->block_pointers) + kfree(open_inode->block_pointers); // free the block pointers cache + kfree(open_inode); + return 0; +} + + +// check the status of an inode +// -1: invalid inode number +// 0: free inode +// 1: allocated inode +int ext2_inode_status(vfs_mount_t *mount, u32_t inode_number) +{ + ext2_super_block_t *super = mount->super; + if (inode_number < 1 || inode_number > super->s_inodes_count) // inode number invalid + return -1; + inode_number--; // turn inode_number into a 0-based index + u32_t group = inode_number / super->s_inodes_per_group; + u32_t index = inode_number % super->s_inodes_per_group; + u32_t inode_bitmap_block = ext2_get_group_desc(mount, group).bg_inode_bitmap + (index >> (13 + super->s_log_block_size)); + u32_t bitmap_index = index % (8192 << super->s_log_block_size); + u8_t *inode_bitmap = kmalloc(1024 << super->s_log_block_size); + block_read(mount->major, mount->minor, + ext2_FSToDiskBlock(inode_bitmap_block, super), 2 << super->s_log_block_size, inode_bitmap); + int inode_status = (inode_bitmap[bitmap_index >> 3] >> (bitmap_index & 0x7)) & 1; + kfree(inode_bitmap); + return inode_status; +} + + +// check the status of a block +// -1: invalid block number +// 0: free block +// 1: allocated block +int ext2_block_status(vfs_mount_t *mount, u32_t block_number) +{ + ext2_super_block_t *super = mount->super; + if (block_number < super->s_first_data_block || block_number > super->s_blocks_count) // block number invalid + return -1; + block_number -= super->s_first_data_block; + u32_t group = block_number / super->s_blocks_per_group; + u32_t index = block_number % super->s_blocks_per_group; + u32_t block_bitmap_block = ext2_get_group_desc(mount, group).bg_block_bitmap + (index >> (13 + super->s_log_block_size)); + u32_t bitmap_index = index % (8192 << super->s_log_block_size); + u8_t *block_bitmap = kmalloc(1024 << super->s_log_block_size); + block_read(mount->major, mount->minor, + ext2_FSToDiskBlock(block_bitmap_block, super), 2 << super->s_log_block_size, block_bitmap); + int block_status = (block_bitmap[bitmap_index >> 3] >> (bitmap_index & 0x7)) & 1; + kfree(block_bitmap); + return block_status; +} + + // transform open_inode->block (a relative block number) to an absolute block number for the filesystem u32_t ext2_block_number(vfs_mount_t *mount, ext2_open_inode_t *open_inode) { @@ -300,15 +335,6 @@ u32_t ext2_block_number(vfs_mount_t *mount, ext2_open_inode_t *open_inode) return open_inode->block_pointers[leftover_2]; } -// close an open inode -int ext2_close_inode(vfs_mount_t *mount, ext2_open_inode_t *open_inode) -{ - mount->refs--; - if (open_inode->block_pointers) - kfree(open_inode->block_pointers); // free the block pointers cache - kfree(open_inode); - return 0; -} // read the inode structure from the device and return it ext2_inode_t ext2_get_inode(vfs_mount_t *mount, u32_t inode) @@ -338,9 +364,34 @@ ext2_group_desc_t ext2_get_group_desc(vfs_mount_t *mount, u32_t group) return gd; } -// called when we are unmounting this filesystem mount -int ext2_umount_super(vfs_mount_t *mount) + +int ext2__open_dir(vfs_mount_t *mount, char *file, vfs_open_dir_t *dir) { - return kfree(mount->super); // free memory that the superblock was taking + u32_t dir_inode = ext2_get_inode_number(mount, file); + if (!dir_inode) + return -1; + ext2_open_dir_t *open_dir = ext2_open_dir(mount, dir_inode); + if (!open_dir) + return -2; + dir->fs_data = open_dir; + return 0; } +int ext2__read_dir(vfs_mount_t *mount, vfs_open_dir_t *dir, vfs_dir_entry_t *dentry) +{ + ext2_dir_entry_t t_dentry; + int status = ext2_dir_read_entry(mount, dir->fs_data, &t_dentry); + if (status) + return status; + memcpy(dentry->name, t_dentry.name, t_dentry.name_length); + dentry->name[t_dentry.name_length] = 0; + return 0; +} + +int ext2__close_dir(vfs_mount_t *mount, vfs_open_dir_t *dir) +{ + return ext2_close_dir(mount, dir->fs_data); +} + + + diff --git a/kernel/fs/ext2.h b/kernel/fs/ext2.h index 009248a..e2cf303 100644 --- a/kernel/fs/ext2.h +++ b/kernel/fs/ext2.h @@ -13,19 +13,20 @@ #define EXT2_MAGIC 0xEF53 #define EXT2_NAME_LEN 255 -#define EXT2_I_MODE_ATTR_MASK 0x0FFF -#define EXT2_I_MODE_OX 0x0001 -#define EXT2_I_MODE_OW 0x0002 -#define EXT2_I_MODE_OR 0x0004 -#define EXT2_I_MODE_GX 0x0008 -#define EXT2_I_MODE_GW 0x0010 -#define EXT2_I_MODE_GR 0x0020 -#define EXT2_I_MODE_UX 0x0040 -#define EXT2_I_MODE_UW 0x0080 -#define EXT2_I_MODE_UR 0x0100 +#define EXT2_I_MODE_ATTR_MASK 0x0FFF +#define EXT2_I_MODE_OX 0x0001 +#define EXT2_I_MODE_OW 0x0002 +#define EXT2_I_MODE_OR 0x0004 +#define EXT2_I_MODE_GX 0x0008 +#define EXT2_I_MODE_GW 0x0010 +#define EXT2_I_MODE_GR 0x0020 +#define EXT2_I_MODE_UX 0x0040 +#define EXT2_I_MODE_UW 0x0080 +#define EXT2_I_MODE_UR 0x0100 #define EXT2_I_MODE_STICKY 0x0200 #define EXT2_I_MODE_SGID 0x0400 #define EXT2_I_MODE_SUID 0x0800 + #define EXT2_I_MODE_TYPE_MASK 0xF000 #define EXT2_I_MODE_FIFO 0x1000 #define EXT2_I_MODE_CHAR 0x2000 @@ -152,7 +153,6 @@ typedef struct u32_t position; } ext2_open_dir_t; - static inline u32_t ext2_diskToFSBlock(u32_t block, ext2_super_block_t *super) { // convert # of disk blocks to # of filesystem blocks @@ -169,7 +169,6 @@ static inline u32_t ext2_FSToDiskBlock(u32_t block, ext2_super_block_t *super) int ext2_init(int fsID); void *ext2_mount_super(major_t major, minor_t minor); int ext2_umount_super(vfs_mount_t *mount); -int ext2_mkfs(major_t major, minor_t minor); ext2_inode_t ext2_get_inode(vfs_mount_t *mount, u32_t inode); ext2_group_desc_t ext2_get_group_desc(vfs_mount_t *mount, u32_t group); int ext2_stat(vfs_mount_t *mount, char *file, vfs_stat_t *stat); @@ -185,8 +184,11 @@ int ext2_block_status(vfs_mount_t *mount, u32_t block_number); ext2_open_dir_t *ext2_open_dir(vfs_mount_t *mount, u32_t inode_number); int ext2_dir_read_entry(vfs_mount_t *mount, ext2_open_dir_t *open_dir, ext2_dir_entry_t *dentry); int ext2_close_dir(vfs_mount_t *mount, ext2_open_dir_t *open_dir); +int ext2_dir_lookup(vfs_mount_t *mount, u32_t dir_inode, char *fileName, ext2_dir_entry_t *direntry); -void ext2_dump_root(vfs_mount_t *mount); +int ext2__open_dir(vfs_mount_t *mount, char *file, vfs_open_dir_t *dir); +int ext2__read_dir(vfs_mount_t *mount, vfs_open_dir_t *dir, vfs_dir_entry_t *dentry); +int ext2__close_dir(vfs_mount_t *mount, vfs_open_dir_t *dir); #endif diff --git a/kernel/fs/vfs.c b/kernel/fs/vfs.c index 629aeca..b40c919 100644 --- a/kernel/fs/vfs.c +++ b/kernel/fs/vfs.c @@ -9,7 +9,7 @@ #include "fs/ext2.h" #include "kernel.h" #include "mm/vmm.h" -#include "lang/asmfuncs.h" +#include "lang/lang.h" vfs_fs_t *fses[VFS_MAX_FS]; // a vfs_fs structure for every filesystem we support vfs_node_t *vfsMountTree; // points to the root node ('/') of the VFS Mount Tree @@ -63,8 +63,6 @@ int vfs_mount(major_t maj, minor_t min, int fsType, char *mountPoint) kfree(mnt); return -4; // could not add mount } - // DEBUG - ext2_dump_root(mnt); return 0; } @@ -243,7 +241,52 @@ int vfs_retire_node(vfs_node_t *node) } -// debug routine to draw the VFS Mount Tree +// stat a file, fills a vfs_stat_t structure with stat information and returns standard status +int vfs_stat(char *file, vfs_stat_t *stat) +{ + vfs_mount_match_t match = vfs_get_rel_path(file); + if (match.mount == NULL) + return -256; + if (fses[match.mount->fs]->stat) + return fses[match.mount->fs]->stat(match.mount, file + match.length - 1, stat); + return -257; +} + + +vfs_open_dir_t *vfs_open_dir(char *file) +{ + vfs_mount_match_t match = vfs_get_rel_path(file); + if (match.mount == NULL) + return NULL; + vfs_open_dir_t *open_dir = New(vfs_open_dir_t); + if (fses[match.mount->fs]->open_dir && !(fses[match.mount->fs]->open_dir(match.mount, file + match.length - 1, open_dir))) + { + open_dir->mount = match.mount; + return open_dir; + } + kfree(open_dir); + return NULL; + +} + +int vfs_read_dir(vfs_open_dir_t *open_dir, vfs_dir_entry_t *dentry) +{ + return !(fses[open_dir->mount->fs]->read_dir && + !(fses[open_dir->mount->fs]->read_dir(open_dir->mount, open_dir, dentry))); +} + +int vfs_close_dir(vfs_open_dir_t *open_dir) +{ + int status = 0; + if (fses[open_dir->mount->fs]->close_dir) + status = fses[open_dir->mount->fs]->close_dir(open_dir->mount, open_dir); + kfree(open_dir); + return status; +} + + +// DEBUG routines to draw the VFS Mount Tree +/******************************************/ void vfs_dump_tree() { if (!vfsMountTree) @@ -269,4 +312,5 @@ void vfs_dump_node(vfs_node_t *node, int level) node = node->next; } } +/******************************************/ diff --git a/kernel/fs/vfs.h b/kernel/fs/vfs.h index 4289e24..fc5927b 100644 --- a/kernel/fs/vfs.h +++ b/kernel/fs/vfs.h @@ -21,6 +21,7 @@ #define VFS_FT_SOCK 6 #define VFS_FT_SYMLINK 7 +#define EOF 1000000 /* Structure to hold information about a mount point */ typedef struct @@ -68,13 +69,34 @@ typedef struct u16_t links; } vfs_stat_t; +typedef struct +{ + vfs_mount_t *mount; + void *fs_data; +} vfs_open_dir_t; + +typedef struct +{ + vfs_mount_t *mount; + void *fs_data; +} vfs_open_file_t; + +typedef struct +{ + char name[257]; +} vfs_dir_entry_t; + /* Every filesystem must provide pointers to its respective functions in a structure like this */ typedef struct { void *(*mount_super)(major_t major, minor_t minor); int (*umount_super)(vfs_mount_t *mount); - int (*mkfs)(major_t major, minor_t minor); int (*stat)(vfs_mount_t *mount, char *file, vfs_stat_t *stat); + + int (*open_dir)(vfs_mount_t *mount, char *file, vfs_open_dir_t *dir); + int (*read_dir)(vfs_mount_t *mount, vfs_open_dir_t *dir, vfs_dir_entry_t *dentry); + int (*close_dir)(vfs_mount_t *mount, vfs_open_dir_t *dir); + } vfs_fs_t; @@ -86,6 +108,15 @@ vfs_mount_t *vfs_find_mount(char *mountPoint); vfs_mount_match_t vfs_get_rel_path(char *path); int vfs_umount(char *mountPoint); int vfs_retire_node(vfs_node_t *node); + +int vfs_stat(char *file, vfs_stat_t *stat); + +vfs_open_dir_t *vfs_open_dir(char *file); +int vfs_read_dir(vfs_open_dir_t *open_dir, vfs_dir_entry_t *dentry); +int vfs_close_dir(vfs_open_dir_t *open_dir); + + +// DEBUG routines void vfs_dump_tree(); void vfs_dump_node(vfs_node_t *node, int level); diff --git a/kernel/kernel.c b/kernel/kernel.c index adc3f14..f10d66d 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -7,7 +7,7 @@ #include "kernel.h" #include "multiboot.h" #include "module.h" -#include "lang/asmfuncs.h" +#include "lang/lang.h" #include "functions.h" #include "mm/mm.h" #include "mm/vmm.h" @@ -136,6 +136,20 @@ void k_init() } } + vfs_open_dir_t *open_dir = vfs_open_dir("/"); + vfs_dir_entry_t dentry; + vfs_stat_t stat; + while (!vfs_read_dir(open_dir, &dentry)) + { + char *name = kcalloc(1, strlen(dentry.name) + 2); + name[0] = '/'; + strcat(name, dentry.name); + vfs_stat(name, &stat); + kfree(name); + kprintf("name '%s'\tinode %d, size %d, permissions 0%o, links %d\n", dentry.name, stat.inode, stat.size, stat.permissions, stat.links); + } + vfs_close_dir(open_dir); + criticalCounter--; } @@ -153,6 +167,9 @@ void isr(u32_t num) isr_keyboard(); pic_eoi(); break; + case 0x30: + kprintf("User interrupt requested\n"); + break; default: kprintf("Unhandled interrupt #%d, CR2 = 0x%x!\n", num, read_cr2()); halt(); diff --git a/kernel/kout.c b/kernel/kout.c index ad65403..e00253f 100644 --- a/kernel/kout.c +++ b/kernel/kout.c @@ -61,6 +61,10 @@ void kprintf(char *fmt, ...) putHex(*params); params++; break; + case 'o': case 'O': + putOct(*params); + params++; + break; case 'b': case 'B': kio_putBCD(*params); params++; @@ -118,6 +122,14 @@ void putHex(u32_t num) } +// This function displays a number in octal +void putOct(u32_t num) +{ + itoo(num, buffer); + puts(buffer); +} + + // This function prints a two-digit binary-coded-decimal value void kio_putBCD(u32_t bcd) { diff --git a/kernel/kout.h b/kernel/kout.h index a25bcd9..10cccd5 100644 --- a/kernel/kout.h +++ b/kernel/kout.h @@ -14,6 +14,7 @@ void putc(int c); void puts(char *str); void putDec(int num); void putDecu(u32_t num); +void putOct(u32_t number); #endif diff --git a/kernel/lang/conv.c b/kernel/lang/conv.c index 850fd8e..25a38d2 100644 --- a/kernel/lang/conv.c +++ b/kernel/lang/conv.c @@ -1,6 +1,7 @@ // conv.h // Author: Josh Holtrop // Date: 08/02/04 +// Modified: 12/30/04 #include "conv.h" #include "hos_defines.h" @@ -34,6 +35,21 @@ int itox(u32_t num, char *buf) } +// convert integer to an octal string +int itoo(u32_t num, char *buf) +{ + int s, i = 0; + for (s = 30; s >= 0; s -= 3) + { + u32_t val = (num >> s) & 0x7; + if (i || val || (!s)) + buf[i++] = val + '0'; + } + buf[i] = 0; + return i - 1; +} + + // convert signed integer to decimal string int itoa(int num, char *buf) { diff --git a/kernel/lang/conv.h b/kernel/lang/conv.h index 35b37be..39505f5 100644 --- a/kernel/lang/conv.h +++ b/kernel/lang/conv.h @@ -1,6 +1,7 @@ // conv.h // Author: Josh Holtrop // Date: 08/02/04 +// Modified: 12/30/04 #ifndef __HOS_CONV__ #define __HOS_CONV__ __HOS_CONV__ @@ -9,6 +10,7 @@ int bcdtoa(u32_t bcd, char *buf); int itox(u32_t num, char *buf); +int itoo(u32_t num, char *buf); int itoa(int num, char *buf); int utoa(u32_t num, char *buf); diff --git a/kernel/lang/asmfuncs.asm b/kernel/lang/lang.asm similarity index 89% rename from kernel/lang/asmfuncs.asm rename to kernel/lang/lang.asm index 732d60a..daf50d2 100644 --- a/kernel/lang/asmfuncs.asm +++ b/kernel/lang/lang.asm @@ -1,7 +1,7 @@ -; asmfuncs.asm +; lang.asm ; Josh Holtrop ; Created: 10/23/03 -; Modified: 07/11/04 +; Modified: 12/30/04 %macro jzfar 1 @@ -58,38 +58,6 @@ _read_cr3: ret -;compares one string to another -;returns 0 if the strings are different -;extern dword strcmp(char *str1, char *str2); -[global _strcmp] -_strcmp: - push ebp - mov ebp, esp - push esi - push edi - - mov esi, [ebp+8] - mov edi, [ebp+12] -strcmp_loop1: - lodsb - mov ah, [edi] - inc edi - cmp ah, al - jnz strcmp_ne - or al, al - jz strcmp_e - jmp strcmp_loop1 -strcmp_e: - mov eax, 1 - jmp short strcmp_done -strcmp_ne: - xor eax, eax -strcmp_done: - - pop edi - pop esi - pop ebp - ret ;copies a string from the source to the destination parameter ;extern void strcpy(char *dest, char *src); diff --git a/kernel/lang/lang.c b/kernel/lang/lang.c new file mode 100644 index 0000000..2782931 --- /dev/null +++ b/kernel/lang/lang.c @@ -0,0 +1,93 @@ +// lang.c +// Author: Josh Holtrop +// Date: 12/30/04 +// Modified: 12/30/04 + +#include "lang.h" + + +/* strcmp compares two strings + * Returns: + * 0 if the strings are equal + * <0 if the second string is less than the first + * >0 if the second string is greater than the first + */ +int strcmp(char *str1, char *str2) +{ + while (*str1 || *str2) + { + if (*str1 != *str2) + return *str2 - *str1; + str1++; + str2++; + } + return 0; +} + +/* strncmp compares up to n characters of two strings + * Returns: + * 0 if the strings are equal + * <0 if the second string is less than the first + * >0 if the second string is greater than the first + */ +int strncmp(char *str1, char *str2, int n) +{ + while (n > 0 && (*str1 || *str2)) + { + if (*str1 != *str2) + return *str2 - *str1; + str1++; + str2++; + n--; + } + return 0; +} + + +// counts the occurrences of lookfor in str +int str_count(char *str, char lookfor) +{ + int count = 0; + while (*str) + { + if (*str == lookfor) + count++; + str++; + } + return count; +} + +// split the string into substrings by the splitchar, return number of substrings +int str_split(char *str, char splitchar) +{ + int subs = 1; + while (*str) + { + if (*str == splitchar) + { + *str = 0; + subs++; + } + str++; + } + return subs; +} + +// advance the string pointer to the next substring, return a pointer to the next substring +char *str_advance(char *str) +{ + char *next = str; + while (*next) + next++; // advance pointer to end of this substring (null character) + return next + 1; +} + + +// concatentate src onto the end of dest +void strcat(char *dest, char *src) +{ + while (*dest) + dest++; + strcpy(dest, src); +} + diff --git a/kernel/lang/asmfuncs.h b/kernel/lang/lang.h similarity index 62% rename from kernel/lang/asmfuncs.h rename to kernel/lang/lang.h index a3340ad..7ce58d1 100644 --- a/kernel/lang/asmfuncs.h +++ b/kernel/lang/lang.h @@ -1,11 +1,14 @@ -// asmfuncs.h +// lang.h // Author: Josh Holtrop // Created: 02/26/04 -// Modified: 07/11/04 +// Modified: 12/30/04 -#ifndef __HOS_ASMFUNCS__ -#define __HOS_ASMFUNCS__ __HOS_ASMFUNCS__ +#ifndef __HOS_LANG__ +#define __HOS_LANG__ __HOS_LANG__ +#include "hos_defines.h" + +/* lang.asm */ u32_t write_cr0(u32_t cr0); u32_t read_cr0(); u32_t write_cr3(u32_t cr3); @@ -23,6 +26,14 @@ void *memsetd(void *buffer, int c, int num); u32_t strlen(const char *str); void invlpg_(u32_t addr); +/* lang.c */ +int strcmp(char *str1, char *str2); +int strncmp(char *str1, char *str2, int n); +int str_count(char *str, char lookfor); +int str_split(char *str, char splitchar); +char *str_advance(char *str); +void strcat(char *dest, char *src); + #endif diff --git a/kernel/mm/vmm.c b/kernel/mm/vmm.c index 44a761c..73bc5a1 100644 --- a/kernel/mm/vmm.c +++ b/kernel/mm/vmm.c @@ -7,7 +7,7 @@ #include "hos_defines.h" #include "kernel.h" #include "mm/vmm.h" -#include "lang/asmfuncs.h" +#include "lang/lang.h" #include "mm/mm.h" int vmm_map_range(void *virt_start, void *virt_end, u32_t phys_start);