From 89d962e33a2d4fdc8551c3040b6864d6ce31e571 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Sat, 31 Dec 2005 22:00:00 -0500 Subject: [PATCH] Import backup from 2005-12-31 --- Makefile | 1 - apps/test1.app | Bin 31 -> 15 bytes apps/test1.asm | 10 +- apps/test2.app | Bin 31 -> 15 bytes apps/test2.asm | 10 +- initrd/bin/init | Bin 0 -> 15 bytes initrd/ulab | 46 ++++++ kernel/fs/ext2/Ext2BlockCache.cpp | 34 ++--- kernel/fs/ext2/Ext2BlockCache.h | 4 +- kernel/fs/ext2/Ext2OpenDirectory.cpp | 24 ++- kernel/fs/ext2/Ext2OpenFile.cpp | 209 ++++++++++++++++++++++++++- kernel/fs/ext2/Ext2OpenFile.h | 19 +++ kernel/fs/ext2/ext2.cpp | 124 +++++++++++++--- kernel/fs/ext2/ext2.h | 5 +- kernel/fs/vfs.h | 2 +- kernel/hos_defines.h | 13 +- kernel/kernel.c | 57 ++++++-- kernel/lang/lang.asm | 37 +++++ kernel/lang/lang.h | 2 + menu.lst | 2 - 20 files changed, 521 insertions(+), 78 deletions(-) create mode 100644 initrd/bin/init create mode 100644 initrd/ulab diff --git a/Makefile b/Makefile index 01077e6..f79a761 100644 --- a/Makefile +++ b/Makefile @@ -57,7 +57,6 @@ install_img: copy_image install install_img: -mkdir $(FLOPPY_MOUNT) $(MOUNT) -t ext2 $(MOUNT_FLAGS) $(FDEV) $(FLOPPY_MOUNT) - -cp apps/*.app $(FLOPPY_MOUNT) -cp kernel/kernel.bin $(FLOPPY_MOUNT) -cp rmmod/rmmod.bin $(FLOPPY_MOUNT) -cp menu.lst $(FLOPPY_MOUNT)/boot/grub diff --git a/apps/test1.app b/apps/test1.app index 714cde462a5416913c98efc789ad6c6bdf045eca..a06f0443d9730440253c2d0bd7d611b710c10b03 100644 GIT binary patch literal 15 VcmdnN$iTp`I|E3ZHF*8$FaRI~1$qDg literal 31 gcmeb95B6nZU|readInode(inum, &myInode); + myInode = inode; myBlockSize = 1024 << fs->getSuper()->s_log_block_size; for (int i = 0; i < 3; i++) { @@ -34,7 +30,7 @@ Ext2BlockCache::~Ext2BlockCache() delete[] myCache[i]; } if (myInodeDirty) - myFS->writeInode(myInum, &myInode); + myFS->writeInode(myInum, myInode); } int Ext2BlockCache::readBlock(u32_t blockNum, void *buf) @@ -68,22 +64,22 @@ u32_t Ext2BlockCache::getFSBlock(u32_t blockNum, int create) { if (blockNum < 12) /* direct pointer */ { - if (create && myInode.i_block[blockNum] == 0) + if (create && myInode->i_block[blockNum] == 0) { - myInode.i_block[blockNum] = myFS->allocBlock(); + myInode->i_block[blockNum] = myFS->allocBlock(); myInodeDirty = 1; } - return myInode.i_block[blockNum]; + return myInode->i_block[blockNum]; } blockNum -= 12; if (blockNum < myBlockSize) /* i_block[12] */ { - if (create && myInode.i_block[12] == 0) + if (create && myInode->i_block[12] == 0) { - myInode.i_block[12] = myFS->allocBlock(); + myInode->i_block[12] = myFS->allocBlock(); myInodeDirty = 1; } - setCache(0, myInode.i_block[12]); + setCache(0, myInode->i_block[12]); /* blockNum indexes cache 0 */ if (create && myCache[0][blockNum] == 0) { @@ -95,12 +91,12 @@ u32_t Ext2BlockCache::getFSBlock(u32_t blockNum, int create) blockNum -= myBlockSize; if (blockNum < (myBlockSize * myBlockSize)) /* i_block[13] */ { - if (create && myInode.i_block[13] == 0) + if (create && myInode->i_block[13] == 0) { - myInode.i_block[13] = myFS->allocBlock(); + myInode->i_block[13] = myFS->allocBlock(); myInodeDirty = 1; } - setCache(0, myInode.i_block[13]); + setCache(0, myInode->i_block[13]); /* blockNum / myBlockSize indexes cache 0 */ if (create && myCache[0][blockNum / myBlockSize] == 0) { @@ -117,12 +113,12 @@ u32_t Ext2BlockCache::getFSBlock(u32_t blockNum, int create) return myCache[1][blockNum % myBlockSize]; } blockNum -= (myBlockSize * myBlockSize); /* i_block[14] */ - if (create && myInode.i_block[14] == 0) + if (create && myInode->i_block[14] == 0) { - myInode.i_block[14] = myFS->allocBlock(); + myInode->i_block[14] = myFS->allocBlock(); myInodeDirty = 1; } - setCache(0, myInode.i_block[14]); + setCache(0, myInode->i_block[14]); /* blockNum / (myBlockSize^2) indexes cache 0 */ if (create && myCache[0][blockNum / (myBlockSize * myBlockSize)] == 0) { diff --git a/kernel/fs/ext2/Ext2BlockCache.h b/kernel/fs/ext2/Ext2BlockCache.h index ad77089..bdf9b15 100644 --- a/kernel/fs/ext2/Ext2BlockCache.h +++ b/kernel/fs/ext2/Ext2BlockCache.h @@ -14,7 +14,7 @@ class Ext2BlockCache protected: Ext2fs *myFS; u32_t myInum; - ext2_inode_t myInode; + ext2_inode_t *myInode; u32_t myBlockSize; u8_t *myCache[3]; u8_t myCacheAddress[3]; @@ -25,7 +25,7 @@ protected: u32_t getFSBlock(u32_t block, int create); public: - Ext2BlockCache(Ext2fs *fs, u32_t inum); + Ext2BlockCache(Ext2fs *fs, u32_t inum, ext2_inode_t *inode); ~Ext2BlockCache(); int readBlock(u32_t blockNum, void *buf); int writeBlock(u32_t blockNum, void *buf); diff --git a/kernel/fs/ext2/Ext2OpenDirectory.cpp b/kernel/fs/ext2/Ext2OpenDirectory.cpp index c26688b..c83c21c 100644 --- a/kernel/fs/ext2/Ext2OpenDirectory.cpp +++ b/kernel/fs/ext2/Ext2OpenDirectory.cpp @@ -4,7 +4,6 @@ // Modified: 12/26/05 extern "C" { -#include "display/kout.h" #include "lang/lang.h" } @@ -19,7 +18,7 @@ Ext2OpenDirectory::Ext2OpenDirectory(Ext2fs *fs, u32_t inum, int mode) myFS = fs; myInum = inum; myMode = mode; - myCache = new Ext2BlockCache(fs, inum); + myCache = new Ext2BlockCache(fs, inum, &myInode); fs->readInode(inum, &myInode); u32_t size = myInode.i_size; u32_t logBlockSize = fs->getSuper()->s_log_block_size; @@ -36,8 +35,7 @@ Ext2OpenDirectory::Ext2OpenDirectory(Ext2fs *fs, u32_t inum, int mode) Ext2OpenDirectory::~Ext2OpenDirectory() { delete myCache; - if ((myMode & VFS_MODE_RW_MASK) == VFS_MODE_READ) - delete[] myBuffer; + delete[] myBuffer; } void Ext2OpenDirectory::readDirectory() @@ -121,6 +119,15 @@ int Ext2OpenDirectory::create(char *name, int mode, u32_t permissions, u32_t dev in.i_mode = ext2_mode | (permissions & EXT2_I_MODE_ATTR_MASK); in.i_links_count = 1; myFS->writeInode(newInode, &in); + if (mode == VFS_FT_DIR) + { + if (myFS->getSuper()->s_free_blocks_count < 3) + return -4; /* out of space on device */ + if (myFS->initializeDirectory(newInode, myInum)) + return -5; /* error initializing directory */ + myInode.i_links_count++; + myFS->writeInode(myInum, &myInode); + } u32_t entryLength = name_length + 8; if (entryLength & 0x3) entryLength = (entryLength + 4) & 0xFFFFFFFC; /* multiple of 4 bytes */ @@ -135,8 +142,8 @@ int Ext2OpenDirectory::create(char *name, int mode, u32_t permissions, u32_t dev if (de->length - thisEntryLength >= entryLength) { /* There is room in this entry for the new one */ - u32_t newLength = de->length - entryLength; - de->length = entryLength; + u32_t newLength = de->length - thisEntryLength; + de->length = thisEntryLength; u32_t firstPosition = myPosition; myPosition += de->length; de = (ext2_dir_entry_t *) (myBuffer + myPosition); @@ -151,7 +158,10 @@ int Ext2OpenDirectory::create(char *name, int mode, u32_t permissions, u32_t dev if (myPosition + de->length >= myInode.i_size) { if (myFS->getSuper()->s_free_blocks_count < 2) + { + myFS->freeInode(newInode); return -4; /* out of space on device */ + } /* This is the last entry, we need to add a block */ myBlocks++; u8_t *newBuffer = new u8_t[myBlockSize * myBlocks]; @@ -173,6 +183,8 @@ int Ext2OpenDirectory::create(char *name, int mode, u32_t permissions, u32_t dev memcpy(de->name, name, name_length); writeInclusiveRange(firstPosition, myPosition + myBlockSize + leftovers - 1); + myInode.i_size += myBlockSize; + myFS->writeInode(myInum, &myInode); return 0; } myPosition += de->length; diff --git a/kernel/fs/ext2/Ext2OpenFile.cpp b/kernel/fs/ext2/Ext2OpenFile.cpp index 98eeb81..3857671 100644 --- a/kernel/fs/ext2/Ext2OpenFile.cpp +++ b/kernel/fs/ext2/Ext2OpenFile.cpp @@ -5,17 +5,224 @@ #include "Ext2OpenFile.h" +extern "C" { +#include "lang/lang.h" +#include "functions.h" +} + +lock_t Ext2OpenFileListLock; +vector *Ext2OpenFileList = NULL; + +/* make an Ext2OpenFile object + * maintain vector of open files for notifying when one is truncated + */ Ext2OpenFile::Ext2OpenFile(Ext2fs *fs, u32_t inum, int mode) { myMode = mode; myFS = fs; myInum = inum; - myCache = new Ext2BlockCache(fs, inum); + myBeenTruncated = 0; + myPosition = 0; + myBlockSize = 1024 << fs->getSuper()->s_log_block_size; + myBlockCache = new u8_t[myBlockSize]; + myBlockCacheBlock = 0; + myBlockCacheStatus = 0; /* 0: invalid; 1: valid; 2: dirty */ fs->readInode(inum, &myInode); + myCache = new Ext2BlockCache(fs, inum, &myInode); + lock(&Ext2OpenFileListLock); + if ((mode & VFS_MODE_RW_MASK) == VFS_MODE_WRITE) + { + if ((mode & VFS_MODE_WRITE_MASK) == VFS_MODE_TRUNCATE) + { + /* file opened for write/truncate + * tell any open files that it's been truncated, then + * tell ext2 filesystem to free its blocks + */ + u32_t size = Ext2OpenFileList->size(); + for (u32_t i = 0; i < size; i++) + { + if ((*Ext2OpenFileList)[i].inode == inum) + (*Ext2OpenFileList)[i].ofile->notifyTruncated(); + } + fs->truncateInode(inum); + fs->readInode(inum, &myInode); /* re-read inode */ + } + else + myPosition = myInode.i_size; + } + if (Ext2OpenFileList == NULL) + Ext2OpenFileList = new vector(); + /* add ourselves to the list */ + Ext2OpenFileHandle thisHandle = {inum, this}; + Ext2OpenFileList->add(thisHandle); + unlock(&Ext2OpenFileListLock); } +/* destroy an Ext2OpenFile object */ Ext2OpenFile::~Ext2OpenFile() { + /* remove ourselves from the open file list */ + lock(&Ext2OpenFileListLock); + u32_t size = Ext2OpenFileList->size(); + for (u32_t i = 0; i < size; i++) + { + if ((*Ext2OpenFileList)[i].ofile == this) + { + Ext2OpenFileList->remove(i); + break; + } + } + unlock(&Ext2OpenFileListLock); + + /* write back any open caches if in write mode */ + if ( !myBeenTruncated && ((myMode & VFS_MODE_RW_MASK) == VFS_MODE_WRITE) ) + { + if (myBlockCacheStatus == 2) + myCache->writeBlock(myBlockCacheBlock, myBlockCache); + myFS->writeInode(myInum, &myInode); + } + /* free the memory we used */ delete myCache; + delete[] myBlockCache; } +/* seek to a certain position in the file (only for reading) */ +int Ext2OpenFile::seek(int pos, int mode) +{ + if ((myMode & VFS_MODE_RW_MASK) != VFS_MODE_READ) + return -1; + if (mode == SEEK_ABSOLUTE) + { + if (pos < 0) + return -2; + if ((u32_t)pos >= myInode.i_size) + return -3; + myPosition = pos; + return 0; + } + else if (mode == SEEK_RELATIVE) + { + if (myPosition + pos < 0) + return -2; + if (myPosition + pos >= myInode.i_size) + return -3; + myPosition += pos; + return 0; + } + else if (mode == SEEK_END) + { + if (myInode.i_size + pos < 0) + return -2; + if (myInode.i_size + pos >= myInode.i_size) + return -3; + myPosition = myInode.i_size + pos; + return 0; + } + return -4; +} + +/* read a byte from the current file position, return error code/EOF */ +int Ext2OpenFile::read() +{ + if ((myMode & VFS_MODE_RW_MASK) != VFS_MODE_READ) + return -1; + if (myBeenTruncated || myPosition >= myInode.i_size) + return EOF; + u32_t theBlock = myPosition / myBlockSize; + updateCache(theBlock); + return myBlockCache[myPosition++ % myBlockSize]; +} + +/* read num bytes from the current file position, put in buf + * return: number of bytes read (>=0) or error code (<0) + */ +int Ext2OpenFile::read(void *buf, u32_t num) +{ + if ((myMode & VFS_MODE_RW_MASK) != VFS_MODE_READ) + return -1; + if (myBeenTruncated || myPosition >= myInode.i_size) + return EOF; + if (myPosition + num > myInode.i_size) + num = myInode.i_size - myPosition; + u32_t bytesRead = 0; + u32_t bytesIntoFirstBlock = myPosition % myBlockSize; + if (bytesIntoFirstBlock) + { + updateCache(myPosition / myBlockSize); + bytesRead = min(myBlockSize - bytesIntoFirstBlock, num); + memcpy(buf, myBlockCache + bytesIntoFirstBlock, bytesRead); + myPosition += bytesRead; + } + while (bytesRead < num) + { + updateCache(myPosition / myBlockSize); + u32_t bytesToRead = min(num - bytesRead, myBlockSize); + memcpy((u8_t *)buf + bytesRead, myBlockCache, bytesToRead); + bytesRead += bytesToRead; + myPosition += bytesToRead; + } + return bytesRead; +} + +/* write a byte to the current file position */ +int Ext2OpenFile::write(int chr) +{ + if ((myMode & VFS_MODE_RW_MASK) != VFS_MODE_WRITE) + return -1; + if (myBeenTruncated) + return EOF; + u32_t theBlock = myPosition / myBlockSize; + updateCache(theBlock); + myBlockCache[myPosition++ % myBlockSize] = chr; + myBlockCacheStatus = 2; + myInode.i_size++; + return 0; +} + +/* write num bytes from buf to the current file position + * return: number of bytes written (>=0) or error code (<0) + */ +int Ext2OpenFile::write(void *buf, u32_t num) +{ + if (myBeenTruncated) + return -1; + if ((myMode & VFS_MODE_RW_MASK) != VFS_MODE_WRITE) + return -2; + u32_t bytesIntoFirstBlock = myPosition % myBlockSize; + u32_t bytesWritten = 0; + if (bytesIntoFirstBlock) + { + updateCache(myPosition / myBlockSize); + bytesWritten = min(myBlockSize - bytesIntoFirstBlock, num); + memcpy(myBlockCache + bytesIntoFirstBlock, buf, bytesWritten); + myBlockCacheStatus = 2; + myPosition += bytesWritten; + } + while (bytesWritten < num) + { + updateCache(myPosition / myBlockSize); + u32_t bytesToWrite = min(num - bytesWritten, myBlockSize); + memcpy(myBlockCache, (u8_t *)buf + bytesWritten, bytesToWrite); + myBlockCacheStatus = 2; + bytesWritten += bytesToWrite; + myPosition += bytesToWrite; + } + myInode.i_size += bytesWritten; + return bytesWritten; +} + +void Ext2OpenFile::updateCache(u32_t blockNum) +{ + if (myBlockCacheStatus && myBlockCacheBlock == blockNum) + return; + if (myBlockCacheStatus == 2) + myCache->writeBlock(myBlockCacheBlock, myBlockCache); + myCache->readBlock(blockNum, myBlockCache); + myBlockCacheStatus = 1; + myBlockCacheBlock = blockNum; +} + +void Ext2OpenFile::notifyTruncated() +{ + myBeenTruncated = 1; +} diff --git a/kernel/fs/ext2/Ext2OpenFile.h b/kernel/fs/ext2/Ext2OpenFile.h index 2767f54..fbaf26b 100644 --- a/kernel/fs/ext2/Ext2OpenFile.h +++ b/kernel/fs/ext2/Ext2OpenFile.h @@ -16,13 +16,32 @@ protected: Ext2fs *myFS; u32_t myInum; int myMode; + int myBeenTruncated; /* set true when the file truncated */ + u32_t myPosition; + u32_t myBlockSize; Ext2BlockCache *myCache; ext2_inode_t myInode; + u8_t *myBlockCache; + u32_t myBlockCacheBlock; + int myBlockCacheStatus; /* 0: invalid; 1: valid; 2: dirty */ + + void updateCache(u32_t blockNum); public: Ext2OpenFile(Ext2fs *fs, u32_t inum, int mode); ~Ext2OpenFile(); + int seek(int pos, int mode); + int read(); + int read(void *buf, u32_t num); + int write(int chr); + int write(void *buf, u32_t num); + void notifyTruncated(); }; +typedef struct +{ + u32_t inode; + Ext2OpenFile *ofile; +} Ext2OpenFileHandle; #endif diff --git a/kernel/fs/ext2/ext2.cpp b/kernel/fs/ext2/ext2.cpp index 8ddda62..2bad74a 100644 --- a/kernel/fs/ext2/ext2.cpp +++ b/kernel/fs/ext2/ext2.cpp @@ -67,14 +67,19 @@ Ext2fs::Ext2fs(ext2_super_block_t *super, device_t dev) (mySuper.s_inodes_per_group + myInodesPerBlock - 1) / myInodesPerBlock; - /* test/debug code */ +/* kprintf("free blocks: %u\n", mySuper.s_free_blocks_count); OpenDirectory *od = openDirectory(2, VFS_MODE_WRITE); kprintf("TEST: %d\n", od->unlink("link")); kprintf("TEST: %d\n", od->create("test", VFS_FT_FILE, 0640, 0)); kprintf("TEST: %d\n", od->create("Block File baby", VFS_FT_BLOCK, 0666, 5 << 8 | 3)); + kprintf("TEST: %d\n", od->unlink("bin")); kprintf("TEST: %d\n", od->create("Character-File", VFS_FT_CHAR, 0644, 130 << 8 | 42)); + kprintf("free blocks: %u\n", mySuper.s_free_blocks_count); + kprintf("TEST: %d\n", od->create("a directory", VFS_FT_DIR, 0755, 0)); + kprintf("free blocks: %u\n", mySuper.s_free_blocks_count); delete od; +*/ } /* this destructor destroys an ext2 filesystem that was mounted */ @@ -87,13 +92,13 @@ Ext2fs::~Ext2fs() /* return the total number of 512-blocks on the filesystem */ u32_t Ext2fs::totalBlocks() { - return mySuper.s_blocks_count >> (mySuper.s_log_block_size + 1); + return mySuper.s_blocks_count << (mySuper.s_log_block_size + 1); } /* return the number of free 512-blocks on the filesystem */ u32_t Ext2fs::freeBlocks() { - return mySuper.s_free_blocks_count >> (mySuper.s_log_block_size + 1); + return mySuper.s_free_blocks_count << (mySuper.s_log_block_size + 1); } /* return the total number of inodes on the filesystem */ @@ -124,6 +129,16 @@ OpenDirectory *Ext2fs::openDirectory(u32_t inum, int mode) return NULL; } +/* open a file */ +OpenFile *Ext2fs::openFile(u32_t inum, int mode) +{ + ext2_inode_t inode; + readInode(inum, &inode); + if ((inode.i_mode & EXT2_I_MODE_TYPE_MASK) == EXT2_I_MODE_FILE) + return new Ext2OpenFile(this, inum, mode); + return NULL; +} + /* stat an inode */ int Ext2fs::stat(u32_t inum, vfs_stat_t *buf) { @@ -450,15 +465,6 @@ void Ext2fs::freeFromBitmap(u32_t blockNum, u32_t node) delete[] block; } -/* this function is called when a file is opened for writing and truncates - * the inode. the function notifies any file handles open on this inode that - * the inode was truncated - */ -void Ext2fs::notifyTruncatedFiles(u32_t inum) -{ - // TODO: notify open files -} - /* unlink an inode: * decrement i_links_count * if it is zero, free the inode @@ -474,7 +480,7 @@ void Ext2fs::unlink(u32_t inum) writeInode(inum, &inode); return; } - freeBlocksFromInode(inum); + truncateInode(inum); freeInode(inum); } @@ -498,12 +504,96 @@ int Ext2fs::attemptRemoveDir(u32_t inum) return -1; } delete od; - unlink(dentry.inode); - unlink(dentry2.inode); + unlink(dentry.inum); + unlink(dentry2.inum); + return 0; } -void Ext2fs::freeBlocksFromInode(u32_t inum) +void Ext2fs::truncateInode(u32_t inum) { - + ext2_inode_t inode; + readInode(inum, &inode); + if ( ((inode.i_mode & EXT2_I_MODE_TYPE_MASK) != EXT2_I_MODE_DIR) && + ((inode.i_mode & EXT2_I_MODE_TYPE_MASK) != EXT2_I_MODE_FILE) ) + return; + for (int i = 0; i < 12; i++) + if (inode.i_block[i]) + freeBlock(inode.i_block[i]); + u32_t entriesPerBlock = 256 << mySuper.s_log_block_size; + u32_t *block = new u32_t[entriesPerBlock]; + if (inode.i_block[12]) + { + readBlock(inode.i_block[12], block); + for (u32_t i = 0; i < entriesPerBlock; i++) + if (block[i]) + freeBlock(block[i]); + freeBlock(inode.i_block[12]); + } + if (inode.i_block[13]) + { + readBlock(inode.i_block[13], block); + u32_t *block2 = new u32_t[entriesPerBlock]; + for (u32_t i = 0; i < entriesPerBlock; i++) + if (block[i]) + { + readBlock(block[i], block2); + for (u32_t j = 0; j < entriesPerBlock; j++) + if (block2[j]) + freeBlock(block2[j]); + freeBlock(block[i]); + } + delete[] block2; + freeBlock(inode.i_block[13]); + } + if (inode.i_block[14]) + { + readBlock(inode.i_block[14], block); + u32_t *block2 = new u32_t[entriesPerBlock]; + u32_t *block3 = new u32_t[entriesPerBlock]; + for (u32_t i = 0; i < entriesPerBlock; i++) + if (block[i]) + { + readBlock(block[i], block2); + for (u32_t j = 0; j < entriesPerBlock; j++) + if (block2[j]) + { + readBlock(block2[j], block3); + for (u32_t k = 0; k < entriesPerBlock; k++) + if (block3[k]) + freeBlock(block3[k]); + freeBlock(block2[j]); + } + freeBlock(block[i]); + } + delete[] block2; + delete[] block3; + freeBlock(inode.i_block[14]); + } + delete[] block; + for (int i = 0; i < 15; i++) + inode.i_block[i] = 0; + inode.i_size = 0; + inode.i_blocks = 0; + writeInode(inum, &inode); } +int Ext2fs::initializeDirectory(u32_t inum, u32_t parent) +{ + ext2_inode_t inode; + readInode(inum, &inode); + if ( !(inode.i_block[0] = allocBlock()) ) + return -1; + u8_t *buffer = new u8_t[1024 << mySuper.s_log_block_size]; + ext2_dir_entry_t *de = (ext2_dir_entry_t *) buffer; + de->name_length = 1; + de->length = 12; + de->inode = inum; + memcpy(de->name, ".", 1); + de = (ext2_dir_entry_t *) (buffer + 12); + de->name_length = 2; + de->length = (1024 << mySuper.s_log_block_size) - 12; + de->inode = parent; + memcpy(de->name, "..", 2); + delete[] buffer; + return 0; +} diff --git a/kernel/fs/ext2/ext2.h b/kernel/fs/ext2/ext2.h index 6663b4a..b93d856 100644 --- a/kernel/fs/ext2/ext2.h +++ b/kernel/fs/ext2/ext2.h @@ -175,20 +175,21 @@ public: u32_t freeInodes(); u32_t getRootInodeNumber(); OpenDirectory *openDirectory(u32_t inum, int mode); + OpenFile *openFile(u32_t inum, int mode); int stat(u32_t inum, vfs_stat_t *buf); int readBlock(u32_t blockNum, void *buf); int writeBlock(u32_t blockNum, void *buf); int link_deref(u32_t inum, char *buf); int readInode(u32_t inum, ext2_inode_t *buf); int writeInode(u32_t inum, ext2_inode_t *buf); - void notifyTruncatedFiles(u32_t inum); u32_t allocInode(); u32_t allocBlock(); int freeInode(u32_t inum); int freeBlock(u32_t bnum); void unlink(u32_t inum); int attemptRemoveDir(u32_t inum); - void freeBlocksFromInode(u32_t inum); + void truncateInode(u32_t inum); + int initializeDirectory(u32_t inum, u32_t parent); /* inlined functions */ inline u32_t numGroups() { return myNumGroups; } diff --git a/kernel/fs/vfs.h b/kernel/fs/vfs.h index 9198a54..47de185 100644 --- a/kernel/fs/vfs.h +++ b/kernel/fs/vfs.h @@ -29,7 +29,7 @@ #define VFS_PERMS_SGID 0x0400 #define VFS_PERMS_SUID 0x0800 -#define EOF 0x100 +#define EOF -256 #define VFS_MAX_FILENAME 255 #define VFS_MAX_PATH_LENGTH 1024 diff --git a/kernel/hos_defines.h b/kernel/hos_defines.h index 5acecf7..8db9dd0 100644 --- a/kernel/hos_defines.h +++ b/kernel/hos_defines.h @@ -33,13 +33,16 @@ #define NULL 0 +#define HOS_INIT_TASK "/bin/init" + #define New(x) kcalloc(1, sizeof(x)) -typedef unsigned long long u64_t; -typedef unsigned int u32_t; -typedef unsigned short u16_t; -typedef unsigned char u8_t; -typedef unsigned char byte; +typedef unsigned long long u64_t; +typedef unsigned int u32_t; +typedef unsigned short u16_t; +typedef unsigned char u8_t; +typedef unsigned char byte; +typedef int lock_t; extern u32_t _end; extern u32_t _bss; diff --git a/kernel/kernel.c b/kernel/kernel.c index ae979ee..18f9eaf 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -149,19 +149,37 @@ void k_init() kprintf("initrd (%dkb) loaded\n", (mb_modules[i].mod_end - mb_modules[i].mod_start) >> 10); k_check(vfs_mount(DEV(MAJOR_RAMDISK, initrd_minor), "ext2", "/"), "Kernel panic: Could not mount initrd to /!"); } -/* else if (((hos_module_header_t*)(mb_modules[i].mod_start))->mod_type == 2) - { - kprintf("Creating a task\n"); - create_task((void *)mb_modules[i].mod_start, - mb_modules[i].mod_end - mb_modules[i].mod_start, - 0, - ((hos_module_header_t*)(mb_modules[i].mod_start))->init); - } -*/ } + } -// vfs_mount_info_t mt_info; -// vfs_get_mount_info(0, &mt_info); -// kprintf("%s, %s, %d, %d, %d, %d\n", mt_info.fs, mt_info.mountPoint, mt_info.totalBlocks, mt_info.freeBlocks, mt_info.totalInodes, mt_info.freeInodes); + char *buffer = kmalloc(2000); + void *ulab; + vfs_stat_t ulabstat; + + vfs_stat("/ulab", &ulabstat); + ulab = vfs_open_file("/ulab", VFS_MODE_READ); + vfs_read_file_block(ulab, buffer, ulabstat.size); + for (i = 0; i < ulabstat.size; i++) + putc(buffer[i]); + kprintf("\n"); + vfs_close_file(ulab); + + ulab = vfs_open_file("/ulab", VFS_MODE_WRITE | VFS_MODE_APPEND); + vfs_write_file_block(ulab, "String!!!", 9); + vfs_write_file(ulab, 'H'); + vfs_write_file_block(ulab, "String!!!", 9); + vfs_write_file(ulab, 'I'); + vfs_write_file_block(ulab, "String!!!", 9); + vfs_write_file(ulab, '!'); + vfs_write_file_block(ulab, "String!!!", 9); + vfs_close_file(ulab); + + vfs_stat("/ulab", &ulabstat); + ulab = vfs_open_file("/ulab", VFS_MODE_READ); + vfs_read_file_block(ulab, buffer, ulabstat.size); + for (i = 0; i < ulabstat.size; i++) + putc(buffer[i]); + kprintf("\n"); + vfs_close_file(ulab); void *root = vfs_open_dir("///"); char name[VFS_MAX_PATH_LENGTH]; @@ -205,6 +223,21 @@ void k_init() else kprintf("Error: Could not open directory\n"); + /* Create the initial task */ +/* vfs_stat_t stat; + if (!vfs_stat(HOS_INIT_TASK, &stat)) + { + if (stat.permissions & + (VFS_PERMS_UX | VFS_PERMS_GX | VFS_PERMS_UX)) + { + u8_t *buf = kmalloc(stat.size); + void *file = vfs_open_file(HOS_INIT_TASK, VFS_MODE_READ); + vfs_read_file_block(file, buf, stat.size); + vfs_close_file(file); + create_task(buf, stat.size, 0, 0); + } + } +*/ criticalCounter--; } diff --git a/kernel/lang/lang.asm b/kernel/lang/lang.asm index 73e8348..8972963 100644 --- a/kernel/lang/lang.asm +++ b/kernel/lang/lang.asm @@ -3,6 +3,7 @@ ; Created: 10/23/03 ; Modified: 12/30/04 +[bits 32] %macro jzfar 1 jnz %%skip @@ -11,6 +12,42 @@ %endmacro +;implements a lock +[global _lock] +_lock: + push ebp + mov ebp, esp + push eax + push ebx + push esi + + mov esi, [ebp + 8] +_lock_loop0: + xor eax, eax + mov ebx, 1 + cmpxchg [esi], ebx + jnz _lock_loop0 ; failed to acquire lock + + pop esi + pop ebx + pop eax + pop ebp + ret + +;releases a lock +[global _unlock] +_unlock: + push ebp + mov ebp, esp + push esi + + mov esi, [ebp + 8] + mov [esi], dword 0 + + pop esi + pop ebp + ret + ;returns the value in the CR0 register ;extern dword read_cr0(); [global _read_cr0] diff --git a/kernel/lang/lang.h b/kernel/lang/lang.h index 500f667..b2d3c05 100644 --- a/kernel/lang/lang.h +++ b/kernel/lang/lang.h @@ -9,6 +9,8 @@ #include "hos_defines.h" /* lang.asm */ +void lock(lock_t *addr); +void unlock(lock_t *addr); u32_t read_cr0(); u32_t write_cr0(u32_t cr0); u32_t read_cr2(); diff --git a/menu.lst b/menu.lst index c44c15c..04fa1f0 100644 --- a/menu.lst +++ b/menu.lst @@ -7,5 +7,3 @@ root (fd0) kernel /kernel.bin module /rmmod.bin module /hos_initrd.gz -module /test1.app -module /test2.app