Added build system and some core boot files
This commit is contained in:
149
.gitignore
vendored
149
.gitignore
vendored
@@ -1,50 +1,59 @@
|
||||
# Created by https://www.gitignore.io/api/c++,vim,linux,cmake,windows
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/vim,macos,windows,linux,rust,c
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=vim,macos,windows,linux,rust,c
|
||||
|
||||
### C++ ###
|
||||
### C ###
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
|
||||
# Linker output
|
||||
*.ilk
|
||||
*.map
|
||||
*.exp
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
# Libraries
|
||||
*.lib
|
||||
*.a
|
||||
*.la
|
||||
*.lo
|
||||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
|
||||
### CMake ###
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
CMakeScripts
|
||||
Testing
|
||||
Makefile
|
||||
cmake_install.cmake
|
||||
install_manifest.txt
|
||||
compile_commands.json
|
||||
CTestTestfile.cmake
|
||||
build
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
*.su
|
||||
*.idb
|
||||
*.pdb
|
||||
|
||||
# Kernel Module Compile Results
|
||||
*.mod*
|
||||
*.cmd
|
||||
.tmp_versions/
|
||||
modules.order
|
||||
Module.symvers
|
||||
Mkfile.old
|
||||
dkms.conf
|
||||
|
||||
### Linux ###
|
||||
*~
|
||||
@@ -61,25 +70,86 @@ build
|
||||
# .nfs files are created when an open file is removed but is still being accessed
|
||||
.nfs*
|
||||
|
||||
### macOS ###
|
||||
# General
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
### macOS Patch ###
|
||||
# iCloud generated files
|
||||
*.icloud
|
||||
|
||||
### Rust ###
|
||||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
debug/
|
||||
target/
|
||||
|
||||
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
|
||||
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
|
||||
Cargo.lock
|
||||
|
||||
# These are backup files generated by rustfmt
|
||||
**/*.rs.bk
|
||||
|
||||
# MSVC Windows builds of rustc generate these, which store debugging information
|
||||
|
||||
### Vim ###
|
||||
# swap
|
||||
.sw[a-p]
|
||||
.*.sw[a-p]
|
||||
# session
|
||||
# Swap
|
||||
[._]*.s[a-v][a-z]
|
||||
!*.svg # comment out if you don't need vector files
|
||||
[._]*.sw[a-p]
|
||||
[._]s[a-rt-v][a-z]
|
||||
[._]ss[a-gi-z]
|
||||
[._]sw[a-p]
|
||||
|
||||
# Session
|
||||
Session.vim
|
||||
# temporary
|
||||
Sessionx.vim
|
||||
|
||||
# Temporary
|
||||
.netrwhist
|
||||
# auto-generated tag files
|
||||
# Auto-generated tag files
|
||||
tags
|
||||
# Persistent undo
|
||||
[._]*.un~
|
||||
|
||||
### Windows ###
|
||||
# Windows thumbnail cache files
|
||||
Thumbs.db
|
||||
Thumbs.db:encryptable
|
||||
ehthumbs.db
|
||||
ehthumbs_vista.db
|
||||
|
||||
# Dump file
|
||||
*.stackdump
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
[Dd]esktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
@@ -87,15 +157,14 @@ $RECYCLE.BIN/
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/vim,macos,windows,linux,rust,c
|
||||
|
||||
# End of https://www.gitignore.io/api/c++,vim,linux,cmake,windows
|
||||
|
||||
.DS_Store
|
||||
build
|
||||
.clang-format
|
||||
.ccls-cache
|
||||
|
||||
44
Makefile
Normal file
44
Makefile
Normal file
@@ -0,0 +1,44 @@
|
||||
KERNEL_EXEC := socks_kernel
|
||||
|
||||
ARCH := x86_64
|
||||
|
||||
include tools/make/gcc-cross-compile.mk
|
||||
include arch/$(ARCH)/config.mk
|
||||
|
||||
BUILDDIR := build
|
||||
|
||||
ARCH_C_FILES := $(wildcard arch/$(ARCH)/*.c)
|
||||
ARCH_ASM_FILES := $(wildcard arch/$(ARCH)/*.S)
|
||||
ARCH_OBJ := $(addprefix $(BUILDDIR)/,$(ARCH_C_FILES:.c=.o) $(ARCH_ASM_FILES:.S=.o))
|
||||
|
||||
SRC_DIRS := core
|
||||
KERNEL_C_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.c))
|
||||
KERNEL_OBJ := $(addprefix $(BUILDDIR)/,$(KERNEL_C_FILES:.c=.o))
|
||||
|
||||
$(BUILDDIR)/$(KERNEL_EXEC): $(KERNEL_OBJ) $(ARCH_OBJ)
|
||||
@echo " \033[1;36mLINK\033[0m \033[1m$@\033[0m"
|
||||
@mkdir -p $(@D)
|
||||
@$(LD) $^ -o $@ $(LDFLAGS) $(ARCH_LDFLAGS)
|
||||
|
||||
$(BUILDDIR)/%.o: %.S
|
||||
@echo " \033[1;32mASM\033[0m $<"
|
||||
@mkdir -p $(@D)
|
||||
@$(ASM) $< -o $@ -c $(ASMFLAGS) $(ARCH_ASMFLAGS)
|
||||
|
||||
$(BUILDDIR)/%.o: %.c
|
||||
@echo " \033[1;32mCC\033[0m $<"
|
||||
@mkdir -p $(@D)
|
||||
@$(CC) $< -o $@ -c $(CFLAGS) $(ARCH_CFLAGS)
|
||||
|
||||
clean:
|
||||
@echo " \033[1;93mCLEAN\033[0m Deleting build artefacts."
|
||||
@rm -rf $(BUILDDIR)
|
||||
|
||||
|
||||
all: $(BUILDDIR)/$(KERNEL_EXEC)
|
||||
|
||||
include arch/$(ARCH)/extra.mk
|
||||
|
||||
.PHONY: all
|
||||
|
||||
.INTERMEDIATE: $(ARCH_TEMP_FILES)
|
||||
2
arch/x86_64/config.mk
Normal file
2
arch/x86_64/config.mk
Normal file
@@ -0,0 +1,2 @@
|
||||
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
|
||||
21
arch/x86_64/extra.mk
Normal file
21
arch/x86_64/extra.mk
Normal file
@@ -0,0 +1,21 @@
|
||||
QEMU := qemu-system-x86_64
|
||||
|
||||
ARCH_TEMP_FILES := $(BUILDDIR)/$(KERNEL_EXEC).elf32
|
||||
|
||||
# qemu refuses to boot ELF64 binaries. this creates a patched version of the kernel
|
||||
# binary to trick qemu into thinking its an ELF32.
|
||||
# this has no effect on the kernel itself; the x86_64 kernel's
|
||||
# entry point is 32-bit machine code.
|
||||
$(BUILDDIR)/$(KERNEL_EXEC).elf32: $(BUILDDIR)/$(KERNEL_EXEC)
|
||||
@cp $(BUILDDIR)/$(KERNEL_EXEC) $(BUILDDIR)/$(KERNEL_EXEC).elf32
|
||||
@printf '\x03\x00' | dd of=$(BUILDDIR)/$(KERNEL_EXEC).elf32 bs=1 seek=18 count=2 conv=notrunc 2> /dev/null
|
||||
|
||||
run: $(BUILDDIR)/$(KERNEL_EXEC) $(BUILDDIR)/$(KERNEL_EXEC).elf32
|
||||
@echo " \033[1;93mBOOT\033[0m $<"
|
||||
|
||||
@$(QEMU) -kernel $(BUILDDIR)/$(KERNEL_EXEC).elf32
|
||||
|
||||
debug: $(BUILDDIR)/$(KERNEL_EXEC) $(BUILDDIR)/$(KERNEL_EXEC).elf32
|
||||
@echo " \033[1;93mBOOT\033[0m $<"
|
||||
|
||||
@$(QEMU) -kernel $(BUILDDIR)/$(KERNEL_EXEC).elf32 -S -s
|
||||
56
arch/x86_64/layout.ld
Normal file
56
arch/x86_64/layout.ld
Normal file
@@ -0,0 +1,56 @@
|
||||
ENTRY(_start)
|
||||
|
||||
KERNEL_LMA = 1M;
|
||||
KERNEL_VMA = 0xFFFFFFFF80000000;
|
||||
|
||||
SECTIONS {
|
||||
. = KERNEL_LMA;
|
||||
|
||||
.boot.text ALIGN(4K) : {
|
||||
*(.boot.text)
|
||||
*(.boot.rodata)
|
||||
}
|
||||
|
||||
.boot.bss ALIGN(4K) : {
|
||||
*(.boot.bss)
|
||||
}
|
||||
|
||||
. += KERNEL_VMA;
|
||||
|
||||
.text ALIGN(4K) : AT(ADDR(.text) - KERNEL_VMA)
|
||||
{
|
||||
*(.text)
|
||||
}
|
||||
|
||||
.data ALIGN(4K) : AT(ADDR(.data) - KERNEL_VMA)
|
||||
{
|
||||
_data = .;
|
||||
*(.data)
|
||||
}
|
||||
|
||||
.eh_frame ALIGN(4K) : AT(ADDR(.eh_frame) - KERNEL_VMA)
|
||||
{
|
||||
_ehframe = .;
|
||||
*(.eh_frame)
|
||||
}
|
||||
|
||||
.bss ALIGN(4K) : AT(ADDR(.bss) - KERNEL_VMA)
|
||||
{
|
||||
_bss = .;
|
||||
*(.bss)
|
||||
|
||||
*/
|
||||
/*
|
||||
* You usually need to include generated COMMON symbols
|
||||
* under kernel BSS section or use gcc's -fno-common
|
||||
*/
|
||||
*(COMMON)
|
||||
}
|
||||
|
||||
_end = .;
|
||||
|
||||
/DISCARD/ :
|
||||
{
|
||||
*(.comment)
|
||||
}
|
||||
}
|
||||
213
arch/x86_64/start_32.S
Normal file
213
arch/x86_64/start_32.S
Normal file
@@ -0,0 +1,213 @@
|
||||
.set ALIGN, 1 << 0
|
||||
.set MEMINFO, 1 << 1
|
||||
.set VIDMODE, 1 << 2
|
||||
.set FLAGS, ALIGN | MEMINFO
|
||||
.set MAGIC, 0x1BADB002
|
||||
.set CHECKSUM, -(MAGIC + FLAGS)
|
||||
|
||||
/* the amount of memory to allocate for bootstrap page directories. */
|
||||
#define BOOTSTRAP_PDIR_SIZE 0x1000
|
||||
|
||||
.extern start_64 # defined in start_64.S
|
||||
|
||||
.code32
|
||||
|
||||
.section .boot.rodata, "a", @progbits
|
||||
no_long_mode_err:
|
||||
.asciz "This system is not 64-bit. Press any key to reboot."
|
||||
|
||||
unsupported_cpu_err:
|
||||
.asciz "Your CPU is not supported by Magenta. Press any key to reboot."
|
||||
|
||||
.section .boot.bss, "aw", @nobits
|
||||
bootstrap_pml4t: # a single PML4T
|
||||
.skip 0x1000
|
||||
bootstrap_pdpt: # a single PDPT
|
||||
.skip 0x1000
|
||||
bootstrap_pdir_buf: # a buffer of page directories. each pdir entry can be used to map 2MB of virtual memory.
|
||||
.skip BOOTSTRAP_PDIR_SIZE
|
||||
bootstrap_stack_bottom:
|
||||
.skip 0x1000
|
||||
bootstrap_stack_top:
|
||||
|
||||
.section .boot.text, "ax", @progbits
|
||||
.align 4
|
||||
.long MAGIC
|
||||
.long FLAGS
|
||||
.long CHECKSUM
|
||||
|
||||
# Print an error message and wait for RETURN if the system's CPU doesn't support long mode.
|
||||
no_long_mode:
|
||||
# print error message
|
||||
mov $no_long_mode_err, %esi
|
||||
|
||||
mov $0xb8000, %edi
|
||||
1:
|
||||
movsb
|
||||
movb $12, (%edi)
|
||||
incl %edi
|
||||
cmpb $0, (%esi)
|
||||
jne 1b
|
||||
|
||||
2:
|
||||
inb $0x64, %al
|
||||
test $0x01, %al
|
||||
jz 3f
|
||||
inb $0x60, %al
|
||||
jmp 2b
|
||||
|
||||
3:
|
||||
inb $0x64, %al
|
||||
test $0x01, %al
|
||||
jz 3b
|
||||
|
||||
int $0xff
|
||||
cli
|
||||
hlt
|
||||
|
||||
# Print an error message and wait for RETURN if the system's CPU isn't supported.
|
||||
unsupported_cpu:
|
||||
# print error message
|
||||
mov $unsupported_cpu_err, %esi
|
||||
|
||||
mov $0xb8000, %edi
|
||||
1:
|
||||
movsb
|
||||
movb $12, (%edi)
|
||||
incl %edi
|
||||
cmpb $0, (%esi)
|
||||
jne 1b
|
||||
|
||||
2:
|
||||
inb $0x64, %al
|
||||
test $0x01, %al
|
||||
jz 3f
|
||||
inb $0x60, %al
|
||||
jmp 2b
|
||||
|
||||
3:
|
||||
inb $0x64, %al
|
||||
test $0x01, %al
|
||||
jz 3b
|
||||
|
||||
int $0xff
|
||||
cli
|
||||
hlt
|
||||
|
||||
init_page_tables:
|
||||
/* STEP 1: add an entry in the PML4T pointing to the PDPT.
|
||||
NOTE that we actually add two entries in the PML4T that both point to the same PDPT.
|
||||
This allows us to map the kernel at both vaddr 0x0 AND vaddr 0xffffffff80000000 using the same PDPT */
|
||||
|
||||
mov $bootstrap_pml4t, %edi
|
||||
mov $bootstrap_pdpt, %esi
|
||||
|
||||
# in %ESI, build a PML4T entry containing the base address of the PDPT
|
||||
xor $0xFFF, %esi
|
||||
or $0x3, %esi
|
||||
|
||||
# add the PML4T entries at PML4T[0] and PML4T[511]
|
||||
mov %esi, (%edi)
|
||||
add $0xFF8, %edi
|
||||
mov %esi, (%edi)
|
||||
|
||||
/* STEP 2: initialise the PDPT.
|
||||
We need to create an entry in the PDPT for every page directory we intend to use. */
|
||||
|
||||
# BOOTSTRAP_PDIR_SIZE contains the total size of the page directory buffer.
|
||||
# use it to calculate the number of page directories we're using.
|
||||
mov $0, %edx
|
||||
mov $BOOTSTRAP_PDIR_SIZE, %eax
|
||||
mov $0x1000, %ebx
|
||||
idiv %ebx
|
||||
|
||||
mov $bootstrap_pdpt, %edi
|
||||
mov $bootstrap_pdir_buf, %esi
|
||||
/* %ESI is a pointer into the pagedir buffer.
|
||||
%EDI is a pointer into the PDPT.
|
||||
%EAX is the total number of page directories.
|
||||
%EBX is where we build the PDPT entry. */
|
||||
1:
|
||||
mov %esi, %ebx
|
||||
xor $0xFFF, %ebx
|
||||
or $0x3, %ebx
|
||||
|
||||
# skip the first 4 bytes of the 8-byte entry, leaving them zero.
|
||||
add $0x4, %edi
|
||||
mov %ebx, (%edi)
|
||||
|
||||
add $0x1000, %esi
|
||||
add $0x4, %edi
|
||||
sub $0x1, %eax
|
||||
|
||||
cmp $0x0, %eax
|
||||
jne 1b
|
||||
|
||||
/* STEP 3: initialise the page directories.
|
||||
Each page directory can be used to map 2MiB of virtual memory.
|
||||
The exact number of page directories in use is determined by BOOTSTRAP_PDIR_SIZE */
|
||||
|
||||
/* the total number of page directory entries is stored in %EAX */
|
||||
mov $0, %edx
|
||||
mov $BOOTSTRAP_PDIR_SIZE, %eax
|
||||
mov $0x8, %ebx
|
||||
idiv %ebx
|
||||
|
||||
mov $0x0, %esi
|
||||
mov $bootstrap_pdir_buf, %edi
|
||||
/* %EDI is a pointer into the pagedir buffer.
|
||||
%ESI is the physical address being mapped. must be a multiple of 2MiB.
|
||||
%EAX is the total number of page directories.
|
||||
%EBX is where we build the pagedir entry. */
|
||||
|
||||
2:
|
||||
mov %esi, %ebx
|
||||
xor $0xFFF, %ebx
|
||||
or $0x3, %ebx
|
||||
|
||||
# skip the first 4 bytes of the 8-byte entry, leaving them zero.
|
||||
add $0x4, %edi
|
||||
mov %ebx, (%edi)
|
||||
|
||||
add $0x200000, %esi
|
||||
add $0x4, %edi
|
||||
dec %eax
|
||||
jnz 2b
|
||||
|
||||
ret
|
||||
|
||||
long_mode_switch:
|
||||
ret
|
||||
|
||||
.global _start
|
||||
.type _start, @function
|
||||
|
||||
_start:
|
||||
mov $bootstrap_stack_top, %esp
|
||||
|
||||
push %ebx # store the pointer to the multiboot info block.
|
||||
|
||||
# check if long mode is supported
|
||||
movl $0x80000000, %eax # Extended-function 80000000h.
|
||||
cpuid # Is largest extended function
|
||||
cmpl $0x80000000, %eax # any function > 80000000h?
|
||||
jbe no_long_mode # If not, no long mode.
|
||||
movl $0x80000001, %eax # Extended-function 80000001h.
|
||||
cpuid # Now EDX = extended-features flags.
|
||||
btl $29, %edx # Test if long mode is supported.
|
||||
jnc no_long_mode # Exit if not supported.
|
||||
|
||||
movl $1, %eax
|
||||
cpuid
|
||||
btl $3, %edx
|
||||
|
||||
mov $0xb8000, %eax
|
||||
movb $76, (%eax)
|
||||
inc %eax
|
||||
movb $0xF, (%eax)
|
||||
|
||||
call init_page_tables
|
||||
call long_mode_switch # calls start_64, does not return
|
||||
|
||||
cli
|
||||
hlt
|
||||
10
arch/x86_64/start_64.S
Normal file
10
arch/x86_64/start_64.S
Normal file
@@ -0,0 +1,10 @@
|
||||
.section .boot.text, "ax", @progbits
|
||||
|
||||
.code64
|
||||
.global start_64
|
||||
.type start_64, @function
|
||||
start_64:
|
||||
mov $0xb8000, %rax
|
||||
movb $77, (%rax)
|
||||
inc %rax
|
||||
movb $0xF, (%rax)
|
||||
4
core/main.c
Normal file
4
core/main.c
Normal file
@@ -0,0 +1,4 @@
|
||||
void kernel_init()
|
||||
{
|
||||
|
||||
}
|
||||
5
tools/make/clang-generic.mk
Normal file
5
tools/make/clang-generic.mk
Normal file
@@ -0,0 +1,5 @@
|
||||
LD := ld.lld
|
||||
CC := clang
|
||||
|
||||
CFLAGS := -fuse-ld=$(LD) -target x86_64-linux-elf -nostdlib -nostdinc -ffreestanding -Wl,-nostdlib -Wno-unused-command-line-argument
|
||||
LDFLAGS := -nostdlib
|
||||
8
tools/make/gcc-cross-compile.mk
Normal file
8
tools/make/gcc-cross-compile.mk
Normal file
@@ -0,0 +1,8 @@
|
||||
LD := $(ARCH)-elf-gcc
|
||||
CC := $(ARCH)-elf-gcc
|
||||
ASM := $(ARCH)-elf-gcc
|
||||
|
||||
CFLAGS := -nostdlib -nostdinc -ffreestanding -Wl,-nostdlib
|
||||
ASMFLAGS := $(CFLAGS)
|
||||
LDFLAGS := -nostdlib
|
||||
|
||||
Reference in New Issue
Block a user