feat: owloysius - dynamic init function invocator
authorMinep <lunaixsky@qq.com>
Sun, 10 Dec 2023 13:50:32 +0000 (13:50 +0000)
committerMinep <lunaixsky@qq.com>
Sun, 10 Dec 2023 13:57:51 +0000 (13:57 +0000)
refactor: add a generic base struct to devices
  this allow us to specialize different kinds of device,
  sparating devfs tree node and real device, to save the overhead
feat: add device aliasing (i.e. hard link in devfs)
feat: add new gdb command to dump system log
feat: make default system console configurable through `console=<dev>` boot command line
fix: trying to delete mount point when unmounted.
fix: ensure frame-point always included regardless optimization level
chore: edit readme
d

48 files changed:
README.md
lunaix-os/GRUB_TEMPLATE
lunaix-os/arch/i386/boot/mb_parser.c
lunaix-os/hal/char/devnull.c
lunaix-os/hal/char/devzero.c
lunaix-os/hal/char/serial.c
lunaix-os/hal/gfxa/gfxm.c
lunaix-os/hal/pci.c
lunaix-os/hal/rng/rngx86.c
lunaix-os/hal/rtc/rtc_device.c
lunaix-os/hal/term/console.c [new file with mode: 0644]
lunaix-os/hal/term/term.c
lunaix-os/hal/timer/timer_device.c
lunaix-os/includes/hal/term.h
lunaix-os/includes/lunaix/compiler.h
lunaix-os/includes/lunaix/device.h
lunaix-os/includes/lunaix/device_num.h
lunaix-os/includes/lunaix/fs.h
lunaix-os/includes/lunaix/owloysius.h [new file with mode: 0644]
lunaix-os/includes/lunaix/spike.h
lunaix-os/kernel/block/block.c
lunaix-os/kernel/debug/trace.c
lunaix-os/kernel/device/devdb.c
lunaix-os/kernel/device/devfs.c
lunaix-os/kernel/device/device.c
lunaix-os/kernel/device/input.c
lunaix-os/kernel/device/poll.c
lunaix-os/kernel/fs/fsm.c
lunaix-os/kernel/fs/mount.c
lunaix-os/kernel/fs/probe_boot.c
lunaix-os/kernel/fs/vfs.c
lunaix-os/kernel/kcmd.c
lunaix-os/kernel/kinit.c
lunaix-os/kernel/kprint/kp_records.c
lunaix-os/kernel/kprint/kp_records.h
lunaix-os/kernel/kprint/kprintf.c
lunaix-os/kernel/proc0.c
lunaix-os/kernel/process/signal.c
lunaix-os/kernel/tty/lxconsole.c
lunaix-os/link/linker.ld
lunaix-os/makefile
lunaix-os/makeinc/toolchain.mkinc
lunaix-os/scripts/gdb/install_lunadbg
lunaix-os/scripts/gdb/lunadbg/commands.py
lunaix-os/scripts/gdb/lunadbg/region_dump.py
lunaix-os/scripts/gdb/lunadbg/symbols.py [new file with mode: 0644]
lunaix-os/scripts/gdb/lunadbg/syslog.py [new file with mode: 0644]
lunaix-os/scripts/gdb/lunadbg/utils.py

index 6e528bdf04a982a0af8c92c7bdda11d759542f1c..213f2132f29818052b9514bf9daf7c30a501a198 100644 (file)
--- a/README.md
+++ b/README.md
@@ -157,6 +157,7 @@ qemu-img create -f vdi machine/disk0.vdi 128M
 + `vmrs [pid]` 列举进程`<pid>`的内存区域图(Memory Regions),如果`<pid>`未指定,则默认为正在运行的进程(smp=1)。
 + `proc [pid]` 打印进程`<pid>`的进程控制块状态,如果`<pid>`未指定,则默认为正在运行的进程(smp=1)。
 + `proc_table` 列举所有非终止的进程以及他们的状态。
 + `vmrs [pid]` 列举进程`<pid>`的内存区域图(Memory Regions),如果`<pid>`未指定,则默认为正在运行的进程(smp=1)。
 + `proc [pid]` 打印进程`<pid>`的进程控制块状态,如果`<pid>`未指定,则默认为正在运行的进程(smp=1)。
 + `proc_table` 列举所有非终止的进程以及他们的状态。
++ `syslog` 打印到目前为止的系统日志。
 
 该插件可以通过运行以下命令来进行安装:
 
 
 该插件可以通过运行以下命令来进行安装:
 
index 176f426af4d82f5784e0de03e9bb548b5879ed30..c33d45f96b921416ffcd3c5b24b540d0dacd0a09 100644 (file)
@@ -2,6 +2,6 @@ default=0
 timeout=0
 
 menuentry "$_OS_NAME" {
 timeout=0
 
 menuentry "$_OS_NAME" {
-       multiboot /boot/kernel.bin
+       multiboot /boot/kernel.bin console=/dev/vcon
        module --nounzip /boot/modksyms modksyms
 }
\ No newline at end of file
        module --nounzip /boot/modksyms modksyms
 }
\ No newline at end of file
index 64a405188511192461140049511149050b899261..aa9a5f029f7b419a24b0ec3fc3f382574eddaffb 100644 (file)
@@ -61,6 +61,7 @@ mb_parse_cmdline(struct boot_handoff* bhctx, void* buffer, char* cmdline)
 
     mb_memcpy(buffer, (u8_t*)cmdline, slen);
     bhctx->kexec.len = slen;
 
     mb_memcpy(buffer, (u8_t*)cmdline, slen);
     bhctx->kexec.len = slen;
+    bhctx->kexec.cmdline = buffer;
 
     return slen;
 }
 
     return slen;
 }
index 747e05f315693c560f6c78e23a2a5dbf301b81c2..410f3ba2cdf932276778011be925a00f91ef3c4c 100644 (file)
@@ -38,7 +38,7 @@ pdev_nulldev_init(struct device_def* def)
     devnull->ops.read_page = __null_rd_pg;
     devnull->ops.read = __null_rd;
 
     devnull->ops.read_page = __null_rd_pg;
     devnull->ops.read = __null_rd;
 
-    device_register(devnull, &def->class, "null");
+    register_device(devnull, &def->class, "null");
 
     return 0;
 }
 
     return 0;
 }
index 9c0b6c75518dd24dccc4043fd8fb35263f635786..77885d7a0e4975252ff244ff0b5d1103e24742d3 100644 (file)
@@ -24,7 +24,7 @@ pdev_zerodev_init(struct device_def* def)
     devzero->ops.read_page = __zero_rd_pg;
     devzero->ops.read = __zero_rd;
 
     devzero->ops.read_page = __zero_rd_pg;
     devzero->ops.read = __zero_rd;
 
-    device_register(devzero, &def->class, "zero");
+    register_device(devzero, &def->class, "zero");
 
     return 0;
 }
 
     return 0;
 }
index 1dbdb6821eec2447a7548e270aedb0f51b9a9212..528f1417d692cb6abecf95c5282eb4d92891673d 100644 (file)
@@ -224,7 +224,7 @@ serial_create(struct devclass* class, char* if_ident)
     rbuffer_init(&sdev->rxbuf, valloc(RXBUF_SIZE), RXBUF_SIZE);
     llist_append(&serial_devs, &sdev->sdev_list);
 
     rbuffer_init(&sdev->rxbuf, valloc(RXBUF_SIZE), RXBUF_SIZE);
     llist_append(&serial_devs, &sdev->sdev_list);
 
-    device_register(dev, class, "port%s%d", if_ident, class->variant);
+    register_device(dev, class, "port%s%d", if_ident, class->variant);
 
     sdev->at_term = term_create(dev, if_ident);
 
 
     sdev->at_term = term_create(dev, if_ident);
 
index 26532a2871cf5f4cee550b3815288ff27af68730..27d1531d77f67a17b072bf24cbc9f481c946ac25 100644 (file)
@@ -10,7 +10,7 @@
 DEFINE_LLIST(gfxa_flat);
 DECLARE_HASHTABLE(gfxa_idset, 8);
 
 DEFINE_LLIST(gfxa_flat);
 DECLARE_HASHTABLE(gfxa_idset, 8);
 
-struct device* gfxa_devcat = NULL;
+struct device_cat* gfxa_devcat = NULL;
 static int id = 0;
 
 static struct devclass gfxa_class = DEVCLASS(DEV_BUILTIN, DEVFN_DISP, DEV_GFXA);
 static int id = 0;
 
 static struct devclass gfxa_class = DEVCLASS(DEV_BUILTIN, DEVFN_DISP, DEV_GFXA);
@@ -92,7 +92,7 @@ gfxm_alloc_adapter(void* hw_obj)
     }
 
     struct gfxa* gfxa = valloc(sizeof(struct gfxa));
     }
 
     struct gfxa* gfxa = valloc(sizeof(struct gfxa));
-    struct device* gfxa_dev = device_allocsys(gfxa_devcat, gfxa);
+    struct device* gfxa_dev = device_allocsys(dev_meta(gfxa_devcat), gfxa);
 
     *gfxa = (struct gfxa){ .dev = gfxa_dev, .hw_obj = hw_obj };
 
 
     *gfxa = (struct gfxa){ .dev = gfxa_dev, .hw_obj = hw_obj };
 
@@ -109,7 +109,7 @@ gfxm_register(struct gfxa* gfxa)
     llist_append(&gfxa_flat, &gfxa->gfxas);
     hashtable_hash_in(gfxa_idset, &gfxa->gfxas_id, gfxa->id);
 
     llist_append(&gfxa_flat, &gfxa->gfxas);
     hashtable_hash_in(gfxa_idset, &gfxa->gfxas_id, gfxa->id);
 
-    device_register(gfxa->dev, &gfxa_class, "gfxa%d", gfxa->id);
+    register_device(gfxa->dev, &gfxa_class, "gfxa%d", gfxa->id);
 }
 
 struct gfxa*
 }
 
 struct gfxa*
index 9a3c581a23c8b77baddabb0bc48aa15e5b1218b2..8a5048b8be7f83d0375db19dc88f1f060722db91 100644 (file)
@@ -22,7 +22,7 @@ LOG_MODULE("PCI")
 static DEFINE_LLIST(pci_devices);
 static DECLARE_HASHTABLE(pci_devcache, 8);
 
 static DEFINE_LLIST(pci_devices);
 static DECLARE_HASHTABLE(pci_devcache, 8);
 
-static struct device* pcidev_cat;
+static struct device_cat* pcidev_cat;
 static struct device_def pci_def;
 
 void
 static struct device_def pci_def;
 
 void
@@ -58,13 +58,13 @@ pci_create_device(pciaddr_t loc, ptr_t pci_base, int devinfo)
     device->cspace_base = pci_base;
     device->intr_info = intr;
 
     device->cspace_base = pci_base;
     device->intr_info = intr;
 
-    device_create(&device->dev, pcidev_cat, DEV_IFSYS, NULL);
+    device_create(&device->dev, dev_meta(pcidev_cat), DEV_IFSYS, NULL);
 
     pci_probe_msi_info(device);
     pci_probe_bar_info(device);
 
     llist_append(&pci_devices, &device->dev_chain);
 
     pci_probe_msi_info(device);
     pci_probe_bar_info(device);
 
     llist_append(&pci_devices, &device->dev_chain);
