Import backup from 2004-12-30

This commit is contained in:
Josh Holtrop 2004-12-30 22:00:00 -05:00
parent 6bad3f2b96
commit 76a243d894
18 changed files with 408 additions and 158 deletions

View File

@ -62,6 +62,7 @@ initrd:
mke2fs -Fv -m0 -r0 -i1024 $(INITRD) mke2fs -Fv -m0 -r0 -i1024 $(INITRD)
-mkdir $(INITRD_MOUNT) -mkdir $(INITRD_MOUNT)
mount -t ext2 -o loop $(INITRD) $(INITRD_MOUNT) mount -t ext2 -o loop $(INITRD) $(INITRD_MOUNT)
touch $(INITRD_MOUNT)/hi\ there
mkdir $(INITRD_MOUNT)/txt mkdir $(INITRD_MOUNT)/txt
cp Makefile $(INITRD_MOUNT)/txt cp Makefile $(INITRD_MOUNT)/txt
umount $(INITRD_MOUNT) umount $(INITRD_MOUNT)

View File

@ -17,13 +17,13 @@ LD_FLAGS=-nodefaultlibs -nostdlib --no-demangle -T link.ld
all: Asm_Kernel C_Kernel all: Asm_Kernel C_Kernel
$(LD) $(LD_FLAGS) -Map kernel.map \ $(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 \ 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: Asm_Kernel:
$(NASM) $(NASM_FLAGS) -l boot.lst boot.asm -o boot.o $(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: C_Kernel:
$(CC) $(CC_FLAGS) -c kernel.c -o kernel.o $(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/devfs.c -o devfs.o
$(CC) $(CC_FLAGS) -c fs/vfs.c -o vfs.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 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 # # Clean up the source directory of any binaries #

View File

@ -7,7 +7,7 @@
#include "fs/devices.h" #include "fs/devices.h"
#include "functions.h" #include "functions.h"
#include "mm/vmm.h" #include "mm/vmm.h"
#include "lang/asmfuncs.h" #include "lang/lang.h"
ramdisk_t *ramdisks[256]; ramdisk_t *ramdisks[256];

View File

@ -7,7 +7,7 @@
#include "hos_defines.h" #include "hos_defines.h"
#include "fs/devices.h" #include "fs/devices.h"
#include "mm/vmm.h" #include "mm/vmm.h"
#include "lang/asmfuncs.h" #include "lang/lang.h"
#include "display.h" #include "display.h"
#include "functions.h" #include "functions.h"

View File

@ -6,7 +6,7 @@
#include "fs/devices.h" #include "fs/devices.h"
#include "char/vconsole.h" #include "char/vconsole.h"
#include "display.h" #include "display.h"
#include "lang/asmfuncs.h" #include "lang/lang.h"
int display_activeConsole = -1; // start with no active console int display_activeConsole = -1; // start with no active console
display_t myDisplays[12]; // f1-f12 change displays display_t myDisplays[12]; // f1-f12 change displays

View File

@ -9,7 +9,7 @@
#include "ext2.h" #include "ext2.h"
#include "mm/vmm.h" #include "mm/vmm.h"
#include "fs/vfs.h" #include "fs/vfs.h"
#include "lang/asmfuncs.h" #include "lang/lang.h"
#include "functions.h" #include "functions.h"
/* Turning an inode number into a (group, inode_index) pair: /* 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->mount_super = ext2_mount_super;
fs->umount_super = ext2_umount_super; fs->umount_super = ext2_umount_super;
fs->mkfs = ext2_mkfs;
fs->stat = ext2_stat; 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); vfs_register_fs(fsID, fs);
return 0; 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 // mount the superblock of the filesystem and return a pointer to it, if valid
void *ext2_mount_super(major_t major, minor_t minor) 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; 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 // stat a file, return a structure of info about it
int ext2_stat(vfs_mount_t *mount, char *file, vfs_stat_t *stat) 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) switch(inode.i_mode & EXT2_I_MODE_TYPE_MASK)
{ {
case EXT2_I_MODE_FIFO: stat->type = VFS_FT_FIFO; case EXT2_I_MODE_FIFO: stat->type = VFS_FT_FIFO; break;
case EXT2_I_MODE_CHAR: stat->type = VFS_FT_CHAR; case EXT2_I_MODE_CHAR: stat->type = VFS_FT_CHAR; break;
case EXT2_I_MODE_DIR: stat->type = VFS_FT_DIR; case EXT2_I_MODE_DIR: stat->type = VFS_FT_DIR; break;
case EXT2_I_MODE_BLOCK: stat->type = VFS_FT_BLOCK; case EXT2_I_MODE_BLOCK: stat->type = VFS_FT_BLOCK; break;
case EXT2_I_MODE_FILE: stat->type = VFS_FT_FILE; case EXT2_I_MODE_FILE: stat->type = VFS_FT_FILE; break;
case EXT2_I_MODE_SYM: stat->type = VFS_FT_SYMLINK; case EXT2_I_MODE_SYM: stat->type = VFS_FT_SYMLINK; break;
case EXT2_I_MODE_SOCK: stat->type = VFS_FT_SOCK; case EXT2_I_MODE_SOCK: stat->type = VFS_FT_SOCK; break;
default: stat->type = VFS_FT_UNKNOWN; default: stat->type = VFS_FT_UNKNOWN; break;
} }
stat->size = inode.i_size; stat->size = inode.i_size;
stat->inode = inode_number; stat->inode = inode_number;
@ -92,34 +95,51 @@ u32_t ext2_get_inode_number(vfs_mount_t *mount, char *file)
{ {
if (file[0] != '/') if (file[0] != '/')
return 0; return 0;
int length = strlen(file); if (strlen(file) == 1)
if (length == 1) return 2; // root inode number
return 2; char *fil = kmalloc(strlen(file));
char *fil = kmalloc(length + 1); strcpy(fil, file + 1);
strcpy(fil, file); int subs = str_split(fil, '/'); // how many levels are there to do lookups on?
if (fil[length-1] == '/') u32_t on_dir = 2; // start on the root directory
char *lookupName = fil;
ext2_dir_entry_t dentry;
while (subs--)
{ {
length--; if (ext2_dir_lookup(mount, on_dir, lookupName, &dentry))
fil[length] = 0; {
kfree(fil);
return 0; // entry not found
}
on_dir = dentry.inode;
lookupName = str_advance(lookupName);
} }
u32_t inode_number = 0;
// TODO: get inode number
kfree(fil); 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; 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", char *dentryName = kcalloc(1, dentry.name_length + 1);
dentry.inode, dentry.length, dentry.name_length, dentry.file_type, dentry.name); 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 // 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_dir_t *open_dir = New(ext2_open_dir_t);
ext2_open_inode_t *open_inode = ext2_open_inode(mount, inode_number); 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); kfree(open_dir);
return NULL; 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); kfree(block);
return -2; // EOF return -2; // EOF
} }
memcpy(dentry, dir_entry, min(dir_entry->length, sizeof(ext2_dir_entry_t))); memcpy(dentry, dir_entry, min(dir_entry->length, sizeof(ext2_dir_entry_t)));
open_dir->position += dir_entry->length; open_dir->position += dir_entry->length;
kfree(block); kfree(block);
@ -167,6 +186,7 @@ int ext2_close_dir(vfs_mount_t *mount, ext2_open_dir_t *open_dir)
return 0; return 0;
} }
// open an inode for reading // open an inode for reading
ext2_open_inode_t *ext2_open_inode(vfs_mount_t *mount, u32_t inode_number) 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; 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 // 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) 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); 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 // 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) 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]; 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 // read the inode structure from the device and return it
ext2_inode_t ext2_get_inode(vfs_mount_t *mount, u32_t inode) 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; 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);
}

View File

@ -13,19 +13,20 @@
#define EXT2_MAGIC 0xEF53 #define EXT2_MAGIC 0xEF53
#define EXT2_NAME_LEN 255 #define EXT2_NAME_LEN 255
#define EXT2_I_MODE_ATTR_MASK 0x0FFF #define EXT2_I_MODE_ATTR_MASK 0x0FFF
#define EXT2_I_MODE_OX 0x0001 #define EXT2_I_MODE_OX 0x0001
#define EXT2_I_MODE_OW 0x0002 #define EXT2_I_MODE_OW 0x0002
#define EXT2_I_MODE_OR 0x0004 #define EXT2_I_MODE_OR 0x0004
#define EXT2_I_MODE_GX 0x0008 #define EXT2_I_MODE_GX 0x0008
#define EXT2_I_MODE_GW 0x0010 #define EXT2_I_MODE_GW 0x0010
#define EXT2_I_MODE_GR 0x0020 #define EXT2_I_MODE_GR 0x0020
#define EXT2_I_MODE_UX 0x0040 #define EXT2_I_MODE_UX 0x0040
#define EXT2_I_MODE_UW 0x0080 #define EXT2_I_MODE_UW 0x0080
#define EXT2_I_MODE_UR 0x0100 #define EXT2_I_MODE_UR 0x0100
#define EXT2_I_MODE_STICKY 0x0200 #define EXT2_I_MODE_STICKY 0x0200
#define EXT2_I_MODE_SGID 0x0400 #define EXT2_I_MODE_SGID 0x0400
#define EXT2_I_MODE_SUID 0x0800 #define EXT2_I_MODE_SUID 0x0800
#define EXT2_I_MODE_TYPE_MASK 0xF000 #define EXT2_I_MODE_TYPE_MASK 0xF000
#define EXT2_I_MODE_FIFO 0x1000 #define EXT2_I_MODE_FIFO 0x1000
#define EXT2_I_MODE_CHAR 0x2000 #define EXT2_I_MODE_CHAR 0x2000
@ -152,7 +153,6 @@ typedef struct
u32_t position; u32_t position;
} ext2_open_dir_t; } ext2_open_dir_t;
static inline u32_t ext2_diskToFSBlock(u32_t block, ext2_super_block_t *super) static inline u32_t ext2_diskToFSBlock(u32_t block, ext2_super_block_t *super)
{ {
// convert # of disk blocks to # of filesystem blocks // 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); int ext2_init(int fsID);
void *ext2_mount_super(major_t major, minor_t minor); void *ext2_mount_super(major_t major, minor_t minor);
int ext2_umount_super(vfs_mount_t *mount); 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_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); 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); 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); 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_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_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 #endif

View File

@ -9,7 +9,7 @@
#include "fs/ext2.h" #include "fs/ext2.h"
#include "kernel.h" #include "kernel.h"
#include "mm/vmm.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_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 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); kfree(mnt);
return -4; // could not add mount return -4; // could not add mount
} }
// DEBUG
ext2_dump_root(mnt);
return 0; 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() void vfs_dump_tree()
{ {
if (!vfsMountTree) if (!vfsMountTree)
@ -269,4 +312,5 @@ void vfs_dump_node(vfs_node_t *node, int level)
node = node->next; node = node->next;
} }
} }
/******************************************/

View File

@ -21,6 +21,7 @@
#define VFS_FT_SOCK 6 #define VFS_FT_SOCK 6
#define VFS_FT_SYMLINK 7 #define VFS_FT_SYMLINK 7
#define EOF 1000000
/* Structure to hold information about a mount point */ /* Structure to hold information about a mount point */
typedef struct typedef struct
@ -68,13 +69,34 @@ typedef struct
u16_t links; u16_t links;
} vfs_stat_t; } 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 */ /* Every filesystem must provide pointers to its respective functions in a structure like this */
typedef struct typedef struct
{ {
void *(*mount_super)(major_t major, minor_t minor); void *(*mount_super)(major_t major, minor_t minor);
int (*umount_super)(vfs_mount_t *mount); 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 (*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; } 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); vfs_mount_match_t vfs_get_rel_path(char *path);
int vfs_umount(char *mountPoint); int vfs_umount(char *mountPoint);
int vfs_retire_node(vfs_node_t *node); 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_tree();
void vfs_dump_node(vfs_node_t *node, int level); void vfs_dump_node(vfs_node_t *node, int level);

View File

@ -7,7 +7,7 @@
#include "kernel.h" #include "kernel.h"
#include "multiboot.h" #include "multiboot.h"
#include "module.h" #include "module.h"
#include "lang/asmfuncs.h" #include "lang/lang.h"
#include "functions.h" #include "functions.h"
#include "mm/mm.h" #include "mm/mm.h"
#include "mm/vmm.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--; criticalCounter--;
} }
@ -153,6 +167,9 @@ void isr(u32_t num)
isr_keyboard(); isr_keyboard();
pic_eoi(); pic_eoi();
break; break;
case 0x30:
kprintf("User interrupt requested\n");
break;
default: default:
kprintf("Unhandled interrupt #%d, CR2 = 0x%x!\n", num, read_cr2()); kprintf("Unhandled interrupt #%d, CR2 = 0x%x!\n", num, read_cr2());
halt(); halt();

