build: add a "user" arch to allow the kernel to run as a program on the host machine

This commit is contained in:
2023-02-25 17:58:23 +00:00
parent 8c87e78797
commit eed73e2414
21 changed files with 286 additions and 26 deletions

18
arch/user/config.mk Normal file
View File

@@ -0,0 +1,18 @@
LD := gcc
CC := gcc
ASM := gcc
OBJCOPY := objcopy
STRIP := strip
CFLAGS :=
ASMFLAGS := $(CFLAGS)
LDFLAGS :=
ARCH_CFLAGS := -D_64BIT
ARCH_LDFLAGS :=
ARCH_DIR := arch/$(SOCKS_ARCH)
ARCH_C_FILES := $(wildcard $(ARCH_DIR)/*.c) $(wildcard $(ARCH_DIR)/acpi/*.c)
ARCH_ASM_FILES := $(wildcard $(ARCH_DIR)/*.S) $(wildcard $(ARCH_DIR)/acpi/*.S)
ARCH_OBJ := $(addprefix $(BUILD_DIR)/,$(ARCH_C_FILES:.c=.o) $(ARCH_ASM_FILES:.S=.o))

24
arch/user/cpu.c Normal file
View File

@@ -0,0 +1,24 @@
#include <unistd.h>
#include <socks/machine/cpu.h>
int ml_init_bootcpu(void)
{
return 0;
}
int ml_cpu_block_init(ml_cpu_block *p)
{
return 0;
}
int ml_cpu_block_use(ml_cpu_block *p)
{
return 0;
}
void ml_halt_cpu(void)
{
while (1) {
sleep(100);
}
}

13
arch/user/extra.mk Normal file
View File

@@ -0,0 +1,13 @@
run: $(BUILD_DIR)/$(KERNEL_EXEC)
@printf " \033[1;93mEXEC\033[0m $<\n"
@$(BUILD_DIR)/$(KERNEL_EXEC)
debug: $(BUILD_DIR)/$(KERNEL_EXEC)
@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) \
else \
printf "No debuggers available." \
endif

27
arch/user/hwlock.c Normal file
View File

@@ -0,0 +1,27 @@
#include <socks/machine/hwlock.h>
#include <socks/compiler.h>
void ml_hwlock_lock(ml_hwlock_t *lck)
{
volatile int q = 0;
while (!__sync_bool_compare_and_swap(lck, 0, 1)) {
q++;
}
}
void ml_hwlock_unlock(ml_hwlock_t *lck)
{
__sync_lock_release(lck);
}
void ml_hwlock_lock_irqsave(ml_hwlock_t *lck, unsigned long *flags)
{
(void)flags;
ml_hwlock_lock(lck);
}
void ml_hwlock_unlock_irqrestore(ml_hwlock_t *lck, unsigned long flags)
{
(void)flags;
ml_hwlock_unlock(lck);
}

View File

@@ -0,0 +1,6 @@
#ifndef ARCH_STDCON_H_
#define ARCH_STDCON_H_
extern void stdcon_init(void);
#endif

View File

@@ -0,0 +1,15 @@
#ifndef SOCKS_USER_CPU_H_
#define SOCKS_USER_CPU_H_
typedef struct ml_cpu_block {
int cpu_reserved;
} ml_cpu_block;
extern int ml_init_bootcpu(void);
extern int ml_cpu_block_init(ml_cpu_block *p);
extern int ml_cpu_block_use(ml_cpu_block *p);
extern void ml_halt_cpu(void);
#endif

View File

@@ -0,0 +1,14 @@
#ifndef SOCKS_USER_HWLOCK_H_
#define SOCKS_USER_HWLOCK_H_
#define ML_HWLOCK_INIT (0)
typedef int ml_hwlock_t;
extern void ml_hwlock_lock(ml_hwlock_t *lck);
extern void ml_hwlock_unlock(ml_hwlock_t *lck);
extern void ml_hwlock_lock_irqsave(ml_hwlock_t *lck, unsigned long *flags);
extern void ml_hwlock_unlock_irqrestore(ml_hwlock_t *lck, unsigned long flags);
#endif

View File

@@ -0,0 +1,8 @@
#ifndef SOCKS_X86_64_INIT_H_
#define SOCKS_X86_64_INIT_H_
#include <stdint.h>
extern int ml_init(uintptr_t arg);
#endif

View File

@@ -0,0 +1,5 @@
#ifndef SOCKS_X86_64_IRQ_H_
#define SOCKS_X86_64_IRQ_H_
#endif

View File

@@ -0,0 +1,9 @@
#ifndef SOCKS_X86_64_PMAP_H_
#define SOCKS_X86_64_PMAP_H_
#include <arch/paging.h>
typedef pml4t_ptr_t ml_pmap_t;
typedef uint64_t ml_pfn_t;
#endif

View File

@@ -0,0 +1,26 @@
#ifndef SOCKS_USER_VM_H_
#define SOCKS_USER_VM_H_
#include <stdint.h>
extern uintptr_t __pagemap_base(void);
extern uintptr_t __pagemap_limit(void);
/* kernel higher-half base virtual address. */
#define VM_KERNEL_VOFFSET (__pagemap_base())
/* direct page-mapping region.
NOTE that these are the maximum bounds of this region.
the actual size depends on the amount of physical
memory present. */
#define VM_PAGEMAP_BASE (__pagemap_base())
#define VM_PAGEMAP_LIMIT (__pagemap_limit())
#define VM_PAGE_SIZE 0x1000
#define VM_PAGE_MASK (VM_PAGE_SIZE-1)
#define VM_PAGE_SHIFT 12
#define VM_PAGE_MIN_ORDER VM_PAGE_4K
#define VM_PAGE_MAX_ORDER VM_PAGE_8M
#endif

68
arch/user/init.c Normal file
View File

@@ -0,0 +1,68 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <socks/init.h>
#include <socks/memblock.h>
#include <socks/vm.h>
#include <socks/object.h>
#include <socks/printk.h>
#include <arch/stdcon.h>
#include <sys/mman.h>
#define PMEM_SIZE 0x2000000
extern void kernel_init(uintptr_t arg);
static void *pmem = NULL;
static void early_vm_init(void)
{
pmem = mmap(NULL, PMEM_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (pmem == MAP_FAILED) {
fprintf(stderr, "arch: cannot map physical memory buffer.");
abort();
}
uintptr_t alloc_start = (uintptr_t)pmem + VM_PAGE_SIZE;
uintptr_t alloc_end = alloc_start + PMEM_SIZE;
memblock_init(alloc_start, alloc_end, (uintptr_t)pmem);
printk("memblock: allocating from [0x%llx-0x%llx]", alloc_start, alloc_end);
}
uintptr_t __pagemap_base(void)
{
return (uintptr_t)pmem;
}
uintptr_t __pagemap_limit(void)
{
return (uintptr_t)pmem + PMEM_SIZE - 1;
}
int ml_init(uintptr_t arg)
{
stdcon_init();
print_kernel_banner();
early_vm_init();
memblock_add(0, PMEM_SIZE);
vm_zone_descriptor_t vm_zones[] = {
{ .zd_id = VM_ZONE_DMA, .zd_node = 0, .zd_name = "dma", .zd_base = 0x00, .zd_limit = 0xffffff },
{ .zd_id = VM_ZONE_NORMAL, .zd_node = 0, .zd_name = "normal", .zd_base = 0x1000000, .zd_limit = UINTPTR_MAX },
};
vm_bootstrap(vm_zones, sizeof vm_zones / sizeof vm_zones[0]);
object_bootstrap();
return 0;
}
int main(int argc, const char **argv)
{
kernel_init(0);
munmap(pmem, PMEM_SIZE);
return 0;
}

27
arch/user/stdcon.c Normal file
View File

@@ -0,0 +1,27 @@
#include <socks/libc/string.h>
#include <socks/libc/ctype.h>
#include <stdint.h>
#include <stdio.h>
#include <socks/console.h>
#include <socks/vm.h>
#include <socks/printk.h>
static void stdcon_write(console_t *con, const char *s, unsigned int len)
{
for (unsigned int i = 0; i < len; i++) {
fputc(s[i], stdout);
}
}
static console_t stdcon = {
.c_name = "stdcon",
.c_flags = CON_BOOT,
.c_write = stdcon_write,
.c_lock = SPIN_LOCK_INIT,
};
void stdcon_init(void)
{
console_register(&stdcon);
early_printk_init(&stdcon);
}