diff --git a/src/binarystore.cpp b/src/binarystore.cpp
new file mode 100644
index 0000000..0760f33
--- /dev/null
+++ b/src/binarystore.cpp
@@ -0,0 +1,432 @@
+#include "binarystore.hpp"
+
+#include "sys_file.hpp"
+
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <blobs-ipmid/blobs.hpp>
+#include <boost/endian/arithmetic.hpp>
+#include <cstdint>
+#include <ipmid/handler.hpp>
+#include <memory>
+#include <optional>
+#include <phosphor-logging/elog.hpp>
+#include <string>
+#include <vector>
+
+#include "binaryblob.pb.h"
+
+using std::size_t;
+using std::uint16_t;
+using std::uint32_t;
+using std::uint64_t;
+using std::uint8_t;
+
+namespace binstore
+{
+
+using namespace phosphor::logging;
+
+std::unique_ptr<BinaryStoreInterface>
+    BinaryStore::createFromConfig(const std::string& baseBlobId,
+                                  std::unique_ptr<SysFile> file,
+                                  std::optional<uint32_t> maxSize)
+{
+    if (baseBlobId.empty() || !file)
+    {
+        log<level::ERR>("Unable to create binarystore from invalid config",
+                        entry("BASE_ID=%s", baseBlobId.c_str()));
+        return nullptr;
+    }
+
+    auto store =
+        std::make_unique<BinaryStore>(baseBlobId, std::move(file), maxSize);
+
+    if (!store->loadSerializedData())
+    {
+        return nullptr;
+    }
+
+    return store;
+}
+
+std::unique_ptr<BinaryStoreInterface>
+    BinaryStore::createFromFile(std::unique_ptr<SysFile> file, bool readOnly,
+                                std::optional<uint32_t> maxSize)
+{
+    if (!file)
+    {
+        log<level::ERR>("Unable to create binarystore from invalid file");
+        return nullptr;
+    }
+
+    auto store =
+        std::make_unique<BinaryStore>(std::move(file), readOnly, maxSize);
+
+    if (!store->loadSerializedData())
+    {
+        return nullptr;
+    }
+
+    return store;
+}
+
+bool BinaryStore::loadSerializedData()
+{
+    /* Load blob from sysfile if we know it might not match what we have.
+     * Note it will overwrite existing unsaved data per design. */
+    if (commitState_ == CommitState::Clean ||
+        commitState_ == CommitState::Uninitialized)
+    {
+        return true;
+    }
+
+    log<level::NOTICE>("Try loading blob from persistent data",
+                       entry("BASE_ID=%s", baseBlobId_.c_str()));
+    try
+    {
+        /* Parse length-prefixed format to protobuf */
+        boost::endian::little_uint64_t size = 0;
+        file_->readToBuf(0, sizeof(size), reinterpret_cast<char*>(&size));
+
+        if (!blob_.ParseFromString(file_->readAsStr(sizeof(uint64_t), size)))
+        {
+            /* Fail to parse the data, which might mean no preexsiting blobs
+             * and is a valid case to handle. Simply init an empty binstore. */
+            commitState_ = CommitState::Uninitialized;
+        }
+
+        // The new max size takes priority
+        if (maxSize)
+        {
+            blob_.set_max_size_bytes(*maxSize);
+        }
+        else
+        {
+            blob_.clear_max_size_bytes();
+        }
+    }
+    catch (const std::system_error& e)
+    {
+        /* Read causes unexpected system-level failure */
+        log<level::ERR>("Reading from sysfile failed",
+                        entry("ERROR=%s", e.what()));
+        return false;
+    }
+    catch (const std::exception& e)
+    {
+        /* Non system error originates from junk value in 'size' */
+        commitState_ = CommitState::Uninitialized;
+    }
+
+    if (commitState_ == CommitState::Uninitialized)
+    {
+        log<level::WARNING>("Fail to parse. There might be no persisted blobs",
+                            entry("BASE_ID=%s", baseBlobId_.c_str()));
+        return true;
+    }
+
+    if (blob_.blob_base_id() != baseBlobId_ && !readOnly_)
+    {
+        /* Uh oh, stale data loaded. Clean it and commit. */
+        // TODO: it might be safer to add an option in config to error out
+        // instead of to overwrite.
+        log<level::ERR>("Stale blob data, resetting internals...",
+                        entry("LOADED=%s", blob_.blob_base_id().c_str()),
+                        entry("EXPECTED=%s", baseBlobId_.c_str()));
+        blob_.Clear();
+        blob_.set_blob_base_id(baseBlobId_);
+        return this->commit();
+    }
+
+    return true;
+}
+
+std::string BinaryStore::getBaseBlobId() const
+{
+    if (!baseBlobId_.empty())
+    {
+        return baseBlobId_;
+    }
+
+    return blob_.blob_base_id();
+}
+
+std::vector<std::string> BinaryStore::getBlobIds() const
+{
+    std::vector<std::string> result;
+    result.push_back(getBaseBlobId());
+
+    for (const auto& blob : blob_.blobs())
+    {
+        result.push_back(blob.blob_id());
+    }
+
+    return result;
+}
+
+bool BinaryStore::openOrCreateBlob(const std::string& blobId, uint16_t flags)
+{
+    if (!(flags & blobs::OpenFlags::read))
+    {
+        log<level::ERR>("OpenFlags::read not specified when opening",
+                        entry("BLOB_ID=%s", blobId.c_str()));
+        return false;
+    }
+
+    if (currentBlob_ && (currentBlob_->blob_id() != blobId))
+    {
+        log<level::ERR>("Already handling a different blob",
+                        entry("EXPECTED=%s", currentBlob_->blob_id().c_str()),
+                        entry("RECEIVED=%s", blobId.c_str()));
+        return false;
+    }
+
+    if (readOnly_ && (flags & blobs::OpenFlags::write))
+    {
+        log<level::ERR>("Can't open the blob for writing: read-only store",
+                        entry("BLOB_ID=%s", blobId.c_str()));
+        return false;
+    }
+
+    writable_ = flags & blobs::OpenFlags::write;
+
+    /* If there are uncommitted data, discard them. */
+    if (!this->loadSerializedData())
+    {
+        return false;
+    }
+
+    /* Iterate and find if there is an existing blob with this id.
+     * blobsPtr points to a BinaryBlob container with STL-like semantics*/
+    auto blobsPtr = blob_.mutable_blobs();
+    auto blobIt =
+        std::find_if(blobsPtr->begin(), blobsPtr->end(),
+                     [&](const auto& b) { return b.blob_id() == blobId; });
+
+    if (blobIt != blobsPtr->end())
+    {
+        currentBlob_ = &(*blobIt);
+        return true;
+    }
+
+    /* Otherwise, create the blob and append it */
+    if (readOnly_)
+    {
+        return false;
+    }
+    else
+    {
+        currentBlob_ = blob_.add_blobs();
+        currentBlob_->set_blob_id(blobId);
+
+        commitState_ = CommitState::Dirty;
+        log<level::NOTICE>("Created new blob",
+                           entry("BLOB_ID=%s", blobId.c_str()));
+    }
+
+    return true;
+}
+
+bool BinaryStore::deleteBlob(const std::string&)
+{
+    return false;
+}
+
+std::vector<uint8_t> BinaryStore::read(uint32_t offset, uint32_t requestedSize)
+{
+    std::vector<uint8_t> result;
+
+    if (!currentBlob_)
+    {
+        log<level::ERR>("No open blob to read");
+        return result;
+    }
+
+    auto dataPtr = currentBlob_->mutable_data();
+
+    /* If it is out of bound, return empty vector */
+    if (offset >= dataPtr->size())
+    {
+        log<level::ERR>("Read offset is beyond data size",
+                        entry("MAX_SIZE=0x%x", dataPtr->size()),
+                        entry("RECEIVED_OFFSET=0x%x", offset));
+        return result;
+    }
+
+    uint32_t requestedEndPos = offset + requestedSize;
+
+    result = std::vector<uint8_t>(
+        dataPtr->begin() + offset,
+        std::min(dataPtr->begin() + requestedEndPos, dataPtr->end()));
+    return result;
+}
+
+std::vector<uint8_t> BinaryStore::readBlob(const std::string& blobId) const
+{
+    const auto blobs = blob_.blobs();
+    const auto blobIt =
+        std::find_if(blobs.begin(), blobs.end(),
+                     [&](const auto& b) { return b.blob_id() == blobId; });
+
+    if (blobIt == blobs.end())
+    {
+        throw ipmi::HandlerCompletion(ipmi::ccUnspecifiedError);
+    }
+
+    const auto blobData = blobIt->data();
+
+    return std::vector<uint8_t>(blobData.begin(), blobData.end());
+}
+
+bool BinaryStore::write(uint32_t offset, const std::vector<uint8_t>& data)
+{
+    if (!currentBlob_)
+    {
+        log<level::ERR>("No open blob to write");
+        return false;
+    }
+
+    if (!writable_)
+    {
+        log<level::ERR>("Open blob is not writable");
+        return false;
+    }
+
+    auto dataPtr = currentBlob_->mutable_data();
+
+    if (offset > dataPtr->size())
+    {
+        log<level::ERR>("Write would leave a gap with undefined data. Return.");
+        return false;
+    }
+
+    bool needResize = offset + data.size() > dataPtr->size();
+
+    // current size is the binary blob proto size + uint64 tracking the total
+    // size of the binary blob.
+    // currentSize = blob_size + x (uint64_t), where x = blob_size.
+    size_t currentSize = blob_.SerializeAsString().size() +
+                         sizeof(boost::endian::little_uint64_t);
+    size_t sizeDelta = needResize ? offset + data.size() - dataPtr->size() : 0;
+
+    if (maxSize && currentSize + sizeDelta > *maxSize)
+    {
+        log<level::ERR>("Write data would make the total size exceed the max "
+                        "size allowed. Return.");
+        return false;
+    }
+
+    commitState_ = CommitState::Dirty;
+    /* Copy (overwrite) the data */
+    if (needResize)
+    {
+        dataPtr->resize(offset + data.size()); // not enough space, extend
+    }
+    std::copy(data.begin(), data.end(), dataPtr->begin() + offset);
+    return true;
+}
+
+bool BinaryStore::commit()
+{
+    if (readOnly_)
+    {
+        log<level::ERR>("ReadOnly blob, not committing");
+        return false;
+    }
+
+    /* Store as little endian to be platform agnostic. Consistent with read. */
+    auto blobData = blob_.SerializeAsString();
+    boost::endian::little_uint64_t sizeLE = blobData.size();
+    std::string commitData(reinterpret_cast<const char*>(sizeLE.data()),
+                           sizeof(sizeLE));
+    commitData += blobData;
+
+    // This should never be true if it is blocked by the write command
+    if (maxSize && sizeof(commitData) > *maxSize)
+    {
+        log<level::ERR>("Commit Data excedded maximum allowed size");
+        return false;
+    }
+
+    try
+    {
+        file_->writeStr(commitData, 0);
+    }
+    catch (const std::exception& e)
+    {
+        commitState_ = CommitState::CommitError;
+        log<level::ERR>("Writing to sysfile failed",
+                        entry("ERROR=%s", e.what()));
+        return false;
+    };
+
+    commitState_ = CommitState::Clean;
+    return true;
+}
+
+bool BinaryStore::close()
+{
+    currentBlob_ = nullptr;
+    writable_ = false;
+    commitState_ = CommitState::Dirty;
+    return true;
+}
+
+/*
+ * Sets |meta| with size and state of the blob. Returns |blobState| with
+ * standard definition from phosphor-ipmi-blobs header blob.hpp, plus OEM
+ * flag bits BinaryStore::CommitState.
+
+enum StateFlags
+{
+    open_read = (1 << 0),
+    open_write = (1 << 1),
+    committing = (1 << 2),
+    committed = (1 << 3),
+    commit_error = (1 << 4),
+};
+
+enum CommitState
+{
+    Dirty = (1 << 8), // In-memory data might not match persisted data
+    Clean = (1 << 9), // In-memory data matches persisted data
+    Uninitialized = (1 << 10), // Cannot find persisted data
+    CommitError = (1 << 11)    // Error happened during committing
+};
+
+*/
+bool BinaryStore::stat(blobs::BlobMeta* meta)
+{
+    uint16_t blobState = blobs::StateFlags::open_read;
+    if (writable_)
+    {
+        blobState |= blobs::StateFlags::open_write;
+    }
+
+    if (commitState_ == CommitState::Clean)
+    {
+        blobState |= blobs::StateFlags::committed;
+    }
+    else if (commitState_ == CommitState::CommitError)
+    {
+        blobState |= blobs::StateFlags::commit_error;
+    }
+    blobState |= commitState_;
+
+    if (currentBlob_)
+    {
+        meta->size = currentBlob_->data().size();
+    }
+    else
+    {
+        meta->size = 0;
+    }
+    meta->blobState = blobState;
+
+    return true;
+}
+
+} // namespace binstore
diff --git a/src/blobtool.cpp b/src/blobtool.cpp
new file mode 100644
index 0000000..ac29abd
--- /dev/null
+++ b/src/blobtool.cpp
@@ -0,0 +1,238 @@
+#include "binarystore.hpp"
+#include "parse_config.hpp"
+#include "sys_file_impl.hpp"
+
+#include <getopt.h>
+
+#include <algorithm>
+#include <fstream>
+#include <iostream>
+#include <nlohmann/json.hpp>
+
+constexpr auto defaultBlobConfigPath = "/usr/share/binaryblob/config.json";
+
+struct BlobToolConfig
+{
+    std::string configPath = defaultBlobConfigPath;
+    std::string programName;
+    std::string binStore;
+    std::string blobName;
+    size_t offsetBytes = 0;
+    enum class Action
+    {
+        HELP,
+        LIST,
+        READ,
+    } action = Action::LIST;
+} toolConfig;
+
+void printUsage(const BlobToolConfig& cfg)
+{
+    std::cout
+        << "Usage: \n"
+        << cfg.programName << " [OPTIONS]\n"
+        << "\t--list\t\tList all supported blobs. This is a default.\n"
+        << "\t--read\t\tRead blob specified in --blob argument"
+           " (which becomes mandatory).\n"
+        << "\t--config\tFILENAME\tPath to the configuration file. The default "
+           "is /usr/share/binaryblob/config.json.\n"
+        << "\t--binary-store\tFILENAME\tPath to the binary storage. If "
+           "specified,"
+           "configuration file is not used.\n"
+        << "\t--blob\tSTRING\tThe name of the blob to read.\n"
+        << "\t--offset\tNUMBER\tThe offset in the binary store file, where"
+           " the binary store actually starts.\n"
+        << "\t--help\t\tPrint this help and exit\n";
+}
+
+bool parseOptions(int argc, char* argv[], BlobToolConfig& cfg)
+{
+    cfg.programName = argv[0];
+
+    struct option longOptions[] = {
+        {"help", no_argument, 0, 'h'},
+        {"list", no_argument, 0, 'l'},
+        {"read", no_argument, 0, 'r'},
+        {"config", required_argument, 0, 'c'},
+        {"binary-store", required_argument, 0, 's'},
+        {"blob", required_argument, 0, 'b'},
+        {"offset", required_argument, 0, 'g'},
+        {0, 0, 0, 0},
+    };
+
+    int optionIndex = 0;
+    std::string configPath = defaultBlobConfigPath;
+    bool res = true;
+    while (1)
+    {
+        int ret = getopt_long_only(argc, argv, "", longOptions, &optionIndex);
+
+        if (ret == -1)
+            break;
+
+        switch (ret)
+        {
+            case 'h':
+                cfg.action = BlobToolConfig::Action::HELP;
+                break;
+            case 'l':
+                cfg.action = BlobToolConfig::Action::LIST;
+                break;
+            case 'r':
+                cfg.action = BlobToolConfig::Action::READ;
+                break;
+            case 'c':
+                cfg.configPath = optarg;
+                break;
+            case 's':
+                cfg.binStore = optarg;
+                break;
+            case 'b':
+                cfg.blobName = optarg;
+                break;
+            case 'g':
+                cfg.offsetBytes = std::stoi(optarg);
+                break;
+            default:
+                res = false;
+                break;
+        }
+    }
+
+    return res;
+}
+
+int main(int argc, char* argv[])
+{
+    parseOptions(argc, argv, toolConfig);
+    if (toolConfig.action == BlobToolConfig::Action::HELP)
+    {
+        printUsage(toolConfig);
+        return 0;
+    }
+
+    std::vector<std::unique_ptr<binstore::BinaryStoreInterface>> stores;
+    if (!toolConfig.binStore.empty())
+    {
+        auto file = std::make_unique<binstore::SysFileImpl>(
+            toolConfig.binStore, toolConfig.offsetBytes);
+        if (!file)
+        {
+            std::cerr << "Can't open binary store " << toolConfig.binStore
+                      << std::endl;
+            printUsage(toolConfig);
+            return 1;
+        }
+
+        auto store =
+            binstore::BinaryStore::createFromFile(std::move(file), true);
+        stores.push_back(std::move(store));
+    }
+    else
+    {
+        std::ifstream input(toolConfig.configPath);
+        json j;
+
+        if (!input.good())
+        {
+            std::cerr << "Config file not found: " << toolConfig.configPath
+                      << std::endl;
+            return 1;
+        }
+
+        try
+        {
+            input >> j;
+        }
+        catch (const std::exception& e)
+        {
+            std::cerr << "Failed to parse config into json: " << std::endl
+                      << e.what() << std::endl;
+            return 1;
+        }
+
+        for (const auto& element : j)
+        {
+            conf::BinaryBlobConfig config;
+            try
+            {
+                conf::parseFromConfigFile(element, config);
+            }
+            catch (const std::exception& e)
+            {
+                std::cerr << "Encountered error when parsing config file:"
+                          << std::endl
+                          << e.what() << std::endl;
+                return 1;
+            }
+
+            auto file = std::make_unique<binstore::SysFileImpl>(
+                config.sysFilePath, config.offsetBytes);
+
+            auto store = binstore::BinaryStore::createFromConfig(
+                config.blobBaseId, std::move(file));
+            stores.push_back(std::move(store));
+        }
+    }
+
+    if (toolConfig.action == BlobToolConfig::Action::LIST)
+    {
+        std::cout << "Supported Blobs: " << std::endl;
+        for (const auto& store : stores)
+        {
+            const auto blobIds = store->getBlobIds();
+            std::copy(
+                blobIds.begin(), blobIds.end(),
+                std::ostream_iterator<decltype(blobIds[0])>(std::cout, "\n"));
+        }
+    }
+    else if (toolConfig.action == BlobToolConfig::Action::READ)
+    {
+        if (toolConfig.blobName.empty())
+        {
+            std::cerr << "Must specify the name of the blob to read."
+                      << std::endl;
+            printUsage(toolConfig);
+            return 1;
+        }
+
+        bool blobFound = false;
+
+        for (const auto& store : stores)
+        {
+            const auto blobIds = store->getBlobIds();
+            if (std::any_of(blobIds.begin(), blobIds.end(),
+                            [](const std::string& bn) {
+                                return bn == toolConfig.blobName;
+                            }))
+            {
+                const auto blobData = store->readBlob(toolConfig.blobName);
+                if (blobData.empty())
+                {
+                    std::cerr << "No data read from " << store->getBaseBlobId()
+                              << std::endl;
+                    continue;
+                }
+
+                blobFound = true;
+
+                std::copy(
+                    blobData.begin(), blobData.end(),
+                    std::ostream_iterator<decltype(blobData[0])>(std::cout));
+
+                // It's assumed that the names of the blobs are unique within
+                // the system.
+                break;
+            }
+        }
+
+        if (!blobFound)
+        {
+            std::cerr << "Blob " << toolConfig.blobName << " not found."
+                      << std::endl;
+            return 1;
+        }
+    }
+
+    return 0;
+}
diff --git a/src/handler.cpp b/src/handler.cpp
new file mode 100644
index 0000000..a391b5a
--- /dev/null
+++ b/src/handler.cpp
@@ -0,0 +1,201 @@
+#include "handler.hpp"
+
+#include <algorithm>
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <vector>
+
+using std::size_t;
+using std::uint16_t;
+using std::uint32_t;
+using std::uint64_t;
+using std::uint8_t;
+
+namespace blobs
+{
+
+namespace internal
+{
+
+/**
+ * @brief: Get baseId from a blob id string
+ * @param blobId: Input blob id which is expected to only contain alphanumerical
+ *                characters and '/'.
+ * @returns: the baseId containing the blobId, stripping all contents from the
+ *           last '/'. If no '/' is present, an empty string is returned.
+ */
+static std::string getBaseFromId(const std::string& blobId)
+{
+    return blobId.substr(0, blobId.find_last_of('/') + 1);
+}
+
+} // namespace internal
+
+void BinaryStoreBlobHandler::addNewBinaryStore(
+    std::unique_ptr<binstore::BinaryStoreInterface> store)
+{
+    // TODO: this is a very rough measure to test the mock interface for now.
+    stores_[store->getBaseBlobId()] = std::move(store);
+}
+
+bool BinaryStoreBlobHandler::canHandleBlob(const std::string& path)
+{
+    auto base = internal::getBaseFromId(path);
+    if (base.empty() || base == path)
+    {
+        /* Operations on baseId itself or an empty base is not allowed */
+        return false;
+    }
+
+    return std::any_of(stores_.begin(), stores_.end(),
+                       [&](const auto& baseStorePair) {
+                           return base == baseStorePair.second->getBaseBlobId();
+                       });
+}
+
+std::vector<std::string> BinaryStoreBlobHandler::getBlobIds()
+{
+    std::vector<std::string> result;
+
+    for (const auto& baseStorePair : stores_)
+    {
+        const auto& ids = baseStorePair.second->getBlobIds();
+        result.insert(result.end(), ids.begin(), ids.end());
+    }
+
+    return result;
+}
+
+bool BinaryStoreBlobHandler::deleteBlob(const std::string& path)
+{
+    auto it = stores_.find(internal::getBaseFromId(path));
+    if (it == stores_.end())
+    {
+        return false;
+    }
+
+    return it->second->deleteBlob(path);
+}
+
+bool BinaryStoreBlobHandler::stat(const std::string& path,
+                                  struct BlobMeta* meta)
+{
+    auto it = stores_.find(internal::getBaseFromId(path));
+    if (it == stores_.end())
+    {
+        return false;
+    }
+
+    return it->second->stat(meta);
+}
+
+bool BinaryStoreBlobHandler::open(uint16_t session, uint16_t flags,
+                                  const std::string& path)
+{
+    if (!canHandleBlob(path))
+    {
+        return false;
+    }
+
+    auto found = sessions_.find(session);
+    if (found != sessions_.end())
+    {
+        /* This session is already active */
+        return false;
+    }
+
+    const auto& base = internal::getBaseFromId(path);
+
+    if (stores_.find(base) == stores_.end())
+    {
+        return false;
+    }
+
+    if (!stores_[base]->openOrCreateBlob(path, flags))
+    {
+        return false;
+    }
+
+    sessions_[session] = stores_[base].get();
+    return true;
+}
+
+std::vector<uint8_t> BinaryStoreBlobHandler::read(uint16_t session,
+                                                  uint32_t offset,
+                                                  uint32_t requestedSize)
+{
+    auto it = sessions_.find(session);
+    if (it == sessions_.end())
+    {
+        return std::vector<uint8_t>();
+    }
+
+    return it->second->read(offset, requestedSize);
+}
+
+bool BinaryStoreBlobHandler::write(uint16_t session, uint32_t offset,
+                                   const std::vector<uint8_t>& data)
+{
+    auto it = sessions_.find(session);
+    if (it == sessions_.end())
+    {
+        return false;
+    }
+
+    return it->second->write(offset, data);
+}
+
+bool BinaryStoreBlobHandler::writeMeta(uint16_t, uint32_t,
+                                       const std::vector<uint8_t>&)
+{
+    /* Binary store handler doesn't support write meta */
+    return false;
+}
+
+bool BinaryStoreBlobHandler::commit(uint16_t session,
+                                    const std::vector<uint8_t>&)
+{
+    auto it = sessions_.find(session);
+    if (it == sessions_.end())
+    {
+        return false;
+    }
+
+    return it->second->commit();
+}
+
+bool BinaryStoreBlobHandler::close(uint16_t session)
+{
+    auto it = sessions_.find(session);
+    if (it == sessions_.end())
+    {
+        return false;
+    }
+
+    if (!it->second->close())
+    {
+        return false;
+    }
+
+    sessions_.erase(session);
+    return true;
+}
+
+bool BinaryStoreBlobHandler::stat(uint16_t session, struct BlobMeta* meta)
+{
+    auto it = sessions_.find(session);
+    if (it == sessions_.end())
+    {
+        return false;
+    }
+
+    return it->second->stat(meta);
+}
+
+bool BinaryStoreBlobHandler::expire(uint16_t session)
+{
+    return close(session);
+}
+
+} // namespace blobs
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644
index 0000000..5cf6c10
--- /dev/null
+++ b/src/main.cpp
@@ -0,0 +1,78 @@
+#include "handler.hpp"
+#include "parse_config.hpp"
+#include "sys_file_impl.hpp"
+
+#include <blobs-ipmid/blobs.hpp>
+#include <exception>
+#include <fstream>
+#include <memory>
+#include <phosphor-logging/elog.hpp>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * This is required by the blob manager.
+ * TODO: move the declaration to blobs.hpp since all handlers need it
+ */
+std::unique_ptr<blobs::GenericBlobInterface> createHandler();
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Configuration file path */
+constexpr auto blobConfigPath = "/usr/share/binaryblob/config.json";
+
+std::unique_ptr<blobs::GenericBlobInterface> createHandler()
+{
+    using namespace phosphor::logging;
+    using nlohmann::json;
+
+    std::ifstream input(blobConfigPath);
+    json j;
+
+    try
+    {
+        input >> j;
+    }
+    catch (const std::exception& e)
+    {
+        log<level::ERR>("Failed to parse config into json",
+                        entry("ERR=%s", e.what()));
+        return nullptr;
+    }
+
+    // Construct binary blobs from config and add to handler
+    auto handler = std::make_unique<blobs::BinaryStoreBlobHandler>();
+
+    for (const auto& element : j)
+    {
+        conf::BinaryBlobConfig config;
+        try
+        {
+            conf::parseFromConfigFile(element, config);
+        }
+        catch (const std::exception& e)
+        {
+            log<level::ERR>("Encountered error when parsing config file",
+                            entry("ERR=%s", e.what()));
+            return nullptr;
+        }
+
+        log<level::INFO>("Loading from config with",
+                         entry("BASE_ID=%s", config.blobBaseId.c_str()),
+                         entry("FILE=%s", config.sysFilePath.c_str()),
+                         entry("MAX_SIZE=%llx", static_cast<unsigned long long>(
+                                                    config.maxSizeBytes)));
+
+        auto file = std::make_unique<binstore::SysFileImpl>(config.sysFilePath,
+                                                            config.offsetBytes);
+
+        handler->addNewBinaryStore(binstore::BinaryStore::createFromConfig(
+            config.blobBaseId, std::move(file), config.maxSizeBytes));
+    }
+
+    return handler;
+}
diff --git a/src/meson.build b/src/meson.build
new file mode 100644
index 0000000..a8917ac
--- /dev/null
+++ b/src/meson.build
@@ -0,0 +1,40 @@
+binarystoreblob_pre = declare_dependency(
+  include_directories: [
+    include_directories('.'),
+    blobstore_includes,
+  ],
+  dependencies: [
+    protobuf_dep,
+    ipmi_blob_dep,
+    phosphor_logging_dep,
+    binaryblobproto_dep,
+  ]
+)
+
+binarystoreblob_lib = library(
+  'binarystore',
+  'binarystore.cpp',
+  'sys.cpp',
+  'sys_file_impl.cpp',
+  'handler.cpp',
+  src_pb,
+  implicit_include_directories: false,
+  dependencies: binarystoreblob_pre,
+  install: true,
+  install_dir: get_option('libdir') / 'blob-ipmid'
+)
+
+binarystoreblob_dep = declare_dependency(
+  link_with: binarystoreblob_lib,
+  dependencies: binarystoreblob_pre
+)
+
+if not get_option('blobtool').disabled()
+  executable(
+    'blobtool',
+    'blobtool.cpp',
+    implicit_include_directories: false,
+    dependencies: binarystoreblob_dep,
+    install: true
+  )
+endif
diff --git a/src/sys.cpp b/src/sys.cpp
new file mode 100644
index 0000000..0a16dcb
--- /dev/null
+++ b/src/sys.cpp
@@ -0,0 +1,41 @@
+#include "sys.hpp"
+
+#include <fcntl.h>
+#include <unistd.h>
+
+namespace binstore
+{
+
+namespace internal
+{
+
+int SysImpl::open(const char* pathname, int flags) const
+{
+    return ::open(pathname, flags);
+}
+
+int SysImpl::close(int fd) const
+{
+    return ::close(fd);
+}
+
+off_t SysImpl::lseek(int fd, off_t offset, int whence) const
+{
+    return ::lseek(fd, offset, whence);
+}
+
+ssize_t SysImpl::read(int fd, void* buf, size_t count) const
+{
+    return ::read(fd, buf, count);
+}
+
+ssize_t SysImpl::write(int fd, const void* buf, size_t count) const
+{
+    return ::write(fd, buf, count);
+}
+
+SysImpl sys_impl;
+
+} // namespace internal
+
+} // namespace binstore
diff --git a/src/sys_file_impl.cpp b/src/sys_file_impl.cpp
new file mode 100644
index 0000000..243d82d
--- /dev/null
+++ b/src/sys_file_impl.cpp
@@ -0,0 +1,131 @@
+#include "sys_file_impl.hpp"
+
+#include <system_error>
+
+using namespace std::string_literals;
+
+static constexpr size_t rwBlockSize = 8192;
+
+namespace binstore
+{
+
+namespace
+{
+
+std::system_error errnoException(const std::string& message)
+{
+    return std::system_error(errno, std::generic_category(), message);
+}
+
+} // namespace
+
+SysFileImpl::SysFileImpl(const std::string& path, size_t offset,
+                         const internal::Sys* sys) :
+    sys(sys)
+{
+    fd_ = sys->open(path.c_str(), O_RDWR);
+    offset_ = offset;
+
+    if (fd_ < 0)
+    {
+        throw errnoException("Error opening file "s + path);
+    }
+}
+
+SysFileImpl::~SysFileImpl()
+{
+    sys->close(fd_);
+}
+
+void SysFileImpl::lseek(size_t pos) const
+{
+    if (sys->lseek(fd_, offset_ + pos, SEEK_SET) < 0)
+    {
+        throw errnoException("Cannot lseek to pos "s + std::to_string(pos));
+    }
+}
+
+size_t SysFileImpl::readToBuf(size_t pos, size_t count, char* buf) const
+{
+
+    lseek(pos);
+
+    size_t bytesRead = 0;
+
+    do
+    {
+        auto ret = sys->read(fd_, &buf[bytesRead], count - bytesRead);
+        if (ret < 0)
+        {
+            if (errno == EINTR)
+            {
+                continue;
+            }
+
+            throw errnoException("Error reading from file"s);
+        }
+        else if (ret > 0)
+        {
+            bytesRead += ret;
+        }
+        else // ret == 0
+        {
+            break;
+        }
+    } while (bytesRead < count);
+
+    return bytesRead;
+}
+
+std::string SysFileImpl::readAsStr(size_t pos, size_t count) const
+{
+    std::string result;
+
+    /* If count is invalid, return an empty string. */
+    if (count == 0 || count > result.max_size())
+    {
+        return result;
+    }
+
+    result.resize(count);
+    size_t bytesRead = readToBuf(pos, count, result.data());
+    result.resize(bytesRead);
+    return result;
+}
+
+std::string SysFileImpl::readRemainingAsStr(size_t pos) const
+{
+    std::string result;
+    size_t bytesRead, size = 0;
+
+    /* Since we don't know how much to read, read 'rwBlockSize' at a time
+     * until there is nothing to read anymore. */
+    do
+    {
+        result.resize(size + rwBlockSize);
+        bytesRead = readToBuf(pos + size, rwBlockSize, result.data() + size);
+        size += bytesRead;
+    } while (bytesRead == rwBlockSize);
+
+    result.resize(size);
+    return result;
+}
+
+void SysFileImpl::writeStr(const std::string& data, size_t pos)
+{
+    lseek(pos);
+    ssize_t ret;
+    ret = sys->write(fd_, data.data(), data.size());
+    if (ret < 0)
+    {
+        throw errnoException("Error writing to file"s);
+    }
+    if (static_cast<size_t>(ret) != data.size())
+    {
+        throw std::runtime_error(
+            "Tried to send data size "s + std::to_string(data.size()) +
+            " but could only send "s + std::to_string(ret));
+    }
+}
+
+} // namespace binstore
