Пример #1
0
void parseCommand(char *command) {
    if (strcmp(command, "help") == 0) {
        putString("command list:\n");
        putString("help  -- display available command\n");
        putString("clear -- clear the screen\n");
        putString("exit  -- halt the machine\n");
        putString("date  -- get date\n");
        putString("time  -- get time\n");
        putString("asc   -- load the custom asc program\n");
        putString("test  -- test program of system calls\n");
    }
    else if (strcmp(command, "clear") == 0)
        clear();
    else if (strcmp(command, "date") == 0) {
        putString(getDate());
        putString("\n");
    }
    else if (strcmp(command, "time") == 0) {
        putString(getTime());
        putString("\n");
    }
    else if (strcmp(command, "asc") == 0)
        loadSector(22, 2);
    else if (strcmp(command, "test") == 0)
        loadSector(24, 3);
    else if (strcmp(command, "exit") == 0)
        status = 0;
}
Пример #2
0
/* 在文件系统中加载文件,文件大小写入size所指变量,返回bool值表示是否成功 */
bool loadFile(const char *path, uint32_t partitionFirstSector, uint32_t *size) {
    printString("    ");

    firstSector = partitionFirstSector;
    loadSector(firstSector + 2, superBlockBuffer);
    blockSize = (uint32_t) (1024 << superBlock->logBlockSize);
    sectorsPerBlock = blockSize / SECTOR_SIZE_512;

    if (superBlock->magic != EXT2_MAGIC_NUM) {
        printLine("incorrect ext2 magic number");
        return false;
    }
    if (superBlock->revLevel < EXT2_DYNAMIC_REV) {
        printLine("reversion of this ext2 filesystem is too old");
        return false;
    }
    if (blockSize > 0x10000) {
        printLine("block size is too large");
        return false;
    }

    uint32_t targetInode = EXT2_INODE_ROOT;

    for (const char *nameEnd = path; *nameEnd != '\0';) {
        for (path = nameEnd; *path == '/'; ++path);
        for (nameEnd = path; *nameEnd != '/' && *nameEnd != '\0'; ++nameEnd);
        if (nameEnd == path) {
            break;
        }
        targetInode = findChild(targetInode, path, nameEnd - path);
        if (targetInode == EXT2_INODE_NULL) {
            printLine("can't find such file");
            return false;
        }
    };

    Ext2Inode inode = loadInode(targetInode);
    if ((inode.mode & EXT2_MODE_FT_MASK) != EXT2_MODE_FT_REG_FILE) {
        printLine("not a regular file");
        return false;
    } else {
        printString("file found, size: ");
        printInt(inode.size);
        printString(" bytes (");
        printStorageSize(inode.size);
        printLine(")");
    }

    uint32_t blkCnt = inode.size / blockSize + (inode.size % blockSize != 0);
    for (uint32_t blockOffset = 0; blockOffset < blkCnt; ++blockOffset) {
        uint32_t block = getBlockIndex(&inode, blockOffset);
        if (!readFileSectorsToBuffer(lbaOfBlock(block), sectorsPerBlock)) {
            return false;
        }
    }

    *size = inode.size;
    return true;
}
Пример #3
0
Файл: clib.c Проект: forwhat/OS
void load_sector(int n)
{
	int head, cylinder, sector;
	sector = (n-1)%18+1;
	n = (n-1)/18;
	head = n/80;
	cylinder = n%80;
	loadSector(head, cylinder, sector);
}
Пример #4
0
static Ext2Inode loadInode(uint32_t inodeIndex) {
    /* 先获取inode所在组,通过其获得inodeTable所在,最后定位到inode */
    --inodeIndex;
    uint32_t grpNum = inodeIndex / superBlock->inodesPerGroup;
    uint32_t offsetInGrp = inodeIndex % superBlock->inodesPerGroup;
    uint32_t grpDescPerSct = (SECTOR_SIZE_512 / sizeof(Ext2BlockGroupDesc));

    Ext2BlockGroupDesc bgdTable[grpDescPerSct];
    uint8_t indTableBuf[SECTOR_SIZE_512];

    loadSector(lbaOfBlock(superBlock->firstDataBlock + 1)
                    + grpNum / grpDescPerSct,
            bgdTable);

    loadSector(lbaOfBlock(bgdTable[grpNum % grpDescPerSct].inodeTable) +
                    offsetInGrp * superBlock->inodeSize / SECTOR_SIZE_512,
            indTableBuf);

    Ext2Inode *inode = (Ext2Inode *) &indTableBuf[
            offsetInGrp * superBlock->inodeSize % SECTOR_SIZE_512];

    return *inode;
}
Пример #5
0
	void SettingsManager::loadSettings(const MyGUI::UString& _fileName, bool _internal)
	{
		std::string _instance = "Editor";

		MyGUI::xml::Document doc;
		if (_internal)
		{
			MyGUI::DataStreamHolder data = MyGUI::DataManager::getInstance().getData(_fileName);
			if (data.getData() != nullptr)
			{
				if (!doc.open(data.getData()))
				{
					MYGUI_LOGGING(LogSection, Error, _instance << " : " << doc.getLastError());
					return;
				}
			}
		}
		else
		{
			if (!doc.open(_fileName))
			{
				MYGUI_LOGGING(LogSection, Error, _instance << " : " << doc.getLastError());
				return;
			}
		}

		MyGUI::xml::ElementPtr root = doc.getRoot();
		if (!root || (root->getName() != "MyGUI"))
		{
			MYGUI_LOGGING(LogSection, Error, _instance << " : '" << _fileName << "', tag 'MyGUI' not found");
			return;
		}

		std::string type;
		if (root->findAttribute("type", type))
		{
			if (type == "Settings")
			{
				// берем детей и крутимся
				MyGUI::xml::ElementEnumerator field = root->getElementEnumerator();
				while (field.next())
					loadSector(field.current());
			}
		}
	}
