فهرست منبع

refactor: special node files and partprobe

do partprobe based on device number instead of /dev/sd*

introduce new kmsg macros

store devices in arrays

create dev files in init script
greatbridf 11 ماه پیش
والد
کامیت
b1b6d920f8
5فایلهای تغییر یافته به همراه97 افزوده شده و 83 حذف شده
  1. 10 4
      include/kernel/log.hpp
  2. 2 2
      include/kernel/vfs.hpp
  3. 2 0
      init_script.sh
  4. 8 9
      src/kernel/process.cpp
  5. 75 68
      src/kernel/vfs.cpp

+ 10 - 4
include/kernel/log.hpp

@@ -1,8 +1,14 @@
 #pragma once
 
+#include <stdio.h>
+
 #include <kernel/tty.hpp>
 
-inline void kmsg(const char* msg)
-{
-    console->print(msg);
-}
+#define kmsgf(fmt, ...) \
+    if (1) {\
+        char buf[512]; \
+        snprintf(buf, sizeof(buf), fmt __VA_OPT__(,) __VA_ARGS__); \
+        console->print(buf); \
+    }
+
+#define kmsg(msg) console->print(msg)

+ 2 - 2
include/kernel/vfs.hpp

@@ -62,8 +62,8 @@ struct user_dirent64 {
 
 inline dentry* fs_root;
 
-int register_block_device(dev_t node, blkdev_ops ops);
-int register_char_device(dev_t node, chrdev_ops ops);
+int register_block_device(dev_t node, const blkdev_ops& ops);
+int register_char_device(dev_t node, const chrdev_ops& ops);
 
 // return value: pointer to created vfs object
 // 1. dev_t: device number

+ 2 - 0
init_script.sh

@@ -11,6 +11,8 @@ mkdir -p /dev
 
 mknod -m 666 /dev/console c 2 0
 mknod -m 666 /dev/null c 1 0
+mknod -m 666 /dev/sda b 8 0
+mknod -m 666 /dev/sda1 b 8 1
 
 cat > /etc/passwd <<EOF
 root:x:0:0:root:/root:/mnt/busybox_ sh

+ 8 - 9
src/kernel/process.cpp

@@ -536,22 +536,21 @@ void NORETURN _kernel_init(void)
         kmsg(buf);
     }
 
-
     // mount fat32 /mnt directory
     // TODO: parse kernel parameters
     if (1) {
-        auto* drive = fs::vfs_open(*fs::fs_root, "/dev/sda1");
-        assert(drive);
-
-        dev_t drive_device;
-        int ret = drive->ind->fs->dev_id(drive->ind, drive_device);
-        assert(ret == 0);
-
         fs::vfs* new_fs;
-        ret = fs::create_fs("fat32", drive_device, new_fs);
+        int ret = fs::create_fs("fat32", fs::make_device(8, 1), new_fs);
         assert(ret == 0);
 
         auto* mount_point = fs::vfs_open(*fs::fs_root, "/mnt");
+        if (!mount_point) {
+            int ret = fs::vfs_mkdir(fs::fs_root, "mnt", 0755);
+            assert(ret == GB_OK);
+
+            mount_point = fs::vfs_open(*fs::fs_root, "/mnt");
+        }
+
         assert(mount_point);
 
         ret = fs::fs_root->ind->fs->mount(mount_point, new_fs);

+ 75 - 68
src/kernel/vfs.cpp

@@ -400,8 +400,8 @@ fs::fifo_file::~fifo_file()
         ppipe->close_write();
 }
 
-static std::map<dev_t, fs::blkdev_ops> blkdevs;
-static std::map<dev_t, fs::chrdev_ops> chrdevs;
+static fs::blkdev_ops** blkdevs[256];
+static fs::chrdev_ops** chrdevs[256];
 
 size_t fs::vfs_read(fs::inode* file, char* buf, size_t buf_size, size_t offset, size_t n)
 {
@@ -515,23 +515,33 @@ int fs::vfs_truncate(inode *file, size_t size)
 
 static std::list<fs::vfs*> fs_es;
 
-int fs::register_block_device(dev_t node, fs::blkdev_ops ops)
+int fs::register_block_device(dev_t node, const fs::blkdev_ops& ops)
 {
-    auto iter = blkdevs.find(node);
-    if (iter)
+    int major = NODE_MAJOR(node);
+    int minor = NODE_MINOR(node);
+
+    if (!blkdevs[major])
+        blkdevs[major] = new blkdev_ops*[256] {};
+
+    if (blkdevs[major][minor])
         return -EEXIST;
 
-    std::tie(iter, std::ignore) = blkdevs.emplace(node, std::move(ops));
+    blkdevs[major][minor] = new blkdev_ops { ops };
     return 0;
 }
 
-int fs::register_char_device(dev_t node, fs::chrdev_ops ops)
+int fs::register_char_device(dev_t node, const fs::chrdev_ops& ops)
 {
-    auto iter = chrdevs.find(node);
-    if (iter)
+    int major = NODE_MAJOR(node);
+    int minor = NODE_MINOR(node);
+
+    if (!chrdevs[major])
+        chrdevs[major] = new chrdev_ops*[256] {};
+
+    if (chrdevs[major][minor])
         return -EEXIST;
 
-    std::tie(iter, std::ignore) = chrdevs.emplace(node, std::move(ops));
+    chrdevs[major][minor] = new chrdev_ops { ops };
     return 0;
 }
 
@@ -580,25 +590,18 @@ struct PACKED mbr {
     uint16_t magic;
 };
 
-static inline void mbr_part_probe(dev_t node, char ch)
+// TODO: devtmpfs
+static int mbr_part_probe(dev_t node)
 {
     mbr buf_mbr;
-    // TODO: devtmpfs
-    auto* dev = fs::vfs_open(*fs::fs_root, "/dev");
-    if (!dev)
-        return;
-
-    char label[] = "sda1";
-    label[2] = ch;
-    auto ret = fs::block_device_read(node, (char*)&buf_mbr, sizeof(mbr), 0, 512);
-    if (ret < 0) {
-        kmsg("[kernel] cannot read device for part probing.\n");
-        return;
-    }
+
+    int ret = fs::block_device_read(node, (char*)&buf_mbr, sizeof(mbr), 0, 512);
+    if (ret < 0)
+        return -EIO;
 
     int n = 1;
     for (const auto& part : buf_mbr.parts) {
-        if (n >= 8)
+        if (n >= 16)
             break;
 
         if (!part.type)
@@ -618,87 +621,94 @@ static inline void mbr_part_probe(dev_t node, char ch)
             }
         });
 
