add fs
This commit is contained in:
parent
142f3eb468
commit
39dae2aa6b
75
src/fs.cpp
Normal file
75
src/fs.cpp
Normal file
@ -0,0 +1,75 @@
|
||||
#include "fs.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
namespace vc5::filesys {
|
||||
|
||||
constexpr auto Ok = Status::Ok;
|
||||
|
||||
using BlockData = std::array<uint8_t, block_size>;
|
||||
|
||||
void Fs::init()
|
||||
{
|
||||
m_super = SuperBlockData {
|
||||
.block_bitmap = {},
|
||||
.inode_bitmap = {},
|
||||
.inode_blocks = {},
|
||||
};
|
||||
write_superblock();
|
||||
}
|
||||
|
||||
Status Fs::make_directory()
|
||||
{
|
||||
uint16_t id;
|
||||
if (auto result = next_inode_id(id); result != Ok) {
|
||||
return result;
|
||||
}
|
||||
|
||||
auto node = INodeData {
|
||||
.id = id,
|
||||
.flags = static_cast<uint16_t>(INodeType::Directory),
|
||||
.blocks_count = 0,
|
||||
.blocks = {},
|
||||
};
|
||||
}
|
||||
|
||||
Status Fs::write_new_inode(INodeData& data)
|
||||
{
|
||||
uint16_t block_id = data.id / inodes_per_block;
|
||||
uint16_t offset = data.id % inodes_per_block * inode_size;
|
||||
|
||||
BlockData block;
|
||||
m_disk->read(&block[0], block_id);
|
||||
}
|
||||
|
||||
Status Fs::next_inode_id(uint16_t& id)
|
||||
{
|
||||
for (uint16_t map_idx = 0; map_idx < sb_inode_bitmap_count; ++map_idx) {
|
||||
auto& map = m_super.inode_bitmap[map_idx];
|
||||
|
||||
for (uint16_t bit_idx = 0; bit_idx < 16; ++bit_idx) {
|
||||
|
||||
if ((map >> bit_idx & 1) == 0) {
|
||||
id = map_idx * sb_inode_bitmap_count + bit_idx;
|
||||
return Ok;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Status::INodeAllocFail;
|
||||
}
|
||||
|
||||
Status Fs::read_superblock()
|
||||
{
|
||||
BlockData block;
|
||||
m_disk->read(&block[0], super_block_location);
|
||||
m_super = *reinterpret_cast<SuperBlockData*>(&block[0]);
|
||||
return Ok;
|
||||
}
|
||||
|
||||
Status Fs::write_superblock()
|
||||
{
|
||||
m_disk->write(
|
||||
reinterpret_cast<const uint8_t*>(&m_super), super_block_location);
|
||||
return Ok;
|
||||
}
|
||||
|
||||
}
|
||||
73
src/fs.hpp
Normal file
73
src/fs.hpp
Normal file
@ -0,0 +1,73 @@
|
||||
#pragma once
|
||||
|
||||
#include "block_device.hpp"
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
namespace vc5::filesys {
|
||||
|
||||
enum class Status : uint16_t {
|
||||
Ok,
|
||||
INodeAllocFail,
|
||||
};
|
||||
|
||||
constexpr uint16_t block_size = 0x200;
|
||||
constexpr uint16_t name_max_len = 255;
|
||||
|
||||
struct DirEntryData {
|
||||
uint16_t inode;
|
||||
uint16_t name_len;
|
||||
std::array<uint8_t, name_max_len> name;
|
||||
};
|
||||
|
||||
enum class INodeType : uint16_t {
|
||||
File = 0,
|
||||
Directory = 1,
|
||||
Symlink = 2,
|
||||
};
|
||||
|
||||
constexpr uint16_t inode_size = 32;
|
||||
constexpr uint16_t inodes_per_block = block_size / inode_size;
|
||||
constexpr uint16_t inode_blocks_count = 8;
|
||||
|
||||
struct INodeData {
|
||||
uint16_t id;
|
||||
uint16_t flags;
|
||||
uint16_t blocks_count;
|
||||
std::array<uint16_t, inode_blocks_count> blocks;
|
||||
};
|
||||
|
||||
constexpr uint16_t super_block_location = 0x400;
|
||||
constexpr uint16_t sb_block_bitmap_count = 8;
|
||||
constexpr uint16_t sb_inode_bitmap_count = 8;
|
||||
constexpr uint16_t sb_inode_blocks_count = 16;
|
||||
|
||||
struct SuperBlockData {
|
||||
std::array<uint16_t, sb_block_bitmap_count> block_bitmap;
|
||||
std::array<uint16_t, sb_inode_bitmap_count> inode_bitmap;
|
||||
std::array<uint16_t, sb_inode_blocks_count> inode_blocks;
|
||||
};
|
||||
|
||||
class Fs {
|
||||
public:
|
||||
explicit Fs(BlockDevice& disk)
|
||||
: m_disk(&disk)
|
||||
{
|
||||
}
|
||||
|
||||
void init();
|
||||
|
||||
private:
|
||||
Status make_directory();
|
||||
|
||||
Status write_new_inode(INodeData& data);
|
||||
Status next_inode_id(uint16_t& id);
|
||||
|
||||
Status read_superblock();
|
||||
Status write_superblock();
|
||||
|
||||
BlockDevice* m_disk;
|
||||
SuperBlockData m_super;
|
||||
};
|
||||
|
||||
}
|
||||
@ -26,7 +26,7 @@ constexpr uint64_t char_data(uint8_t ch)
|
||||
case '$': return 0x00187e6218467e18;
|
||||
case '%': return 0x0022562c18346a44;
|
||||
case '&': return 0x00784c38724a4638;
|
||||
case '\'': return 0x0018180000000000;
|
||||
case '\'': return 0x0018181800000000;
|
||||
case '(': return 0x000c18303030180c;
|
||||
case ')': return 0x0030180c0c0c1830;
|
||||
case '*': return 0x0000241818240000;
|
||||
@ -91,7 +91,7 @@ constexpr uint64_t char_data(uint8_t ch)
|
||||
case 'a': return 0x0000003c023e423e;
|
||||
case 'b': return 0x004040407c42427c;
|
||||
case 'c': return 0x000000003c40403c;
|
||||
case 'd': return 0x00020202023e423e;
|
||||
case 'd': return 0x000202023e42423e;
|
||||
case 'e': return 0x0000003c427c403c;
|
||||
case 'f': return 0x00000c103c101010;
|
||||
case 'g': return 0x003e645840784438;
|
||||
|
||||
@ -195,6 +195,11 @@ struct InsReader {
|
||||
VM* vm;
|
||||
uint16_t ins;
|
||||
|
||||
auto op() -> Op
|
||||
{
|
||||
return static_cast<Op>(ins & 0b11'1111);
|
||||
}
|
||||
|
||||
auto to_u16() const -> uint16_t
|
||||
{
|
||||
return ins;
|
||||
@ -277,7 +282,8 @@ int VM::run_instruction()
|
||||
return -1;
|
||||
|
||||
auto ins = InsReader(*this);
|
||||
auto op = static_cast<Op>(ins.to_u16() & 0b11'1111);
|
||||
auto op = ins.op();
|
||||
|
||||
std::println(
|
||||
" [{: >3x}]: 0x{:04x} {: <6} {:04b} {:04b} {:04b} {:04b} {:04x}",
|
||||
ip,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user