diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 104e0f192c..0ea8d132cb 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -20,6 +20,7 @@ set(KERNEL_SOURCES kernel/Device/Device.cpp kernel/Device/FramebufferDevice.cpp kernel/Device/NullDevice.cpp + kernel/Device/RandomDevice.cpp kernel/Device/ZeroDevice.cpp kernel/Errors.cpp kernel/FS/DevFS/FileSystem.cpp diff --git a/kernel/include/kernel/Device/DeviceNumbers.h b/kernel/include/kernel/Device/DeviceNumbers.h index cb57f9d25a..3a3617acef 100644 --- a/kernel/include/kernel/Device/DeviceNumbers.h +++ b/kernel/include/kernel/Device/DeviceNumbers.h @@ -12,6 +12,7 @@ namespace Kernel PTSMaster, Null, Zero, + Random, Debug, Keyboard, Mouse, diff --git a/kernel/include/kernel/Device/RandomDevice.h b/kernel/include/kernel/Device/RandomDevice.h new file mode 100644 index 0000000000..4016908c84 --- /dev/null +++ b/kernel/include/kernel/Device/RandomDevice.h @@ -0,0 +1,32 @@ +#include + +namespace Kernel +{ + + class RandomDevice : public CharacterDevice + { + public: + static BAN::ErrorOr> create(mode_t, uid_t, gid_t); + + virtual dev_t rdev() const override { return m_rdev; } + + virtual BAN::StringView name() const override { return "random"_sv; } + + protected: + RandomDevice(mode_t mode, uid_t uid, gid_t gid, dev_t rdev) + : CharacterDevice(mode, uid, gid) + , m_rdev(rdev) + { } + + virtual BAN::ErrorOr read_impl(off_t, BAN::ByteSpan) override; + virtual BAN::ErrorOr write_impl(off_t, BAN::ConstByteSpan buffer) override { return buffer.size(); }; + + virtual bool can_read_impl() const override { return true; } + virtual bool can_write_impl() const override { return false; } + virtual bool has_error_impl() const override { return false; } + + private: + const dev_t m_rdev; + }; + +} diff --git a/kernel/kernel/Device/RandomDevice.cpp b/kernel/kernel/Device/RandomDevice.cpp new file mode 100644 index 0000000000..10aec9f52f --- /dev/null +++ b/kernel/kernel/Device/RandomDevice.cpp @@ -0,0 +1,32 @@ +#include +#include +#include + +#include + +namespace Kernel +{ + + BAN::ErrorOr> RandomDevice::create(mode_t mode, uid_t uid, gid_t gid) + { + static uint32_t minor = 0; + auto* result = new RandomDevice(mode, uid, gid, makedev(DeviceNumber::Random, minor++)); + if (result == nullptr) + return BAN::Error::from_errno(ENOMEM); + return BAN::RefPtr::adopt(result); + } + + BAN::ErrorOr RandomDevice::read_impl(off_t, BAN::ByteSpan buffer) + { + size_t nwritten = 0; + while (nwritten < buffer.size()) + { + const uint64_t random = Random::get_u64(); + const size_t to_copy = BAN::Math::min(buffer.size() - nwritten, sizeof(random)); + memcpy(buffer.data() + nwritten, &random, to_copy); + nwritten += to_copy; + } + return buffer.size(); + } + +} diff --git a/kernel/kernel/FS/DevFS/FileSystem.cpp b/kernel/kernel/FS/DevFS/FileSystem.cpp index 2f05440c48..6a9d5c862f 100644 --- a/kernel/kernel/FS/DevFS/FileSystem.cpp +++ b/kernel/kernel/FS/DevFS/FileSystem.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -26,6 +27,7 @@ namespace Kernel MUST(s_instance->TmpFileSystem::initialize(0755, 0, 0)); s_instance->add_device(MUST(DebugDevice::create(0666, 0, 0))); s_instance->add_device(MUST(NullDevice::create(0666, 0, 0))); + s_instance->add_device(MUST(RandomDevice::create(0666, 0, 0))); s_instance->add_device(MUST(ZeroDevice::create(0666, 0, 0))); s_instance->add_device(MUST(KeyboardDevice::create(0440, 0, 901))); s_instance->add_device(MUST(MouseDevice::create(0440, 0, 901)));