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

View File

@@ -1,6 +1,6 @@
KERNEL_EXEC := socks_kernel KERNEL_EXEC := socks_kernel
ARCH := x86_64 SOCKS_ARCH ?= x86_64
MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
ROOT_DIR := $(patsubst %/,%,$(dir $(MAKEFILE_PATH))) ROOT_DIR := $(patsubst %/,%,$(dir $(MAKEFILE_PATH)))
@@ -13,7 +13,7 @@ BUILD_DIR := build
# Architecture-specific source files # Architecture-specific source files
#################################### ####################################
include arch/$(ARCH)/config.mk include arch/$(SOCKS_ARCH)/config.mk
#################################### ####################################
# Platform-independent kernel source files # Platform-independent kernel source files
@@ -31,10 +31,10 @@ LIBC_SRC_DIRS := stdio string ctype
LIBC_C_FILES := $(foreach dir,$(LIBC_SRC_DIRS),$(wildcard libc/$(dir)/*.c)) LIBC_C_FILES := $(foreach dir,$(LIBC_SRC_DIRS),$(wildcard libc/$(dir)/*.c))
LIBC_OBJ := $(addprefix $(BUILD_DIR)/,$(LIBC_C_FILES:.c=.o)) LIBC_OBJ := $(addprefix $(BUILD_DIR)/,$(LIBC_C_FILES:.c=.o))
BUILD_ID := $(shell tools/generate_build_id.py --arch $(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/$(ARCH)/include -Ilibc/include -Os -Iinclude -Iarch/$(SOCKS_ARCH)/include -Ilibc/include -Os
ASMFLAGS := $(ASMFLAGS) -DBUILD_ID=\"$(BUILD_ID)\" ASMFLAGS := $(ASMFLAGS) -DBUILD_ID=\"$(BUILD_ID)\"
LDFLAGS := $(LDFLAGS) -g -Os LDFLAGS := $(LDFLAGS) -g -Os
@@ -77,7 +77,7 @@ compile-db: $(BUILD_DIR)/compile_commands.json
tools: tools:
@$(MAKE) --no-print-directory -C tools @$(MAKE) --no-print-directory -C tools
include arch/$(ARCH)/extra.mk include arch/$(SOCKS_ARCH)/extra.mk
.PHONY: all tools compile-db $(BUILD_DIR)/compile_commands.json .PHONY: all tools compile-db $(BUILD_DIR)/compile_commands.json

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);
}

View File

@@ -1,7 +1,17 @@
LD := $(SOCKS_ARCH)-elf-gcc
CC := $(SOCKS_ARCH)-elf-gcc
ASM := $(SOCKS_ARCH)-elf-gcc
OBJCOPY := $(SOCKS_ARCH)-elf-objcopy
STRIP := $(SOCKS_ARCH)-elf-strip
CFLAGS := -ffreestanding -nostdlib
ASMFLAGS := $(CFLAGS)
LDFLAGS := -nostdlib
ARCH_CFLAGS := -z max-page-size=0x1000 -m64 -mcmodel=large -mno-red-zone -mno-mmx -mno-sse -mno-sse2 -D_64BIT -DBYTE_ORDER=1234 ARCH_CFLAGS := -z max-page-size=0x1000 -m64 -mcmodel=large -mno-red-zone -mno-mmx -mno-sse -mno-sse2 -D_64BIT -DBYTE_ORDER=1234
ARCH_LDFLAGS := -z max-page-size=0x1000 -T arch/x86_64/layout.ld ARCH_LDFLAGS := -z max-page-size=0x1000 -T arch/x86_64/layout.ld
ARCH_DIR := arch/$(ARCH) ARCH_DIR := arch/$(SOCKS_ARCH)
ARCH_C_FILES := $(wildcard $(ARCH_DIR)/*.c) $(wildcard $(ARCH_DIR)/acpi/*.c) 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_ASM_FILES := $(wildcard $(ARCH_DIR)/*.S) $(wildcard $(ARCH_DIR)/acpi/*.S)

View File

@@ -1,5 +1,5 @@
QEMU := qemu-system-x86_64 QEMU := qemu-system-x86_64
QEMU_FLAGS := -m 64M -smp 4 -cpu qemu64,pdpe1gb QEMU_FLAGS := -m 10M -smp 4 -cpu qemu64,pdpe1gb
ARCH_TEMP_FILES := $(BUILD_DIR)/$(KERNEL_EXEC).elf32 ARCH_TEMP_FILES := $(BUILD_DIR)/$(KERNEL_EXEC).elf32

View File

@@ -9,7 +9,7 @@ extern "C" {
#endif #endif
extern char *strcpy(char *output, const char *input); extern char *strcpy(char *output, const char *input);
extern char *strncpy(char *output, const char *input, unsigned int count); extern char *strncpy(char *output, const char *input, unsigned long count);
extern char *strchrnul(const char *s, int c); extern char *strchrnul(const char *s, int c);
extern char *strchr(const char *s, int c); extern char *strchr(const char *s, int c);
extern size_t lfind(const char *str, const char accept); extern size_t lfind(const char *str, const char accept);
@@ -19,7 +19,7 @@ extern char *strpbrk(const char *s, const char *b);
extern size_t strlen(const char *str); extern size_t strlen(const char *str);
extern char *strrchr(const char *str, int c); extern char *strrchr(const char *str, int c);
extern int strcmp(const char *s1, const char *s2); extern int strcmp(const char *s1, const char *s2);
extern int strncmp(const char *s1, const char *s2, unsigned int n); extern int strncmp(const char *s1, const char *s2, unsigned long n);
extern void *memcpy(void *str1, const void *str2, size_t n); extern void *memcpy(void *str1, const void *str2, size_t n);
extern int memcmp(const void *str1, const void *str2, size_t n); extern int memcmp(const void *str1, const void *str2, size_t n);
extern void *memset(void *str, int c, size_t n); extern void *memset(void *str, int c, size_t n);
@@ -28,7 +28,7 @@ extern char *strdup(const char *src);
extern char *strtok_r(char *str, const char *delim, char **saveptr); extern char *strtok_r(char *str, const char *delim, char **saveptr);
extern char *strcat(char *dest, const char *src); extern char *strcat(char *dest, const char *src);
extern char *strncat(char *dest, const char *src, size_t num); extern char *strncat(char *dest, const char *src, size_t num);
extern void *memchr(const void *ptr, int value, size_t num); extern void *memchr(const void *ptr, int value, unsigned long num);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -1,10 +1,10 @@
#include <stddef.h> #include <stddef.h>
const void *memchr(const void *ptr, int value, size_t num) { void *memchr(const void *ptr, int value, unsigned long num) {
const unsigned char *buf = ptr; const unsigned char *buf = ptr;
unsigned char val = value; unsigned char val = value;
for (size_t i = 0; i < num; i++) { for (unsigned long i = 0; i < num; i++) {
if (buf[i] == val) { if (buf[i] == val) {
return (void *)(buf + i); return (void *)(buf + i);
} }

View File

@@ -8,7 +8,7 @@ int strcmp(const char *s1, const char *s2)
return s1[i] - s2[i]; return s1[i] - s2[i];
} }
int strncmp(const char *s1, const char *s2, unsigned int n) int strncmp(const char *s1, const char *s2, unsigned long n)
{ {
for (; n > 0; s1++, s2++, --n) for (; n > 0; s1++, s2++, --n)
if (*s1 != *s2) if (*s1 != *s2)

View File

@@ -11,10 +11,10 @@ char *strcpy(char *output, const char *input)
return output; return output;
} }
char *strncpy(char *output, const char *input, unsigned int count) char *strncpy(char *output, const char *input, unsigned long count)
{ {
unsigned int size = count; unsigned long size = count;
unsigned int i; unsigned long i;
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
output[i] = input[i]; output[i] = input[i];

View File

@@ -1,10 +0,0 @@
LD := $(ARCH)-elf-gcc
CC := $(ARCH)-elf-gcc
ASM := $(ARCH)-elf-gcc
OBJCOPY := $(ARCH)-elf-objcopy
STRIP := $(ARCH)-elf-strip
CFLAGS := -ffreestanding -nostdlib
ASMFLAGS := $(CFLAGS)
LDFLAGS := -nostdlib