kernel: implement initcalls and a testing system
This commit is contained in:
@@ -3,11 +3,11 @@ run: $(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 \
|
||||
gdb -tui $(BUILD_DIR)/$(KERNEL_EXEC) \
|
||||
elif commad -v lldb &> /dev/null; then \
|
||||
lldb -- $(BUILD_DIR)/$(KERNEL_EXEC) \
|
||||
gdb -tui $(BUILD_DIR)/$(KERNEL_EXEC).dbg; \
|
||||
elif command -v lldb &> /dev/null; then \
|
||||
lldb -- $(BUILD_DIR)/$(KERNEL_EXEC).dbg; \
|
||||
else \
|
||||
printf "No debuggers available." \
|
||||
endif
|
||||
printf "No debuggers available.\n"; \
|
||||
fi
|
||||
|
||||
@@ -3,6 +3,19 @@
|
||||
|
||||
#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);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <arch/stdcon.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#define PMEM_SIZE 0x2000000
|
||||
#define PMEM_SIZE 0x4000000
|
||||
|
||||
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]);
|
||||
|
||||
object_bootstrap();
|
||||
|
||||
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>
|
||||
|
||||
#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);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <socks/vm.h>
|
||||
#include <socks/printk.h>
|
||||
#include <socks/machine/cpu.h>
|
||||
#include <socks/libc/stdio.h>
|
||||
#include <arch/vgacon.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)
|
||||
}
|
||||
|
||||
.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)
|
||||
{
|
||||
_ehframe = .;
|
||||
|
||||
Reference in New Issue
Block a user