build: add a "user" arch to allow the kernel to run as a program on the host machine
This commit is contained in:
10
Makefile
10
Makefile
@@ -1,6 +1,6 @@
|
||||
KERNEL_EXEC := socks_kernel
|
||||
|
||||
ARCH := x86_64
|
||||
SOCKS_ARCH ?= x86_64
|
||||
|
||||
MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
|
||||
ROOT_DIR := $(patsubst %/,%,$(dir $(MAKEFILE_PATH)))
|
||||
@@ -13,7 +13,7 @@ BUILD_DIR := build
|
||||
# Architecture-specific source files
|
||||
####################################
|
||||
|
||||
include arch/$(ARCH)/config.mk
|
||||
include arch/$(SOCKS_ARCH)/config.mk
|
||||
|
||||
####################################
|
||||
# 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_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 \
|
||||
-Iinclude -Iarch/$(ARCH)/include -Ilibc/include -Os
|
||||
-Iinclude -Iarch/$(SOCKS_ARCH)/include -Ilibc/include -Os
|
||||
|
||||
ASMFLAGS := $(ASMFLAGS) -DBUILD_ID=\"$(BUILD_ID)\"
|
||||
LDFLAGS := $(LDFLAGS) -g -Os
|
||||
@@ -77,7 +77,7 @@ compile-db: $(BUILD_DIR)/compile_commands.json
|
||||
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
|
||||
|
||||
|
||||
18
arch/user/config.mk
Normal file
18
arch/user/config.mk
Normal 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
24
arch/user/cpu.c
Normal 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
13
arch/user/extra.mk
Normal 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
27
arch/user/hwlock.c
Normal 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);
|
||||
}
|
||||
6
arch/user/include/arch/stdcon.h
Normal file
6
arch/user/include/arch/stdcon.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef ARCH_STDCON_H_
|
||||
#define ARCH_STDCON_H_
|
||||
|
||||
extern void stdcon_init(void);
|
||||
|
||||
#endif
|
||||
15
arch/user/include/socks/machine/cpu.h
Normal file
15
arch/user/include/socks/machine/cpu.h
Normal 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
|
||||
14
arch/user/include/socks/machine/hwlock.h
Normal file
14
arch/user/include/socks/machine/hwlock.h
Normal 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
|
||||
8
arch/user/include/socks/machine/init.h
Normal file
8
arch/user/include/socks/machine/init.h
Normal 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
|
||||
5
arch/user/include/socks/machine/irq.h
Normal file
5
arch/user/include/socks/machine/irq.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#ifndef SOCKS_X86_64_IRQ_H_
|
||||
#define SOCKS_X86_64_IRQ_H_
|
||||
|
||||
|
||||
#endif
|
||||
9
arch/user/include/socks/machine/pmap.h
Normal file
9
arch/user/include/socks/machine/pmap.h
Normal 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
|
||||
26
arch/user/include/socks/machine/vm.h
Normal file
26
arch/user/include/socks/machine/vm.h
Normal 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
68
arch/user/init.c
Normal 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
27
arch/user/stdcon.c
Normal 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);
|
||||
}
|
||||
@@ -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_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_ASM_FILES := $(wildcard $(ARCH_DIR)/*.S) $(wildcard $(ARCH_DIR)/acpi/*.S)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
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
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
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 *strchr(const char *s, int c);
|
||||
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 char *strrchr(const char *str, int c);
|
||||
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 int memcmp(const void *str1, const void *str2, 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 *strcat(char *dest, const char *src);
|
||||
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
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#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;
|
||||
unsigned char val = value;
|
||||
|
||||
for (size_t i = 0; i < num; i++) {
|
||||
for (unsigned long i = 0; i < num; i++) {
|
||||
if (buf[i] == val) {
|
||||
return (void *)(buf + i);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ int strcmp(const char *s1, const char *s2)
|
||||
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)
|
||||
if (*s1 != *s2)
|
||||
|
||||
@@ -11,10 +11,10 @@ char *strcpy(char *output, const char *input)
|
||||
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 int i;
|
||||
unsigned long size = count;
|
||||
unsigned long i;
|
||||
for (i = 0; i < size; i++) {
|
||||
output[i] = input[i];
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user