feat: simple device abstraction layer
authorMinep <zelong56@gmail.com>
Sat, 30 Jul 2022 14:09:18 +0000 (15:09 +0100)
committerMinep <zelong56@gmail.com>
Sat, 30 Jul 2022 14:09:18 +0000 (15:09 +0100)
feat: integrate tty console into fs
refactor: timer now using cake allocator
refactor: adjust initialization sequence
chore: code clean up and minor refactoring

16 files changed:
lunaix-os/hal/acpi/acpi.c
lunaix-os/includes/klibc/stdio.h
lunaix-os/includes/lunaix/block.h
lunaix-os/includes/lunaix/device.h [new file with mode: 0644]
lunaix-os/includes/lunaix/fs.h
lunaix-os/includes/lunaix/fs/twifs.h
lunaix-os/kernel/block.c
lunaix-os/kernel/demos/iotest.c
lunaix-os/kernel/device.c [new file with mode: 0644]
lunaix-os/kernel/fs/twifs.c
lunaix-os/kernel/fs/vfs.c
lunaix-os/kernel/k_init.c
lunaix-os/kernel/lxconsole.c
lunaix-os/kernel/proc0.c
lunaix-os/kernel/time/timer.c
lunaix-os/libs/klibc/stdio/sprintf.c

index 0b1d9883b00ce7e381247696852ed0cb3913df2a..5c1eb17d408d95af26137acc3c24e7e4524741de 100644 (file)
@@ -26,8 +26,6 @@ acpi_init(multiboot_info_t* mb_info)
     assert_msg(rsdp, "Fail to locate ACPI_RSDP");
     assert_msg(acpi_rsdp_validate(rsdp), "Invalid ACPI_RSDP (checksum failed)");
 
     assert_msg(rsdp, "Fail to locate ACPI_RSDP");
     assert_msg(acpi_rsdp_validate(rsdp), "Invalid ACPI_RSDP (checksum failed)");
 
-    kprintf(KDEBUG "RSDP found at %p, RSDT: %p\n", rsdp, rsdp->rsdt);
-
     acpi_rsdt_t* rsdt = rsdp->rsdt;
 
     ctx = lxcalloc(1, sizeof(acpi_context));
     acpi_rsdt_t* rsdt = rsdp->rsdt;
 
     ctx = lxcalloc(1, sizeof(acpi_context));
@@ -55,15 +53,7 @@ acpi_init(multiboot_info_t* mb_info)
         }
     }
 
         }
     }
 
-    kprintf(KINFO "OEM: %s\n", ctx->oem_id);
-
-    for (size_t i = 0; i < 24; i++) {
-        acpi_intso_t* intso = ctx->madt.irq_exception[i];
-        if (!intso)
-            continue;
-
-        kprintf(KDEBUG "IRQ #%u -> GSI #%u\n", intso->source, intso->gsi);
-    }
+    kprintf(KINFO "ACPI: %s\n", ctx->oem_id);
 }
 
 acpi_context*
 }
 
 acpi_context*
index 07f47169a9c5e9726c55c12107c76fad63d937df..d97f0285968d09e16bac247760d29b2157381280 100644 (file)
@@ -3,9 +3,11 @@
 #include <stdarg.h>
 #include <stddef.h>
 
 #include <stdarg.h>
 #include <stddef.h>
 
-void
+size_t
 __sprintf_internal(char* buffer, char* fmt, size_t max_len, va_list vargs);
 
 __sprintf_internal(char* buffer, char* fmt, size_t max_len, va_list vargs);
 
-void sprintf(char* buffer, char* fmt, ...);
-void snprintf(char* buffer, size_t n, char* fmt, ...);
+size_t
+sprintf(char* buffer, char* fmt, ...);
+size_t
+snprintf(char* buffer, size_t n, char* fmt, ...);
 #endif /* __LUNAIX_STDIO_H */
 #endif /* __LUNAIX_STDIO_H */
index 94e87754c703436758d3f6cfeed92b96ce7cd6b9..40935f9f630bb79da872ea7874606e743630647c 100644 (file)
@@ -2,6 +2,7 @@
 #define __LUNAIX_BLOCK_H
 
 #include <hal/ahci/hba.h>
 #define __LUNAIX_BLOCK_H
 
 #include <hal/ahci/hba.h>
+#include <lunaix/device.h>
 
 #define LPT_SIG 0x414e554c
 #define PARTITION_NAME_SIZE 48
 
 #define LPT_SIG 0x414e554c
 #define PARTITION_NAME_SIZE 48
@@ -15,6 +16,7 @@ struct block_dev
     char bdev_id[DEV_ID_SIZE];
     char name[PARTITION_NAME_SIZE];
     struct hba_device* hd_dev;
     char bdev_id[DEV_ID_SIZE];
     char name[PARTITION_NAME_SIZE];
     struct hba_device* hd_dev;
+    struct device* dev;
     uint64_t base_lba;
     uint64_t end_lba;
 };
     uint64_t base_lba;
     uint64_t end_lba;
 };
diff --git a/lunaix-os/includes/lunaix/device.h b/lunaix-os/includes/lunaix/device.h
new file mode 100644 (file)
index 0000000..dde14a3
--- /dev/null
@@ -0,0 +1,36 @@
+#ifndef __LUNAIX_DEVICE_H
+#define __LUNAIX_DEVICE_H
+
+#define DEVICE_NAME_SIZE 32
+
+#include <lunaix/ds/hstr.h>
+#include <lunaix/ds/llist.h>
+
+struct device
+{
+    struct llist_header dev_list;
+    struct device* parent;
+    struct hstr name;
+    char name_val[DEVICE_NAME_SIZE];
+    void* underlay;
+    void* fs_node;
+    int (*read)(struct device* dev,
+                void* buf,
+                unsigned int offset,
+                unsigned int len);
+    int (*write)(struct device* dev,
+                 void* buf,
+                 unsigned int offset,
+                 unsigned int len);
+};
+
+void
+device_init();
+
+struct device*
+device_add(struct device* parent, void* underlay, char* name_fmt, ...);
+
+void
+device_remove(struct device* dev);
+
+#endif /* __LUNAIX_DEVICE_H */
index fce04ca1dfbb1dbd86fbf40c241512be686d6887..fe9b39b6ea2cdff27de62b585c18a4bccf82a38c 100644 (file)
 
 #define VFS_IOBUF_FDIRTY 0x1
 
 
 #define VFS_IOBUF_FDIRTY 0x1
 
