#include "fs/devices/DeviceRegistry.h" #include "Log.h" #include "fs/VFS.h" #include "fs/devices/ConsoleDevice.h" #include "fs/devices/FramebufferDevice.h" #include "fs/devices/FullDevice.h" #include "fs/devices/NullDevice.h" #include "fs/devices/ZeroDevice.h" #include "fs/tmpfs/FileSystem.h" #include "thread/Thread.h" #include struct DeviceDescriptor { SharedPtr device; u32 major; u32 minor; const char* name; mode_t mode; }; Vector g_available_devices = {}; SharedPtr g_device_fs; namespace DeviceRegistry { Result> fetch_special_device(u32 major, u32 minor) { for (const auto& descriptor : g_available_devices) { if (descriptor.major == major && descriptor.minor == minor) return descriptor.device; } return err(ENODEV); } Result create_special_device_inode(DeviceDescriptor& descriptor) { auto inode = TRY(g_device_fs->create_device_inode(descriptor.major, descriptor.minor)); inode->chmod(descriptor.mode); TRY(g_device_fs->root_inode()->add_entry(inode, descriptor.name)); return {}; } Result register_special_device(u32 major, u32 minor, SharedPtr device, const char* name, mode_t mode) { for (const auto& descriptor : g_available_devices) { if (descriptor.major == major && descriptor.minor == minor) return err(EEXIST); } kdbgln("DeviceRegistry: registered new device type %u:%u at path /dev/%s", major, minor, name); auto desc = DeviceDescriptor { .device = device, .major = major, .minor = minor, .name = name, .mode = mode }; TRY(g_available_devices.try_append(desc)); TRY(create_special_device_inode(desc)); return {}; } Result init() { auto device_fs = TRY(TmpFS::FileSystem::create()); TRY(VFS::mount("/dev", device_fs, Credentials {})); g_device_fs = device_fs; NullDevice::create(); ZeroDevice::create(); FullDevice::create(); ConsoleDevice::create(); FramebufferDevice::create(); return {}; } dev_t next_null_device_id() { static u32 next_minor = 0; return luna_dev_makedev(0, next_minor++); } }