/// <summary> /// 流写入 /// </summary> /// <param name="cin">待写入的流</param> /// <param name="position">写入起始位置</param> /// <param name="count">需写入的数量</param> protected void WriteStream(byte[] cin, int itemNum, int count, InodeStr dinode) { int pos = _dire.BMap(dinode, itemNum / 512); _diskFile.OpenFile(); _diskFile.SeekFilePosition(pos * 512 + itemNum % 512, System.IO.SeekOrigin.Begin); _diskFile.WriteFile(ref cin, 0, count); _diskFile.CloseFile(); }
/// <summary> /// 初始化数据块 /// </summary> public void InitDataBlock() { byte[] writeTo; _initSuper._s_nfree = 0; _initSuper._s_free[_initSuper._s_nfree++] = 0; _diskFile.OpenFile(); //从最后一块往前走,每100块之前的一块为管理块 //其内容包括 //1:该管理块管理的块数 //2:该管理块管理的所有块号 for (int i = _dataBlkNum - 1; i >= 0; --i) { if (_initSuper._s_nfree >= 100) { //找到要写入的位置,将s_nfree和s_free写入i + datablkstart号磁盘块 _diskFile.SeekFilePosition(_diskFile.ConvertPosition(i + _dataBlkStart, 0), System.IO.SeekOrigin.Begin); //转换成流,写入磁盘 writeTo = Helper.Struct2Bytes(_initSuper._s_nfree); _diskFile.WriteFile(ref writeTo, 0, 4); for (int j = 0; j < _initSuper._s_nfree; ++j) { //转换成流,写入磁盘 writeTo = Helper.Struct2Bytes(_initSuper._s_free[j]); _diskFile.WriteFile(ref writeTo, 0, 4); } _initSuper._s_nfree = 0; } //数组元素初始化(数组元素用于管理空闲块号) _initSuper._s_free[_initSuper._s_nfree++] = i + _dataBlkStart; } //关闭磁盘文件 _diskFile.CloseFile(); //将更新后的超级快信息写回 _initSuper.UpdateSuperBlockToDisk(); }
/// <summary> /// 将编译好的启动文件boot.bin按规定写入磁盘 /// </summary> public void WriteBootBlock() { int bootSize = MachinePara.Boot_Size * MachinePara.Block_Size; byte[] writeTo = new byte[bootSize]; //读取boot.bin _bootFile.OpenFile(); _bootFile.SeekFilePosition(0, System.IO.SeekOrigin.Begin); _bootFile.ReadFile(ref writeTo, 0, 512); _bootFile.CloseFile(); //写入c.img _diskFile.OpenFile(); _diskFile.SeekFilePosition(0, System.IO.SeekOrigin.Begin); _diskFile.WriteFile(ref writeTo, 0, bootSize); _diskFile.CloseFile(); }
/// <summary> /// 将编译好的内核kernel.bin文件按规定写入磁盘 /// </summary> public void WriteKernelBlock() { _kernelFile.OpenFile(); int kernelFileLength = (int)_kernelFile.ReturnFileLength(); byte[] writeTo; writeTo = new byte[kernelFileLength]; //读出kernel.bin文件的内容 _kernelFile.SeekFilePosition(0, System.IO.SeekOrigin.Begin); _kernelFile.ReadFile(ref writeTo, 0, kernelFileLength); _kernelFile.CloseFile(); //将kernel.bin的内容写入c.img _diskFile.OpenFile(); _diskFile.SeekFilePosition(1 * 512, System.IO.SeekOrigin.Begin); _diskFile.WriteFile(ref writeTo, 0, kernelFileLength); _diskFile.CloseFile(); }
/// <summary> /// 虚实地址转换 /// </summary>\ /// /// <param name="DirInode"></param> /// <param name="no"></param> /// <returns></returns> public int BMap(InodeStr dirInode, int itemNum) { int blockNum; byte[] blockNumBuf = new byte[4]; //直接索引0~5项,一次间接索引6~7项,二次间接索引8~9项 //直接索引所引用的逻辑块号为0~5块,一次间接引用索引项6~261块 //二次间接引用索引项128*2+6~128*128*2+128*2+6-1项 //直接索引 if (itemNum < 6) { blockNum = dirInode._i_addr[itemNum]; //如果该逻辑块还没有相应的物理块与之对应,则分配一个物理块 if (blockNum == 0) { try { blockNum = _dataBlock.GetFreeBlock(); } catch (Exception ex) { Console.WriteLine(ex.Message); } dirInode._i_addr[itemNum] = blockNum; } return(blockNum); } //间接引用bn>=6 else { int firstIndex; //一次间接块 if (itemNum - 262 < 0) { firstIndex = ((itemNum - 6) / 128) + 6; //6或7 } else //二次间接块 { firstIndex = ((itemNum - 262) / (128 * 128)) + 8; //8或9 } //该项为空,则到数据区分配一块空闲块 if (dirInode._i_addr[firstIndex] == 0) { try { dirInode._i_addr[firstIndex] = _dataBlock.GetFreeBlock(); } catch (Exception ex) { Console.WriteLine(ex.Message); } } blockNum = dirInode._i_addr[firstIndex]; //如果是二次间接索引,则再获取二级索引块的块号 if (firstIndex >= 8) { int secondIndex = ((itemNum - 262) / 128) % 128; //0-128 _diskFile.OpenFile(); _diskFile.SeekFilePosition(dirInode._i_addr[firstIndex] * 512 + secondIndex * 4, System.IO.SeekOrigin.Begin); _diskFile.ReadFile(ref blockNumBuf, 0, 4); _diskFile.CloseFile(); blockNum = (int)Helper.Bytes2Struct(blockNumBuf, typeof(int)); if (blockNum == 0) { try { blockNum = _dataBlock.GetFreeBlock(); } catch (Exception ex) { Console.WriteLine(ex.Message); } blockNumBuf = Helper.Struct2Bytes(blockNum); _diskFile.OpenFile(); _diskFile.SeekFilePosition(dirInode._i_addr[firstIndex] * 512 + secondIndex * 4, System.IO.SeekOrigin.Begin); _diskFile.WriteFile(ref blockNumBuf, 0, 4); _diskFile.CloseFile(); } } } int directIndex; //一次间接块 if (itemNum - 262 < 0) { directIndex = ((itemNum - 6) % 128); } else //二次间接块 { directIndex = ((itemNum - 262) % 128); } _diskFile.OpenFile(); _diskFile.SeekFilePosition(512 * blockNum + 4 * directIndex, System.IO.SeekOrigin.Begin); _diskFile.ReadFile(ref blockNumBuf, 0, 4); _diskFile.CloseFile(); int tmpBlockNum = (int)Helper.Bytes2Struct(blockNumBuf, typeof(int)); //若该目录索引项为空,则分配 if (tmpBlockNum == 0) { try { tmpBlockNum = _dataBlock.GetFreeBlock(); } catch (Exception ex) { Console.WriteLine(ex.Message); } blockNumBuf = Helper.Struct2Bytes(tmpBlockNum); _diskFile.OpenFile(); _diskFile.SeekFilePosition(512 * blockNum + 4 * directIndex, System.IO.SeekOrigin.Begin); _diskFile.WriteFile(ref blockNumBuf, 0, 4); _diskFile.CloseFile(); } blockNum = tmpBlockNum; return(blockNum); }
/// <summary> /// 将当前的超级快信息更新到磁盘 /// </summary> public void UpdateSuperBlockToDisk() { byte[] writeTo; //定位到超级块起始位置 _diskFile.OpenFile(); _diskFile.SeekFilePosition(MachinePara.BootAndKernelSize * 512, System.IO.SeekOrigin.Begin); //inode区占据的磁盘块数 writeTo = Helper.Struct2Bytes(_s_isize); _diskFile.WriteFile(ref writeTo, 0, 4); //总的磁盘块数,为扇区数的一半 writeTo = Helper.Struct2Bytes(_s_fsize); _diskFile.WriteFile(ref writeTo, 0, 4); //得到直接管理块数 writeTo = Helper.Struct2Bytes(_s_nfree); _diskFile.WriteFile(ref writeTo, 0, 4); //得到空闲列表 for (int i = 0; i < 100; ++i) { writeTo = Helper.Struct2Bytes(_s_free[i]); _diskFile.WriteFile(ref writeTo, 0, 4); } //得到直接管理的inodee数量 writeTo = Helper.Struct2Bytes(_s_ninode); _diskFile.WriteFile(ref writeTo, 0, 4); //得到空闲inode列表 for (int i = 0; i < 100; ++i) { writeTo = Helper.Struct2Bytes(_s_inode[i]); _diskFile.WriteFile(ref writeTo, 0, 4); } //封锁标志 writeTo = Helper.Struct2Bytes(_s_flock); _diskFile.WriteFile(ref writeTo, 0, 4); //inode封锁标志 writeTo = Helper.Struct2Bytes(_s_ilock); _diskFile.WriteFile(ref writeTo, 0, 4); //已修改标志 writeTo = Helper.Struct2Bytes(_s_fmod); _diskFile.WriteFile(ref writeTo, 0, 4); //只读标志 writeTo = Helper.Struct2Bytes(_s_ronly); _diskFile.WriteFile(ref writeTo, 0, 4); //最后修改时间 writeTo = Helper.Struct2Bytes(_s_time); _diskFile.WriteFile(ref writeTo, 0, 4); //填充字段 if (_s_padding[0] == 1) { for (int i = 0; i < 47; i++) { writeTo = Helper.Struct2Bytes(_s_padding[i]); _diskFile.WriteFile(ref writeTo, 0, 4); } _s_padding[0] = 0; } _diskFile.CloseFile(); }