+#define FSTYPE_ROFS 0x1
+
 #define VFS_VALID_CHAR(chr)                                                    \
     ('A' <= (chr) && (chr) <= 'Z' || 'a' <= (chr) && (chr) <= 'z' ||           \
      '0' <= (chr) && (chr) <= '9' || (chr) == '.' || (chr) == '_' ||           \
      (chr) == '-')
 
 #define VFS_VALID_CHAR(chr)                                                    \
     ('A' <= (chr) && (chr) <= 'Z' || 'a' <= (chr) && (chr) <= 'z' ||           \
      '0' <= (chr) && (chr) <= '9' || (chr) == '.' || (chr) == '_' ||           \
      (chr) == '-')
 
+extern struct hstr vfs_ddot;
+extern struct hstr vfs_dot;
+
 struct v_dnode;
 
 struct filesystem
 {
     struct hlist_node fs_list;
     struct hstr fs_name;
 struct v_dnode;
 
 struct filesystem
 {
     struct hlist_node fs_list;
     struct hstr fs_name;
+    uint32_t types;
     int (*mount)(struct v_superblock* vsb, struct v_dnode* mount_point);
     int (*unmount)(struct v_superblock* vsb);
 };
     int (*mount)(struct v_superblock* vsb, struct v_dnode* mount_point);
     int (*unmount)(struct v_superblock* vsb);
 };
index b83b1a4e84a53128fb230f9373c95f8632b100ba..bd9dfeb63032dd4885397e28b239737df88c02a8 100644 (file)
@@ -26,4 +26,7 @@ twifs_dir_node(struct twifs_node* parent, const char* name, int name_len);
 struct twifs_node*
 twifs_toplevel_node(const char* name, int name_len);
 
 struct twifs_node*
 twifs_toplevel_node(const char* name, int name_len);
 
+void
+twifs_rm_node(struct twifs_node* node);
+
 #endif /* __LUNAIX_TWIFS_H */
 #endif /* __LUNAIX_TWIFS_H */
index 23b937488a9b1cd197c942e0f1dcb60d8c4404a7..a4c1942b7756e2632900efb83e69c5a2295590b4 100644 (file)
@@ -39,59 +39,25 @@ block_init()
 }
 
 int
 }
 
 int
-__block_read(struct v_file* file, void* buffer, size_t len);
-
-int
-__block_write(struct v_file* file, void* buffer, size_t len);
-
-void
-block_twifs_create()
+__block_read(struct device* dev,
+             void* buf,
+             unsigned int offset,
+             unsigned int len)
 {
 {
-    struct twifs_node* dev = twifs_toplevel_node("dev", 3);
-    struct twifs_node* dev_block = twifs_dir_node(dev, "block", 5);
-
-    if (!dev_block) {
-        kprintf(KERROR "fail to create twifs node");
-        return;
-    }
-
-    struct block_dev* bdev;
-    struct twifs_node* bdev_node;
-    for (size_t i = 0; i < MAX_DEV; i++) {
-        if (!(bdev = dev_registry[i])) {
-            continue;
-        }
-
-        bdev_node =
-          twifs_dir_node(dev_block, bdev->bdev_id, strlen(bdev->bdev_id));
-        bdev_node->fops.read = __block_read;
-        bdev_node->fops.write = __block_write;
-        bdev_node->data = i;
-        bdev_node->inode->fsize = bdev->hd_dev->max_lba;
-    }
-}
-
-int
-__block_read(struct v_file* file, void* buffer, size_t len)
-{
-    int index = (int)((struct twifs_node*)file->inode->data)->data;
     int errno;
     int errno;
-    struct block_dev* bdev;
-    if (index < 0 || index >= MAX_DEV || !(bdev = dev_registry[index])) {
-        return ENXIO;
-    }
+    struct block_dev* bdev = (struct block_dev*)dev->underlay;
     size_t acc_size = 0, rd_size = 0, bsize = bdev->hd_dev->block_size,
            rd_block = 0;
     void* block = valloc(bsize);
 
     while (acc_size < len) {
         if (!bdev->hd_dev->ops.read_buffer(
     size_t acc_size = 0, rd_size = 0, bsize = bdev->hd_dev->block_size,
            rd_block = 0;
     void* block = valloc(bsize);
 
     while (acc_size < len) {
         if (!bdev->hd_dev->ops.read_buffer(
-              bdev->hd_dev, file->f_pos + rd_block, block, bsize)) {
+              bdev->hd_dev, offset + rd_block, block, bsize)) {
             errno = ENXIO;
             goto error;
         }
         rd_size = MIN(len - acc_size, bsize);
             errno = ENXIO;
             goto error;
         }
         rd_size = MIN(len - acc_size, bsize);
-        memcpy(buffer + acc_size, block, rd_size);
+        memcpy(buf + acc_size, block, rd_size);
         acc_size += rd_size;
         rd_block++;
     }
         acc_size += rd_size;
         rd_block++;
     }
@@ -105,23 +71,22 @@ error:
 }
 
 int
 }
 
 int
