[*] initial commit
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
build
|
||||
.env
|
||||
doc/html
|
||||
doc/latex
|
||||
@@ -0,0 +1,28 @@
|
||||
ifeq ($(ARCH),)
|
||||
$(error Target architecture is not specified: $${ARCH})
|
||||
endif
|
||||
|
||||
ifeq ($(ARCH),amd64)
|
||||
CFLAGS+=-DARCH_AMD64
|
||||
endif
|
||||
|
||||
export CC?=$(CC)
|
||||
export CROSSCC?=$(CROSS_COMPILE)$(CC)
|
||||
export LD?=$(LD)
|
||||
export CROSSLD?=$(CROSS_COMPILE)$(LD)
|
||||
export S=$(abspath src)
|
||||
export O?=$(abspath build)
|
||||
|
||||
include conf/make/none.mk
|
||||
include conf/make/$(ARCH).mk
|
||||
|
||||
all: mkdirs _doc $(TARGETS)
|
||||
|
||||
clean:
|
||||
@rm -rf $(O)
|
||||
|
||||
mkdirs:
|
||||
@mkdir -p $(O) $(DIRS)
|
||||
|
||||
_doc:
|
||||
@make -sC doc all
|
||||
@@ -0,0 +1,24 @@
|
||||
all:
|
||||
### Kernel build
|
||||
OBJS+=
|
||||
|
||||
### Kernel loader build
|
||||
TARGETS+=$(O)/loader.elf
|
||||
DIRS+=$(O)/arch/amd64/loader
|
||||
loader_OBJS+=$(O)/arch/amd64/loader/boot.o \
|
||||
$(O)/arch/amd64/loader/loader.o
|
||||
loader_LINKER=$(S)/arch/amd64/loader/link.ld
|
||||
loader_CFLAGS=-ffreestanding -nostdlib -I$(S) -m32
|
||||
loader_LDFLAGS=-nostdlib -melf_i386 -T$(loader_LINKER)
|
||||
|
||||
$(O)/loader.elf: $(loader_OBJS) $(HEADERS) $(loader_LINKER)
|
||||
@printf " LD\t%s\n" $@
|
||||
@$(CROSSLD) $(loader_LDFLAGS) -o $@ $(loader_OBJS)
|
||||
|
||||
$(O)/arch/amd64/loader/%.o: $(S)/arch/amd64/loader/%.S
|
||||
@printf " AS\t%s\n" $@
|
||||
@$(CROSSCC) $(loader_CFLAGS) -c -o $@ $<
|
||||
|
||||
$(O)/arch/amd64/loader/%.o: $(S)/arch/amd64/loader/%.c
|
||||
@printf " CC\t%s\n" $@
|
||||
@$(CROSSCC) $(loader_CFLAGS) -c -o $@ $<
|
||||
@@ -0,0 +1,3 @@
|
||||
HEADERS=$(shell find $(S) -name "*.h")
|
||||
|
||||
OBJS+=
|
||||
@@ -0,0 +1,11 @@
|
||||
PROJECT_NAME = "Yggdrasil Kernel"
|
||||
INPUT = $(S)
|
||||
RECURSIVE = YES
|
||||
EXTRACT_STATIC = YES
|
||||
EXTRACT_PRIVATE = YES
|
||||
EXTRACT_ALL = YES
|
||||
HIDE_UNDOC_MEMBERS = YES
|
||||
HIDE_UNDOC_CLASSES = YES
|
||||
ENABLE_PREPROCESSING = YES
|
||||
HAVE_DOT = NO
|
||||
SORT_MEMBER_DOCS = NO
|
||||
@@ -0,0 +1,2 @@
|
||||
all:
|
||||
S=.. doxygen Doxyfile >/dev/null
|
||||
@@ -0,0 +1,40 @@
|
||||
.set ALIGN, 1 << 0
|
||||
.set MEMINFO, 1 << 1
|
||||
.set FLAGS, ALIGN | MEMINFO
|
||||
.set MAGIC, 0x1BADB002
|
||||
.set CHECKSUM, -(MAGIC + FLAGS)
|
||||
|
||||
.section .multiboot
|
||||
.align 4
|
||||
.long MAGIC
|
||||
.long FLAGS
|
||||
.long CHECKSUM
|
||||
|
||||
.section .bss
|
||||
stack_bottom:
|
||||
.skip 65536
|
||||
stack_top:
|
||||
|
||||
.section .text
|
||||
.global _start
|
||||
_start:
|
||||
// Setup stack
|
||||
mov $stack_top, %esp
|
||||
|
||||
//push %ebx
|
||||
//push %eax
|
||||
|
||||
// Check if the CPU supports long mode
|
||||
mov $0x80000001, %eax
|
||||
cpuid
|
||||
test $(1 << 29), %edx
|
||||
jz .not_supported
|
||||
|
||||
// call loader_entry
|
||||
// add $8, %esp
|
||||
1:
|
||||
cli
|
||||
hlt
|
||||
jmp 1b
|
||||
.not_supported:
|
||||
jmp 1b
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* amd64 loader linker script
|
||||
* (this is not kernel)
|
||||
*/
|
||||
|
||||
ENTRY(_start)
|
||||
|
||||
SECTIONS {
|
||||
. = 0x100000;
|
||||
|
||||
.text : ALIGN(4K)
|
||||
{
|
||||
*(.multiboot)
|
||||
*(.text)
|
||||
}
|
||||
|
||||
.rodata : ALIGN(4K)
|
||||
{
|
||||
*(.rodata)
|
||||
}
|
||||
|
||||
.data : ALIGN(4K)
|
||||
{
|
||||
*(.data)
|
||||
}
|
||||
|
||||
.bss : ALIGN(4K)
|
||||
{
|
||||
*(COMMON)
|
||||
*(.bss)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
void loader_main(void) {
|
||||
while (1) {}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
/// The place where the kernel pages are virtually mapped to
|
||||
#define KERNEL_VIRT_BASE 0xFFFFFF0000000000
|
||||
|
||||
/// Page map level 4
|
||||
typedef uint64_t *mm_pml4_t;
|
||||
/// Page directory pointer table
|
||||
typedef uint64_t *mm_pdpt_t;
|
||||
/// Page directory
|
||||
typedef uint64_t *mm_pagedir_t;
|
||||
/// Page table
|
||||
typedef uint64_t *mm_pagetab_t;
|
||||
|
||||
/// Virtual memory space
|
||||
typedef mm_pml4_t mm_space_t;
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
#pragma once
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(ARCH_AMD64)
|
||||
#include "arch/amd64/mm.h"
|
||||
#endif
|
||||
|
||||
/// An invalid address analogous to NULL
|
||||
#define MM_NADDR ((uintptr_t) -1)
|
||||
|
||||
#define userspace
|
||||
|
||||
/**
|
||||
* @brief Creates a virtual memory space with underlying data structures specific to current
|
||||
* platform
|
||||
*/
|
||||
mm_space_t mm_space_create(void);
|
||||
|
||||
/**
|
||||
* @brief Copies the mappings from one memory space to another preserving the original physical
|
||||
* pages
|
||||
* @param dst - Destination space
|
||||
* @param src - Source space
|
||||
* @param flags - Flags:
|
||||
* * MM_CLONE_FLG_KERNEL - clone kernel-region mappings
|
||||
* * MM_CLONE_FLG_USER - clone userspace mappings
|
||||
* @return 0 on success
|
||||
* @return Non-zero values in case of error
|
||||
*/
|
||||
int mm_space_clone(mm_space_t dst, const mm_space_t src, uint32_t flags);
|
||||
|
||||
/**
|
||||
* @brief Performs a "fork" of a memory space: copies the original mappings to the destination space
|
||||
* and optionally replaces userspace mappings with cloned physical pages
|
||||
* @param dst - Destination space
|
||||
* @param src - Source space
|
||||
* @param flags - Flags:
|
||||
* * MM_CLONE_FLG_KERNEL - clone kernel-region mappings
|
||||
* * MM_CLONE_FLG_USER - clone userspace mappings and underlying physical pages
|
||||
* @return 0 on success
|
||||
* @return Non-zero values in case of error
|
||||
*/
|
||||
int mm_space_fork(mm_space_t dst, const mm_space_t src, uint32_t flags);
|
||||
|
||||
/**
|
||||
* @brief Destroy the virtual memory space and free used resources
|
||||
* @param pd - Virtual memory space
|
||||
*/
|
||||
void mm_space_free(mm_space_t pd);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Map a contiguous physical memory region to a contiguous virtual memory region
|
||||
* @param pd - Memory space
|
||||
* @param virt_base - Beginning of the virtual memory range
|
||||
* @param phys_base - Beginning of the physical memory range
|
||||
* @param count - Count of pages to be mapped
|
||||
* @param flags - Flags:
|
||||
* * MM_FLG_WR - Writable
|
||||
* * MM_FLG_US - Available for userspace
|
||||
* @return 0 on success
|
||||
* @return Non-zero values in case of error
|
||||
*/
|
||||
int mm_map_pages_contiguous(mm_space_t pd, uintptr_t virt_base, uintptr_t phys_base, size_t count, uint32_t flags);
|
||||
|
||||
/**
|
||||
* @brief Map a set of physical pages to a virtual memory region
|
||||
* @param pd - Memory space
|
||||
* @param virt_base - Beginning of the virtual memory range
|
||||
* @param pages - Array of physical pages to be mapped
|
||||
* @param count - Count of pages to be mapped
|
||||
* @param flags - Flags:
|
||||
* * MM_FLG_WR - Writable
|
||||
* * MM_FLG_US - Available for userspace
|
||||
* @return 0 on success
|
||||
* @return Non-zero values in case of error
|
||||
*/
|
||||
int mm_map_range_pages(mm_space_t pd, uintptr_t virt_base, uintptr_t *pages, size_t count, uint32_t flags);
|
||||
|
||||
/**
|
||||
* @brief Remove virtual memory mappings for the specified region, optionally de-allocating the
|
||||
* underlying physical memory pages
|
||||
* @param pd - Memory space
|
||||
* @param virt_base - Beginning of the virtual memory range
|
||||
* @param count - Count of pages to unmap
|
||||
* @param flags - Flags:
|
||||
* * MM_FLG_NOPHYS - Don't de-allocate the physical pages used by the mappings
|
||||
* @return 0 on success
|
||||
* @return Non-zero values in case of error
|
||||
*/
|
||||
int mm_umap_range(mm_space_t pd, uintptr_t virt_base, size_t count, uint32_t flags);
|
||||
|
||||
/**
|
||||
* @brief Translate a virtual memory address to its physical counterpart
|
||||
* @param pd - Memory space
|
||||
* @param virt - Virtual address
|
||||
* @param rflags - (output, nullable) variable to store the mapping's flags:
|
||||
* * MM_FLG_WR
|
||||
* * MM_FLG_US
|
||||
* @return Physical address if the mapping is present
|
||||
* @return MM_NADDR if the mapping is not present
|
||||
*/
|
||||
uintptr_t mm_translate(mm_space_t pd, uintptr_t virt, uint32_t *rflags);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Copy data from kernel memory space to user
|
||||
* @param pd - Memory space
|
||||
* @param dst - Destination address
|
||||
* @param src - Source address
|
||||
* @param count - Number of bytes to transfer
|
||||
* @return Number of bytes copied on success
|
||||
* @return -1 on error
|
||||
*/
|
||||
int mm_memcpy_kernel_to_user(mm_space_t pd, userspace void *dst, const void *src, size_t count);
|
||||
|
||||
/**
|
||||
* @brief Copy data from user memory space to kernel
|
||||
* @param pd - Memory space
|
||||
* @param dst - Destination address
|
||||
* @param src - Source address
|
||||
* @param count - Number of bytes to transfer
|
||||
* @return Number of bytes copied on success
|
||||
* @return -1 on error
|
||||
*/
|
||||
int mm_memcpy_user_to_kernel(mm_space_t pd, void *dst, const userspace void *src, size_t count);
|
||||
Reference in New Issue
Block a user