View File

@ -61,6 +61,10 @@ void kprintf(char *fmt, ...)
putHex(*params); putHex(*params);
params++; params++;
break; break;
case 'o': case 'O':
putOct(*params);
params++;
break;
case 'b': case 'B': case 'b': case 'B':
kio_putBCD(*params); kio_putBCD(*params);
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 // This function prints a two-digit binary-coded-decimal value
void kio_putBCD(u32_t bcd) void kio_putBCD(u32_t bcd)
{ {

View File

@ -14,6 +14,7 @@ void putc(int c);
void puts(char *str); void puts(char *str);
void putDec(int num); void putDec(int num);
void putDecu(u32_t num); void putDecu(u32_t num);
void putOct(u32_t number);
#endif #endif

View File

@ -1,6 +1,7 @@
// conv.h // conv.h
// Author: Josh Holtrop // Author: Josh Holtrop
// Date: 08/02/04 // Date: 08/02/04
// Modified: 12/30/04
#include "conv.h" #include "conv.h"
#include "hos_defines.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 // convert signed integer to decimal string
int itoa(int num, char *buf) int itoa(int num, char *buf)
{ {

View File

@ -1,6 +1,7 @@
// conv.h // conv.h
// Author: Josh Holtrop // Author: Josh Holtrop
// Date: 08/02/04 // Date: 08/02/04
// Modified: 12/30/04
#ifndef __HOS_CONV__ #ifndef __HOS_CONV__
#define __HOS_CONV__ __HOS_CONV__ #define __HOS_CONV__ __HOS_CONV__
@ -9,6 +10,7 @@
int bcdtoa(u32_t bcd, char *buf); int bcdtoa(u32_t bcd, char *buf);
int itox(u32_t num, char *buf); int itox(u32_t num, char *buf);
int itoo(u32_t num, char *buf);
int itoa(int num, char *buf); int itoa(int num, char *buf);
int utoa(u32_t num, char *buf); int utoa(u32_t num, char *buf);

View File

@ -1,7 +1,7 @@
; asmfuncs.asm ; lang.asm
; Josh Holtrop ; Josh Holtrop
; Created: 10/23/03 ; Created: 10/23/03
; Modified: 07/11/04 ; Modified: 12/30/04
%macro jzfar 1 %macro jzfar 1
@ -58,38 +58,6 @@ _read_cr3:
ret 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 ;copies a string from the source to the destination parameter
;extern void strcpy(char *dest, char *src); ;extern void strcpy(char *dest, char *src);

93
kernel/lang/lang.c Normal file
View File

@ -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);
}

View File

@ -1,11 +1,14 @@
// asmfuncs.h // lang.h
// Author: Josh Holtrop // Author: Josh Holtrop
// Created: 02/26/04 // Created: 02/26/04
// Modified: 07/11/04 // Modified: 12/30/04
#ifndef __HOS_ASMFUNCS__ #ifndef __HOS_LANG__
#define __HOS_ASMFUNCS__ __HOS_ASMFUNCS__ #define __HOS_LANG__ __HOS_LANG__
#include "hos_defines.h"
/* lang.asm */
u32_t write_cr0(u32_t cr0); u32_t write_cr0(u32_t cr0);
u32_t read_cr0(); u32_t read_cr0();
u32_t write_cr3(u32_t cr3); 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); u32_t strlen(const char *str);
void invlpg_(u32_t addr); 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 #endif

View File

@ -7,7 +7,7 @@
#include "hos_defines.h" #include "hos_defines.h"
#include "kernel.h" #include "kernel.h"
#include "mm/vmm.h" #include "mm/vmm.h"
#include "lang/asmfuncs.h" #include "lang/lang.h"
#include "mm/mm.h" #include "mm/mm.h"
int vmm_map_range(void *virt_start, void *virt_end, u32_t phys_start); int vmm_map_range(void *virt_start, void *virt_end, u32_t phys_start);