-    device_register(&device->dev, &pci_def.class, "%x", loc);
+    register_device(&device->dev, &pci_def.class, "%x", loc);
     pci_def.class.variant++;
 
     return device;
     pci_def.class.variant++;
 
     return device;
index 5c12ca662c6d95ef19e5c008d84e2427c3e1bde0..2dd6d089ba5e42b513c5c1d95ca075697a659ff4 100644 (file)
@@ -35,7 +35,7 @@ pdev_randdev_init(struct device_def* devdef)
     devrand->ops.read = __rand_rd;
     devrand->ops.read_page = __rand_rd_pg;
 
     devrand->ops.read = __rand_rd;
     devrand->ops.read_page = __rand_rd_pg;
 
-    device_register(devrand, &devdef->class, "rand");
+    register_device(devrand, &devdef->class, "rand");
 
     return 0;
 }
 
     return 0;
 }
index b322103720a876e62542dd01404c1c268ab18798..ad063437c842de98fc7e1d8f75a695c71dd5f3e2 100644 (file)
@@ -91,7 +91,7 @@ hwrtc_register(struct devclass* class, struct hwrtc* rtc)
     }
 
     class->variant = rtc->id;
     }
 
     class->variant = rtc->id;
-    device_register(rtc->rtc_dev, class, "rtc%d", rtc->id);
+    register_device(rtc->rtc_dev, class, "rtc%d", rtc->id);
 }
 
 static void
 }
 
 static void
diff --git a/lunaix-os/hal/term/console.c b/lunaix-os/hal/term/console.c
new file mode 100644 (file)
index 0000000..4410358
--- /dev/null
@@ -0,0 +1,41 @@
+#include <lunaix/device.h>
+#include <lunaix/owloysius.h>
+#include <lunaix/spike.h>
+#include <lunaix/kcmd.h>
+#include <lunaix/fs.h>
+#include <lunaix/syslog.h>
+
+#include <hal/term.h>
+
+LOG_MODULE("console")
+
+static void 
+setup_default_tty()  
+{
+    char* console_dev;
+    if(!kcmd_get_option("console", &console_dev)) {
+        FATAL("I am expecting a console!");
+        // should not reach
+    }
+
+    struct v_dnode* dn;
+    int err;
+
+    if ((err = vfs_walk(NULL, console_dev, &dn, NULL, 0))) {
+        FATAL("unable to set console: %s, err=%d", console_dev, err);
+        // should not reach
+    }
+
+    struct device* dev = resolve_device(dn->inode->data);
+    if (!dev) {
+        FATAL("not a device: %s", console_dev);
+        // should not reach
+    }
+
+    assert(device_addalias(NULL, dev_meta(dev), "tty"));
+    
+    // TODO implement capability list
+    // for now, we just assume the parameter always pointed to valid device
+    sysconsole = dev;
+}
+lunaix_initfn(setup_default_tty, call_on_boot);
\ No newline at end of file
index 0c404a51208d035111b54a936e5c8db55ff494ae..160b62981a7a5b10cda1eb8f4169f4c64dce719e 100644 (file)
@@ -18,6 +18,8 @@ static struct term_lcntl* line_controls[] = {[ANSI_LCNTL] =
 
 static struct devclass termdev = DEVCLASS(DEVIF_NON, DEVFN_TTY, DEV_VTERM);
 
 
 static struct devclass termdev = DEVCLASS(DEVIF_NON, DEVFN_TTY, DEV_VTERM);
 
+struct device* sysconsole = NULL;
+
 static int
 term_exec_cmd(struct device* dev, u32_t req, va_list args)
 {
 static int
 term_exec_cmd(struct device* dev, u32_t req, va_list args)
 {
@@ -47,7 +49,7 @@ term_exec_cmd(struct device* dev, u32_t req, va_list args)
                 goto done;
             }
 
                 goto done;
             }
 
-            struct device* cdev = device_cast(vfd->file->inode->data);
+            struct device* cdev = resolve_device(vfd->file->inode->data);
             if (!cdev) {
                 err = ENOTDEV;
                 goto done;
             if (!cdev) {
                 err = ENOTDEV;
                 goto done;
@@ -121,7 +123,10 @@ tdev_do_write(struct device* dev, void* buf, size_t offset, size_t len)
             term_flush(tdev);
         }
     }
             term_flush(tdev);
         }
     }
-
+    
+    if (!rbuffer_empty(deref(current))) {
+        term_flush(tdev);
+    }
     return 0;
 }
 
     return 0;
 }
 
@@ -147,6 +152,15 @@ tdev_do_read(struct device* dev, void* buf, size_t offset, size_t len)
 
 static cc_t default_cc[_NCCS] = {4, '\n', 0x7f, 3, 1, 24, 22, 0, 0, 1, 1};
 
 
 static cc_t default_cc[_NCCS] = {4, '\n', 0x7f, 3, 1, 24, 22, 0, 0, 1, 1};
 
+static void 
+load_default_setting(struct term* tdev) 
+{
+    tdev->lflags = _ICANON | _IEXTEN | _ISIG | _ECHO | _ECHOE | _ECHONL;
+    tdev->iflags = _ICRNL | _IGNBRK;
+    tdev->oflags = _ONLCR | _OPOST;
+    memcpy(tdev->cc, default_cc, _NCCS * sizeof(cc_t));
+}
+
 struct term*
 term_create(struct device* chardev, char* suffix)
 {
 struct term*
 term_create(struct device* chardev, char* suffix)
 {
@@ -170,15 +184,12 @@ term_create(struct device* chardev, char* suffix)
 
     if (chardev) {
         int cdev_var = DEV_VAR_FROM(chardev->ident.unique);
 
     if (chardev) {
         int cdev_var = DEV_VAR_FROM(chardev->ident.unique);
-        device_register(terminal->dev, &termdev, "tty%s%d", suffix, cdev_var);
+        register_device(terminal->dev, &termdev, "tty%s%d", suffix, cdev_var);
     } else {
     } else {
-        device_register(terminal->dev, &termdev, "tty%d", termdev.variant++);
+        register_device(terminal->dev, &termdev, "tty%d", termdev.variant++);
     }
 
     }
 
-    terminal->lflags = _ICANON | _IEXTEN | _ISIG | _ECHO | _ECHOE | _ECHONL;
-    terminal->iflags = _ICRNL | _IGNBRK;
-    terminal->oflags = _ONLCR | _OPOST;
-    memcpy(terminal->cc, default_cc, _NCCS * sizeof(cc_t));
+    load_default_setting(terminal);
 
     return terminal;
 }
 
     return terminal;
 }
index c5341bed3886db14fe60e4e5c5f460c1ff61a4c1..3e47fac5f088b58cc2c6798e1d45cbc3faa117ac 100644 (file)
@@ -62,5 +62,5 @@ hwtimer_init(u32_t hertz, void* tick_callback)
 
     timerdev->ops.exec_cmd = __hwtimer_ioctl;
 
 
     timerdev->ops.exec_cmd = __hwtimer_ioctl;
 
-    device_register(timerdev, &hwt_ctx->class, hwt_ctx->name);
+    register_device(timerdev, &hwt_ctx->class, hwt_ctx->name);
 }
\ No newline at end of file
 }
\ No newline at end of file
index 84da769beb0d4b4c4c9a805d074f08196822adca..6b76db3b75e3c56ea48772c1578b1fbaad1699c8 100644 (file)
@@ -53,6 +53,8 @@ struct term
     speed_t iospeed;
 };
 
     speed_t iospeed;
 };
 
+extern struct device* sysconsole;
+
 struct term*
 term_create(struct device* chardev, char* suffix);
 
 struct term*
 term_create(struct device* chardev, char* suffix);
 
index 3ee6fa0ebff472b42afae3a14ab2bdda96b51813..75819785a212fa47fa656e4d366714983074197c 100644 (file)
@@ -1,14 +1,15 @@
 #ifndef __LUNAIX_COMPILER_H
 #define __LUNAIX_COMPILER_H
 
 #ifndef __LUNAIX_COMPILER_H
 #define __LUNAIX_COMPILER_H
 
-#define likely(x) __builtin_expect((x), 1)
-#define unlikely(x) __builtin_expect((x), 0)
+#define likely(x) __builtin_expect(!!(x), 1)
+#define unlikely(x) __builtin_expect(!!(x), 0)
 
 #define weak_alias(name) __attribute__((weak, alias(name)))
 #define weak __attribute__((weak))
 #define noret __attribute__((noreturn))
 #define optimize(opt) __attribute__((optimize(opt)))
 #define must_inline __attribute__((always_inline))
 
 #define weak_alias(name) __attribute__((weak, alias(name)))
 #define weak __attribute__((weak))
 #define noret __attribute__((noreturn))
 #define optimize(opt) __attribute__((optimize(opt)))
 #define must_inline __attribute__((always_inline))
+#define must_emit __attribute__((used))
 
 #define clz(bits) __builtin_clz(bits)
 #define sadd_overflow(a, b, of) __builtin_sadd_overflow(a, b, of)
 
 #define clz(bits) __builtin_clz(bits)
 #define sadd_overflow(a, b, of) __builtin_sadd_overflow(a, b, of)
@@ -24,6 +25,9 @@
 #define compact __attribute__((packed))
 #define align(v) __attribute__((aligned (v)))
 
 #define compact __attribute__((packed))
 #define align(v) __attribute__((aligned (v)))
 
+#define export_symbol(domain, symbol)\
+    typeof(symbol)* must_emit __SYMEXPORT_Z##domain##_##symbol = &(symbol)
+
 inline static void noret
 spin()
 {
 inline static void noret
 spin()
 {
index 1844590dce24ace0263102ff95a7551e02060dfb..05b8639a6579c790582a4bf379ea206a72b7a3ab 100644 (file)
         .variant = (devvar)                                                    \
     }
 
         .variant = (devvar)                                                    \
     }
 
-#define DEV_STRUCT_MAGIC 0x5645444c
+#define DEV_STRUCT_MAGIC_MASK 0x56454440U
+#define DEV_STRUCT 0xc
+#define DEV_CAT 0xd
+#define DEV_ALIAS 0xf
+
+#define DEV_STRUCT_MAGIC (DEV_STRUCT_MAGIC_MASK | DEV_STRUCT)
+#define DEV_CAT_MAGIC (DEV_STRUCT_MAGIC_MASK | DEV_CAT)
+#define DEV_ALIAS_MAGIC (DEV_STRUCT_MAGIC_MASK | DEV_ALIAS)
 
 #define DEV_MSKIF 0x00000003
 
 #define DEV_IFVOL 0x0 // volumetric (block) device
 #define DEV_IFSEQ 0x1 // sequential (character) device
 
 #define DEV_MSKIF 0x00000003
 
 #define DEV_IFVOL 0x0 // volumetric (block) device
 #define DEV_IFSEQ 0x1 // sequential (character) device
-#define DEV_IFCAT 0x2 // a device category (as device groupping)
 #define DEV_IFSYS 0x3 // a system device
 
 #define DEV_IFSYS 0x3 // a system device
 
