diff options
author | Liav A <liavalb@gmail.com> | 2021-12-20 11:48:25 +0200 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-01-23 00:38:02 +0000 |
commit | 4da7b543c6aa96b399b5df4ecf54dd695b1ed844 (patch) | |
tree | d42f94fa05d75852bf7dbeda8ed2d8e65304b27c | |
parent | eaad77b286fbc663f281ef0fb7a903b2928df572 (diff) | |
download | serenity-4da7b543c6aa96b399b5df4ecf54dd695b1ed844.zip |
SystemServer: Create /dev/devctl and create devices based on its events
We first create the /dev/devctl based on the information from the SysFS.
Then, we create block devices and character devices based on the events
we read from that device.
-rw-r--r-- | Userland/Services/SystemServer/main.cpp | 281 |
1 files changed, 159 insertions, 122 deletions
diff --git a/Userland/Services/SystemServer/main.cpp b/Userland/Services/SystemServer/main.cpp index 5fb051e55e..2070717350 100644 --- a/Userland/Services/SystemServer/main.cpp +++ b/Userland/Services/SystemServer/main.cpp @@ -9,6 +9,7 @@ #include <AK/Assertions.h> #include <AK/ByteBuffer.h> #include <AK/Debug.h> +#include <Kernel/API/DeviceEvent.h> #include <LibCore/ArgsParser.h> #include <LibCore/ConfigFile.h> #include <LibCore/DirIterator.h> @@ -132,45 +133,13 @@ static void create_devtmpfs_block_device(String name, mode_t mode, unsigned majo VERIFY_NOT_REACHED(); } -static void populate_devtmpfs_block_devices() -{ - Core::DirIterator di("/sys/dev/block/", Core::DirIterator::SkipParentAndBaseDir); - if (di.has_error()) { - warnln("Failed to open /sys/dev/block - {}", di.error()); - VERIFY_NOT_REACHED(); - } - while (di.has_next()) { - auto entry_name = di.next_path().split(':'); - VERIFY(entry_name.size() == 2); - auto major_number = entry_name[0].to_uint<unsigned>().value(); - auto minor_number = entry_name[1].to_uint<unsigned>().value(); - switch (major_number) { - case 29: { - create_devtmpfs_block_device(String::formatted("/dev/fb{}", minor_number), 0666, 29, minor_number); - break; - } - case 30: { - create_devtmpfs_block_device(String::formatted("/dev/kcov{}", minor_number), 0666, 30, minor_number); - break; - } - case 3: { - create_devtmpfs_block_device(String::formatted("/dev/hd{}", offset_character_with_number('a', minor_number)), 0600, 3, minor_number); - break; - } - default: - warnln("Unknown block device {}:{}", major_number, minor_number); - break; - } - } -} - static void create_devtmpfs_char_device(String name, mode_t mode, unsigned major, unsigned minor) { if (auto rc = mknod(name.characters(), mode | S_IFCHR, makedev(major, minor)); rc < 0) VERIFY_NOT_REACHED(); } -static void populate_devtmpfs_char_devices() +static void populate_devtmpfs_char_devices_based_on_sysfs() { Core::DirIterator di("/sys/dev/char/", Core::DirIterator::SkipParentAndBaseDir); if (di.has_error()) { @@ -183,10 +152,10 @@ static void populate_devtmpfs_char_devices() auto major_number = entry_name[0].to_uint<unsigned>().value(); auto minor_number = entry_name[1].to_uint<unsigned>().value(); switch (major_number) { - case 42: { + case 2: { switch (minor_number) { - case 42: { - create_devtmpfs_char_device("/dev/audio", 0220, 42, 42); + case 10: { + create_devtmpfs_char_device("/dev/devctl", 0660, 2, 10); break; } default: @@ -194,7 +163,48 @@ static void populate_devtmpfs_char_devices() } break; } + + default: + break; + } + } +} + +static void populate_devtmpfs_devices_based_on_devctl() +{ + auto f = Core::File::construct("/dev/devctl"); + if (!f->open(Core::OpenMode::ReadOnly)) { + warnln("Failed to open /dev/devctl - {}", f->error_string()); + VERIFY_NOT_REACHED(); + } + + DeviceEvent event; + while (f->read((u8*)&event, sizeof(DeviceEvent)) > 0) { + if (event.state != DeviceEvent::Inserted) + continue; + auto major_number = event.major_number; + auto minor_number = event.minor_number; + bool is_block_device = (event.is_block_device == 1); + switch (major_number) { + case 42: { + if (!is_block_device) { + switch (minor_number) { + case 42: { + create_devtmpfs_char_device("/dev/audio", 0220, 42, 42); + break; + } + default: + warnln("Unknown character device {}:{}", major_number, minor_number); + } + } + break; + } case 29: { + if (is_block_device) { + create_devtmpfs_block_device(String::formatted("/dev/fb{}", minor_number), 0666, 29, minor_number); + break; + } + switch (minor_number) { case 0: { create_devtmpfs_char_device("/dev/full", 0660, 29, 0); @@ -206,115 +216,142 @@ static void populate_devtmpfs_char_devices() break; } case 229: { - create_devtmpfs_char_device(String::formatted("/dev/hvc0p{}", minor_number), 0666, major_number, minor_number); + if (!is_block_device) { + create_devtmpfs_char_device(String::formatted("/dev/hvc0p{}", minor_number), 0666, major_number, minor_number); + } break; } case 10: { - switch (minor_number) { - case 0: { - create_devtmpfs_char_device("/dev/mouse0", 0660, 10, 0); - break; - } - case 183: { - create_devtmpfs_char_device("/dev/hwrng", 0660, 10, 183); - break; - } - default: - warnln("Unknown character device {}:{}", major_number, minor_number); + if (!is_block_device) { + switch (minor_number) { + case 0: { + create_devtmpfs_char_device("/dev/mouse0", 0660, 10, 0); + break; + } + case 183: { + create_devtmpfs_char_device("/dev/hwrng", 0660, 10, 183); + break; + } + default: + warnln("Unknown character device {}:{}", major_number, minor_number); + } } break; } case 85: { - switch (minor_number) { - case 0: { - create_devtmpfs_char_device("/dev/keyboard0", 0660, 85, 0); - break; - } - default: - warnln("Unknown character device {}:{}", major_number, minor_number); + if (!is_block_device) { + switch (minor_number) { + case 0: { + create_devtmpfs_char_device("/dev/keyboard0", 0660, 85, 0); + break; + } + default: + warnln("Unknown character device {}:{}", major_number, minor_number); + } } break; } case 1: { - switch (minor_number) { - case 5: { - create_devtmpfs_char_device("/dev/zero", 0666, 1, 5); - break; + if (!is_block_device) { + switch (minor_number) { + case 5: { + create_devtmpfs_char_device("/dev/zero", 0666, 1, 5); + break; + } + case 1: { + create_devtmpfs_char_device("/dev/mem", 0660, 1, 1); + break; + } + case 3: { + create_devtmpfs_char_device("/dev/null", 0666, 1, 3); + break; + } + case 8: { + create_devtmpfs_char_device("/dev/random", 0666, 1, 8); + break; + } + default: + warnln("Unknown character device {}:{}", major_number, minor_number); + break; + } } - case 1: { - create_devtmpfs_char_device("/dev/mem", 0660, 1, 1); - break; - } - case 3: { - create_devtmpfs_char_device("/dev/null", 0666, 1, 3); - break; - } - case 8: { - create_devtmpfs_char_device("/dev/random", 0666, 1, 8); - break; + break; + } + case 30: { + if (is_block_device) { + create_devtmpfs_block_device(String::formatted("/dev/kcov{}", minor_number), 0666, 30, minor_number); } - default: - warnln("Unknown character device {}:{}", major_number, minor_number); - break; + break; + } + case 3: { + if (is_block_device) { + create_devtmpfs_block_device(String::formatted("/dev/hd{}", offset_character_with_number('a', minor_number)), 0600, 3, minor_number); } break; } case 5: { - switch (minor_number) { - case 1: { - create_devtmpfs_char_device("/dev/console", 0666, 5, 1); - break; - } - case 2: { - create_devtmpfs_char_device("/dev/ptmx", 0666, 5, 2); - break; - } - default: - warnln("Unknown character device {}:{}", major_number, minor_number); + if (!is_block_device) { + switch (minor_number) { + case 1: { + create_devtmpfs_char_device("/dev/console", 0666, 5, 1); + break; + } + case 2: { + create_devtmpfs_char_device("/dev/ptmx", 0666, 5, 2); + break; + } + default: + warnln("Unknown character device {}:{}", major_number, minor_number); + } } break; } case 4: { - switch (minor_number) { - case 0: { - create_devtmpfs_char_device("/dev/tty0", 0620, 4, 0); - break; - } - case 1: { - create_devtmpfs_char_device("/dev/tty1", 0620, 4, 1); - break; - } - case 2: { - create_devtmpfs_char_device("/dev/tty2", 0620, 4, 2); - break; - } - case 3: { - create_devtmpfs_char_device("/dev/tty3", 0620, 4, 3); - break; - } - case 64: { - create_devtmpfs_char_device("/dev/ttyS0", 0620, 4, 64); - break; - } - case 65: { - create_devtmpfs_char_device("/dev/ttyS1", 0620, 4, 65); - break; - } - case 66: { - create_devtmpfs_char_device("/dev/ttyS2", 0620, 4, 66); - break; - } - case 67: { - create_devtmpfs_char_device("/dev/ttyS3", 0666, 4, 67); - break; - } - default: - warnln("Unknown character device {}:{}", major_number, minor_number); + if (!is_block_device) { + switch (minor_number) { + case 0: { + create_devtmpfs_char_device("/dev/tty0", 0620, 4, 0); + break; + } + case 1: { + create_devtmpfs_char_device("/dev/tty1", 0620, 4, 1); + break; + } + case 2: { + create_devtmpfs_char_device("/dev/tty2", 0620, 4, 2); + break; + } + case 3: { + create_devtmpfs_char_device("/dev/tty3", 0620, 4, 3); + break; + } + case 64: { + create_devtmpfs_char_device("/dev/ttyS0", 0620, 4, 64); + break; + } + case 65: { + create_devtmpfs_char_device("/dev/ttyS1", 0620, 4, 65); + break; + } + case 66: { + create_devtmpfs_char_device("/dev/ttyS2", 0620, 4, 66); + break; + } + case 67: { + create_devtmpfs_char_device("/dev/ttyS3", 0666, 4, 67); + break; + } + default: + warnln("Unknown character device {}:{}", major_number, minor_number); + } } break; } default: - warnln("Unknown character device {}:{}", major_number, minor_number); + if (!is_block_device) + warnln("Unknown character device {}:{}", major_number, minor_number); + else + warnln("Unknown block device {}:{}", major_number, minor_number); break; } } @@ -324,8 +361,8 @@ static void populate_devtmpfs() { mode_t old_mask = umask(0); printf("Changing umask %#o\n", old_mask); - populate_devtmpfs_char_devices(); - populate_devtmpfs_block_devices(); + populate_devtmpfs_char_devices_based_on_sysfs(); + populate_devtmpfs_devices_based_on_devctl(); umask(old_mask); } |