From ef10ed5cd253aa55506c834fe02171a1bcd9a518 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Fri, 17 Feb 2023 19:36:14 +0000 Subject: [PATCH] kernel: add initial object manager definitions --- Makefile | 2 +- arch/x86_64/init.c | 12 +---- include/socks/object.h | 69 ++++++++++++++++++++++++++ obj/namespace.c | 46 +++++++++++++++++ obj/object.c | 109 +++++++++++++++++++++++++++++++++++++++++ obj/set.c | 16 ++++++ 6 files changed, 243 insertions(+), 11 deletions(-) create mode 100644 include/socks/object.h create mode 100644 obj/namespace.c create mode 100644 obj/object.c create mode 100644 obj/set.c diff --git a/Makefile b/Makefile index cdada1e..ab3fd12 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,7 @@ include arch/$(ARCH)/config.mk # Platform-independent kernel source files #################################### -KERNEL_SRC_DIRS := init kernel vm ds util +KERNEL_SRC_DIRS := init kernel vm ds util obj KERNEL_C_FILES := $(foreach dir,$(KERNEL_SRC_DIRS),$(wildcard $(dir)/*.c)) KERNEL_OBJ := $(addprefix $(BUILD_DIR)/,$(KERNEL_C_FILES:.c=.o)) diff --git a/arch/x86_64/init.c b/arch/x86_64/init.c index 8d1cfb2..e40d848 100644 --- a/arch/x86_64/init.c +++ b/arch/x86_64/init.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -45,7 +46,6 @@ int ml_init(uintptr_t arg) print_kernel_banner(); - early_vm_init(); e820_scan(PTR32(mb->mmap_addr), mb->mmap_length); @@ -61,15 +61,7 @@ int ml_init(uintptr_t arg) vm_bootstrap(vm_zones, sizeof vm_zones / sizeof vm_zones[0]); - /* test allocation */ - vm_page_t *p = vm_page_alloc(VM_PAGE_16K, 0); - if (p) { - void *p_ptr = vm_page_get_vaddr(p); - - printk("allocated 16K at %p", p_ptr); - } else { - printk("alloc failed"); - } + object_bootstrap(); return 0; } diff --git a/include/socks/object.h b/include/socks/object.h new file mode 100644 index 0000000..d26a9ca --- /dev/null +++ b/include/socks/object.h @@ -0,0 +1,69 @@ +#ifndef SOCKS_OBJECT_H_ +#define SOCKS_OBJECT_H_ + +#include +#include +#include +#include + +#define OBJECT_MAGIC 0xBADDCAFE + +struct object; + +typedef enum object_type_flags { + OBJTYPE_INIT = 0x01u, +} object_type_flags_t; + +typedef struct object_ops { + kern_status_t(*open)(struct object *obj); + kern_status_t(*close)(struct object *obj); + kern_status_t(*delete)(struct object *obj); + kern_status_t(*query_name)(struct object *obj, char *out, size_t max); + kern_status_t(*parse)(struct object *obj, const char *path, struct object **out); + kern_status_t(*get_name)(struct object *obj, const char *name, struct object **out); + kern_status_t(*get_at)(struct object *obj, size_t at, struct object **out); +} object_ops_t; + +typedef struct object_type { + object_type_flags_t ob_flags; + char ob_name[32]; + unsigned int ob_size; + vm_cache_t ob_cache; + queue_entry_t ob_list; + const object_ops_t *ob_ops; +} object_type_t; + +typedef struct object { + uint32_t ob_magic; + object_type_t *ob_type; + spin_lock_t ob_lock; + unsigned int ob_refcount; + unsigned int ob_handles; +} __aligned(sizeof(long)) object_t; + +typedef struct object_namespace object_namespace_t; + +extern kern_status_t object_bootstrap(void); +extern kern_status_t object_type_register(object_type_t *p); +extern kern_status_t object_type_unregister(object_type_t *p); + +extern object_namespace_t *global_namespace(void); +extern object_namespace_t *object_namespace_create(void); +extern kern_status_t object_namespace_get_object(object_namespace_t *ns, const char *path, object_t **out); +extern kern_status_t object_publish(object_namespace_t *ns, const char *path, object_t *obj); +extern kern_status_t object_unpublish(object_namespace_t *ns, object_t *obj); + +extern object_t *object_create(object_type_t *type); +extern object_t *object_ref(object_t *obj); +extern void object_deref(object_t *obj); +extern void *object_data(object_t *obj); +extern object_t *object_header(void *p); +static inline kern_status_t object_get(const char *path, object_t **out) +{ + return object_namespace_get_object(global_namespace(), path, out); +} + +extern void init_set_objects(void); +extern void init_global_namespace(void); + +#endif diff --git a/obj/namespace.c b/obj/namespace.c new file mode 100644 index 0000000..7c16e72 --- /dev/null +++ b/obj/namespace.c @@ -0,0 +1,46 @@ +#include +#include + +struct object_namespace { + object_t *ns_root; +}; + +static object_type_t ns_type = { + .ob_name = "namespace", + .ob_size = sizeof(object_namespace_t), +}; + +static object_namespace_t *global_ns; + +void init_global_namespace(void) +{ + object_type_register(&ns_type); + global_ns = object_namespace_create(); + printk("obj: initialised global namespace"); +} + +object_namespace_t *global_namespace(void) +{ + return global_ns; +} + +object_namespace_t *object_namespace_create(void) +{ + object_t *ns = object_create(&ns_type); + return object_data(ns); +} + +kern_status_t object_namespace_get_object(object_namespace_t *ns, const char *path, object_t **out) +{ + return KERN_OK; +} + +kern_status_t object_publish(object_namespace_t *ns, const char *path, object_t *obj) +{ + return KERN_OK; +} + +kern_status_t object_unpublish(object_namespace_t *ns, object_t *obj) +{ + return KERN_OK; +} diff --git a/obj/object.c b/obj/object.c new file mode 100644 index 0000000..8a2b446 --- /dev/null +++ b/obj/object.c @@ -0,0 +1,109 @@ +#include +#include +#include + +#define HAS_OP(obj, opname) ((obj)->ob_type->ob_ops && (obj)->ob_type->ob_ops->opname) + +static queue_t object_types; +static spin_lock_t object_types_lock = SPIN_LOCK_INIT; + +kern_status_t object_bootstrap(void) +{ + init_set_objects(); + init_global_namespace(); + return KERN_OK; +} + +kern_status_t object_type_register(object_type_t *p) +{ + unsigned long flags; + spin_lock_irqsave(&object_types_lock, &flags); + queue_push_back(&object_types, &p->ob_list); + spin_unlock_irqrestore(&object_types_lock, flags); + + p->ob_cache.c_name = p->ob_name; + p->ob_cache.c_obj_size = sizeof(object_t) + p->ob_size; + p->ob_cache.c_page_order = VM_PAGE_16K; + + vm_cache_init(&p->ob_cache); + p->ob_flags |= OBJTYPE_INIT; + + return KERN_OK; +} + +kern_status_t object_type_unregister(object_type_t *p) +{ + unsigned long flags; + spin_lock_irqsave(&object_types_lock, &flags); + queue_delete(&object_types, &p->ob_list); + spin_unlock_irqrestore(&object_types_lock, flags); + + return KERN_OK; +} + +object_t *object_create(object_type_t *type) +{ + if (!(type->ob_flags & OBJTYPE_INIT)) { + return NULL; + } + + vm_cache_t *cache = &type->ob_cache; + object_t *obj = vm_cache_alloc(cache, 0); + if (!obj) { + return NULL; + } + + obj->ob_lock = SPIN_LOCK_INIT; + obj->ob_magic = OBJECT_MAGIC; + obj->ob_refcount = 1; + obj->ob_handles = 0; + + return obj; +} + +object_t *object_ref(object_t *obj) +{ + obj->ob_refcount++; + return obj; +} + +void object_deref(object_t *obj) +{ + unsigned long flags; + spin_lock_irqsave(&obj->ob_lock, &flags); + + if (obj->ob_refcount == 0) { + spin_unlock_irqrestore(&obj->ob_lock, flags); + return; + } + + obj->ob_refcount--; + + if (obj->ob_refcount > 0) { + spin_unlock_irqrestore(&obj->ob_lock, flags); + return; + } + + if (HAS_OP(obj, delete)) { + obj->ob_type->ob_ops->delete(obj); + } + + vm_cache_free(&obj->ob_type->ob_cache, obj); + + spin_unlock_irqrestore(&obj->ob_lock, flags); +} + +void *object_data(object_t *obj) +{ + return (char *)obj + sizeof *obj; +} + +object_t *object_header(void *p) +{ + object_t *obj = (object_t *)((char *)p - sizeof *obj); + if (obj->ob_magic != OBJECT_MAGIC) { + return NULL; + } + + return obj; +} diff --git a/obj/set.c b/obj/set.c new file mode 100644 index 0000000..2a8d2c0 --- /dev/null +++ b/obj/set.c @@ -0,0 +1,16 @@ +#include + +struct set { + queue_t s_list; + spin_lock_t s_lock; +}; + +static object_type_t set_type = { + .ob_name = "set", + .ob_size = sizeof(struct set), +}; + +void init_set_objects(void) +{ + object_type_register(&set_type); +}