-struct device
+struct device_meta
 {
 {
-    /* -- device structing -- */
-
     u32_t magic;
     struct llist_header siblings;
     struct llist_header children;
     u32_t magic;
     struct llist_header siblings;
     struct llist_header children;
-    struct device* parent;
+    struct device_meta* parent;
+    struct hstr name;
+    
+    u32_t dev_uid;
+    
+    char name_val[DEVICE_NAME_SIZE];
+};
+
+#define DEVICE_METADATA                             \
+    union {                                         \
+        struct device_meta meta;                    \
+        struct {                                    \
+            u32_t magic;                            \
+            struct llist_header siblings;           \
+            struct llist_header children;           \
+            struct device_meta* parent;             \
+            struct hstr name;                       \
+                                                    \
+            u32_t dev_uid;                          \
+                                                    \
+            char name_val[DEVICE_NAME_SIZE];        \
+        };                                          \
+    }                                              
+
+#define dev_meta(dev) (&(dev)->meta)
+#define to_dev(dev) (container_of(dev,struct device, meta))
+#define to_catdev(dev) (container_of(dev,struct device_cat, meta))
+#define to_aliasdev(dev) (container_of(dev,struct device_alias, meta))
+
+struct device_alias {
+    DEVICE_METADATA;
+    struct device_meta* alias;
+};
+
+struct device_cat {
+    DEVICE_METADATA;
+};
+
+struct device
+{
+    /* -- device structing -- */
+
+    DEVICE_METADATA;
 
     /* -- device state -- */
 
     mutex_t lock;
 
 
     /* -- device state -- */
 
     mutex_t lock;
 
-    struct hstr name;
-    struct devident ident;
-
-    u32_t dev_uid;
     int dev_type;
     int dev_type;
-    char name_val[DEVICE_NAME_SIZE];
+    struct devident ident;
     void* underlay;
 
     /* -- polling -- */
     void* underlay;
 
     /* -- polling -- */
@@ -168,6 +210,30 @@ struct device_def
     int (*free)(struct device_def*, void* instance);
 };
 
     int (*free)(struct device_def*, void* instance);
 };
 
+static inline bool must_inline
+valid_device_ref(void* maybe_dev) {
+    if (!maybe_dev) 
+        return false;
+        
+    unsigned int magic = ((struct device_meta*)maybe_dev)->magic;
+    return (magic ^ DEV_STRUCT_MAGIC_MASK) <= 0xfU;
+}
+
+static inline bool must_inline
+valid_device_subtype_ref(void* maybe_dev, unsigned int subtype) {
+    if (!maybe_dev) 
+        return false;
+    
+    unsigned int magic = ((struct device_meta*)maybe_dev)->magic;
+    return (magic ^ DEV_STRUCT_MAGIC_MASK) == subtype;
+}
+
+struct device*
+resolve_device(void* maybe_dev);
+
+struct device_meta*
+resolve_device_meta(void* maybe_dev);
+
 #define mark_device_doing_write(dev_ptr) (dev_ptr)->poll_evflags &= ~_POLLOUT
 #define mark_device_done_write(dev_ptr) (dev_ptr)->poll_evflags |= _POLLOUT
 
 #define mark_device_doing_write(dev_ptr) (dev_ptr)->poll_evflags &= ~_POLLOUT
 #define mark_device_done_write(dev_ptr) (dev_ptr)->poll_evflags |= _POLLOUT
 
@@ -187,61 +253,64 @@ void
 device_scan_drivers();
 
 void
 device_scan_drivers();
 
 void
-device_setname_vargs(struct device* dev, char* fmt, va_list args);
+device_setname_vargs(struct device_meta* dev, char* fmt, va_list args);
 
 void
 
 void
-device_setname(struct device* dev, char* fmt, ...);
+device_setname(struct device_meta* dev, char* fmt, ...);
 
 void
 
 void