-__block_write(struct v_file* file, void* buffer, size_t len)
+__block_write(struct device* dev,
+              void* buf,
+              unsigned int offset,
+              unsigned int len)
 {
 {
-    int index = (int)((struct twifs_node*)file->inode->data)->data;
     int errno;
     int errno;
-    struct block_dev* bdev;
-    if (index < 0 || index >= MAX_DEV || !(bdev = dev_registry[index])) {
-        return ENXIO;
-    }
+    struct block_dev* bdev = (struct block_dev*)dev->underlay;
     size_t acc_size = 0, wr_size = 0, bsize = bdev->hd_dev->block_size,
            wr_block = 0;
     void* block = valloc(bsize);
 
     while (acc_size < len) {
         wr_size = MIN(len - acc_size, bsize);
     size_t acc_size = 0, wr_size = 0, bsize = bdev->hd_dev->block_size,
            wr_block = 0;
     void* block = valloc(bsize);
 
     while (acc_size < len) {
         wr_size = MIN(len - acc_size, bsize);
-        memcpy(block, buffer + acc_size, wr_size);
+        memcpy(block, buf + acc_size, wr_size);
         if (!bdev->hd_dev->ops.write_buffer(
         if (!bdev->hd_dev->ops.write_buffer(
-              bdev->hd_dev, file->f_pos + wr_block, block, bsize)) {
+              bdev->hd_dev, offset + wr_block, block, bsize)) {
             errno = ENXIO;
             break;
         }
             errno = ENXIO;
             break;
         }
@@ -141,12 +106,12 @@ int
 block_mount_disk(struct hba_device* hd_dev)
 {
     int errno = 0;
 block_mount_disk(struct hba_device* hd_dev)
 {
     int errno = 0;
-    struct block_dev* dev = cake_grab(lbd_pile);
-    strncpy(dev->name, hd_dev->model, PARTITION_NAME_SIZE);
-    dev->hd_dev = hd_dev;
-    dev->base_lba = 0;
-    dev->end_lba = hd_dev->max_lba;
-    if (!__block_register(dev)) {
+    struct block_dev* bdev = cake_grab(lbd_pile);
+    strncpy(bdev->name, hd_dev->model, PARTITION_NAME_SIZE);
+    bdev->hd_dev = hd_dev;
+    bdev->base_lba = 0;
+    bdev->end_lba = hd_dev->max_lba;
+    if (!__block_register(bdev)) {
         errno = BLOCK_EFULL;
         goto error;
     }
         errno = BLOCK_EFULL;
         goto error;
     }
@@ -160,63 +125,18 @@ error:
             -errno);
 }
 
             -errno);
 }
 
-// FIXME make it more general, manipulate the device through vfs mapping
 int
 int
-__block_mount_partitions(struct hba_device* hd_dev)
-{
-    int errno = 0;
-    void* buffer = valloc_dma(hd_dev->block_size);
-    if (!hd_dev->ops.read_buffer(hd_dev, 1, buffer, hd_dev->block_size)) {
-        errno = BLOCK_EREAD;
-        goto done;
-    }
-
-    struct lpt_header* header = (struct lpt_header*)buffer;
-    if (header->signature != LPT_SIG) {
-        errno = BLOCK_ESIG;
-        goto done;
-    }
-
-    if (header->crc != crc32b(buffer, sizeof(*header))) {
-        errno = BLOCK_ECRC;
-        goto done;
-    }
-
-    uint64_t lba = header->pt_start_lba;
-    int j = 0;
-    int count_per_sector = hd_dev->block_size / sizeof(struct lpt_entry);
-    while (lba < header->pt_end_lba) {
-        if (!hd_dev->ops.read_buffer(hd_dev, lba, buffer, hd_dev->block_size)) {
-            errno = BLOCK_EREAD;
-            goto done;
-        }
-        struct lpt_entry* entry = (struct lpt_entry*)buffer;
-        for (int i = 0; i < count_per_sector; i++, j++) {
-            struct block_dev* dev = cake_grab(lbd_pile);
-            strncpy(dev->name, entry->part_name, PARTITION_NAME_SIZE);
-            dev->hd_dev = hd_dev;
-            dev->base_lba = entry->base_lba;
-            dev->end_lba = entry->end_lba;
-            __block_register(dev);
-
-            if (j >= header->table_len) {
-                goto done;
-            }
-        }
-    }
-
-done:
-    vfree_dma(buffer);
-    return -errno;
-}
-
-int
-__block_register(struct block_dev* dev)
+__block_register(struct block_dev* bdev)
 {
     if (free_slot >= MAX_DEV) {
         return 0;
     }
 {
     if (free_slot >= MAX_DEV) {
         return 0;
     }
-    snprintf(dev->bdev_id, DEV_ID_SIZE, "bd%x", free_slot);
-    dev_registry[free_slot++] = dev;
+
+    struct device* dev = device_add(NULL, bdev, "sd%c", 'a' + free_slot);
+    dev->write = __block_write;
+    dev->read = __block_read;
+
+    bdev->dev = dev;
+    dev_registry[free_slot++] = bdev;
     return 1;
 }
\ No newline at end of file
     return 1;
 }
\ No newline at end of file
index 3fc89148e38fd8f996fe29d2027e440aee3034ad..2ddeb1a2f29c0593b54208d7d62785edcf2786ce 100644 (file)
@@ -11,19 +11,28 @@ _iotest_main()
     char test_sequence[] = "Once upon a time, in a magical land of Equestria. "
                            "There were two regal sisters who ruled together "
                            "and created harmony for all the land.";
     char test_sequence[] = "Once upon a time, in a magical land of Equestria. "
                            "There were two regal sisters who ruled together "
                            "and created harmony for all the land.";
-    int fd = open("/dev/block/bd0", 0);
 
 
-    if (fd < 0) {
+    int fd = open("/dev/sda", 0);  // bd0 设备 - 硬盘
+    int tty = open("/dev/tty", 0); // tty 设备 - 控制台
+
+    if (fd < 0 || tty < 0) {
         kprintf(KERROR "fail to open (%d)\n", geterrno());
         return;
     }
 
         kprintf(KERROR "fail to open (%d)\n", geterrno());
         return;
     }
 
+    // 移动指针至第二个逻辑扇区(LBA=1),并写入
     lseek(fd, 1, FSEEK_SET);
     write(fd, test_sequence, sizeof(test_sequence));
 
     lseek(fd, 1, FSEEK_SET);
     write(fd, test_sequence, sizeof(test_sequence));
 
-    lseek(fd, -1, FSEEK_CUR);
+    // 读出我们写的内容
     char read_out[256];
     char read_out[256];
+    lseek(fd, -1, FSEEK_CUR);
     read(fd, read_out, sizeof(read_out));
 
     read(fd, read_out, sizeof(read_out));
 
-    kprintf("%s", read_out);
+    write(tty, read_out, sizeof(read_out));
+
+    close(fd);
+    close(tty);
+
+    kprint_hex(read_out, sizeof(read_out));
 }
\ No newline at end of file
 }