Пример #6
0
static uint32_t getBlockIndex(Ext2Inode *inode, uint32_t offset) {
    const uint32_t DIRECT_BLOCK_POINTER_COUNT =
            sizeof(inode->blockPointers) / sizeof(inode->blockPointers[0]);
    if (offset < DIRECT_BLOCK_POINTER_COUNT) {
        return inode->blockPointers[offset];
    }

    /* 过程需要用到循环,blockPointer为当前得出的块指针 */
    uint32_t blockPointer;
    /* recursion为寻找块号的迭代(循环)次数(0开始计数),对于可能为0,1,2 */
    uint8_t recursion;
    /* 对于间接块指针,其中的一个item对应一个块,是为blocksPerItem[0]=1
     * 而二阶间接块,则乘每个块中可以存储的块指针数目,三阶同理
     * 而blocksPerItem[3]是为了代码的方便计算值,并不存在四阶间接块
     */
    uint32_t blocksPerItem[4];
    blocksPerItem[0] = 1;
    blocksPerItem[1] = blockSize / sizeof(inode->blockPointers[0]);
    blocksPerItem[2] = blocksPerItem[1] * blocksPerItem[1];
    blocksPerItem[3] = blocksPerItem[2] * blocksPerItem[1];

    offset -= DIRECT_BLOCK_POINTER_COUNT;
    if (offset < blocksPerItem[1]) {
        blockPointer = inode->indirectBlockPointer;
        recursion = 0;

    } else {
        offset -= blocksPerItem[1];
        if (offset < blocksPerItem[2]) {
            blockPointer = inode->doublyIndirectBlockPointer;
            recursion = 1;

        } else {
            offset -= blocksPerItem[2];
            if (offset < blocksPerItem[3]) {
                blockPointer = inode->triplyIndirectBlockPointer;
                recursion = 2;

            } else {
                return INVALID_DATA_BLOCK;
            }
        }
    }

    /* 引入缓存提高效率,因为0扇区不可能被块指针指向,所以用来标记无缓存 */
    static uint32_t caches[3][SECTOR_SIZE_512 / sizeof(uint32_t)];
    static uint32_t itemsPerCache = sizeof(caches[0]) / sizeof(caches[0][0]);
    static uint32_t cachedSectors[3] = {0, 0, 0};
    /* 每次只缓存一个扇区,其中包含的块指针项目数为itemsPerCache */
    do {
        uint32_t sector = lbaOfBlock(blockPointer) +
                offset / blocksPerItem[recursion] / itemsPerCache;

        if (sector != cachedSectors[recursion]) {
            loadSector(cachedSectors[recursion] = sector, caches[recursion]);
        }

        blockPointer = caches[recursion][
                offset / blocksPerItem[recursion] % itemsPerCache];
        offset = offset % blocksPerItem[recursion];
    } while (recursion-- > 0);

    return blockPointer;
}
Пример #7
0
static uint32_t findChild(
        uint32_t dirInode, const char *childName, uint32_t nameLen) {
    Ext2Inode inode = loadInode(dirInode);
    if ((inode.mode & EXT2_MODE_FT_MASK) != EXT2_MODE_FT_DIR) {
        return EXT2_INODE_NULL;
    }

    /* 目录项一定占用整数个块,blkCnt */
    uint32_t blkCnt = inode.size / blockSize + (inode.size % blockSize != 0);
    /* 一个目录项不可能跨块,但可能跨扇区,用第二个缓冲区作为副缓冲区 */
    uint8_t buffers[2][SECTOR_SIZE_512];
    uint32_t bufferedSector2 = 0;
    /* 当前的目录项和下一个目录项的指针 */
    Ext2DirEntry *curEntry;
    Ext2DirEntry *nextEntry;

    /* 遍历目录文件的每一个块 */
    for (uint32_t blockOffset = 0; blockOffset < blkCnt; ++blockOffset) {

        uint32_t block = getBlockIndex(&inode, blockOffset);
        if (block == INVALID_DATA_BLOCK) {
            return EXT2_INODE_NULL;
        }

        nextEntry = (Ext2DirEntry *) &buffers[0];

        /* 遍历目录文件的每一个扇区 */
        for (uint32_t sectorOffset = 0; sectorOffset < sectorsPerBlock;) {

            /* 副缓冲区本用作存储长文件名,但若其中有对应扇区,复制之,避免IO */
            uint32_t sector = lbaOfBlock(block) + sectorOffset;
            if (sector == bufferedSector2) {
                for (uint32_t i = 0; i < SECTOR_SIZE_512; ++i) {
                    buffers[0][i] = buffers[1][i];
                }
            } else {
                loadSector(sector, buffers[0]);
            }

            /* 遍历目录项,不确定退出时机 */
            for (;;) {
                /* 空目录项或者文件名不相等就直接跳过 */
                if ((curEntry = nextEntry)->inode != EXT2_INODE_NULL &&
                        curEntry->nameLen == nameLen) {

                    /* 如果文件名跨扇区,就要用副缓冲区延伸保存了 */
                    if (((uintptr_t) curEntry + offsetof(Ext2DirEntry, name) +
                            curEntry->nameLen) >=
                            (uintptr_t) &buffers[0] + SECTOR_SIZE_512) {
                        bufferedSector2 = sector + 1;
                        loadSector(bufferedSector2, buffers[1]);
                    }

                    /* 文件名一致就返回正确inode */
                    for (uint32_t i = 0; i < nameLen; ++i) {
                        if (curEntry->name[i] != childName[i]) {
                            break;
                        }
                        if (i == nameLen - 1) {
                            return curEntry->inode;
                        }
                    }
                }

                /* next是nextEntry的uintptr_t形式表达 */
                uintptr_t next = (uintptr_t) curEntry + curEntry->recLen;
                /* 下一个目录项是否超过扇区大小 */
                if (next >= (uintptr_t) &buffers[0] + SECTOR_SIZE_512) {
                    /* 是则要增加扇区偏移并且回滚nextEntry值,并结束当前扇区 */
                    uintptr_t offset = next - (uintptr_t) &buffers[0];
                    sectorOffset += offset / SECTOR_SIZE_512;
                    next = (uintptr_t) &buffers[0] + offset % SECTOR_SIZE_512;
                    nextEntry = (Ext2DirEntry *) next;
                    break;
                } else {
                    /* 否则继续在本扇区寻找 */
                    nextEntry = (Ext2DirEntry *) next;
                }
            }
        }
    }

    return EXT2_INODE_NULL;
}