-device_register(struct device* dev, struct devclass* class, char* fmt, ...);
+device_register_generic(struct device_meta* dev, struct devclass* class, char* fmt, ...);
+
+#define register_device(dev, class, fmt, ...) \
+            device_register_generic(dev_meta(dev), class, fmt, ## __VA_ARGS__)
 
 void
 device_create(struct device* dev,
 
 void
 device_create(struct device* dev,
-              struct device* parent,
+              struct device_meta* parent,
               u32_t type,
               void* underlay);
 
 struct device*
               u32_t type,
               void* underlay);
 
 struct device*
-device_alloc(struct device* parent, u32_t type, void* underlay);
+device_alloc(struct device_meta* parent, u32_t type, void* underlay);
 
 
-static inline struct device*
-device_allocsys(struct device* parent, void* underlay)
+static inline struct device* must_inline
+device_allocsys(struct device_meta* parent, void* underlay)
 {
     return device_alloc(parent, DEV_IFSYS, underlay);
 }
 
 {
     return device_alloc(parent, DEV_IFSYS, underlay);
 }
 
-static inline struct device*
-device_allocseq(struct device* parent, void* underlay)
+static inline struct device* must_inline
+device_allocseq(struct device_meta* parent, void* underlay)
 {
     return device_alloc(parent, DEV_IFSEQ, underlay);
 }
 
 {
     return device_alloc(parent, DEV_IFSEQ, underlay);
 }
 
-static inline struct device*
-device_allocvol(struct device* parent, void* underlay)
+static inline struct device* must_inline
+device_allocvol(struct device_meta* parent, void* underlay)
 {
     return device_alloc(parent, DEV_IFVOL, underlay);
 }
 
 {
     return device_alloc(parent, DEV_IFVOL, underlay);
 }
 
-struct device*
-device_addcat(struct device* parent, char* name_fmt, ...);
+struct device_alias*
+device_addalias(struct device_meta* parent, struct device_meta* aliased, char* name_fmt, ...);
+
+struct device_cat*
+device_addcat(struct device_meta* parent, char* name_fmt, ...);
 
 void
 
 void
-device_remove(struct device* dev);
+device_remove(struct device_meta* dev);
 
 
-struct device*
+struct device_meta*
 device_getbyid(struct llist_header* devlist, u32_t id);
 
 device_getbyid(struct llist_header* devlist, u32_t id);
 
-struct device*
-device_getbyhname(struct device* root_dev, struct hstr* name);
+struct device_meta*
+device_getbyhname(struct device_meta* root_dev, struct hstr* name);
 
 
-struct device*
-device_getbyname(struct device* root_dev, const char* name, size_t len);
-
-struct device*
-device_getbyoffset(struct device* root_dev, int pos);
+struct device_meta*
+device_getbyname(struct device_meta* root_dev, const char* name, size_t len);
 
 
-struct device*
-device_cast(void* obj);
+struct device_meta*
+device_getbyoffset(struct device_meta* root_dev, int pos);
 
 struct hbucket*
 device_definitions_byif(int if_type);
 
 struct hbucket*
 device_definitions_byif(int if_type);
@@ -258,7 +327,7 @@ device_scan_drivers();
 /*------ Load hooks ------*/
 
 void
 /*------ Load hooks ------*/
 
 void
-device_onbooot_load();
+device_onboot_load();
 
 void
 device_postboot_load();
 
 void
 device_postboot_load();
index 9011da3d567edd623e7cf1e37ca660cb3828cc9d..b59c857bae2205a37c3af28ca9c83f6e61c72559 100644 (file)
@@ -89,6 +89,7 @@
 #define DEV_BUILTIN 0
 #define DEV_BUILTIN_NULL 0
 #define DEV_BUILTIN_ZERO 1
 #define DEV_BUILTIN 0
 #define DEV_BUILTIN_NULL 0
 #define DEV_BUILTIN_ZERO 1
+#define DEV_BUILTIN_KMSG 2
 
 #define DEV_VTERM 1
 #define DEV_RNG 2
 
 #define DEV_VTERM 1
 #define DEV_RNG 2
index 1fe37f1562c4976e21f82216c5562d06fb6f26aa..0e2169e7c9f54d54acb679960659289ccf5afc62 100644 (file)
@@ -98,6 +98,7 @@ extern struct v_dnode* vfs_sysroot;
 
 struct filesystem
 {
 
 struct filesystem
 {
+    struct llist_header fs_flat;
     struct hlist_node fs_list;
     struct hstr fs_name;
     u32_t types;
     struct hlist_node fs_list;
     struct hstr fs_name;
     u32_t types;
diff --git a/lunaix-os/includes/lunaix/owloysius.h b/lunaix-os/includes/lunaix/owloysius.h
new file mode 100644 (file)
index 0000000..7948066
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef __LUNAIX_OWLOYSIUS_H
+#define __LUNAIX_OWLOYSIUS_H
+
+#include <lunaix/ds/ldga.h>
+
+#define call_on_earlyboot c_earlyboot
+#define call_on_boot c_boot
+#define call_on_postboot c_postboot
+
+#define lunaix_initfn(func, call_stage)                                     \
+    export_ldga_el(lunainit, func, ptr_t, func);                            \
+    export_ldga_el_sfx(lunainit, func##_##call_stage, ptr_t, func, call_stage);
+
+#define invoke_init_function(stage) ldga_invoke_fn0(lunainit##_##stage)
+
+#endif /* __LUNAIX_OWLOYSIUS_H */
index 9e2d427e42bc59150faaa77359040ea34a32a7ef..f73fbe1d2bb7e061c5492af6e4b367e20a12c186 100644 (file)
 
 #ifndef __LUNAIXOS_NASSERT__
 #define assert(cond)                                                           \
 
 #ifndef __LUNAIXOS_NASSERT__
 #define assert(cond)                                                           \
-    if (!(cond)) {                                                             \
-        __assert_fail(#cond, __FILE__, __LINE__);                              \
-    }
+    do {                                                                       \
+        if (!(cond)) {                                                         \
+            __assert_fail(#cond, __FILE__, __LINE__);                          \
+        }                                                                      \
+    } while(0)
 
 #define assert_msg(cond, msg)                                                  \
 
 #define assert_msg(cond, msg)                                                  \
-    if (!(cond)) {                                                             \
-        __assert_fail(msg, __FILE__, __LINE__);                                \
-    }
+    do {                                                                       \
+        if (!(cond)) {                                                         \
+            __assert_fail(msg, __FILE__, __LINE__);                            \
+        }                                                                      \
+    } while(0)
+
+#define must_success(statement)                                                \
+    do {                                                                       \
+        int err = (statement);                                                 \
+        if (err) panickf(#statement "failed with errcode=%d", err);           \
+    } while(0)
 
 #define fail(msg) __assert_fail(msg, __FILE__, __LINE__);
 
 
 #define fail(msg) __assert_fail(msg, __FILE__, __LINE__);
 
index a2242adb39c43b898bba75f562ca67243f9b760a..bf83b5f223a7db3dfcf6b846e970cfeeddb27c86 100644 (file)
@@ -26,7 +26,7 @@ LOG_MODULE("BLOCK")
 static struct cake_pile* lbd_pile;
 static struct block_dev** dev_registry;
 static struct twifs_node* blk_sysroot;
 static struct cake_pile* lbd_pile;
 static struct block_dev** dev_registry;
 static struct twifs_node* blk_sysroot;
-static struct device* blk_parent_dev;
+static struct device_cat* blk_parent_dev;
 
 int free_slot = 0;
 
 
 int free_slot = 0;
 
@@ -299,7 +299,7 @@ __block_register(struct block_dev* bdev)
         return 0;
     }
 
         return 0;
     }
 
-    struct device* dev = device_allocvol(blk_parent_dev, bdev);
+    struct device* dev = device_allocvol(dev_meta(blk_parent_dev), bdev);
     dev->ops.write = __block_write;
     dev->ops.write_page = __block_write_page;
     dev->ops.read = __block_read;
     dev->ops.write = __block_write;
     dev->ops.write_page = __block_write_page;
     dev->ops.read = __block_read;
@@ -307,7 +307,7 @@ __block_register(struct block_dev* bdev)
 
     bdev->dev = dev;
 
 
     bdev->dev = dev;
 
-    device_register(dev, bdev->class, "sd%c", 'a' + free_slot);
+    register_device(dev, bdev->class, "sd%c", 'a' + free_slot);
     dev_registry[free_slot++] = bdev;
 
     strcpy(bdev->bdev_id, dev->name_val);
     dev_registry[free_slot++] = bdev;
 
     strcpy(bdev->bdev_id, dev->name_val);
@@ -342,7 +342,7 @@ blk_mount_part(struct block_dev* bdev,
 
     llist_append(&bdev->parts, &pbdev->parts);
 
 
     llist_append(&bdev->parts, &pbdev->parts);
 
-    device_register(dev, pbdev->class, "%sp%d", bdev->bdev_id, index + 1);
+    register_device(dev, pbdev->class, "%sp%d", bdev->bdev_id, index + 1);
 
     return pbdev;
 }
\ No newline at end of file
 
     return pbdev;
 }
\ No newline at end of file
index 8c5c1800fd6676ab9ec65d959eea2dc17cbf7706..1c909197bc8f0a594ba34ed4f91c73dabdc6e917 100644 (file)
@@ -104,6 +104,10 @@ trace_walkback(struct trace_record* tb_buffer,
         i++;
     }
 
         i++;
     }
 
+    if (!valid_fp((ptr_t)frame)) {
+        frame = NULL;
+    }
+
     if (last_fp) {
         *last_fp = (ptr_t)frame;
     }
     if (last_fp) {
         *last_fp = (ptr_t)frame;
     }
index 236ac5aa33613655b17c7b361ebacd84217a5802..eb9e612320494db1107d9a31a06de0fa57e4eaa1 100644 (file)
@@ -10,7 +10,7 @@ static DECLARE_HASHTABLE(dev_registry, 32);
 static DECLARE_HASHTABLE(dev_byif, 8);
 static DEFINE_LLIST(dev_registry_flat);
 
 static DECLARE_HASHTABLE(dev_byif, 8);
 static DEFINE_LLIST(dev_registry_flat);
 
-static struct device* adhoc_devcat;
+static struct device_cat* adhoc_devcat;
 
 static inline u32_t
 hash_dev(u32_t fngrp, u32_t dev)
 
 static inline u32_t
 hash_dev(u32_t fngrp, u32_t dev)
@@ -97,7 +97,7 @@ device_definitions_byif(int if_type)
 #define device_load_on_stage(stage) __device_load_on_stage(stage)
 
 void
 #define device_load_on_stage(stage) __device_load_on_stage(stage)
 
 void
-device_onbooot_load()
+device_onboot_load()
 {
     device_load_on_stage(load_onboot);
 }
 {
     device_load_on_stage(load_onboot);
 }
@@ -136,7 +136,7 @@ __devdb_twifs_lsdb(struct twimap* mapping)
     ksnprintf(flags, 64, "if=%x,fn=%x", DEV_IF(meta), DEV_FN(meta));
 
     twimap_printf(mapping,
     ksnprintf(flags, 64, "if=%x,fn=%x", DEV_IF(meta), DEV_FN(meta));
 
     twimap_printf(mapping,
-                  "%xh:%d \"%s\" %s\n",
+                  "%08xh:%04d \"%s\" %s\n",
                   def->class.fn_grp,
                   def->class.device,
                   def->name,
                   def->class.fn_grp,
                   def->class.device,
                   def->name,
index f586addca408066d9c44ee2d0a470df02e0d4af1..350bbd65e447ab64ed5b50de1757490ef75a27a4 100644 (file)
@@ -13,9 +13,9 @@ devfs_read(struct v_inode* inode, void* buffer, size_t len, size_t fpos)
 {
     assert(inode->data);
 
 {
     assert(inode->data);
 
-    struct device* dev = (struct device*)inode->data;
+    struct device* dev = resolve_device(inode->data);
 
 
-    if (!dev->ops.read) {
+    if (!dev || !dev->ops.read) {
         return ENOTSUP;
     }
 
         return ENOTSUP;
     }
 
@@ -27,9 +27,9 @@ devfs_write(struct v_inode* inode, void* buffer, size_t len, size_t fpos)
 {
     assert(inode->data);
 
 {
     assert(inode->data);
 
-    struct device* dev = (struct device*)inode->data;
+    struct device* dev = resolve_device(inode->data);
 
 
-    if (!dev->ops.write) {
+    if (!dev || !dev->ops.write) {
         return ENOTSUP;
     }
 
         return ENOTSUP;
     }
 
@@ -41,9 +41,9 @@ devfs_read_page(struct v_inode* inode, void* buffer, size_t fpos)
 {
     assert(inode->data);
 
 {
     assert(inode->data);
 
-    struct device* dev = (struct device*)inode->data;
+    struct device* dev = resolve_device(inode->data);
 
 
-    if (!dev->ops.read_page) {
+    if (!dev || !dev->ops.read_page) {
         return ENOTSUP;
     }
 
         return ENOTSUP;
     }
 
@@ -55,9 +55,9 @@ devfs_write_page(struct v_inode* inode, void* buffer, size_t fpos)
 {
     assert(inode->data);
 
 {
     assert(inode->data);
 
-    struct device* dev = (struct device*)inode->data;
+    struct device* dev = resolve_device(inode->data);
 
 
-    if (!dev->ops.read_page) {
+    if (!dev || !dev->ops.read_page) {
         return ENOTSUP;
     }
 
         return ENOTSUP;
     }
 
@@ -65,13 +65,18 @@ devfs_write_page(struct v_inode* inode, void* buffer, size_t fpos)
 }
 
 int
 }
 
 int
-devfs_get_itype(struct device* dev)
+devfs_get_itype(struct device_meta* dm)
 {
     int itype = VFS_IFFILE;
 {
     int itype = VFS_IFFILE;
+
+    if (valid_device_subtype_ref(dm, DEV_CAT)) {
+        return VFS_IFDIR;
+    }
+
+    struct device* dev = resolve_device(dm);
     int dev_if = dev->dev_type & DEV_MSKIF;
     int dev_if = dev->dev_type & DEV_MSKIF;
-    if (dev_if == DEV_IFCAT) {
-        itype = VFS_IFDIR;
-    } else if (dev_if == DEV_IFVOL) {
+    
+    if (dev_if == DEV_IFVOL) {
         itype |= VFS_IFVOLDEV;
     } else if (dev_if == DEV_IFSEQ) {
         itype |= VFS_IFSEQDEV;
         itype |= VFS_IFVOLDEV;
     } else if (dev_if == DEV_IFSEQ) {
         itype |= VFS_IFSEQDEV;
@@ -82,19 +87,16 @@ devfs_get_itype(struct device* dev)
 }
 
 int
 }
 
 int
-devfs_get_dtype(struct device* dev)
+devfs_get_dtype(struct device_meta* dev)
 {
 {
-    switch (dev->dev_type & DEV_MSKIF) {
-        case DEV_IFCAT:
-            return DT_DIR;
-
-        default:
-            return DT_FILE;
+    if (valid_device_subtype_ref(dev, DEV_CAT)) {
+        return DT_DIR;
     }
     }
+    return DT_FILE;
 }
 
 int
 }
 
 int
-devfs_mknod(struct v_dnode* dnode, struct device* dev)
+devfs_mknod(struct v_dnode* dnode, struct device_meta* dev)
 {
     assert(dev);
 
 {
     assert(dev);
 
@@ -118,22 +120,40 @@ devfs_mknod(struct v_dnode* dnode, struct device* dev)
 int
 devfs_dirlookup(struct v_inode* this, struct v_dnode* dnode)
 {
 int
 devfs_dirlookup(struct v_inode* this, struct v_dnode* dnode)
 {
-    struct device* dev =
-      device_getbyhname((struct device*)this->data, &dnode->name);
+    void* data = this->data;
+    struct device_meta* rootdev = resolve_device_meta(data);
+
+    if (data && !rootdev) {
+        return ENOTDIR;
+    }
+
+    struct device_meta* dev =
+      device_getbyhname(rootdev, &dnode->name);
+    
     if (!dev) {
         return ENOENT;
     }
     if (!dev) {
         return ENOENT;
     }
+
     return devfs_mknod(dnode, dev);
 }
 
 int
 devfs_readdir(struct v_file* file, struct dir_context* dctx)
 {
     return devfs_mknod(dnode, dev);
 }
 
 int
 devfs_readdir(struct v_file* file, struct dir_context* dctx)
 {
-    struct device* dev =
-      device_getbyoffset((struct device*)(file->inode->data), dctx->index);
+    void* data = file->inode->data;
+    struct device_meta* rootdev = resolve_device_meta(data);
+
+    if (data && !rootdev) {
+        return ENOTDIR;
+    }
+
+    struct device_meta* dev =
+      device_getbyoffset(rootdev, dctx->index);
+    
     if (!dev) {
         return 0;
     }
     if (!dev) {
         return 0;
     }
+
     dctx->read_complete_callback(
       dctx, dev->name.value, dev->name.len, devfs_get_dtype(dev));
     return 1;
     dctx->read_complete_callback(
       dctx, dev->name.value, dev->name.len, devfs_get_dtype(dev));
     return 1;
index cce51b19dbec4aaf9c3bbc9b94a0e8bddc18b018..b88f8f6c283ea311fb3e524059f67a6eabe3d143 100644 (file)
@@ -18,7 +18,7 @@ static volatile u32_t devid = 0;
 struct devclass default_devclass = {};
 
 void
 struct devclass default_devclass = {};
 
 void
-device_setname_vargs(struct device* dev, char* fmt, va_list args)
+device_setname_vargs(struct device_meta* dev, char* fmt, va_list args)
 {
     size_t strlen = ksnprintfv(dev->name_val, fmt, DEVICE_NAME_SIZE, args);
 
 {
     size_t strlen = ksnprintfv(dev->name_val, fmt, DEVICE_NAME_SIZE, args);
 
@@ -28,52 +28,61 @@ device_setname_vargs(struct device* dev, char* fmt, va_list args)
 }
 
 void
 }
 
 void
-device_register(struct device* dev, struct devclass* class, char* fmt, ...)
+device_register_generic(struct device_meta* devm, struct devclass* class, char* fmt, ...)
 {
     va_list args;
     va_start(args, fmt);
 
     if (fmt) {
 {
     va_list args;
     va_start(args, fmt);
 
     if (fmt) {
-        device_setname_vargs(dev, fmt, args);
+        device_setname_vargs(devm, fmt, args);
     }
 
     }
 
-    if (class) {
+    if (class && valid_device_subtype_ref(devm, DEV_STRUCT)) {
+        struct device* dev = to_dev(devm);
         dev->ident = (struct devident){ .fn_grp = class->fn_grp,
                                         .unique = DEV_UNIQUE(class->device,
                                                              class->variant) };
     }
 
         dev->ident = (struct devident){ .fn_grp = class->fn_grp,
                                         .unique = DEV_UNIQUE(class->device,
                                                              class->variant) };
     }
 
-    dev->dev_uid = devid++;
+    devm->dev_uid = devid++;
 
 
-    struct device* parent = dev->parent;
+    struct device_meta* parent = devm->parent;
     if (parent) {
     if (parent) {
-        assert((parent->dev_type & DEV_MSKIF) == DEV_IFCAT);
-        llist_append(&parent->children, &dev->siblings);
+        assert(valid_device_subtype_ref(parent, DEV_CAT));
+        llist_append(&parent->children, &devm->siblings);
     } else {
     } else {
-        llist_append(&root_list, &dev->siblings);
+        llist_append(&root_list, &devm->siblings);
     }
 
     va_end(args);
 }
 
     }
 
     va_end(args);
 }
 
+static void
+device_init_meta(struct device_meta* dmeta, struct device_meta* parent, unsigned int subtype) 
+{
+    dmeta->magic = DEV_STRUCT_MAGIC_MASK | subtype;
+    dmeta->parent = parent;
+
+    llist_init_head(&dmeta->children);
+}
+
 void
 device_create(struct device* dev,
 void
 device_create(struct device* dev,
-              struct device* parent,
+              struct device_meta* parent,
               u32_t type,
               void* underlay)
 {
     dev->magic = DEV_STRUCT_MAGIC;
     dev->underlay = underlay;
     dev->dev_type = type;
               u32_t type,
               void* underlay)
 {
     dev->magic = DEV_STRUCT_MAGIC;
     dev->underlay = underlay;
     dev->dev_type = type;
-    dev->parent = parent;
 
 
-    llist_init_head(&dev->children);
+    device_init_meta(dev_meta(dev), parent, DEV_STRUCT);
     mutex_init(&dev->lock);
     iopoll_init_evt_q(&dev->pollers);
 }
 
 struct device*
     mutex_init(&dev->lock);
     iopoll_init_evt_q(&dev->pollers);
 }
 
 struct device*
-device_alloc(struct device* parent, u32_t type, void* underlay)
+device_alloc(struct device_meta* parent, u32_t type, void* underlay)
 {
     struct device* dev = vzalloc(sizeof(struct device));
 
 {
     struct device* dev = vzalloc(sizeof(struct device));
 
@@ -86,8 +95,38 @@ device_alloc(struct device* parent, u32_t type, void* underlay)
     return dev;
 }
 
     return dev;
 }
 
+struct device_alias*
+device_alloc_alias(struct device_meta* parent, struct device_meta* aliased)
+{
+    struct device_alias* dev = vzalloc(sizeof(struct device_alias));
+
+    if (!dev) {
+        return NULL;
+    }
+
+    device_init_meta(dev_meta(dev), parent, DEV_ALIAS);
+    dev->alias = aliased;
+
+    return dev;
+}
+
+struct device_cat*
+device_alloc_cat(struct device_meta* parent)
+{
+    struct device_cat* dev = vzalloc(sizeof(struct device_cat));
+
+    if (!dev) {
+        return NULL;
+    }
+
+    device_init_meta(dev_meta(dev), parent, DEV_CAT);
+
+    return dev;
+}
+
+
 void
 void
-device_setname(struct device* dev, char* fmt, ...)
+device_setname(struct device_meta* dev, char* fmt, ...)
 {
     va_list args;
     va_start(args, fmt);
 {
     va_list args;
     va_start(args, fmt);
@@ -97,26 +136,41 @@ device_setname(struct device* dev, char* fmt, ...)
     va_end(args);
 }
 
     va_end(args);
 }
 
-struct device*
-device_addcat(struct device* parent, char* name_fmt, ...)
+struct device_cat*
+device_addcat(struct device_meta* parent, char* name_fmt, ...)
 {
     va_list args;
     va_start(args, name_fmt);
 
 {
     va_list args;
     va_start(args, name_fmt);
 
-    struct device* dev = device_alloc(parent, DEV_IFCAT, NULL);
+    struct device_cat* dev = device_alloc_cat(parent);
 
 
-    device_setname_vargs(dev, name_fmt, args);
-    device_register(dev, NULL, NULL);
+    device_setname_vargs(dev_meta(dev), name_fmt, args);
+    device_register_generic(dev_meta(dev), NULL, NULL);
 
     va_end(args);
     return dev;
 }
 
 
     va_end(args);
     return dev;
 }
 
-struct device*
+struct device_alias*
+device_addalias(struct device_meta* parent, struct device_meta* aliased, char* name_fmt, ...)
+{
+    va_list args;
+    va_start(args, name_fmt);
+
+    struct device_alias* dev = device_alloc_alias(parent, aliased);
+
+    device_setname_vargs(dev_meta(dev), name_fmt, args);
+    device_register_generic(dev_meta(dev), NULL, NULL);
+
+    va_end(args);
+    return dev;
+}
+
+struct device_meta*
 device_getbyid(struct llist_header* devlist, u32_t id)
 {
     devlist = devlist ? devlist : &root_list;
 device_getbyid(struct llist_header* devlist, u32_t id)
 {
     devlist = devlist ? devlist : &root_list;
-    struct device *pos, *n;
+    struct device_meta *pos, *n;
     llist_for_each(pos, n, devlist, siblings)
     {
         if (pos->dev_uid == id) {
     llist_for_each(pos, n, devlist, siblings)
     {
         if (pos->dev_uid == id) {
@@ -127,11 +181,11 @@ device_getbyid(struct llist_header* devlist, u32_t id)
     return NULL;
 }
 
     return NULL;
 }
 
-struct device*
-device_getbyhname(struct device* root_dev, struct hstr* name)
+struct device_meta*
+device_getbyhname(struct device_meta* root_dev, struct hstr* name)
 {
     struct llist_header* devlist = root_dev ? &root_dev->children : &root_list;
 {
     struct llist_header* devlist = root_dev ? &root_dev->children : &root_list;
-    struct device *pos, *n;
+    struct device_meta *pos, *n;
     llist_for_each(pos, n, devlist, siblings)
     {
         if (HSTR_EQ(&pos->name, name)) {
     llist_for_each(pos, n, devlist, siblings)
     {
         if (HSTR_EQ(&pos->name, name)) {
@@ -142,8 +196,8 @@ device_getbyhname(struct device* root_dev, struct hstr* name)
     return NULL;
 }
 
     return NULL;
 }
 
-struct device*
-device_getbyname(struct device* root_dev, const char* name, size_t len)
+struct device_meta*
+device_getbyname(struct device_meta* root_dev, const char* name, size_t len)
 {
     struct hstr hname = HSTR(name, len);
     hstr_rehash(&hname, HSTR_FULL_HASH);
 {
     struct hstr hname = HSTR(name, len);
     hstr_rehash(&hname, HSTR_FULL_HASH);
@@ -152,17 +206,17 @@ device_getbyname(struct device* root_dev, const char* name, size_t len)
 }
 
 void
 }
 
 void
-device_remove(struct device* dev)
+device_remove(struct device_meta* dev)
 {
     llist_delete(&dev->siblings);
     vfree(dev);
 }
 
 {
     llist_delete(&dev->siblings);
     vfree(dev);
 }
 
-struct device*
-device_getbyoffset(struct device* root_dev, int offset)
+struct device_meta*
+device_getbyoffset(struct device_meta* root_dev, int offset)
 {
     struct llist_header* devlist = root_dev ? &root_dev->children : &root_list;
 {
     struct llist_header* devlist = root_dev ? &root_dev->children : &root_list;
-    struct device *pos, *n;
+    struct device_meta *pos, *n;
     int off = 0;
     llist_for_each(pos, n, devlist, siblings)
     {
     int off = 0;
     llist_for_each(pos, n, devlist, siblings)
     {
@@ -190,15 +244,44 @@ device_populate_info(struct device* dev, struct dev_info* devinfo)
     devinfo->dev_name.buf[buflen - 1] = 0;
 }
 
     devinfo->dev_name.buf[buflen - 1] = 0;
 }
 
+struct device_meta*
+resolve_device_meta(void* maybe_dev) {
+    if (!valid_device_ref(maybe_dev)) {
+        return NULL;
+    }
+
+    struct device_meta* dm = (struct device_meta*)maybe_dev;
+    unsigned int subtype = dm->magic ^ DEV_STRUCT_MAGIC_MASK;
+    
+    switch (subtype)
+    {
+        case DEV_STRUCT:
+        case DEV_CAT:
+            return dm;
+        
+        case DEV_ALIAS: {
+            struct device_meta* aliased_dm = dm;
+            
+            while(valid_device_subtype_ref(aliased_dm, DEV_ALIAS)) {
+                aliased_dm = to_aliasdev(aliased_dm)->alias;
+            }
+
+            return aliased_dm;
+        }
+        default:
+            return NULL;
+    }
+}
+
 struct device*
 struct device*
-device_cast(void* obj)
-{
-    struct device* dev = (struct device*)obj;
-    if (dev && dev->magic == DEV_STRUCT_MAGIC) {
-        return dev;
+resolve_device(void* maybe_dev) {
+    struct device_meta* dm = resolve_device_meta(maybe_dev);
+    
+    if (!valid_device_subtype_ref(dm, DEV_STRUCT)) {
+        return NULL;
     }
 
     }
 
-    return NULL;
+    return to_dev(dm);
 }
 
 void
 }
 
 void
@@ -217,7 +300,7 @@ __DEFINE_LXSYSCALL3(int, ioctl, int, fd, int, req, va_list, args)
     }
 
     struct device* dev = (struct device*)fd_s->file->inode->data;
     }
 
     struct device* dev = (struct device*)fd_s->file->inode->data;
-    if (dev->magic != DEV_STRUCT_MAGIC) {
+    if (valid_device_subtype_ref(dev, DEV_STRUCT)) {
         errno &= ENODEV;
         goto done;
     }
         errno &= ENODEV;
         goto done;
     }
index 3d974a7987d84f12cea8251d778163b303a473ce..6ced39d0ad9efadf2e61d73bf2c6846cd1d79ebe 100644 (file)
@@ -9,7 +9,7 @@
 
 static DEFINE_LLIST(listener_chain);
 
 
 static DEFINE_LLIST(listener_chain);
 
-static struct device* input_devcat = NULL;
+static struct device_cat* input_devcat = NULL;
 
 void
 input_init()
 
 void
 input_init()
@@ -80,10 +80,10 @@ input_add_device(struct devclass* class, char* name_fmt, ...)
     va_list args;
     va_start(args, name_fmt);
 
     va_list args;
     va_start(args, name_fmt);
 
-    struct device* dev = device_allocseq(input_devcat, idev);
+    struct device* dev = device_allocseq(dev_meta(input_devcat), idev);
 
 
-    device_setname_vargs(dev, name_fmt, args);
-    device_register(dev, class, NULL);
+    device_setname_vargs(dev_meta(dev), name_fmt, args);
+    register_device(dev, class, NULL);
 
     idev->dev_if = dev;
     dev->ops.read = __input_dev_read;
 
     idev->dev_if = dev;
     dev->ops.read = __input_dev_read;
index bf7edd7c645eb760263c8947bd3992fdfa8feda7..ca204a28428dba9ab11da8b0fb9c270b8121257e 100644 (file)
@@ -37,7 +37,7 @@ __do_poll(struct poll_info* pinfo, int pld)
     struct device* dev;
     int evt = 0;
 
     struct device* dev;
     int evt = 0;
 
-    if ((dev = device_cast(poller->file_ref->inode->data))) {
+    if ((dev = resolve_device(poller->file_ref->inode->data))) {
         dev->ops.poll(dev);
     } else {
         // TODO handle generic file
         dev->ops.poll(dev);
     } else {
         // TODO handle generic file
@@ -111,7 +111,7 @@ __do_poll_all(struct poll_info* pinfo)
     return 0;
 }
 
     return 0;
 }
 
-#define fd2dev(fd) device_cast((fd)->file->inode->data)
+#define fd2dev(fd) resolve_device((fd)->file->inode->data)
 
 static int
 __alloc_pld()
 
 static int
 __alloc_pld()
index ca1221c095a0e063a6d3dd0c5dea16cbbe8a0232..950583857b981857d2a5d2ce35e2f1c990f60b6a 100644 (file)
 #include <lunaix/fs.h>
 #include <lunaix/mm/valloc.h>
 
 #include <lunaix/fs.h>
 #include <lunaix/mm/valloc.h>
 
+#include <lunaix/fs/twimap.h>
+#include <lunaix/fs/twifs.h>
+
 #define HASH_BUCKET_BITS 4
 #define HASH_BUCKET_NUM (1 << HASH_BUCKET_BITS)
 
 #define HASH_BUCKET_BITS 4
 #define HASH_BUCKET_NUM (1 << HASH_BUCKET_BITS)
 
+DEFINE_LLIST(fs_flatlist);
 DECLARE_HASHTABLE(fs_registry, HASH_BUCKET_NUM);
 
 void
 DECLARE_HASHTABLE(fs_registry, HASH_BUCKET_NUM);
 
 void
@@ -31,6 +35,7 @@ fsm_register(struct filesystem* fs)
 {
     hstr_rehash(&fs->fs_name, HSTR_FULL_HASH);
     hashtable_hash_in(fs_registry, &fs->fs_list, fs->fs_name.hash);
 {
     hstr_rehash(&fs->fs_name, HSTR_FULL_HASH);
     hashtable_hash_in(fs_registry, &fs->fs_list, fs->fs_name.hash);
+    llist_append(&fs_flatlist, &fs->fs_flat);
 }
 
 struct filesystem*
 }
 
 struct filesystem*
@@ -59,4 +64,22 @@ fsm_new_fs(char* name, size_t name_len)
     }
     fs->fs_name = HHSTR(name, name_len, 0);
     return fs;
     }
     fs->fs_name = HHSTR(name, name_len, 0);
     return fs;
-}
\ No newline at end of file
+}
+
+static void
+read_fslist(struct twimap *mapping)
+{
+    struct filesystem *pos, *n;
+    llist_for_each(pos, n, &fs_flatlist, fs_flat)
+    {
+        twimap_printf(mapping, "%s %d\n", pos->fs_name.value, pos->types);
+    }
+}
+
+static void
+fstab_twifs_plugin()
+{
+    struct twimap* map = twifs_mapping(NULL, NULL, "fstab");
+    map->read = read_fslist;
+}
+EXPORT_TWIFS_PLUGIN(fstab, fstab_twifs_plugin);
\ No newline at end of file
index 084a400a1993000a09f7a770fa844a3ec21f5927..96cc7418cec8a702573120a70b824d79fcaf89ac 100644 (file)
@@ -33,7 +33,7 @@ vfs_create_mount(struct v_mount* parent, struct v_dnode* mnt_point)
         llist_append(&parent->submnts, &mnt->sibmnts);
         mutex_unlock(&mnt->parent->lock);
     }
         llist_append(&parent->submnts, &mnt->sibmnts);
         mutex_unlock(&mnt->parent->lock);
     }
-
+    
     atomic_fetch_add(&mnt_point->ref_count, 1);
 
     return mnt;
     atomic_fetch_add(&mnt_point->ref_count, 1);
 
     return mnt;
@@ -64,7 +64,7 @@ __vfs_do_unmount(struct v_mount* mnt)
     mnt_chillax(mnt->parent);
 
     vfs_sb_free(sb);
     mnt_chillax(mnt->parent);
 
     vfs_sb_free(sb);
-    vfs_d_free(mnt->mnt_point);
+    atomic_fetch_sub(&mnt->mnt_point->ref_count, 1);
     vfree(mnt);
 
     return errno;
     vfree(mnt);
 
     return errno;
index 77b4dff6eca146790e333886a4cadcf5a21586a5..3cb40494b26dd5d1c17a9aed711355d3477e2586 100644 (file)
@@ -10,24 +10,30 @@ LOG_MODULE("PROBE")
 struct device*
 probe_boot_medium()
 {
 struct device*
 probe_boot_medium()
 {
-    struct device* block_cat = device_getbyname(NULL, "block", 5);
+    struct device_meta* block_cat = device_getbyname(NULL, "block", 5);
     if (!block_cat) {
         return NULL;
     }
 
     struct iso_vol_primary* volp = valloc(ISO9660_BLKSZ);
 
     if (!block_cat) {
         return NULL;
     }
 
     struct iso_vol_primary* volp = valloc(ISO9660_BLKSZ);
 
-    struct device *pos, *n;
+    struct device* dev = NULL;
+    struct device_meta *pos, *n;
     llist_for_each(pos, n, &block_cat->children, siblings)
     {
     llist_for_each(pos, n, &block_cat->children, siblings)
     {
+        dev = resolve_device(pos);
+        if (!dev) {
+            continue;
+        }
+
         int errno =
         int errno =
-          pos->ops.read(pos, (void*)volp, ISO9660_READ_OFF, ISO9660_BLKSZ);
+          dev->ops.read(dev, (void*)volp, ISO9660_READ_OFF, ISO9660_BLKSZ);
         if (errno < 0) {
             kprintf(KINFO "failed %xh:%xh, /dev/%s",
         if (errno < 0) {
             kprintf(KINFO "failed %xh:%xh, /dev/%s",
-                    pos->ident.fn_grp,
-                    pos->ident.unique,
-                    pos->name.value);
-            pos = NULL;
+                    dev->ident.fn_grp,
+                    dev->ident.unique,
+                    dev->name.value);
+            dev = NULL;
             goto done;
         }
 
             goto done;
         }
 
@@ -37,9 +43,9 @@ probe_boot_medium()
 
         if (*(u32_t*)volp->sys_id == LUNAIX_ID) {
             kprintf(KINFO "%xh:%xh, /dev/%s, %s",
 
         if (*(u32_t*)volp->sys_id == LUNAIX_ID) {
             kprintf(KINFO "%xh:%xh, /dev/%s, %s",
-                    pos->ident.fn_grp,
-                    pos->ident.unique,
-                    pos->name.value,
+                    dev->ident.fn_grp,
+                    dev->ident.unique,
+                    dev->name.value,
                     (char*)volp->vol_id);
             break;
         }
                     (char*)volp->vol_id);
             break;
         }
@@ -47,5 +53,5 @@ probe_boot_medium()
 
 done:
     vfree(volp);
 
 done:
     vfree(volp);
-    return pos;
+    return dev;
 }
\ No newline at end of file
 }
\ No newline at end of file
index 490b4dfd285cc05a7c7791427a60984f3ebc2204..80d2036b88ab8657e48fa45ab96ab566d3b7f256 100644 (file)
@@ -1235,14 +1235,19 @@ void
 vfs_ref_dnode(struct v_dnode* dnode)
 {
     atomic_fetch_add(&dnode->ref_count, 1);
 vfs_ref_dnode(struct v_dnode* dnode)
 {
     atomic_fetch_add(&dnode->ref_count, 1);
-    mnt_mkbusy(dnode->mnt);
+    
+    if (dnode->mnt) {
+        mnt_mkbusy(dnode->mnt);
+    }
 }
 
 void
 vfs_unref_dnode(struct v_dnode* dnode)
 {
     atomic_fetch_sub(&dnode->ref_count, 1);
 }
 
 void
 vfs_unref_dnode(struct v_dnode* dnode)
 {
     atomic_fetch_sub(&dnode->ref_count, 1);
-    mnt_chillax(dnode->mnt);
+    if (dnode->mnt) {
+        mnt_chillax(dnode->mnt);
+    }
 }
 
 int
 }
 
 int
@@ -1448,7 +1453,7 @@ __DEFINE_LXSYSCALL2(int, fstat, int, fd, struct file_stat*, stat)
                                .st_blksize = vino->sb->blksize};
 
     if (VFS_DEVFILE(vino->itype)) {
                                .st_blksize = vino->sb->blksize};
 
     if (VFS_DEVFILE(vino->itype)) {
-        struct device* rdev = (struct device*)vino->data;
+        struct device* rdev = resolve_device(vino->data);
         if (!rdev || rdev->magic != DEV_STRUCT_MAGIC) {
             errno = EINVAL;
             goto done;
         if (!rdev || rdev->magic != DEV_STRUCT_MAGIC) {
             errno = EINVAL;
             goto done;
index dc06c189a05a3b1ed0fca9875603155f41efe5cc..6860065fa0a5732e9c79130fafff74d7b1d4d0d5 100644 (file)
@@ -34,6 +34,10 @@ extract_next_option(struct extractor* ctx)
     s->len = 0;
     s->pos = i;
 
     s->len = 0;
     s->pos = i;
 
+    if (!ctx->cmdline[i]) {
+        return false;
+    }
+
     while((c = ctx->cmdline[i++])) {
         if (c == ' ') {
             while ((c = ctx->cmdline[i++]) && c == ' ');
     while((c = ctx->cmdline[i++])) {
         if (c == ' ') {
             while ((c = ctx->cmdline[i++]) && c == ' ');
@@ -50,21 +54,17 @@ extract_next_option(struct extractor* ctx)
                 state = PARSE_VAL;
                 s = &ctx->val;
                 s->len = 0;
                 state = PARSE_VAL;
                 s = &ctx->val;
                 s->len = 0;
-                s->pos = i + 1;
+                s->pos = i;
                 continue;
             }
         }
 
                 continue;
             }
         }
 
-        while ((c = ctx->cmdline[i++]) && c != ' ') {
-            s->len++;
-        }
-
-        i--;
+        s->len++;
     }
 
     }
 
-    ctx->pos = i;
+    ctx->pos = i - 1;
 
 
-    return !!c;
+    return true;
 }
 
 #define MAX_KEYSIZE 16
 }
 
 #define MAX_KEYSIZE 16
index b21a7596f97afd39b4ee393d7b1c26d41fff4933..5884e5bb681e5cfc45b12a1025c7adecc1440488 100644 (file)
@@ -1,3 +1,4 @@
+#include <lunaix/types.h>
 #include <lunaix/block.h>
 #include <lunaix/boot_generic.h>
 #include <lunaix/device.h>
 #include <lunaix/block.h>
 #include <lunaix/boot_generic.h>
 #include <lunaix/device.h>
@@ -16,7 +17,7 @@
 #include <lunaix/spike.h>
 #include <lunaix/trace.h>
 #include <lunaix/tty/tty.h>
 #include <lunaix/spike.h>
 #include <lunaix/trace.h>
 #include <lunaix/tty/tty.h>
-#include <lunaix/types.h>
+#include <lunaix/owloysius.h>
 
 #include <hal/acpi/acpi.h>
 #include <hal/intc.h>
 
 #include <hal/acpi/acpi.h>
 #include <hal/intc.h>
@@ -81,14 +82,16 @@ kernel_bootstrap(struct boot_handoff* bhctx)
     block_init();
     sched_init();
 
     block_init();
     sched_init();
 
-    device_onbooot_load();
+    device_onboot_load();
 
     /* the bare metal are now happy, let's get software over with */
 
 
     /* the bare metal are now happy, let's get software over with */
 
-    int errno = 0;
-    if ((errno = vfs_mount_root("ramfs", NULL))) {
-        panickf("Fail to mount root. (errno=%d)", errno);
-    }
+    must_success(vfs_mount_root("ramfs", NULL));
+    must_success(vfs_mount("/dev", "devfs", NULL, 0));
+    
+    invoke_init_function(call_on_boot);
+
+    must_success(vfs_unmount("/dev"));
 
     /* Finish up bootstrapping sequence, we are ready to spawn the root process
      * and start geting into uspace
 
     /* Finish up bootstrapping sequence, we are ready to spawn the root process
      * and start geting into uspace
index 61eb2135282a6fcbc77603f25fb8c752ece98243..59516c5a69d986087dd5f95e32067f7fe59b76d1 100644 (file)
@@ -51,6 +51,7 @@ kprec_put(struct kp_records* recs, int lvl, char* content, size_t len)
     ent->lvl = lvl;
     ent->content = _content;
     ent->time = clock_systime();
     ent->lvl = lvl;
     ent->content = _content;
     ent->time = clock_systime();
+    ent->len = len;
 
     return ent;
 }
\ No newline at end of file
 
     return ent;
 }
\ No newline at end of file
index 1a157fe2e99d8ea3351551fcee6513eeeae3af22..f4183b5be6142214706b419923feed561981bd5d 100644 (file)
@@ -10,6 +10,7 @@ struct kp_entry
     int lvl;
     time_t time;
     char* content;
     int lvl;
     time_t time;
     char* content;
+    size_t len;
 };
 #define KP_ENT_SIZE sizeof(struct kp_entry)
 
 };
 #define KP_ENT_SIZE sizeof(struct kp_entry)
 
index 12c421fd6d252ff48eda3c1345adb96d64e5cab0..310b1f67d1b8ba8da48a3b90fa88255ce42bd392 100644 (file)
@@ -2,8 +2,10 @@
 #include <lunaix/fs/twimap.h>
 #include <lunaix/syscall.h>
 #include <lunaix/syslog.h>
 #include <lunaix/fs/twimap.h>
 #include <lunaix/syscall.h>
 #include <lunaix/syslog.h>
+#include <lunaix/device.h>
+#include <lunaix/owloysius.h>
 
 
-#include <lunaix/lxconsole.h>
+#include <hal/term.h>
 
 #include <klibc/strfmt.h>
 
 
 #include <klibc/strfmt.h>
 
@@ -21,6 +23,7 @@ static struct kp_records kprecs = {
     .max_recs = MAX_KPENT_NUM,
     .kp_ent_wp = &kprecs.kp_ents.ents
 };
     .max_recs = MAX_KPENT_NUM,
     .kp_ent_wp = &kprecs.kp_ents.ents
 };
+export_symbol(debug, kprecs);
 
 static char*
 shift_level(const char* str, int* level)
 
 static char*
 shift_level(const char* str, int* level)
@@ -39,14 +42,14 @@ static inline void
 kprintf_ml(const char* component, int level, const char* fmt, va_list args)
 {
     char* buf = &tmp_buf[MAX_BUFSZ_HLF];
 kprintf_ml(const char* component, int level, const char* fmt, va_list args)
 {
     char* buf = &tmp_buf[MAX_BUFSZ_HLF];
-    ksnprintf(buf, MAX_BUFSZ_HLF, "%s: %s", component, fmt);
+    ksnprintf(buf, MAX_BUFSZ_HLF, "%s: %s\n", component, fmt);
 
     size_t sz = ksnprintfv(tmp_buf, buf, MAX_BUFSZ_HLF, args);
     kprec_put(&kprecs, level, tmp_buf, sz);
 
 
     size_t sz = ksnprintfv(tmp_buf, buf, MAX_BUFSZ_HLF, args);
     kprec_put(&kprecs, level, tmp_buf, sz);
 
-    // FIXME temp measure, get some output
-    console_write_str(tmp_buf);
-    console_write_char('\n');
+    if (likely(sysconsole)) {
+        sysconsole->ops.write(sysconsole, tmp_buf, 0, sz);
+    }
 }
 
 void
 }
 
 void
@@ -61,14 +64,14 @@ kprintf_m(const char* component, const char* fmt, va_list args)
 static void
 __twimap_kprintf_read(struct twimap* map)
 {
 static void
 __twimap_kprintf_read(struct twimap* map)
 {
-    struct kp_records* kprecs = twimap_data(map, struct kp_records*);
+    struct kp_records* __kprecs = twimap_data(map, struct kp_records*);
 
     /*
         XXX we can foreach all records in a single twimap read call,
             as records is monotonic increasing by design.
     */
     struct kp_entry *pos, *n;
 
     /*
         XXX we can foreach all records in a single twimap read call,
             as records is monotonic increasing by design.
     */
     struct kp_entry *pos, *n;
-    llist_for_each(pos, n, kprecs->kp_ent_wp, ents)
+    llist_for_each(pos, n, __kprecs->kp_ent_wp, ents)
     {
         time_t s = pos->time / 1000;
         time_t ms = pos->time % 1000;
     {
         time_t s = pos->time / 1000;
         time_t ms = pos->time % 1000;
@@ -83,6 +86,20 @@ kprintf_mapping_init()
 }
 EXPORT_TWIFS_PLUGIN(kprintf, kprintf_mapping_init);
 
 }
 EXPORT_TWIFS_PLUGIN(kprintf, kprintf_mapping_init);
 
+
+static void kprintf_init() {
+    if (unlikely(!sysconsole)) {
+        return;
+    }
+
+    struct kp_entry *pos, *n;
+    llist_for_each(pos, n, kprecs.kp_ent_wp, ents)
+    {
+        sysconsole->ops.write(sysconsole, pos->content, 0, pos->len);
+    }
+}
+lunaix_initfn(kprintf_init, call_on_postboot);
+
 __DEFINE_LXSYSCALL3(void, syslog, int, level, const char*, fmt, va_list, args)
 {
     kprintf_ml("syslog", level, fmt, args);
 __DEFINE_LXSYSCALL3(void, syslog, int, level, const char*, fmt, va_list, args)
 {
     kprintf_ml("syslog", level, fmt, args);
index 31a100df9c33333749a12e9378e5b79b48573ea4..a9d25a78cf186a27108c93b59e116ac07ca94226 100644 (file)
@@ -1,22 +1,13 @@
-#include <lunaix/block.h>
 #include <lunaix/boot_generic.h>
 #include <lunaix/exec.h>
 #include <lunaix/foptions.h>
 #include <lunaix/fs.h>
 #include <lunaix/fs/probe_boot.h>
 #include <lunaix/fs/twifs.h>
 #include <lunaix/boot_generic.h>
 #include <lunaix/exec.h>
 #include <lunaix/foptions.h>
 #include <lunaix/fs.h>
 #include <lunaix/fs/probe_boot.h>
 #include <lunaix/fs/twifs.h>
-#include <lunaix/lxconsole.h>
-#include <lunaix/mm/cake.h>
-#include <lunaix/mm/pmm.h>
-#include <lunaix/mm/valloc.h>
-#include <lunaix/mm/vmm.h>
-#include <lunaix/peripheral/serial.h>
 #include <lunaix/spike.h>
 #include <lunaix/spike.h>
-#include <lunaix/syscall.h>
 #include <lunaix/syslog.h>
 #include <lunaix/types.h>
 #include <lunaix/syslog.h>
 #include <lunaix/types.h>
-
-#include <sdbg/protocol.h>
+#include <lunaix/owloysius.h>
 
 #include <klibc/string.h>
 
 
 #include <klibc/string.h>
 
@@ -82,9 +73,7 @@ __proc0()
     init_proc_user_space(__current);
 
     if (!mount_bootmedium() || !exec_initd()) {
     init_proc_user_space(__current);
 
     if (!mount_bootmedium() || !exec_initd()) {
-        while (1) {
-            asm("hlt");
-        }
+        FATAL("failed to initd");
         // should not reach
     }
 }
         // should not reach
     }
 }
@@ -93,13 +82,10 @@ void
 init_platform()
 {
     device_postboot_load();
 init_platform()
 {
     device_postboot_load();
+    invoke_init_function(call_on_postboot);
 
     twifs_register_plugins();
 
     // FIXME Re-design needed!!
     // sdbg_init();
 
     twifs_register_plugins();
 
     // FIXME Re-design needed!!
     // sdbg_init();
-
-    // console
-    console_start_flushing();
-    console_flush();
 }
\ No newline at end of file
 }
\ No newline at end of file
index 8b66663a676faa743390e7be02aa2f359c2c65a6..6690f98eb09399cd4ea7b3b1b819ad794659f6eb 100644 (file)
@@ -121,7 +121,7 @@ signal_send(pid_t pid, int signum)
         return -1;
     }
 
         return -1;
     }
 
-send_grp:
+send_grp: ;
     struct proc_info *pos, *n;
     llist_for_each(pos, n, &proc->grp_member, grp_member)
     {
     struct proc_info *pos, *n;
     llist_for_each(pos, n, &proc->grp_member, grp_member)
     {
index fa20202807432f03c6a821dfd4960f9bb16b8ee0..cf2d43c4e15d195b428fa97e7cedc859e882e0ec 100644 (file)
@@ -353,7 +353,7 @@ lxconsole_spawn_ttydev(struct device_def* devdef)
     waitq_init(&lx_reader);
     input_add_listener(__lxconsole_listener);
 
     waitq_init(&lx_reader);
     input_add_listener(__lxconsole_listener);
 
-    device_register(tty_dev, &devdef->class, "tty");
+    register_device(tty_dev, &devdef->class, "vcon");
 
     return 0;
 }
 
     return 0;
 }
@@ -363,4 +363,5 @@ static struct device_def lxconsole_def = {
     .class = DEVCLASSV(DEVIF_NON, DEVFN_TTY, DEV_BUILTIN, 12),
     .init = lxconsole_spawn_ttydev
 };
     .class = DEVCLASSV(DEVIF_NON, DEVFN_TTY, DEV_BUILTIN, 12),
     .init = lxconsole_spawn_ttydev
 };
+// FIXME
 EXPORT_DEVICE(lxconsole, &lxconsole_def, load_onboot);
\ No newline at end of file
 EXPORT_DEVICE(lxconsole, &lxconsole_def, load_onboot);
\ No newline at end of file
index 236edcdc050722330d96eab45ec2eb4f84a94ae8..c91bcb2100e728113e3c6e1f61aaed373ceb6ea5 100644 (file)
@@ -126,6 +126,26 @@ SECTIONS {
 
         PROVIDE(__lga_fs_end = .);
 
 
         PROVIDE(__lga_fs_end = .);
 
+        /* ---- */
+
+        . = ALIGN(8);
+
+        PROVIDE(__lga_lunainit_call_on_boot_start = .);
+        
+        KEEP(*(.lga.lunainit.c_boot));
+
+        PROVIDE(__lga_lunainit_call_on_boot_end = .);
+
+        /* ---- */
+
+        . = ALIGN(8);
+
+        PROVIDE(__lga_lunainit_call_on_postboot_start = .);
+        
+        KEEP(*(.lga.lunainit.c_postboot));
+
+        PROVIDE(__lga_lunainit_call_on_postboot_end = .);
+
     }
 
     .bss BLOCK(4K) : AT ( ADDR(.bss) - 0xC0000000 ) {
     }
 
     .bss BLOCK(4K) : AT ( ADDR(.bss) - 0xC0000000 ) {
index 779a38ee2eaf6ca5b0dbe17feb6de3a1b8923259..4e0ea8662dc7bf4b35d71a6df59e5d922e5f230f 100644 (file)
@@ -74,7 +74,6 @@ instable: CFLAGS := -g -std=gnu99 -ffreestanding $(O) $(W) $(ARCH_OPT) -D__LUNAI
 instable: all
 
 all-debug: bootable-debug
 instable: all
 
 all-debug: bootable-debug
-       @echo "Dumping the disassembled kernel code to $(kbuild_dir)/kdump.txt"
 
 clean:
        @rm -rf $(kbuild_dir) || exit 1
 
 clean:
        @rm -rf $(kbuild_dir) || exit 1
@@ -90,7 +89,7 @@ debug-qemu: all-debug
        @i686-elf-objcopy --only-keep-debug $(kbin) $(kbuild_dir)/kernel.dbg
        @qemu-system-i386 $(call get_qemu_options,$(kimg))
        @sleep 1
        @i686-elf-objcopy --only-keep-debug $(kbin) $(kbuild_dir)/kernel.dbg
        @qemu-system-i386 $(call get_qemu_options,$(kimg))
        @sleep 1
-       @QMPORT=$(QEMU_MON_PORT) gdb -s $(kbuild_dir)/kernel.dbg -ex "target remote localhost:1234"
+       @QMPORT=$(QEMU_MON_PORT) gdb $(kbin) -ex "target remote localhost:1234"
 
 debug-qemu-vscode: all-debug
        @i686-elf-objcopy --only-keep-debug $(kbin) $(kbuild_dir)/kernel.dbg
 
 debug-qemu-vscode: all-debug
        @i686-elf-objcopy --only-keep-debug $(kbin) $(kbuild_dir)/kernel.dbg
index 9326150c3a71ee4941c80a8567bfe1a5c9e97bbb..6882e8d9d64a4bb56b97ca17ed975a5a40e4638d 100644 (file)
@@ -24,7 +24,8 @@ OFLAGS := -fno-gcse\
                  -fno-optimize-strlen\
                  -fno-inline-functions-called-once \
                  -fno-inline-small-functions \
                  -fno-optimize-strlen\
                  -fno-inline-functions-called-once \
                  -fno-inline-small-functions \
-                 -fno-indirect-inlining
+                 -fno-indirect-inlining\
+                 -fno-omit-frame-pointer
 
 CFLAGS := $(ARCH_OPT) -std=gnu99 -MMD $(OFLAGS) $(W)
 
 
 CFLAGS := $(ARCH_OPT) -std=gnu99 -MMD $(OFLAGS) $(W)
 
index 5c0de1d0ec4889198f28c274d5461bf1d21b6c04..22e4fdae2579c38de0b3f6959900bdbb87c4bb09 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/env bash
+#!/bin/bash
 
 SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
 echo "source \"${SCRIPT_DIR}/gdbinit.py\"" >> ~/.gdbinit
\ No newline at end of file
 
 SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
 echo "source \"${SCRIPT_DIR}/gdbinit.py\"" >> ~/.gdbinit
\ No newline at end of file
index 698ea85d80d5b7bc39809b89746f147349f3d615..f7520207efa5db3c705c7d04f7c3a4f5c00a2b24 100644 (file)
@@ -1,8 +1,10 @@
 from .region_dump import MemoryRegionDump
 from .proc_table_dump import ProcessDump, ProcessTableDump
 from .region_dump import MemoryRegionDump
 from .proc_table_dump import ProcessDump, ProcessTableDump
+from .syslog import SysLogDump
 
 
 def load_commands():
     MemoryRegionDump()
     ProcessTableDump()
 
 
 def load_commands():
     MemoryRegionDump()
     ProcessTableDump()
-    ProcessDump()
\ No newline at end of file
+    ProcessDump()
+    SysLogDump()
\ No newline at end of file
index 92ee65d75fb8f9c6a2939799b8c7f80a61cb8c3a..223766bff3eb9c7413366196d741f2195311b989 100644 (file)
@@ -1,11 +1,35 @@
 import gdb
 import gdb
-from .utils import pid_argument
+from .utils import pid_argument, llist_foreach
 
 class MemoryRegionDump(gdb.Command):
     """Dump virtual memory regions associated with a process"""
     def __init__(self) -> None:
         super().__init__("vmrs", gdb.COMMAND_USER)
 
 
 class MemoryRegionDump(gdb.Command):
     """Dump virtual memory regions associated with a process"""
     def __init__(self) -> None:
         super().__init__("vmrs", gdb.COMMAND_USER)
 
+    def region_callback(self, idx, region):
+        print(f"VMR #{idx}:")
+        print( "  0x%x...0x%x [0x%x]"%(
+            region['start'], region['end'], 
+            region['end'] - region['start']))
+        
+        attr = region["attr"]
+        attr_str = []
+        if (attr & (1 << 2)):
+            attr_str.append("R")
+        if (attr & (1 << 3)):
+            attr_str.append("W")
+        if (attr & (1 << 4)):
+            attr_str.append("X")
+        print( "  attr: 0x%x (%s)"%(attr, "".join(attr_str)))
+        
+        file = region["mfile"]
+        if file == 0:
+            print( "  anonymous region")
+        else:
+            print( "  file mapped:")
+            print( "     dnode: %s @0x%x"%(file["dnode"]["name"]["value"].string(), file))
+            print( "     frange: 0x%x+0x%x"%(region["foff"], region["flen"]))
+
     def invoke(self, argument: str, from_tty: bool) -> None:
         argument = pid_argument(argument)
         
     def invoke(self, argument: str, from_tty: bool) -> None:
         argument = pid_argument(argument)
         
@@ -19,31 +43,4 @@ class MemoryRegionDump(gdb.Command):
         
         print("VMRS (pid: %d)"%(pid))
 
         
         print("VMRS (pid: %d)"%(pid))
 
-        i = 0
-        while(val["next"] != head):
-            region = val["next"].cast(region_t)
-            print(f"VMR #{i}:")
-            print( "  0x%x...0x%x [0x%x]"%(
-                region['start'], region['end'], 
-                region['end'] - region['start']))
-            
-            attr = region["attr"]
-            attr_str = []
-            if (attr & (1 << 2)):
-                attr_str.append("R")
-            if (attr & (1 << 3)):
-                attr_str.append("W")
-            if (attr & (1 << 4)):
-                attr_str.append("X")
-            print( "  attr: 0x%x (%s)"%(attr, "".join(attr_str)))
-            
-            file = region["mfile"]
-            if file == 0:
-                print( "  anonymous region")
-            else:
-                print( "  file mapped:")
-                print( "     dnode: %s @0x%x"%(file["dnode"]["name"]["value"].string(), file))
-                print( "     frange: 0x%x+0x%x"%(region["foff"], region["flen"]))
-
-            val = val["next"]
-            i+=1
+        llist_foreach(val, region_t, lambda a,b: self.region_callback(a,b))
diff --git a/lunaix-os/scripts/gdb/lunadbg/symbols.py b/lunaix-os/scripts/gdb/lunadbg/symbols.py
new file mode 100644 (file)
index 0000000..a996501
--- /dev/null
@@ -0,0 +1,21 @@
+import gdb
+from enum import StrEnum
+
+class SymbolDomain(StrEnum):
+    DEBUG = "debug"
+
+class LunaixSymbols:
+    class SymbolAccesser:
+        def __init__(self, sym) -> None:
+            self.sym = f"({sym})"
+        
+        def deref_and_access(self, members):
+            return gdb.parse_and_eval(f"{self.sym}->{members}")
+        
+        def access(self, members):
+            return gdb.parse_and_eval(f"{self.sym}.{members}")
+
+    @staticmethod
+    def exported(domain, sym_name):
+        name = f"*__SYMEXPORT_Z{domain.value}_{sym_name}"
+        return LunaixSymbols.SymbolAccesser(name)
\ No newline at end of file
diff --git a/lunaix-os/scripts/gdb/lunadbg/syslog.py b/lunaix-os/scripts/gdb/lunadbg/syslog.py
new file mode 100644 (file)
index 0000000..307b5f3
--- /dev/null
@@ -0,0 +1,24 @@
+import gdb
+from .symbols import LunaixSymbols, SymbolDomain
+from .utils import llist_foreach
+
+class SysLogDump(gdb.Command):
+    """Dump the system log"""
+    def __init__(self) -> None:
+        super().__init__("syslog", gdb.COMMAND_USER)
+        self.log_level = ["debug", "info", "warn", "error", "fatal"]
+
+    def syslog_entry_callback(self, idx, ent):
+        time = ent["time"]
+        lvl = ent["lvl"]
+        log = ent["content"]
+
+        time_str = "%04d.%03d"%(int(time / 1000), time % 1000)
+        print(f"[{time_str}] <L{self.log_level[lvl]}> {log.string()}")
+
+    def invoke(self, argument: str, from_tty: bool) -> None:
+        log_recs = LunaixSymbols.exported(SymbolDomain.DEBUG, "kprecs")
+        head = log_recs.deref_and_access("kp_ents.ents").address
+
+        ent_type = gdb.lookup_type("struct kp_entry").pointer()
+        llist_foreach(head, ent_type, lambda a,b: self.syslog_entry_callback(a, b))
\ No newline at end of file
index b48adee776a8bc2961c134ef0a8aa84cde6d07a3..43d947a3df4a1342d409aaf68863084ae38203c5 100644 (file)
@@ -1,6 +1,16 @@
+import gdb
 
 def pid_argument(argument):
     if not argument:
         return "__current"
     else:
 
 def pid_argument(argument):
     if not argument:
         return "__current"
     else:
-        return f"sched_ctx._procs[({argument})]"
\ No newline at end of file
+        return f"sched_ctx._procs[({argument})]"
+
+def llist_foreach(head, container_type, cb):
+    c = head
+    i = 0
+    while (c["next"] != head):
+        el = c["next"].cast(container_type)
+        cb(i, el)
+        c = c["next"]
+        i+=1
\ No newline at end of file