Import backup from 2004-12-30
This commit is contained in:
parent
6bad3f2b96
commit
76a243d894
1
Makefile
1
Makefile
@ -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)
|
||||||
|
@ -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 #
|
||||||
|
@ -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];
|
||||||
|
|
||||||
|
@ -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"
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
249
kernel/fs/ext2.c
249
kernel/fs/ext2.c
@ -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;
|
||||||
length--;
|
|
||||||
fil[length] = 0;
|
|
||||||
}
|
|
||||||
u32_t inode_number = 0;
|
|
||||||
// TODO: get inode number
|
|
||||||
|
|
||||||
kfree(fil);
|
|
||||||
return inode_number;
|
|
||||||
}
|
|
||||||
|
|
||||||
// DEBUG
|
|
||||||
void ext2_dump_root(vfs_mount_t *mount)
|
|
||||||
{
|
|
||||||
ext2_open_dir_t *root_dir = ext2_open_dir(mount, 2);
|
|
||||||
ext2_dir_entry_t dentry;
|
ext2_dir_entry_t dentry;
|
||||||
while (!ext2_dir_read_entry(mount, root_dir, &dentry))
|
while (subs--)
|
||||||
{
|
{
|
||||||
kprintf("Directory Entry: inode %d, length %d, name_length %d, file_type 0x%x, name '%s'\n",
|
if (ext2_dir_lookup(mount, on_dir, lookupName, &dentry))
|
||||||
dentry.inode, dentry.length, dentry.name_length, dentry.file_type, dentry.name);
|
{
|
||||||
|
kfree(fil);
|
||||||
|
return 0; // entry not found
|
||||||
}
|
}
|
||||||
ext2_close_dir(mount, root_dir);
|
on_dir = dentry.inode;
|
||||||
|
lookupName = str_advance(lookupName);
|
||||||
|
}
|
||||||
|
kfree(fil);
|
||||||
|
return on_dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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 *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, dir, &dentry))
|
||||||
|
{
|
||||||
|
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, 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#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
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/******************************************/
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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
93
kernel/lang/lang.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user