/* This file is part of Fennix Kernel. Fennix Kernel is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Fennix Kernel is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Fennix Kernel. If not, see . */ #include #include extern Driver::Manager *DriverManager; namespace Driver::MemoryDevices { dev_t DriverID; struct { dev_t null; dev_t zero; dev_t random; dev_t urandom; dev_t mem; } ids; int Open(struct Inode *Node, int Flags, mode_t Mode) { return -ENOENT; } int Close(struct Inode *Node) { return -ENOSYS; } int Ioctl(struct Inode *Node, unsigned long Request, void *Argp) { return -ENOSYS; } ssize_t Read(struct Inode *Node, void *Buffer, size_t Size, off_t Offset) { dev_t min = Node->GetMinor(); if (min == ids.null) return 0; else if (min == ids.zero) { if (Size <= 0) return 0; memset(Buffer, 0, Size); return Size; } else if (min == ids.random || min == ids.urandom) { if (Size <= 0) return 0; if (Size < sizeof(uint64_t)) { uint8_t *buf = (uint8_t *)Buffer; for (size_t i = 0; i < Size; i++) buf[i] = (uint8_t)(Random::rand16() & 0xFF); return Size; } uint64_t *buf = (uint64_t *)Buffer; for (size_t i = 0; i < Size / sizeof(uint64_t); i++) buf[i] = Random::rand64(); return Size; } else if (min == ids.mem) { stub; return 0; } return -ENODEV; } ssize_t Write(struct Inode *Node, const void *Buffer, size_t Size, off_t Offset) { dev_t min = Node->GetMinor(); if (min == ids.null) return Size; else if (min == ids.zero) return Size; else if (min == ids.random || min == ids.urandom) return Size; else if (min == ids.mem) return Size; return -ENODEV; } off_t Seek(struct Inode *Node, off_t Offset) { return -ENOSYS; } int Stat(struct Inode *Node, struct kstat *Stat) { return -ENOSYS; } const struct InodeOperations ops = { .Lookup = nullptr, .Create = nullptr, .Remove = nullptr, .Rename = nullptr, .Read = Read, .Write = Write, .Truncate = nullptr, .Open = Open, .Close = Close, .Ioctl = Ioctl, .ReadDir = nullptr, .MkDir = nullptr, .RmDir = nullptr, .SymLink = nullptr, .ReadLink = nullptr, .Seek = Seek, .Stat = Stat, }; int Entry() { mode_t mode = 0; /* c rw- rw- rw- */ mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH | S_IFCHR; ids.null = DriverManager->CreateDeviceFile(DriverID, "null", mode, &ops); ids.zero = DriverManager->CreateDeviceFile(DriverID, "zero", mode, &ops); ids.random = DriverManager->CreateDeviceFile(DriverID, "random", mode, &ops); ids.urandom = DriverManager->CreateDeviceFile(DriverID, "urandom", mode, &ops); /* c rw- r-- --- */ mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR; ids.mem = DriverManager->CreateDeviceFile(DriverID, "mem", mode, &ops); return 0; } int Final() { DriverManager->UnregisterDevice(DriverID, ids.null); DriverManager->UnregisterDevice(DriverID, ids.zero); DriverManager->UnregisterDevice(DriverID, ids.random); DriverManager->UnregisterDevice(DriverID, ids.urandom); DriverManager->UnregisterDevice(DriverID, ids.mem); return 0; } int Panic() { return 0; } int Probe() { return 0; } REGISTER_BUILTIN_DRIVER(mem, "Memory Devices Driver", "enderice2", 1, 0, 0, Entry, Final, Panic, Probe); }