-        ret = fs::vfs_mknode(dev, label, 0660 | S_IFBLK, node + n);
-        ++n, ++label[3];
+        ++n;
     }
+
+    return 0;
 }
 
 void fs::partprobe()
 {
-    auto* dev = fs::vfs_open(*fs::fs_root, "/dev");
-    if (!dev)
-        return;
-
-    char ch = 'a';
-    char name[] = "sd*";
-    types::string<> path = "/dev/sd*";
-    for (const auto& device : blkdevs) {
-        // only the devices whose minor number is a multiple of 8
-        // are considered as a disk instead of partitions
-        if (NODE_MINOR(device.first) % 8 != 0)
-            continue;
-
-        path.pop();
-        path += ch;
-        name[2] = ch;
+    for (int i = 0; i < 256; i += 16) {
+        int ret = mbr_part_probe(make_device(8, i));
 
-        auto* blkfile = fs::vfs_open(*fs::fs_root, path.c_str());
-        if (!blkfile)
-            vfs_mknode(dev, name, 0660 | S_IFBLK, device.first);
-
-        mbr_part_probe(device.first, ch);
+        if (ret != 0)
+            continue;
 
-        ++ch;
+        kmsgf("[info] found disk drive sd%c\n", 'a' + (i / 16));
     }
 }
 
 ssize_t fs::block_device_read(dev_t node, char* buf, size_t buf_size, size_t offset, size_t n)
 {
-    auto iter = blkdevs.find(node);
-    if (!iter || !iter->second.read)
+    int major = NODE_MAJOR(node);
+    int minor = NODE_MINOR(node);
+
+    if (!blkdevs[major] || !blkdevs[major][minor])
         return -EINVAL;
 
-    return iter->second.read(buf, buf_size, offset, n);
+    auto& read = blkdevs[major][minor]->read;
+    if (!read)
+        return -EINVAL;
+
+    return read(buf, buf_size, offset, n);
 }
 
 ssize_t fs::block_device_write(dev_t node, const char* buf, size_t offset, size_t n)
 {
-    auto iter = blkdevs.find(node);
-    if (!iter || !iter->second.write)
+    int major = NODE_MAJOR(node);
+    int minor = NODE_MINOR(node);
+
+    if (!blkdevs[major] || !blkdevs[major][minor])
+        return -EINVAL;
+
+    auto& write = blkdevs[major][minor]->write;
+    if (!write)
         return -EINVAL;
 
-    return iter->second.write(buf, offset, n);
+    return write(buf, offset, n);
 }
 
 ssize_t fs::char_device_read(dev_t node, char* buf, size_t buf_size, size_t n)
 {
-    auto iter = chrdevs.find(node);
-    if (!iter || !iter->second.read)
+    int major = NODE_MAJOR(node);
+    int minor = NODE_MINOR(node);
+
+    if (!chrdevs[major] || !chrdevs[major][minor])
+        return -EINVAL;
+
+    auto& read = chrdevs[major][minor]->read;
+    if (!read)
         return -EINVAL;
 
-    return iter->second.read(buf, buf_size, n);
+    return read(buf, buf_size, n);
 }
 
 ssize_t fs::char_device_write(dev_t node, const char* buf, size_t n)
 {
-    auto iter = chrdevs.find(node);
-    if (!iter || !iter->second.read)
+    int major = NODE_MAJOR(node);
+    int minor = NODE_MINOR(node);
+
+    if (!chrdevs[major] || !chrdevs[major][minor])
         return -EINVAL;
 
-    return iter->second.write(buf, n);
+    auto& write = chrdevs[major][minor]->write;
+    if (!write)
+        return -EINVAL;
+
+    return write(buf, n);
 }
 
-ssize_t b_null_read(char* buf, size_t buf_size, size_t n)
+ssize_t b_null_read(char*, size_t, size_t)
 {
-    if (n >= buf_size)
-        n = buf_size;
-    memset(buf, 0x00, n);
-    return n;
+    return 0;
 }
+
 ssize_t b_null_write(const char*, size_t n)
 {
     return n;
 }
+
 static ssize_t console_read(char* buf, size_t buf_size, size_t n)
 {
     return console->read(buf, buf_size, n);
@@ -821,7 +831,4 @@ void init_vfs(void)
 
     assert(ret == 0);
     fs_root = rootfs->root();
-
-    vfs_mkdir(fs_root, "dev", 0755);
-    vfs_mkdir(fs_root, "mnt", 0755);
 }