kernel: implement initcalls and a testing system
This commit is contained in:
6
Makefile
6
Makefile
@@ -19,7 +19,7 @@ include arch/$(SOCKS_ARCH)/config.mk
|
|||||||
# Platform-independent kernel source files
|
# Platform-independent kernel source files
|
||||||
####################################
|
####################################
|
||||||
|
|
||||||
KERNEL_SRC_DIRS := init kernel vm ds util obj
|
KERNEL_SRC_DIRS := init kernel vm ds util obj test
|
||||||
KERNEL_C_FILES := $(foreach dir,$(KERNEL_SRC_DIRS),$(wildcard $(dir)/*.c))
|
KERNEL_C_FILES := $(foreach dir,$(KERNEL_SRC_DIRS),$(wildcard $(dir)/*.c))
|
||||||
KERNEL_OBJ := $(addprefix $(BUILD_DIR)/,$(KERNEL_C_FILES:.c=.o))
|
KERNEL_OBJ := $(addprefix $(BUILD_DIR)/,$(KERNEL_C_FILES:.c=.o))
|
||||||
|
|
||||||
@@ -34,10 +34,10 @@ LIBC_OBJ := $(addprefix $(BUILD_DIR)/,$(LIBC_C_FILES:.c=.o))
|
|||||||
BUILD_ID := $(shell tools/generate_build_id.py --arch $(SOCKS_ARCH))
|
BUILD_ID := $(shell tools/generate_build_id.py --arch $(SOCKS_ARCH))
|
||||||
|
|
||||||
CFLAGS := $(CFLAGS) -DBUILD_ID=\"$(BUILD_ID)\" -g -Wall -Werror -pedantic \
|
CFLAGS := $(CFLAGS) -DBUILD_ID=\"$(BUILD_ID)\" -g -Wall -Werror -pedantic \
|
||||||
-Iinclude -Iarch/$(SOCKS_ARCH)/include -Ilibc/include -Os
|
-Iinclude -Iarch/$(SOCKS_ARCH)/include -Ilibc/include
|
||||||
|
|
||||||
ASMFLAGS := $(ASMFLAGS) -DBUILD_ID=\"$(BUILD_ID)\"
|
ASMFLAGS := $(ASMFLAGS) -DBUILD_ID=\"$(BUILD_ID)\"
|
||||||
LDFLAGS := $(LDFLAGS) -g -Os
|
LDFLAGS := $(LDFLAGS) -g
|
||||||
|
|
||||||
ALL_KERNEL_OBJECT_FILES := $(KERNEL_OBJ) $(ARCH_OBJ) $(LIBC_OBJ)
|
ALL_KERNEL_OBJECT_FILES := $(KERNEL_OBJ) $(ARCH_OBJ) $(LIBC_OBJ)
|
||||||
ALL_KERNEL_DEPS := $(ALL_KERNEL_OBJECT_FILES:.o=.d)
|
ALL_KERNEL_DEPS := $(ALL_KERNEL_OBJECT_FILES:.o=.d)
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ run: $(BUILD_DIR)/$(KERNEL_EXEC)
|
|||||||
|
|
||||||
@$(BUILD_DIR)/$(KERNEL_EXEC)
|
@$(BUILD_DIR)/$(KERNEL_EXEC)
|
||||||
|
|
||||||
debug: $(BUILD_DIR)/$(KERNEL_EXEC)
|
debug: $(BUILD_DIR)/$(KERNEL_EXEC) $(BUILD_DIR)/$(KERNEL_EXEC).dbg
|
||||||
@if command -v gdb &> /dev/null; then \
|
@if command -v gdb &> /dev/null; then \
|
||||||
gdb -tui $(BUILD_DIR)/$(KERNEL_EXEC) \
|
gdb -tui $(BUILD_DIR)/$(KERNEL_EXEC).dbg; \
|
||||||
elif commad -v lldb &> /dev/null; then \
|
elif command -v lldb &> /dev/null; then \
|
||||||
lldb -- $(BUILD_DIR)/$(KERNEL_EXEC) \
|
lldb -- $(BUILD_DIR)/$(KERNEL_EXEC).dbg; \
|
||||||
else \
|
else \
|
||||||
printf "No debuggers available." \
|
printf "No debuggers available.\n"; \
|
||||||
endif
|
fi
|
||||||
|
|||||||
@@ -3,6 +3,19 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define __X2(x) #x
|
||||||
|
#define __X(x) __X2(x)
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#define __define_initcall(fn, id) \
|
||||||
|
static initcall_t __initcall_##fn##id __used \
|
||||||
|
__section("__DATA,__initcall" __X(id) ".init") = (fn)
|
||||||
|
#else
|
||||||
|
#define __define_initcall(fn, id) \
|
||||||
|
static initcall_t __initcall_##fn##id __used \
|
||||||
|
__section("initcall" __X(id) "_init") = (fn)
|
||||||
|
#endif
|
||||||
|
|
||||||
extern int ml_init(uintptr_t arg);
|
extern int ml_init(uintptr_t arg);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#include <arch/stdcon.h>
|
#include <arch/stdcon.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
|
||||||
#define PMEM_SIZE 0x2000000
|
#define PMEM_SIZE 0x4000000
|
||||||
|
|
||||||
extern void kernel_init(uintptr_t arg);
|
extern void kernel_init(uintptr_t arg);
|
||||||
|
|
||||||
@@ -56,6 +56,7 @@ int ml_init(uintptr_t arg)
|
|||||||
vm_bootstrap(vm_zones, sizeof vm_zones / sizeof vm_zones[0]);
|
vm_bootstrap(vm_zones, sizeof vm_zones / sizeof vm_zones[0]);
|
||||||
|
|
||||||
object_bootstrap();
|
object_bootstrap();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
96
arch/user/initcall.c
Normal file
96
arch/user/initcall.c
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
#include <socks/init.h>
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
extern char __start_initcall0[] __asm("section$start$__DATA$__initcall0.init");
|
||||||
|
extern char __stop_initcall0[] __asm("section$end$__DATA$__initcall0.init");
|
||||||
|
extern char __start_initcall1[] __asm("section$start$__DATA$__initcall1.init");
|
||||||
|
extern char __stop_initcall1[] __asm("section$end$__DATA$__initcall1.init");
|
||||||
|
extern char __start_initcall2[] __asm("section$start$__DATA$__initcall2.init");
|
||||||
|
extern char __stop_initcall2[] __asm("section$end$__DATA$__initcall2.init");
|
||||||
|
extern char __start_initcall3[] __asm("section$start$__DATA$__initcall3.init");
|
||||||
|
extern char __stop_initcall3[] __asm("section$end$__DATA$__initcall3.init");
|
||||||
|
extern char __start_initcall4[] __asm("section$start$__DATA$__initcall4.init");
|
||||||
|
extern char __stop_initcall4[] __asm("section$end$__DATA$__initcall4.init");
|
||||||
|
extern char __start_initcall5[] __asm("section$start$__DATA$__initcall5.init");
|
||||||
|
extern char __stop_initcall5[] __asm("section$end$__DATA$__initcall5.init");
|
||||||
|
extern char __start_initcall6[] __asm("section$start$__DATA$__initcall6.init");
|
||||||
|
extern char __stop_initcall6[] __asm("section$end$__DATA$__initcall6.init");
|
||||||
|
extern char __start_initcall7[] __asm("section$start$__DATA$__initcall7.init");
|
||||||
|
extern char __stop_initcall7[] __asm("section$end$__DATA$__initcall7.init");
|
||||||
|
extern char __start_initcall8[] __asm("section$start$__DATA$__initcall8.init");
|
||||||
|
extern char __stop_initcall8[] __asm("section$end$__DATA$__initcall8.init");
|
||||||
|
#else
|
||||||
|
extern char __start_initcall0_init[];
|
||||||
|
extern char __stop_initcall0_init[];
|
||||||
|
extern char __start_initcall1_init[];
|
||||||
|
extern char __stop_initcall1_init[];
|
||||||
|
extern char __start_initcall2_init[];
|
||||||
|
extern char __stop_initcall2_init[];
|
||||||
|
extern char __start_initcall3_init[];
|
||||||
|
extern char __stop_initcall3_init[];
|
||||||
|
extern char __start_initcall4_init[];
|
||||||
|
extern char __stop_initcall4_init[];
|
||||||
|
extern char __start_initcall5_init[];
|
||||||
|
extern char __stop_initcall5_init[];
|
||||||
|
extern char __start_initcall6_init[];
|
||||||
|
extern char __stop_initcall6_init[];
|
||||||
|
extern char __start_initcall7_init[];
|
||||||
|
extern char __stop_initcall7_init[];
|
||||||
|
extern char __start_initcall8_init[];
|
||||||
|
extern char __stop_initcall8_init[];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static initcall_t *initcall_start[] = {
|
||||||
|
(initcall_t *)__start_initcall0_init,
|
||||||
|
(initcall_t *)__start_initcall1_init,
|
||||||
|
(initcall_t *)__start_initcall2_init,
|
||||||
|
(initcall_t *)__start_initcall3_init,
|
||||||
|
(initcall_t *)__start_initcall4_init,
|
||||||
|
(initcall_t *)__start_initcall5_init,
|
||||||
|
(initcall_t *)__start_initcall6_init,
|
||||||
|
(initcall_t *)__start_initcall7_init,
|
||||||
|
(initcall_t *)__start_initcall8_init,
|
||||||
|
};
|
||||||
|
|
||||||
|
static initcall_t *initcall_end[] = {
|
||||||
|
(initcall_t *)__stop_initcall0_init,
|
||||||
|
(initcall_t *)__stop_initcall1_init,
|
||||||
|
(initcall_t *)__stop_initcall2_init,
|
||||||
|
(initcall_t *)__stop_initcall3_init,
|
||||||
|
(initcall_t *)__stop_initcall4_init,
|
||||||
|
(initcall_t *)__stop_initcall5_init,
|
||||||
|
(initcall_t *)__stop_initcall6_init,
|
||||||
|
(initcall_t *)__stop_initcall7_init,
|
||||||
|
(initcall_t *)__stop_initcall8_init,
|
||||||
|
};
|
||||||
|
|
||||||
|
int start_initlevel(int level)
|
||||||
|
{
|
||||||
|
if (initcall_start[level] == initcall_end[level]) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (initcall_t *fn = initcall_start[level]; fn < initcall_end[level]; fn++) {
|
||||||
|
int res = (*fn)();
|
||||||
|
|
||||||
|
if (res != 0) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* define a stub initcall for each initlevel to ensure
|
||||||
|
the corresponding exec section gets created */
|
||||||
|
static int stub_initcall(void) { return 0; }
|
||||||
|
|
||||||
|
__define_initcall(stub_initcall, 0);
|
||||||
|
__define_initcall(stub_initcall, 1);
|
||||||
|
__define_initcall(stub_initcall, 2);
|
||||||
|
__define_initcall(stub_initcall, 3);
|
||||||
|
__define_initcall(stub_initcall, 4);
|
||||||
|
__define_initcall(stub_initcall, 5);
|
||||||
|
__define_initcall(stub_initcall, 6);
|
||||||
|
__define_initcall(stub_initcall, 7);
|
||||||
|
__define_initcall(stub_initcall, 8);
|
||||||
@@ -3,6 +3,13 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define __X2(x) #x
|
||||||
|
#define __X(x) __X2(x)
|
||||||
|
|
||||||
|
#define __define_initcall(fn, id) \
|
||||||
|
static initcall_t __initcall_##fn##id __used \
|
||||||
|
__section(".initcall" __X(id) ".init") = (fn)
|
||||||
|
|
||||||
extern int ml_init(uintptr_t arg);
|
extern int ml_init(uintptr_t arg);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <socks/vm.h>
|
#include <socks/vm.h>
|
||||||
#include <socks/printk.h>
|
#include <socks/printk.h>
|
||||||
#include <socks/machine/cpu.h>
|
#include <socks/machine/cpu.h>
|
||||||
|
#include <socks/libc/stdio.h>
|
||||||
#include <arch/vgacon.h>
|
#include <arch/vgacon.h>
|
||||||
#include <arch/acpi.h>
|
#include <arch/acpi.h>
|
||||||
|
|
||||||
|
|||||||
41
arch/x86_64/initcall.c
Normal file
41
arch/x86_64/initcall.c
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#include <socks/init.h>
|
||||||
|
|
||||||
|
extern char __initcall0_start[];
|
||||||
|
extern char __initcall1_start[];
|
||||||
|
extern char __initcall2_start[];
|
||||||
|
extern char __initcall3_start[];
|
||||||
|
extern char __initcall4_start[];
|
||||||
|
extern char __initcall5_start[];
|
||||||
|
extern char __initcall6_start[];
|
||||||
|
extern char __initcall7_start[];
|
||||||
|
extern char __initcall8_start[];
|
||||||
|
extern char __initcall_end[];
|
||||||
|
|
||||||
|
static initcall_t *m_init_func_levels[] = {
|
||||||
|
(initcall_t *)__initcall0_start,
|
||||||
|
(initcall_t *)__initcall1_start,
|
||||||
|
(initcall_t *)__initcall2_start,
|
||||||
|
(initcall_t *)__initcall3_start,
|
||||||
|
(initcall_t *)__initcall4_start,
|
||||||
|
(initcall_t *)__initcall5_start,
|
||||||
|
(initcall_t *)__initcall6_start,
|
||||||
|
(initcall_t *)__initcall7_start,
|
||||||
|
(initcall_t *)__initcall8_start,
|
||||||
|
(initcall_t *)__initcall_end,
|
||||||
|
};
|
||||||
|
|
||||||
|
int start_initlevel(int level) {
|
||||||
|
if (m_init_func_levels[level] == m_init_func_levels[level + 1]) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (initcall_t *fn = m_init_func_levels[level]; fn < m_init_func_levels[level + 1]; fn++) {
|
||||||
|
int res = (*fn)();
|
||||||
|
|
||||||
|
if (res != 0) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -31,6 +31,28 @@ SECTIONS {
|
|||||||
*(.data)
|
*(.data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.initcall ALIGN(4K) : AT(ADDR(.initcall) - KERNEL_VMA) {
|
||||||
|
__initcall0_start = .;
|
||||||
|
*(.initcall0.init)
|
||||||
|
__initcall1_start = .;
|
||||||
|
*(.initcall1.init)
|
||||||
|
__initcall2_start = .;
|
||||||
|
*(.initcall2.init)
|
||||||
|
__initcall3_start = .;
|
||||||
|
*(.initcall3.init)
|
||||||
|
__initcall4_start = .;
|
||||||
|
*(.initcall4.init)
|
||||||
|
__initcall5_start = .;
|
||||||
|
*(.initcall5.init)
|
||||||
|
__initcall6_start = .;
|
||||||
|
*(.initcall6.init)
|
||||||
|
__initcall7_start = .;
|
||||||
|
*(.initcall7.init)
|
||||||
|
__initcall8_start = .;
|
||||||
|
*(.initcall8.init)
|
||||||
|
__initcall_end = .;
|
||||||
|
}
|
||||||
|
|
||||||
.eh_frame ALIGN(4K) : AT(ADDR(.eh_frame) - KERNEL_VMA)
|
.eh_frame ALIGN(4K) : AT(ADDR(.eh_frame) - KERNEL_VMA)
|
||||||
{
|
{
|
||||||
_ehframe = .;
|
_ehframe = .;
|
||||||
|
|||||||
@@ -2,32 +2,32 @@
|
|||||||
#define SOCKS_INIT_H_
|
#define SOCKS_INIT_H_
|
||||||
|
|
||||||
#include <socks/compiler.h>
|
#include <socks/compiler.h>
|
||||||
|
#include <socks/machine/init.h>
|
||||||
|
|
||||||
typedef int (*initcall_t)(void);
|
typedef int (*initcall_t)(void);
|
||||||
|
|
||||||
#define __INITLEVEL_EARLY 0
|
#define INITLEVEL_EARLY 0
|
||||||
#define __INITLEVEL_CORE 1
|
#define INITLEVEL_CORE 1
|
||||||
#define __INITLEVEL_POSTCORE 2
|
#define INITLEVEL_POSTCORE 2
|
||||||
#define __INITLEVEL_ARCH 3
|
#define INITLEVEL_ARCH 3
|
||||||
#define __INITLEVEL_SUBSYS 4
|
#define INITLEVEL_SUBSYS 4
|
||||||
#define __INITLEVEL_ROOTFS 5
|
#define INITLEVEL_ROOTFS 5
|
||||||
#define __INITLEVEL_DEVICE 6
|
#define INITLEVEL_DEVICE 6
|
||||||
#define __INITLEVEL_LATE 7
|
#define INITLEVEL_LATE 7
|
||||||
|
#define INITLEVEL_TESTS 8
|
||||||
|
|
||||||
#define __define_initcall(fn, id) \
|
#define early_initcall(fn) __define_initcall(fn, INITLEVEL_EARLY)
|
||||||
static initcall_t __initcall_##fn##id __used \
|
#define core_initcall(fn) __define_initcall(fn, INITLEVEL_CORE)
|
||||||
__section(".initcall" #id ".init") = (fn)
|
#define postcore_initcall(fn) __define_initcall(fn, INITLEVEL_POSTCORE)
|
||||||
|
#define arch_initcall(fn) __define_initcall(fn, INITLEVEL_ARCH)
|
||||||
#define early_initcall(fn) __define_initcall(fn, __INITLEVEL_EARLY)
|
#define subsys_initcall(fn) __define_initcall(fn, INITLEVEL_SUBSYS)
|
||||||
#define core_initcall(fn) __define_initcall(fn, __INITLEVEL_CORE)
|
#define rootfs_initcall(fn) __define_initcall(fn, INITLEVEL_ROOTFS)
|
||||||
#define postcore_initcall(fn) __define_initcall(fn, __INITLEVEL_POSTCORE)
|
#define device_initcall(fn) __define_initcall(fn, INITLEVEL_DEVICE)
|
||||||
#define arch_initcall(fn) __define_initcall(fn, __INITLEVEL_ARCH)
|
#define late_initcall(fn) __define_initcall(fn, INITLEVEL_LATE)
|
||||||
#define subsys_initcall(fn) __define_initcall(fn, __INITLEVEL_SUBSYS)
|
#define test_initcall(fn) __define_initcall(fn, INITLEVEL_TESTS)
|
||||||
#define rootfs_initcall(fn) __define_initcall(fn, __INITLEVEL_ROOTFS)
|
|
||||||
#define device_initcall(fn) __define_initcall(fn, __INITLEVEL_DEVICE)
|
|
||||||
#define late_initcall(fn) __define_initcall(fn, __INITLEVEL_LATE)
|
|
||||||
|
|
||||||
extern void print_kernel_banner(void);
|
extern void print_kernel_banner(void);
|
||||||
extern int do_initcalls(void);
|
extern int do_initcalls(void);
|
||||||
|
extern int start_initlevel(int level);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
6
include/socks/test.h
Normal file
6
include/socks/test.h
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef SOCKS_TEST_H_
|
||||||
|
#define SOCKS_TEST_H_
|
||||||
|
|
||||||
|
extern int run_all_tests(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
#include <socks/init.h>
|
#include <socks/init.h>
|
||||||
|
|
||||||
|
|
||||||
int do_initcalls(void)
|
int do_initcalls(void)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <socks/init.h>
|
#include <socks/init.h>
|
||||||
|
#include <socks/test.h>
|
||||||
#include <socks/printk.h>
|
#include <socks/printk.h>
|
||||||
#include <socks/machine/init.h>
|
#include <socks/machine/init.h>
|
||||||
#include <socks/machine/cpu.h>
|
#include <socks/machine/cpu.h>
|
||||||
@@ -17,5 +18,7 @@ void kernel_init(uintptr_t arg)
|
|||||||
{
|
{
|
||||||
ml_init(arg);
|
ml_init(arg);
|
||||||
|
|
||||||
|
run_all_tests();
|
||||||
|
|
||||||
ml_halt_cpu();
|
ml_halt_cpu();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,10 @@
|
|||||||
#include <socks/libc/string.h>
|
#include <socks/libc/string.h>
|
||||||
|
|
||||||
size_t strlen(const char *str) {
|
size_t strlen(const char *str) {
|
||||||
if (!str) {
|
size_t res = 0;
|
||||||
return 0;
|
while (str[res]) {
|
||||||
}
|
res++;
|
||||||
|
}
|
||||||
|
|
||||||
size_t res = 0;
|
return res;
|
||||||
while (str[res]) {
|
|
||||||
res++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|||||||
79
test/obj.c
Normal file
79
test/obj.c
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
#include <socks/object.h>
|
||||||
|
#include <socks/printk.h>
|
||||||
|
#include <socks/init.h>
|
||||||
|
#include <socks/libc/stdio.h>
|
||||||
|
|
||||||
|
struct test_object {
|
||||||
|
char name[OBJECT_NAME_MAX];
|
||||||
|
};
|
||||||
|
|
||||||
|
static kern_status_t test_query_name(object_t *obj, char out[OBJECT_NAME_MAX])
|
||||||
|
{
|
||||||
|
struct test_object *test = object_data(obj);
|
||||||
|
strncpy(out, test->name, OBJECT_NAME_MAX);
|
||||||
|
out[OBJECT_NAME_MAX - 1] = 0;
|
||||||
|
return KERN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static object_type_t test_type = {
|
||||||
|
.ob_name = "test",
|
||||||
|
.ob_size = sizeof(struct test_object),
|
||||||
|
.ob_ops = {
|
||||||
|
.query_name = test_query_name,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static void print_object_tree(object_t *obj, int depth)
|
||||||
|
{
|
||||||
|
char msg[256] = {0};
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < depth; i++) {
|
||||||
|
len += snprintf(msg + len, sizeof msg - len, " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
char name[OBJECT_NAME_MAX];
|
||||||
|
object_query_name(obj, name);
|
||||||
|
|
||||||
|
len += snprintf(msg + len, sizeof msg - len, "%s", name);
|
||||||
|
printk(msg);
|
||||||
|
|
||||||
|
object_t *child = NULL;
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
kern_status_t status = object_get_child_at(obj, i, &child);
|
||||||
|
if (status != KERN_OK) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
print_object_tree(child, depth + 1);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int run_obj_tests(void)
|
||||||
|
{
|
||||||
|
object_type_register(&test_type);
|
||||||
|
|
||||||
|
object_t *test_obj = object_create(&test_type);
|
||||||
|
struct test_object *test = object_data(test_obj);
|
||||||
|
snprintf(test->name, sizeof test->name, "object1");
|
||||||
|
kern_status_t status = object_publish(global_namespace(), "/misc/objects", test_obj);
|
||||||
|
if (status == KERN_OK) {
|
||||||
|
printk("published object at /misc/objects/object1");
|
||||||
|
} else {
|
||||||
|
printk("publish failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (object_publish(global_namespace(), "/misc/objects/object1", test_obj) == KERN_OK) {
|
||||||
|
printk("second publish succeeded but shouldn't have");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
print_object_tree(object_header(global_namespace()), 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
test_initcall(run_obj_tests);
|
||||||
8
test/test.c
Normal file
8
test/test.c
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#include <socks/init.h>
|
||||||
|
#include <socks/printk.h>
|
||||||
|
|
||||||
|
int run_all_tests(void)
|
||||||
|
{
|
||||||
|
printk("############ RUNNING KERNEL TESTS ############");
|
||||||
|
return start_initlevel(INITLEVEL_TESTS);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user