From: Minep Date: Sun, 10 Dec 2023 13:50:32 +0000 (+0000) Subject: feat: owloysius - dynamic init function invocator X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/commitdiff_plain/7b8a1bcad75628f9add4590db2bb9b8e418ee8eb?ds=sidebyside feat: owloysius - dynamic init function invocator 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=` boot command line fix: trying to delete mount point when unmounted. fix: ensure frame-point always included regardless optimization level chore: edit readme d --- diff --git a/README.md b/README.md index 6e528bd..213f213 100644 --- a/README.md +++ b/README.md @@ -157,6 +157,7 @@ qemu-img create -f vdi machine/disk0.vdi 128M + `vmrs [pid]` 列举进程``的内存区域图(Memory Regions),如果``未指定,则默认为正在运行的进程(smp=1)。 + `proc [pid]` 打印进程``的进程控制块状态,如果``未指定,则默认为正在运行的进程(smp=1)。 + `proc_table` 列举所有非终止的进程以及他们的状态。 ++ `syslog` 打印到目前为止的系统日志。 该插件可以通过运行以下命令来进行安装: diff --git a/lunaix-os/GRUB_TEMPLATE b/lunaix-os/GRUB_TEMPLATE index 176f426..c33d45f 100644 --- a/lunaix-os/GRUB_TEMPLATE +++ b/lunaix-os/GRUB_TEMPLATE @@ -2,6 +2,6 @@ default=0 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 diff --git a/lunaix-os/arch/i386/boot/mb_parser.c b/lunaix-os/arch/i386/boot/mb_parser.c index 64a4051..aa9a5f0 100644 --- a/lunaix-os/arch/i386/boot/mb_parser.c +++ b/lunaix-os/arch/i386/boot/mb_parser.c @@ -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; + bhctx->kexec.cmdline = buffer; return slen; } diff --git a/lunaix-os/hal/char/devnull.c b/lunaix-os/hal/char/devnull.c index 747e05f..410f3ba 100644 --- a/lunaix-os/hal/char/devnull.c +++ b/lunaix-os/hal/char/devnull.c @@ -38,7 +38,7 @@ pdev_nulldev_init(struct device_def* def) 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; } diff --git a/lunaix-os/hal/char/devzero.c b/lunaix-os/hal/char/devzero.c index 9c0b6c7..77885d7 100644 --- a/lunaix-os/hal/char/devzero.c +++ b/lunaix-os/hal/char/devzero.c @@ -24,7 +24,7 @@ pdev_zerodev_init(struct device_def* def) 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; } diff --git a/lunaix-os/hal/char/serial.c b/lunaix-os/hal/char/serial.c index 1dbdb68..528f141 100644 --- a/lunaix-os/hal/char/serial.c +++ b/lunaix-os/hal/char/serial.c @@ -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); - 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); diff --git a/lunaix-os/hal/gfxa/gfxm.c b/lunaix-os/hal/gfxa/gfxm.c index 26532a2..27d1531 100644 --- a/lunaix-os/hal/gfxa/gfxm.c +++ b/lunaix-os/hal/gfxa/gfxm.c @@ -10,7 +10,7 @@ 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); @@ -92,7 +92,7 @@ gfxm_alloc_adapter(void* hw_obj) } 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 }; @@ -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); - device_register(gfxa->dev, &gfxa_class, "gfxa%d", gfxa->id); + register_device(gfxa->dev, &gfxa_class, "gfxa%d", gfxa->id); } struct gfxa* diff --git a/lunaix-os/hal/pci.c b/lunaix-os/hal/pci.c index 9a3c581..8a5048b 100644 --- a/lunaix-os/hal/pci.c +++ b/lunaix-os/hal/pci.c @@ -22,7 +22,7 @@ LOG_MODULE("PCI") 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 @@ -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_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); - device_register(&device->dev, &pci_def.class, "%x", loc); + register_device(&device->dev, &pci_def.class, "%x", loc); pci_def.class.variant++; return device; diff --git a/lunaix-os/hal/rng/rngx86.c b/lunaix-os/hal/rng/rngx86.c index 5c12ca6..2dd6d08 100644 --- a/lunaix-os/hal/rng/rngx86.c +++ b/lunaix-os/hal/rng/rngx86.c @@ -35,7 +35,7 @@ pdev_randdev_init(struct device_def* devdef) 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; } diff --git a/lunaix-os/hal/rtc/rtc_device.c b/lunaix-os/hal/rtc/rtc_device.c index b322103..ad06343 100644 --- a/lunaix-os/hal/rtc/rtc_device.c +++ b/lunaix-os/hal/rtc/rtc_device.c @@ -91,7 +91,7 @@ hwrtc_register(struct devclass* class, struct hwrtc* rtc) } 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 diff --git a/lunaix-os/hal/term/console.c b/lunaix-os/hal/term/console.c new file mode 100644 index 0000000..4410358 --- /dev/null +++ b/lunaix-os/hal/term/console.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include +#include +#include + +#include + +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 diff --git a/lunaix-os/hal/term/term.c b/lunaix-os/hal/term/term.c index 0c404a5..160b629 100644 --- a/lunaix-os/hal/term/term.c +++ b/lunaix-os/hal/term/term.c @@ -18,6 +18,8 @@ static struct term_lcntl* line_controls[] = {[ANSI_LCNTL] = 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) { @@ -47,7 +49,7 @@ term_exec_cmd(struct device* dev, u32_t req, va_list args) 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; @@ -121,7 +123,10 @@ tdev_do_write(struct device* dev, void* buf, size_t offset, size_t len) term_flush(tdev); } } - + + if (!rbuffer_empty(deref(current))) { + term_flush(tdev); + } 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 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) { @@ -170,15 +184,12 @@ term_create(struct device* chardev, char* suffix) 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 { - 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; } diff --git a/lunaix-os/hal/timer/timer_device.c b/lunaix-os/hal/timer/timer_device.c index c5341be..3e47fac 100644 --- a/lunaix-os/hal/timer/timer_device.c +++ b/lunaix-os/hal/timer/timer_device.c @@ -62,5 +62,5 @@ hwtimer_init(u32_t hertz, void* tick_callback) 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 diff --git a/lunaix-os/includes/hal/term.h b/lunaix-os/includes/hal/term.h index 84da769..6b76db3 100644 --- a/lunaix-os/includes/hal/term.h +++ b/lunaix-os/includes/hal/term.h @@ -53,6 +53,8 @@ struct term speed_t iospeed; }; +extern struct device* sysconsole; + struct term* term_create(struct device* chardev, char* suffix); diff --git a/lunaix-os/includes/lunaix/compiler.h b/lunaix-os/includes/lunaix/compiler.h index 3ee6fa0..7581978 100644 --- a/lunaix-os/includes/lunaix/compiler.h +++ b/lunaix-os/includes/lunaix/compiler.h @@ -1,14 +1,15 @@ #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 must_emit __attribute__((used)) #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 export_symbol(domain, symbol)\ + typeof(symbol)* must_emit __SYMEXPORT_Z##domain##_##symbol = &(symbol) + inline static void noret spin() { diff --git a/lunaix-os/includes/lunaix/device.h b/lunaix-os/includes/lunaix/device.h index 1844590..05b8639 100644 --- a/lunaix-os/includes/lunaix/device.h +++ b/lunaix-os/includes/lunaix/device.h @@ -85,34 +85,76 @@ .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_IFCAT 0x2 // a device category (as device groupping) #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; - 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; - struct hstr name; - struct devident ident; - - u32_t dev_uid; int dev_type; - char name_val[DEVICE_NAME_SIZE]; + struct devident ident; void* underlay; /* -- polling -- */ @@ -168,6 +210,30 @@ struct device_def 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 @@ -187,61 +253,64 @@ 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 -device_setname(struct device* dev, char* fmt, ...); +device_setname(struct device_meta* dev, char* fmt, ...); 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, - struct device* parent, + struct device_meta* parent, 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); } -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); } -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); } -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 -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); -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); @@ -258,7 +327,7 @@ device_scan_drivers(); /*------ Load hooks ------*/ void -device_onbooot_load(); +device_onboot_load(); void device_postboot_load(); diff --git a/lunaix-os/includes/lunaix/device_num.h b/lunaix-os/includes/lunaix/device_num.h index 9011da3..b59c857 100644 --- a/lunaix-os/includes/lunaix/device_num.h +++ b/lunaix-os/includes/lunaix/device_num.h @@ -89,6 +89,7 @@ #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 diff --git a/lunaix-os/includes/lunaix/fs.h b/lunaix-os/includes/lunaix/fs.h index 1fe37f1..0e2169e 100644 --- a/lunaix-os/includes/lunaix/fs.h +++ b/lunaix-os/includes/lunaix/fs.h @@ -98,6 +98,7 @@ extern struct v_dnode* vfs_sysroot; struct filesystem { + struct llist_header fs_flat; 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 index 0000000..7948066 --- /dev/null +++ b/lunaix-os/includes/lunaix/owloysius.h @@ -0,0 +1,16 @@ +#ifndef __LUNAIX_OWLOYSIUS_H +#define __LUNAIX_OWLOYSIUS_H + +#include + +#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 */ diff --git a/lunaix-os/includes/lunaix/spike.h b/lunaix-os/includes/lunaix/spike.h index 9e2d427..f73fbe1 100644 --- a/lunaix-os/includes/lunaix/spike.h +++ b/lunaix-os/includes/lunaix/spike.h @@ -68,14 +68,24 @@ #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) \ - 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__); diff --git a/lunaix-os/kernel/block/block.c b/lunaix-os/kernel/block/block.c index a2242ad..bf83b5f 100644 --- a/lunaix-os/kernel/block/block.c +++ b/lunaix-os/kernel/block/block.c @@ -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 device* blk_parent_dev; +static struct device_cat* blk_parent_dev; int free_slot = 0; @@ -299,7 +299,7 @@ __block_register(struct block_dev* bdev) 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; @@ -307,7 +307,7 @@ __block_register(struct block_dev* bdev) 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); @@ -342,7 +342,7 @@ blk_mount_part(struct block_dev* bdev, 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 diff --git a/lunaix-os/kernel/debug/trace.c b/lunaix-os/kernel/debug/trace.c index 8c5c180..1c90919 100644 --- a/lunaix-os/kernel/debug/trace.c +++ b/lunaix-os/kernel/debug/trace.c @@ -104,6 +104,10 @@ trace_walkback(struct trace_record* tb_buffer, i++; } + if (!valid_fp((ptr_t)frame)) { + frame = NULL; + } + if (last_fp) { *last_fp = (ptr_t)frame; } diff --git a/lunaix-os/kernel/device/devdb.c b/lunaix-os/kernel/device/devdb.c index 236ac5a..eb9e612 100644 --- a/lunaix-os/kernel/device/devdb.c +++ b/lunaix-os/kernel/device/devdb.c @@ -10,7 +10,7 @@ static DECLARE_HASHTABLE(dev_registry, 32); 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) @@ -97,7 +97,7 @@ device_definitions_byif(int if_type) #define device_load_on_stage(stage) __device_load_on_stage(stage) void -device_onbooot_load() +device_onboot_load() { 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, - "%xh:%d \"%s\" %s\n", + "%08xh:%04d \"%s\" %s\n", def->class.fn_grp, def->class.device, def->name, diff --git a/lunaix-os/kernel/device/devfs.c b/lunaix-os/kernel/device/devfs.c index f586add..350bbd6 100644 --- a/lunaix-os/kernel/device/devfs.c +++ b/lunaix-os/kernel/device/devfs.c @@ -13,9 +13,9 @@ devfs_read(struct v_inode* inode, void* buffer, size_t len, size_t fpos) { 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; } @@ -27,9 +27,9 @@ devfs_write(struct v_inode* inode, void* buffer, size_t len, size_t fpos) { 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; } @@ -41,9 +41,9 @@ devfs_read_page(struct v_inode* inode, void* buffer, size_t fpos) { 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; } @@ -55,9 +55,9 @@ devfs_write_page(struct v_inode* inode, void* buffer, size_t fpos) { 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; } @@ -65,13 +65,18 @@ devfs_write_page(struct v_inode* inode, void* buffer, size_t fpos) } int -devfs_get_itype(struct device* dev) +devfs_get_itype(struct device_meta* dm) { 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; - 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; @@ -82,19 +87,16 @@ devfs_get_itype(struct device* dev) } 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 -devfs_mknod(struct v_dnode* dnode, struct device* dev) +devfs_mknod(struct v_dnode* dnode, struct device_meta* 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) { - 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; } + 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; } + dctx->read_complete_callback( dctx, dev->name.value, dev->name.len, devfs_get_dtype(dev)); return 1; diff --git a/lunaix-os/kernel/device/device.c b/lunaix-os/kernel/device/device.c index cce51b1..b88f8f6 100644 --- a/lunaix-os/kernel/device/device.c +++ b/lunaix-os/kernel/device/device.c @@ -18,7 +18,7 @@ static volatile u32_t devid = 0; 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); @@ -28,52 +28,61 @@ device_setname_vargs(struct device* dev, char* fmt, va_list args) } 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) { - 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->dev_uid = devid++; + devm->dev_uid = devid++; - struct device* parent = dev->parent; + struct device_meta* parent = devm->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 { - llist_append(&root_list, &dev->siblings); + llist_append(&root_list, &devm->siblings); } 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, - struct device* parent, + struct device_meta* parent, 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* -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)); @@ -86,8 +95,38 @@ device_alloc(struct device* parent, u32_t type, void* underlay) 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 -device_setname(struct device* dev, char* fmt, ...) +device_setname(struct device_meta* dev, char* fmt, ...) { va_list args; va_start(args, fmt); @@ -97,26 +136,41 @@ device_setname(struct device* dev, char* fmt, ...) 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); - 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; } -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; - struct device *pos, *n; + struct device_meta *pos, *n; 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; } -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 device *pos, *n; + struct device_meta *pos, *n; 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; } -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); @@ -152,17 +206,17 @@ device_getbyname(struct device* root_dev, const char* name, size_t len) } void -device_remove(struct device* dev) +device_remove(struct device_meta* 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 device *pos, *n; + struct device_meta *pos, *n; 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; } +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* -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 @@ -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; - if (dev->magic != DEV_STRUCT_MAGIC) { + if (valid_device_subtype_ref(dev, DEV_STRUCT)) { errno &= ENODEV; goto done; } diff --git a/lunaix-os/kernel/device/input.c b/lunaix-os/kernel/device/input.c index 3d974a7..6ced39d 100644 --- a/lunaix-os/kernel/device/input.c +++ b/lunaix-os/kernel/device/input.c @@ -9,7 +9,7 @@ static DEFINE_LLIST(listener_chain); -static struct device* input_devcat = NULL; +static struct device_cat* input_devcat = NULL; void input_init() @@ -80,10 +80,10 @@ input_add_device(struct devclass* class, char* 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; diff --git a/lunaix-os/kernel/device/poll.c b/lunaix-os/kernel/device/poll.c index bf7edd7..ca204a2 100644 --- a/lunaix-os/kernel/device/poll.c +++ b/lunaix-os/kernel/device/poll.c @@ -37,7 +37,7 @@ __do_poll(struct poll_info* pinfo, int pld) 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 @@ -111,7 +111,7 @@ __do_poll_all(struct poll_info* pinfo) return 0; } -#define fd2dev(fd) device_cast((fd)->file->inode->data) +#define fd2dev(fd) resolve_device((fd)->file->inode->data) static int __alloc_pld() diff --git a/lunaix-os/kernel/fs/fsm.c b/lunaix-os/kernel/fs/fsm.c index ca1221c..9505838 100644 --- a/lunaix-os/kernel/fs/fsm.c +++ b/lunaix-os/kernel/fs/fsm.c @@ -13,9 +13,13 @@ #include #include +#include +#include + #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 @@ -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); + llist_append(&fs_flatlist, &fs->fs_flat); } 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; -} \ 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 diff --git a/lunaix-os/kernel/fs/mount.c b/lunaix-os/kernel/fs/mount.c index 084a400..96cc741 100644 --- a/lunaix-os/kernel/fs/mount.c +++ b/lunaix-os/kernel/fs/mount.c @@ -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); } - + 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); - vfs_d_free(mnt->mnt_point); + atomic_fetch_sub(&mnt->mnt_point->ref_count, 1); vfree(mnt); return errno; diff --git a/lunaix-os/kernel/fs/probe_boot.c b/lunaix-os/kernel/fs/probe_boot.c index 77b4dff..3cb4049 100644 --- a/lunaix-os/kernel/fs/probe_boot.c +++ b/lunaix-os/kernel/fs/probe_boot.c @@ -10,24 +10,30 @@ LOG_MODULE("PROBE") 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); - struct device *pos, *n; + struct device* dev = NULL; + struct device_meta *pos, *n; llist_for_each(pos, n, &block_cat->children, siblings) { + dev = resolve_device(pos); + if (!dev) { + continue; + } + 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", - 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; } @@ -37,9 +43,9 @@ probe_boot_medium() 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; } @@ -47,5 +53,5 @@ probe_boot_medium() done: vfree(volp); - return pos; + return dev; } \ No newline at end of file diff --git a/lunaix-os/kernel/fs/vfs.c b/lunaix-os/kernel/fs/vfs.c index 490b4df..80d2036 100644 --- a/lunaix-os/kernel/fs/vfs.c +++ b/lunaix-os/kernel/fs/vfs.c @@ -1235,14 +1235,19 @@ void 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); - mnt_chillax(dnode->mnt); + if (dnode->mnt) { + mnt_chillax(dnode->mnt); + } } 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)) { - 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; diff --git a/lunaix-os/kernel/kcmd.c b/lunaix-os/kernel/kcmd.c index dc06c18..6860065 100644 --- a/lunaix-os/kernel/kcmd.c +++ b/lunaix-os/kernel/kcmd.c @@ -34,6 +34,10 @@ extract_next_option(struct extractor* ctx) 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 == ' '); @@ -50,21 +54,17 @@ extract_next_option(struct extractor* ctx) state = PARSE_VAL; s = &ctx->val; s->len = 0; - s->pos = i + 1; + s->pos = i; 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 diff --git a/lunaix-os/kernel/kinit.c b/lunaix-os/kernel/kinit.c index b21a759..5884e5b 100644 --- a/lunaix-os/kernel/kinit.c +++ b/lunaix-os/kernel/kinit.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -16,7 +17,7 @@ #include #include #include -#include +#include #include #include @@ -81,14 +82,16 @@ kernel_bootstrap(struct boot_handoff* bhctx) block_init(); sched_init(); - device_onbooot_load(); + device_onboot_load(); /* 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 diff --git a/lunaix-os/kernel/kprint/kp_records.c b/lunaix-os/kernel/kprint/kp_records.c index 61eb213..59516c5 100644 --- a/lunaix-os/kernel/kprint/kp_records.c +++ b/lunaix-os/kernel/kprint/kp_records.c @@ -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->len = len; return ent; } \ No newline at end of file diff --git a/lunaix-os/kernel/kprint/kp_records.h b/lunaix-os/kernel/kprint/kp_records.h index 1a157fe..f4183b5 100644 --- a/lunaix-os/kernel/kprint/kp_records.h +++ b/lunaix-os/kernel/kprint/kp_records.h @@ -10,6 +10,7 @@ struct kp_entry int lvl; time_t time; char* content; + size_t len; }; #define KP_ENT_SIZE sizeof(struct kp_entry) diff --git a/lunaix-os/kernel/kprint/kprintf.c b/lunaix-os/kernel/kprint/kprintf.c index 12c421f..310b1f6 100644 --- a/lunaix-os/kernel/kprint/kprintf.c +++ b/lunaix-os/kernel/kprint/kprintf.c @@ -2,8 +2,10 @@ #include #include #include +#include +#include -#include +#include #include @@ -21,6 +23,7 @@ static struct kp_records kprecs = { .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) @@ -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]; - 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); - // 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 @@ -61,14 +64,14 @@ kprintf_m(const char* component, const char* fmt, va_list args) 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; - 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; @@ -83,6 +86,20 @@ 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); diff --git a/lunaix-os/kernel/proc0.c b/lunaix-os/kernel/proc0.c index 31a100d..a9d25a7 100644 --- a/lunaix-os/kernel/proc0.c +++ b/lunaix-os/kernel/proc0.c @@ -1,22 +1,13 @@ -#include #include #include #include #include #include #include -#include -#include -#include -#include -#include -#include #include -#include #include #include - -#include +#include #include @@ -82,9 +73,7 @@ __proc0() init_proc_user_space(__current); if (!mount_bootmedium() || !exec_initd()) { - while (1) { - asm("hlt"); - } + FATAL("failed to initd"); // should not reach } } @@ -93,13 +82,10 @@ void init_platform() { device_postboot_load(); + invoke_init_function(call_on_postboot); twifs_register_plugins(); // FIXME Re-design needed!! // sdbg_init(); - - // console - console_start_flushing(); - console_flush(); } \ No newline at end of file diff --git a/lunaix-os/kernel/process/signal.c b/lunaix-os/kernel/process/signal.c index 8b66663..6690f98 100644 --- a/lunaix-os/kernel/process/signal.c +++ b/lunaix-os/kernel/process/signal.c @@ -121,7 +121,7 @@ signal_send(pid_t pid, int signum) return -1; } -send_grp: +send_grp: ; struct proc_info *pos, *n; llist_for_each(pos, n, &proc->grp_member, grp_member) { diff --git a/lunaix-os/kernel/tty/lxconsole.c b/lunaix-os/kernel/tty/lxconsole.c index fa20202..cf2d43c 100644 --- a/lunaix-os/kernel/tty/lxconsole.c +++ b/lunaix-os/kernel/tty/lxconsole.c @@ -353,7 +353,7 @@ lxconsole_spawn_ttydev(struct device_def* devdef) 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; } @@ -363,4 +363,5 @@ static struct device_def lxconsole_def = { .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 diff --git a/lunaix-os/link/linker.ld b/lunaix-os/link/linker.ld index 236edcd..c91bcb2 100644 --- a/lunaix-os/link/linker.ld +++ b/lunaix-os/link/linker.ld @@ -126,6 +126,26 @@ SECTIONS { 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 ) { diff --git a/lunaix-os/makefile b/lunaix-os/makefile index 779a38e..4e0ea86 100644 --- a/lunaix-os/makefile +++ b/lunaix-os/makefile @@ -74,7 +74,6 @@ instable: CFLAGS := -g -std=gnu99 -ffreestanding $(O) $(W) $(ARCH_OPT) -D__LUNAI instable: all all-debug: bootable-debug - @echo "Dumping the disassembled kernel code to $(kbuild_dir)/kdump.txt" 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 - @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 diff --git a/lunaix-os/makeinc/toolchain.mkinc b/lunaix-os/makeinc/toolchain.mkinc index 9326150..6882e8d 100644 --- a/lunaix-os/makeinc/toolchain.mkinc +++ b/lunaix-os/makeinc/toolchain.mkinc @@ -24,7 +24,8 @@ OFLAGS := -fno-gcse\ -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) diff --git a/lunaix-os/scripts/gdb/install_lunadbg b/lunaix-os/scripts/gdb/install_lunadbg index 5c0de1d..22e4fda 100644 --- a/lunaix-os/scripts/gdb/install_lunadbg +++ b/lunaix-os/scripts/gdb/install_lunadbg @@ -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 diff --git a/lunaix-os/scripts/gdb/lunadbg/commands.py b/lunaix-os/scripts/gdb/lunadbg/commands.py index 698ea85..f752020 100644 --- a/lunaix-os/scripts/gdb/lunadbg/commands.py +++ b/lunaix-os/scripts/gdb/lunadbg/commands.py @@ -1,8 +1,10 @@ from .region_dump import MemoryRegionDump from .proc_table_dump import ProcessDump, ProcessTableDump +from .syslog import SysLogDump def load_commands(): MemoryRegionDump() ProcessTableDump() - ProcessDump() \ No newline at end of file + ProcessDump() + SysLogDump() \ No newline at end of file diff --git a/lunaix-os/scripts/gdb/lunadbg/region_dump.py b/lunaix-os/scripts/gdb/lunadbg/region_dump.py index 92ee65d..223766b 100644 --- a/lunaix-os/scripts/gdb/lunadbg/region_dump.py +++ b/lunaix-os/scripts/gdb/lunadbg/region_dump.py @@ -1,11 +1,35 @@ 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) + 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) @@ -19,31 +43,4 @@ class MemoryRegionDump(gdb.Command): 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 index 0000000..a996501 --- /dev/null +++ b/lunaix-os/scripts/gdb/lunadbg/symbols.py @@ -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 index 0000000..307b5f3 --- /dev/null +++ b/lunaix-os/scripts/gdb/lunadbg/syslog.py @@ -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}] {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 diff --git a/lunaix-os/scripts/gdb/lunadbg/utils.py b/lunaix-os/scripts/gdb/lunadbg/utils.py index b48adee..43d947a 100644 --- a/lunaix-os/scripts/gdb/lunadbg/utils.py +++ b/lunaix-os/scripts/gdb/lunadbg/utils.py @@ -1,6 +1,16 @@ +import gdb 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