\ No newline at end of file
diff --git a/lunaix-os/kernel/device.c b/lunaix-os/kernel/device.c
new file mode 100644 (file)
index 0000000..9cb2fa1
--- /dev/null
@@ -0,0 +1,84 @@
+#include <klibc/stdio.h>
+#include <lunaix/device.h>
+#include <lunaix/fs/twifs.h>
+#include <lunaix/mm/valloc.h>
+
+struct llist_header dev_list;
+
+static struct twifs_node* dev_root;
+
+int
+__dev_read(struct v_file* file, void* buffer, size_t len);
+
+int
+__dev_write(struct v_file* file, void* buffer, size_t len);
+
+void
+device_init()
+{
+    dev_root = twifs_toplevel_node("dev", 3);
+
+    llist_init_head(&dev_list);
+}
+
+struct device*
+device_add(struct device* parent, void* underlay, char* name_fmt, ...)
+{
+    struct device* dev = vzalloc(sizeof(struct device));
+
+    va_list args;
+    va_start(args, name_fmt);
+
+    size_t strlen =
+      __sprintf_internal(dev->name_val, name_fmt, DEVICE_NAME_SIZE, args);
+
+    dev->name = HSTR(dev->name_val, strlen);
+    dev->parent = parent;
+    dev->underlay = underlay;
+
+    hstr_rehash(&dev->name, HSTR_FULL_HASH);
+    llist_append(&dev_list, &dev->dev_list);
+
+    struct twifs_node* dev_node =
+      twifs_file_node(dev_root, dev->name_val, strlen);
+    dev_node->data = dev;
+    dev_node->fops.read = __dev_read;
+    dev_node->fops.write = __dev_write;
+
+    dev->fs_node = dev_node;
+
+    va_end(args);
+    return dev;
+}
+
+int
+__dev_read(struct v_file* file, void* buffer, size_t len)
+{
+    struct twifs_node* dev_node = (struct twifs_node*)file->inode->data;
+    struct device* dev = (struct device*)dev_node->data;
+
+    if (!dev->read) {
+        return ENOTSUP;
+    }
+    return dev->read(dev, buffer, file->f_pos, len);
+}
+
+int
+__dev_write(struct v_file* file, void* buffer, size_t len)
+{
+    struct twifs_node* dev_node = (struct twifs_node*)file->inode->data;
+    struct device* dev = (struct device*)dev_node->data;
+
+    if (!dev->write) {
+        return ENOTSUP;
+    }
+    return dev->write(dev, buffer, file->f_pos, len);
+}
+
+void
+device_remove(struct device* dev)
+{
+    llist_delete(&dev->dev_list);
+    twifs_rm_node((struct twifs_node*)dev->fs_node);
+    vfree(dev);
+}
\ No newline at end of file
index ad226ca8d74a2d0069808b7ffadd9a6bd342f11c..37af44e2777fcf9bf7c3fb5139ba749b26aa192f 100644 (file)
@@ -37,6 +37,9 @@ __twifs_iterate_dir(struct v_file* file, struct dir_context* dctx);
 int
 __twifs_mount(struct v_superblock* vsb, struct v_dnode* mount_point);
 
 int
 __twifs_mount(struct v_superblock* vsb, struct v_dnode* mount_point);
 
+int
+__twifs_mkdir(struct v_inode* inode, struct v_dnode* dnode);
+
 void
 twifs_init()
 {
 void
 twifs_init()
 {
@@ -49,11 +52,6 @@ twifs_init()
     fsm_register(twifs);
 
     fs_root = twifs_dir_node(NULL, NULL, 0);
     fsm_register(twifs);
 
     fs_root = twifs_dir_node(NULL, NULL, 0);
-
-    // 预备一些常用的类别
-    twifs_toplevel_node("kernel", 6);
-    twifs_toplevel_node("dev", 3);
-    twifs_toplevel_node("bus", 3);
 }
 
 struct twifs_node*
 }
 
 struct twifs_node*
@@ -73,6 +71,23 @@ __twifs_new_node(struct twifs_node* parent, const char* name, int name_len)
     return node;
 }
 
     return node;
 }
 
+void
+twifs_rm_node(struct twifs_node* node)
+{
+    // TODO recursivly delete any sub-directories.
+    if ((node->itype & VFS_INODE_TYPE_DIR)) {
+        struct twifs_node* dir = __twifs_get_node(node, &vfs_dot);
+        struct twifs_node* dir2 = __twifs_get_node(node, &vfs_ddot);
+        vfs_i_free(dir->inode);
+        vfs_i_free(dir2->inode);
+        cake_release(twi_pile, dir);
+        cake_release(twi_pile, dir2);
+    }
+    llist_delete(&node->siblings);
+    vfs_i_free(node->inode);
+    cake_release(twi_pile, node);
+}
+
 struct twifs_node*
 twifs_file_node(struct twifs_node* parent, const char* name, int name_len)
 {
 struct twifs_node*
 twifs_file_node(struct twifs_node* parent, const char* name, int name_len)
 {
@@ -82,7 +97,7 @@ twifs_file_node(struct twifs_node* parent, const char* name, int name_len)
     struct v_inode* twi_inode = __twifs_create_inode(twi_node);
     twi_node->inode = twi_inode;
 
     struct v_inode* twi_inode = __twifs_create_inode(twi_node);
     twi_node->inode = twi_inode;
 
-    return twi_inode;
+    return twi_node;
 }
 
 struct twifs_node*
 }
 
 struct twifs_node*
@@ -119,11 +134,25 @@ twifs_toplevel_node(const char* name, int name_len)
     return twifs_dir_node(fs_root, name, name_len);
 }
 
     return twifs_dir_node(fs_root, name, name_len);
 }
 
+int
+__twifs_mkdir(struct v_inode* inode, struct v_dnode* dnode)
+{
+    struct twifs_node* parent_node = (struct twifs_node*)inode->data;
+    if (!(parent_node->itype & VFS_INODE_TYPE_DIR)) {
+        return ENOTDIR;
+    }
+    struct twifs_node* new_node =
+      twifs_dir_node(parent_node, dnode->name.value, dnode->name.len);
+    dnode->inode = new_node->inode;
+
+    return 0;
+}
+
 int
 __twifs_mount(struct v_superblock* vsb, struct v_dnode* mount_point)
 {
     mount_point->inode = fs_root->inode;
 int
 __twifs_mount(struct v_superblock* vsb, struct v_dnode* mount_point)
 {
     mount_point->inode = fs_root->inode;
-    // FIXME: try to mitigate this special case or pull it up to higher level of
+    // FIXME try to mitigate this special case or pull it up to higher level of
     // abstraction
     if (mount_point->parent && mount_point->parent->inode) {
         struct hstr ddot_name = HSTR("..", 2);
     // abstraction
     if (mount_point->parent && mount_point->parent->inode) {
         struct hstr ddot_name = HSTR("..", 2);
@@ -145,6 +174,7 @@ __twifs_create_inode(struct twifs_node* twi_node)
                                .mtime = 0,
                                .ref_count = 0 };
     inode->ops.dir_lookup = __twifs_dirlookup;
                                .mtime = 0,
                                .ref_count = 0 };
     inode->ops.dir_lookup = __twifs_dirlookup;
+    inode->ops.mkdir = __twifs_mkdir;
     inode->ops.open = __twifs_openfile;
 
     return inode;
     inode->ops.open = __twifs_openfile;
 
     return inode;
@@ -171,6 +201,10 @@ __twifs_dirlookup(struct v_inode* inode, struct v_dnode* dnode)
 {
     struct twifs_node* twi_node = (struct twifs_node*)inode->data;
 
 {
     struct twifs_node* twi_node = (struct twifs_node*)inode->data;
 
+    if (!(twi_node->itype & VFS_INODE_TYPE_DIR)) {
+        return ENOTDIR;
+    }
+
     struct twifs_node* child_node = __twifs_get_node(twi_node, &dnode->name);
     if (child_node) {
         dnode->inode = child_node->inode;
     struct twifs_node* child_node = __twifs_get_node(twi_node, &dnode->name);
     if (child_node) {
         dnode->inode = child_node->inode;
index 09668f501d09c09bec83b1a8492b6379760ed615..48ec27dc18d06155be990d6926f20b1da413f993 100644 (file)
@@ -37,6 +37,9 @@ static struct hbucket* dnode_cache;
 
 static int fs_id = 0;
 
 
 static int fs_id = 0;
 
+struct hstr vfs_ddot = HSTR("..", 2);
+struct hstr vfs_dot = HSTR(".", 1);
+
 struct v_dnode*
 vfs_d_alloc();
 
 struct v_dnode*
 vfs_d_alloc();
 
@@ -62,6 +65,9 @@ vfs_init()
 
     dnode_cache = vzalloc(DNODE_HASHTABLE_SIZE * sizeof(struct hbucket));
 
 
     dnode_cache = vzalloc(DNODE_HASHTABLE_SIZE * sizeof(struct hbucket));
 
+    hstr_rehash(&vfs_ddot, HSTR_FULL_HASH);
+    hstr_rehash(&vfs_dot, HSTR_FULL_HASH);
+
     // 创建一个根superblock,用来蕴含我们的根目录。
     root_sb = vfs_sb_alloc();
     root_sb->root = vfs_d_alloc();
     // 创建一个根superblock,用来蕴含我们的根目录。
     root_sb = vfs_sb_alloc();
     root_sb->root = vfs_d_alloc();
@@ -349,7 +355,9 @@ struct v_dnode*
 vfs_d_alloc()
 {
     struct v_dnode* dnode = cake_grab(dnode_pile);
 vfs_d_alloc()
 {
     struct v_dnode* dnode = cake_grab(dnode_pile);
+    memset(dnode, 0, sizeof(*dnode));
     llist_init_head(&dnode->children);
     llist_init_head(&dnode->children);
+    return dnode;
 }
 
 void
 }
 
 void
@@ -376,14 +384,15 @@ vfs_i_free(struct v_inode* inode)
     cake_release(inode_pile, inode);
 }
 
     cake_release(inode_pile, inode);
 }
 
-__DEFINE_LXSYSCALL2(int, open, const char*, path, int, options)
+int
+__vfs_do_open(struct v_file** file_out, const char* path, int options)
 {
     char name_str[VFS_NAME_MAXLEN];
     struct hstr name = HSTR(name_str, 0);
     struct v_dnode *dentry, *file;
 {
     char name_str[VFS_NAME_MAXLEN];
     struct hstr name = HSTR(name_str, 0);
     struct v_dnode *dentry, *file;
-    int errno, fd;
+    int errno;
     if ((errno = vfs_walk(NULL, path, &dentry, &name, VFS_WALK_PARENT))) {
     if ((errno = vfs_walk(NULL, path, &dentry, &name, VFS_WALK_PARENT))) {
-        return -1;
+        return ENOENT;
     }
 
     vfs_walk(dentry, name.value, &file, NULL, 0);
     }
 
     vfs_walk(dentry, name.value, &file, NULL, 0);
@@ -399,13 +408,23 @@ __DEFINE_LXSYSCALL2(int, open, const char*, path, int, options)
         errno = vfs_open(file, &opened_file);
     }
 
         errno = vfs_open(file, &opened_file);
     }
 
+    *file_out = opened_file;
+    return errno;
+}
+
+__DEFINE_LXSYSCALL2(int, open, const char*, path, int, options)
+{
+    struct v_file* opened_file;
+    int errno = __vfs_do_open(&opened_file, path, options), fd;
+
     __current->k_status = errno;
 
     if (!errno && !(errno = vfs_alloc_fdslot(&fd))) {
         struct v_fd* fd_s = vzalloc(sizeof(*fd_s));
         fd_s->file = opened_file;
     __current->k_status = errno;
 
     if (!errno && !(errno = vfs_alloc_fdslot(&fd))) {
         struct v_fd* fd_s = vzalloc(sizeof(*fd_s));
         fd_s->file = opened_file;
-        fd_s->pos = file->inode->fsize & -((options & FO_APPEND) != 0);
+        fd_s->pos = opened_file->inode->fsize & -((options & FO_APPEND) != 0);
         __current->fdtable->fds[fd] = fd_s;
         __current->fdtable->fds[fd] = fd_s;
+        return fd;
     }
 
     return SYSCALL_ESTATUS(errno);
     }
 
     return SYSCALL_ESTATUS(errno);
@@ -474,7 +493,9 @@ __DEFINE_LXSYSCALL1(int, mkdir, const char*, path)
         goto done;
     }
 
         goto done;
     }
 
-    if (!parent->inode->ops.mkdir) {
+    if ((parent->super_block->fs->types & FSTYPE_ROFS)) {
+        errno = ENOTSUP;
+    } else if (!parent->inode->ops.mkdir) {
         errno = ENOTSUP;
     } else if (!(parent->inode->itype & VFS_INODE_TYPE_DIR)) {
         errno = ENOTDIR;
         errno = ENOTSUP;
     } else if (!(parent->inode->itype & VFS_INODE_TYPE_DIR)) {
         errno = ENOTDIR;
index ffc287ff37bb840d7bb2f8ecc8ff7368a7ab9211..b0aee844c2376206ea6312ce934fa876c17b6f0d 100644 (file)
@@ -2,6 +2,7 @@
 #include <lunaix/tty/tty.h>
 
 #include <lunaix/clock.h>
 #include <lunaix/tty/tty.h>
 
 #include <lunaix/clock.h>
+#include <lunaix/device.h>
 #include <lunaix/lxconsole.h>
 #include <lunaix/mm/kalloc.h>
 #include <lunaix/mm/page.h>
 #include <lunaix/lxconsole.h>
 #include <lunaix/mm/kalloc.h>
 #include <lunaix/mm/page.h>
@@ -77,14 +78,20 @@ _kernel_pre_init()
 void
 _kernel_init()
 {
 void
 _kernel_init()
 {
-    lxconsole_init();
 
     cake_init();
     valloc_init();
 
 
     cake_init();
     valloc_init();
 
-    kprintf(KINFO "[MM] Allocated %d pages for stack start at %p\n",
-            KSTACK_SIZE >> PG_SIZE_BITS,
-            KSTACK_START);
+    fsm_init();
+    vfs_init();
+    twifs_init();
+
+    device_init();
+
+    // 挂载 TwiFS 为根目录
+    vfs_mount("/", "twifs", -1);
+
+    lxconsole_init();
 
     sched_init();
 
 
     sched_init();
 
index d6b92f8c719b425571ce7235580f9d23f36172b6..894a1b8e9837d636bbca6bf1a65355000b5316c4 100644 (file)
@@ -1,4 +1,5 @@
 #include <klibc/string.h>
 #include <klibc/string.h>
+#include <lunaix/device.h>
 #include <lunaix/lxconsole.h>
 #include <lunaix/mm/pmm.h>
 #include <lunaix/mm/vmm.h>
 #include <lunaix/lxconsole.h>
 #include <lunaix/mm/pmm.h>
 #include <lunaix/mm/vmm.h>
@@ -7,6 +8,12 @@
 
 static struct console lx_console;
 
 
 static struct console lx_console;
 
+int
+__tty_write(struct device* dev,
+            void* buf,
+            unsigned int offset,
+            unsigned int len);
+
 void
 lxconsole_init()
 {
 void
 lxconsole_init()
 {
@@ -28,6 +35,19 @@ lxconsole_init()
     memset(lx_console.buffer.data, 0, lx_console.buffer.size);
 
     lx_console.flush_timer = NULL;
     memset(lx_console.buffer.data, 0, lx_console.buffer.size);
 
     lx_console.flush_timer = NULL;
+
+    struct device* tty_dev = device_add(NULL, &lx_console, "tty");
+    tty_dev->write = __tty_write;
+}
+
+int
+__tty_write(struct device* dev,
+            void* buf,
+            unsigned int offset,
+            unsigned int len)
+{
+    struct console* console = (struct console*)dev->underlay;
+    console_write(console, buf, len);
 }
 
 void
 }
 
 void
index 3ad6476679e9e76ff677bfb3a9b561f4900078b8..ec997425b9c0161ab817d19f91591c9c4c5585d2 100644 (file)
@@ -126,9 +126,6 @@ extern uint8_t __kernel_end;              /* link/linker.ld */
 extern uint8_t __init_hhk_end;            /* link/linker.ld */
 extern multiboot_info_t* _k_init_mb_info; /* k_init.c */
 
 extern uint8_t __init_hhk_end;            /* link/linker.ld */
 extern multiboot_info_t* _k_init_mb_info; /* k_init.c */
 
-extern void
-block_twifs_create();
-
 void
 init_platform()
 {
 void
 init_platform()
 {
@@ -147,17 +144,6 @@ init_platform()
     block_init();
     ahci_init();
     // ahci_list_device();
     block_init();
     ahci_init();
     // ahci_list_device();
-
-    fsm_init();
-    vfs_init();
-    twifs_init();
-
-    block_twifs_create();
-
-    vfs_mount("/", "twifs", -1);
-
-    //__test_disk_io();
-
     // cake_stats();
 
     syscall_install();
     // cake_stats();
 
     syscall_install();
index b9d333b1273856d202d2db4a0625e6cb9948654e..f479f581a34f6849593824bdb5dc1d37f4bcb59e 100644 (file)
@@ -13,7 +13,8 @@
 #include <hal/apic.h>
 #include <hal/rtc.h>
 
 #include <hal/apic.h>
 #include <hal/rtc.h>
 
-#include <lunaix/mm/kalloc.h>
+#include <lunaix/mm/cake.h>
+#include <lunaix/mm/valloc.h>
 #include <lunaix/sched.h>
 #include <lunaix/spike.h>
 #include <lunaix/syslog.h>
 #include <lunaix/sched.h>
 #include <lunaix/spike.h>
 #include <lunaix/syslog.h>
@@ -42,18 +43,20 @@ static volatile uint8_t apic_timer_done = 0;
 static volatile uint32_t sched_ticks = 0;
 static volatile uint32_t sched_ticks_counter = 0;
 
 static volatile uint32_t sched_ticks = 0;
 static volatile uint32_t sched_ticks_counter = 0;
 
+static struct cake_pile* timer_pile;
+
 #define APIC_CALIBRATION_CONST 0x100000
 
 void
 timer_init_context()
 {
 #define APIC_CALIBRATION_CONST 0x100000
 
 void
 timer_init_context()
 {
+    timer_pile = cake_new_pile("timer", sizeof(struct lx_timer), 1, 0);
     timer_ctx =
     timer_ctx =
-      (struct lx_timer_context*)lxmalloc(sizeof(struct lx_timer_context));
+      (struct lx_timer_context*)valloc(sizeof(struct lx_timer_context));
 
     assert_msg(timer_ctx, "Fail to initialize timer contex");
 
 
     assert_msg(timer_ctx, "Fail to initialize timer contex");
 
-    timer_ctx->active_timers =
-      (struct lx_timer*)lxmalloc(sizeof(struct lx_timer));
+    timer_ctx->active_timers = (struct lx_timer*)cake_grab(timer_pile);
     llist_init_head(timer_ctx->active_timers);
 }
 
     llist_init_head(timer_ctx->active_timers);
 }
 
@@ -164,8 +167,7 @@ timer_run_ms(uint32_t millisecond,
 struct lx_timer*
 timer_run(ticks_t ticks, void (*callback)(void*), void* payload, uint8_t flags)
 {
 struct lx_timer*
 timer_run(ticks_t ticks, void (*callback)(void*), void* payload, uint8_t flags)
 {
-    struct lx_timer* timer =
-      (struct lx_timer*)lxmalloc(sizeof(struct lx_timer));
+    struct lx_timer* timer = (struct lx_timer*)cake_grab(timer_pile);
 
     if (!timer)
         return NULL;
 
     if (!timer)
         return NULL;
@@ -199,7 +201,7 @@ timer_update(const isr_param* param)
             pos->counter = pos->deadline;
         } else {
             llist_delete(&pos->link);
             pos->counter = pos->deadline;
         } else {
             llist_delete(&pos->link);
-            lxfree(pos);
+            cake_release(timer_pile, pos);
         }
     }
 
         }
     }
 
index 460b206e08a1a131e1f76d0b4324c8fa0fda0625..d35706883ea8facc7ade8668a4a659859fb460ec 100644 (file)
@@ -8,20 +8,20 @@
 
 static const char flag_chars[] = "#0- +";
 
 
 static const char flag_chars[] = "#0- +";
 
-#define FLAG_ALT                (1<<0)
-#define FLAG_ZERO               (1<<1)
-#define FLAG_LEFTJUSTIFY        (1<<2)
-#define FLAG_SPACEPOSITIVE      (1<<3)
-#define FLAG_PLUSPOSITIVE       (1<<4)
-#define FLAG_NUMERIC            (1<<5)
-#define FLAG_SIGNED             (1<<6)
-#define FLAG_NEGATIVE           (1<<7)
-#define FLAG_ALT2               (1<<8)
-#define FLAG_CAPS               (1<<9)
-
-
-// FIXME: use something like IO_FILE to abstract this into a more flexible, stream based, vprintf
-void
+#define FLAG_ALT (1 << 0)
+#define FLAG_ZERO (1 << 1)
+#define FLAG_LEFTJUSTIFY (1 << 2)
+#define FLAG_SPACEPOSITIVE (1 << 3)
+#define FLAG_PLUSPOSITIVE (1 << 4)
+#define FLAG_NUMERIC (1 << 5)
+#define FLAG_SIGNED (1 << 6)
+#define FLAG_NEGATIVE (1 << 7)
+#define FLAG_ALT2 (1 << 8)
+#define FLAG_CAPS (1 << 9)
+
+// FIXME: use something like IO_FILE to abstract this into a more flexible,
+// stream based, vprintf
+size_t
 __sprintf_internal(char* buffer, char* fmt, size_t max_len, va_list vargs)
 {
     // This sprintf just a random implementation I found it on Internet . lol.
 __sprintf_internal(char* buffer, char* fmt, size_t max_len, va_list vargs)
 {
     // This sprintf just a random implementation I found it on Internet . lol.
@@ -33,7 +33,7 @@ __sprintf_internal(char* buffer, char* fmt, size_t max_len, va_list vargs)
         if (max_len && ptr >= max_len - 1) {
             break;
         }
         if (max_len && ptr >= max_len - 1) {
             break;
         }
-        
+
         if (*fmt != '%') {
             buffer[ptr++] = *fmt;
             continue;
         if (*fmt != '%') {
             buffer[ptr++] = *fmt;
             continue;
@@ -53,7 +53,7 @@ __sprintf_internal(char* buffer, char* fmt, size_t max_len, va_list vargs)
         // process width
         int width = -1;
         if (*fmt >= '1' && *fmt <= '9') {
         // process width
         int width = -1;
         if (*fmt >= '1' && *fmt <= '9') {
-            for (width = 0; *fmt >= '0' && *fmt <= '9'; ) {
+            for (width = 0; *fmt >= '0' && *fmt <= '9';) {
                 width = 10 * width + *fmt++ - '0';
             }
         } else if (*fmt == '*') {
                 width = 10 * width + *fmt++ - '0';
             }
         } else if (*fmt == '*') {
@@ -66,7 +66,7 @@ __sprintf_internal(char* buffer, char* fmt, size_t max_len, va_list vargs)
         if (*fmt == '.') {
             ++fmt;
             if (*fmt >= '0' && *fmt <= '9') {
         if (*fmt == '.') {
             ++fmt;
             if (*fmt >= '0' && *fmt <= '9') {
-                for (precision = 0; *fmt >= '0' && *fmt <= '9'; ) {
+                for (precision = 0; *fmt >= '0' && *fmt <= '9';) {
                     precision = 10 * precision + *fmt++ - '0';
                 }
             } else if (*fmt == '*') {
                     precision = 10 * precision + *fmt++ - '0';
                 }
             } else if (*fmt == '*') {
@@ -85,60 +85,60 @@ __sprintf_internal(char* buffer, char* fmt, size_t max_len, va_list vargs)
         char* data = "";
     again:
         switch (*fmt) {
         char* data = "";
     again:
         switch (*fmt) {
-        case 'l':
-        case 'z':
-            length = 1;
-            ++fmt;
-            goto again;
-        case 'd':
-        case 'i': {
-            long x = length ? va_arg(vargs, long) : va_arg(vargs, int);
-            int negative = x < 0 ? FLAG_NEGATIVE : 0;
-            num = negative ? -x : x;
-            flags |= FLAG_NUMERIC | FLAG_SIGNED | negative;
-            break;
-        }
-        case 'u':
-        format_unsigned:
-            num = length ? va_arg(vargs, unsigned long) : va_arg(vargs, unsigned);
-            flags |= FLAG_NUMERIC;
-            break;
-        case 'x':
-            base = 16;
-            goto format_unsigned;
-        case 'X':
-            flags = flags | FLAG_CAPS;
-            base = 16;
-            goto format_unsigned;
-        case 'p':
-            num = (uintptr_t) va_arg(vargs, void*);
-            base = 16;
-            flags |= FLAG_ALT | FLAG_ALT2 | FLAG_NUMERIC;
-            break;
-        case 's':
-            data = va_arg(vargs, char*);
-            break;
-        case 'c':
-            data = numbuf;
-            numbuf[0] = va_arg(vargs, int);
-            numbuf[1] = '\0';
-            break;
-        default:
-            data = numbuf;
-            numbuf[0] = (*fmt ? *fmt : '%');
-            numbuf[1] = '\0';
-            if (!*fmt) {
-                fmt--;
+            case 'l':
+            case 'z':
+                length = 1;
+                ++fmt;
+                goto again;
+            case 'd':
+            case 'i': {
+                long x = length ? va_arg(vargs, long) : va_arg(vargs, int);
+                int negative = x < 0 ? FLAG_NEGATIVE : 0;
+                num = negative ? -x : x;
+                flags |= FLAG_NUMERIC | FLAG_SIGNED | negative;
+                break;
             }
             }
-            break;
+            case 'u':
+            format_unsigned:
+                num = length ? va_arg(vargs, unsigned long)
+                             : va_arg(vargs, unsigned);
+                flags |= FLAG_NUMERIC;
+                break;
+            case 'x':
+                base = 16;
+                goto format_unsigned;
+            case 'X':
+                flags = flags | FLAG_CAPS;
+                base = 16;
+                goto format_unsigned;
+            case 'p':
+                num = (uintptr_t)va_arg(vargs, void*);
+                base = 16;
+                flags |= FLAG_ALT | FLAG_ALT2 | FLAG_NUMERIC;
+                break;
+            case 's':
+                data = va_arg(vargs, char*);
+                break;
+            case 'c':
+                data = numbuf;
+                numbuf[0] = va_arg(vargs, int);
+                numbuf[1] = '\0';
+                break;
+            default:
+                data = numbuf;
+                numbuf[0] = (*fmt ? *fmt : '%');
+                numbuf[1] = '\0';
+                if (!*fmt) {
+                    fmt--;
+                }
+                break;
         }
 
         if (flags & FLAG_NUMERIC) {
             data = itoa(num, numbuf, base);
             int i = 0;
             char c;
         }
 
         if (flags & FLAG_NUMERIC) {
             data = itoa(num, numbuf, base);
             int i = 0;
             char c;
-            while ((flags & FLAG_CAPS) && (c = data[i]))
-            {
+            while ((flags & FLAG_CAPS) && (c = data[i])) {
                 data[i] = c & ~((c & 0x40) >> 1);
                 i++;
             }
                 data[i] = c & ~((c & 0x40) >> 1);
                 i++;
             }
@@ -153,9 +153,9 @@ __sprintf_internal(char* buffer, char* fmt, size_t max_len, va_list vargs)
             } else if (flags & FLAG_SPACEPOSITIVE) {
                 prefix = " ";
             }
             } else if (flags & FLAG_SPACEPOSITIVE) {
                 prefix = " ";
             }
-        } else if ((flags & FLAG_NUMERIC) && (flags & FLAG_ALT)
-                   && (base == 16 || base == -16)
-                   && (num || (flags & FLAG_ALT2))) {
+        } else if ((flags & FLAG_NUMERIC) && (flags & FLAG_ALT) &&
+                   (base == 16 || base == -16) &&
+                   (num || (flags & FLAG_ALT2))) {
             prefix = "0x";
         }
 
             prefix = "0x";
         }
 
@@ -168,9 +168,9 @@ __sprintf_internal(char* buffer, char* fmt, size_t max_len, va_list vargs)
         int zeros;
         if ((flags & FLAG_NUMERIC) && precision >= 0) {
             zeros = precision > len ? precision - len : 0;
         int zeros;
         if ((flags & FLAG_NUMERIC) && precision >= 0) {
             zeros = precision > len ? precision - len : 0;
-        } else if ((flags & FLAG_NUMERIC) && (flags & FLAG_ZERO)
-                   && !(flags & FLAG_LEFTJUSTIFY)
-                   && len + (int) strlen(prefix) < width) {
+        } else if ((flags & FLAG_NUMERIC) && (flags & FLAG_ZERO) &&
+                   !(flags & FLAG_LEFTJUSTIFY) &&
+                   len + (int)strlen(prefix) < width) {
             zeros = width - len - strlen(prefix);
         } else {
             zeros = 0;
             zeros = width - len - strlen(prefix);
         } else {
             zeros = 0;
@@ -193,22 +193,26 @@ __sprintf_internal(char* buffer, char* fmt, size_t max_len, va_list vargs)
         }
     }
     buffer[ptr++] = '\0';
         }
     }
     buffer[ptr++] = '\0';
+
+    return ptr;
 }
 
 }
 
-void
+size_t
 sprintf(char* buffer, char* fmt, ...)
 {
     va_list args;
     va_start(args, fmt);
 sprintf(char* buffer, char* fmt, ...)
 {
     va_list args;
     va_start(args, fmt);
-    __sprintf_internal(buffer, fmt, 0, args);
+    size_t len = __sprintf_internal(buffer, fmt, 0, args);
     va_end(args);
     va_end(args);
+    return len;
 }
 
 }
 
-void
+size_t
 snprintf(char* buffer, size_t n, char* fmt, ...)
 {
     va_list args;
     va_start(args, fmt);
 snprintf(char* buffer, size_t n, char* fmt, ...)
 {
     va_list args;
     va_start(args, fmt);
-    __sprintf_internal(buffer, fmt, n, args);
+    size_t len = __sprintf_internal(buffer, fmt, n, args);
     va_end(args);
     va_end(args);
+    return len;
 }
\ No newline at end of file
 }
\ No newline at end of file