Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loader #115

Open
wants to merge 52 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
bdb1d06
Don't truncate module when signing
iankronquist Jun 29, 2017
f12949e
Merge branch 'master' of github.com:iankronquist/kernel-of-truth
iankronquist Jul 8, 2017
ece4e82
First stab at the loader
iankronquist Jul 8, 2017
f0cca1e
Relocation successful
iankronquist Jul 9, 2017
9e064f8
Optimize for a smaller header file
iankronquist Jul 9, 2017
185036c
Make kernel_main a constructor
iankronquist Jul 9, 2017
81a6116
Paging and elf loader
iankronquist Jul 9, 2017
31df394
Align embedded kernel array
iankronquist Jul 9, 2017
0402ffb
Link kernel properly
iankronquist Jul 9, 2017
b53a114
Don't use a silly script to embed the elf kernel
iankronquist Jul 11, 2017
5a5d9d3
Tags should include loader
iankronquist Jul 11, 2017
210bb7b
Don't need Python in the Makefile
iankronquist Jul 11, 2017
014353e
Remove debug lines
iankronquist Jul 11, 2017
e50a476
Define 64 bit symtab macros as macro functions
iankronquist Jul 11, 2017
305d0a9
Remove debug logs & fix warnings
iankronquist Jul 11, 2017
41b00c7
Remove more debug logs
iankronquist Jul 11, 2017
8e3a1ac
Assembly definitions
iankronquist Jul 11, 2017
2ca93d4
Remove silly python script
iankronquist Jul 11, 2017
1ce6181
Fix Makefile loader dependencies & loader header
iankronquist Jul 11, 2017
8519a2e
Initialize BSS.
iankronquist Jul 11, 2017
6fc95a1
More parens around macro argument symbols
iankronquist Jul 11, 2017
d32d4c1
Remove unnecessary instruction
iankronquist Jul 11, 2017
f0f4960
Nuke unused debug code
iankronquist Jul 11, 2017
88eb7ae
Use header e_entry as opposed to init_array
iankronquist Jul 11, 2017
475c2b1
Propagate const
iankronquist Jul 11, 2017
99c5a70
Define funky symbols as typed macros
iankronquist Jul 11, 2017
f0addba
Refactor map bss function
iankronquist Jul 11, 2017
90948f4
Force remap option
iankronquist Jul 12, 2017
8c237b9
Checked wrong cpuid leaf
iankronquist Jul 12, 2017
a10eb1a
Boot remap sections
iankronquist Jul 12, 2017
54d37fe
Pass boot info from loader to kernel
iankronquist Jul 12, 2017
a5d9b41
Bounds check against right table during so loading
iankronquist Jul 12, 2017
6f55997
Add KASLR to readme feature list
iankronquist Jul 12, 2017
58d01f3
Change strip target
iankronquist Jul 12, 2017
3dfec77
Don't fractal map in loader
iankronquist Jul 12, 2017
407c071
Remove unused function
iankronquist Jul 12, 2017
522b985
Unused symbols
iankronquist Jul 12, 2017
6ef784c
Remove unused functions
iankronquist Jul 12, 2017
a2a4e53
Move string functions into own file
iankronquist Jul 12, 2017
d5d94f9
Split monolith into logical little pieces
iankronquist Jul 12, 2017
a87e1e6
Move structure definitions to header file
iankronquist Jul 12, 2017
1e7acfc
Add #pragma once to elf header
iankronquist Jul 12, 2017
3cde7c3
Change inline assembly to make clang-tidy happy
iankronquist Jul 12, 2017
a41b454
Define atomic macro which old clang doesn't have
iankronquist Jul 12, 2017
eebcd94
Split elf and segments into separate files
iankronquist Jul 12, 2017
64005ae
Fix forgotten includes
iankronquist Jul 12, 2017
3423c5c
Clang complains about inline asm
iankronquist Jul 12, 2017
cdf881d
Create clang tidy target
iankronquist Jul 12, 2017
45c75df
Make clang-tidy not error
iankronquist Jul 12, 2017
03ac795
Use toolchain strip
iankronquist Jul 12, 2017
a119ca2
Fix NULL pointer dereference
iankronquist Jul 12, 2017
0c55688
Forgot some loader includes
iankronquist Jul 12, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 52 additions & 28 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,45 +16,54 @@ MACROS := -dD \
BUILD_DIR := build

KERNEL := $(BUILD_DIR)/truth.$(ARCH).elf
KERNEL64 := $(BUILD_DIR)/truth.$(ARCH).elf64
LOADER := $(BUILD_DIR)/truth_loader.$(ARCH).elf
LOADER64 := $(BUILD_DIR)/truth_loader.$(ARCH).elf64

OBJ :=
LOADER_OBJS :=
MODULES :=
MODULE_CFLAGS := -std=c11 -MP -MMD -ffreestanding -O2 -Wall -Wextra \
-fpic -nostdlib -I ../../include -D __C__ -mno-sse
include loader/$(ARCH)/Makefile
include kernel/arch/$(ARCH)/Makefile
include kernel/core/Makefile
include kernel/crypto/Makefile
include kernel/device/Makefile
include modules/Makefile


PYTHON := python
CLANG_TIDY := clang-tidy
OD := od

LOADER_FLAGS := -O2 -MP -MMD \
-ffreestanding \
-Wall -Wextra \
-I ./include -mno-sse

RANOM_NUMBER := $(strip $(shell $(OD) -vAn -N8 -tu8 < /dev/urandom))
LOADER_CFLAGS := $(LOADER_FLAGS) -D __C__ -std=c11 -D Boot_Compile_Random_Number=$(RANOM_NUMBER)ul
LOADER_ASFLAGS := $(LOADER_FLAGS) -D __ASM__


KERNEL_FLAGS := -O2 -MP -MMD -mno-sse -Wall -Wextra -ffreestanding -I ./include -fPIC
CC := $(TRIPLE)-gcc
CFLAGS := -std=c11 -O2 -MP -MMD -mcmodel=kernel \
-ffreestanding -fstack-protector-all \
-Wall -Wextra \
-I ./include $(MACROS) -D __C__ -mno-sse
CFLAGS := -std=c11 $(KERNEL_FLAGS) $(MACROS) -D __C__

AS := $(TRIPLE)-gcc
ASFLAGS := -O2 -MP -MMD -mcmodel=kernel \
-ffreestanding \
-Wall -Wextra \
-I ./include $(MACROS) -D __ASM__
ASFLAGS := $(KERNEL_FLAGS) $(MACROS) -D __ASM__

LD := $(TRIPLE)-gcc
LDFLAGS := -nostdlib -ffreestanding -O2 -mcmodel=kernel
LD := $(TRIPLE)-ld
LDFLAGS := -nostdlib -O2 -soname="Kernel of Truth" -m elf_x86_64 -z max-page-size=0x1000 -fPIE -fPIC

MODULE_CC := $(CC)
MODULE_LD := $(TRIPLE)-ld
MODULE_AS := $(AS)


OBJCOPY := objcopy
OBJCOPY := $(TRIPLE)-objcopy
GRUB_MKRESCUE := grub-mkrescue
STRIP := strip
STRIP := $(TRIPLE)-strip

TOOLS_CC := gcc

Expand All @@ -64,9 +73,16 @@ QEMU_FLAGS := -no-reboot -m 256M -serial file:$(BUILD_DIR)/serial.txt \

MAKE := make

.PHONY: all clean debug iso release start start-log tools
.PHONY: all clean debug iso release start start-log tools tidy

all: $(LOADER) $(MODULES)

all: $(KERNEL) tools

$(LOADER64): loader/$(ARCH)/link.ld $(LOADER_OBJS) $(KERNEL64)
$(CC) -T loader/$(ARCH)/link.ld $(LOADER_OBJS) $(LOADER_CFLAGS) -o $@ $< -nostdlib

$(LOADER): $(LOADER64)
$(OBJCOPY) $< -O elf32-i386 $@

tools: $(BUILD_DIR)/tools/truesign

Expand All @@ -77,16 +93,18 @@ debug: CFLAGS += -g -fsanitize=undefined
debug: ASFLAGS += -g
debug: all

release: LOADER_CFLAGS += -Werror
release: LOADER_ASFLAGS += -Werror
release: CFLAGS += -Werror
release: AFLAGS += -Werror
release: all
$(STRIP) -s $(KERNEL)
$(STRIP) -s $(KERNEL64)

$(KERNEL): $(KERNEL)64 $(MODULES)
$(OBJCOPY) $< -O elf32-i386 $@

$(KERNEL)64: kernel/arch/$(ARCH)/link.ld $(BUILD_DIR)/symbols.o
$(LD) -T kernel/arch/$(ARCH)/link.ld $(OBJ) $(BUILD_DIR)/symbols.o -o $@ $(LDFLAGS)
$(KERNEL64): kernel/arch/$(ARCH)/link.ld $(OBJ)
$(LD) -T kernel/arch/$(ARCH)/link.ld -o $@ $(OBJ) -shared -soname="truth" -ffreestanding -nostdlib -z max-page-size=0x1000 -e kernel_main

$(BUILD_DIR)/%.c.o: kernel/%.c include/truth/key.h
mkdir -p $(shell dirname $@)
Expand All @@ -96,29 +114,35 @@ $(BUILD_DIR)/%.S.o: kernel/%.S
mkdir -p $(shell dirname $@)
$(AS) -c $< -o $@ $(ASFLAGS)

$(BUILD_DIR)/loader/%.S.o: loader/%.S $(KERNEL64)
mkdir -p $(shell dirname $@)
$(AS) -c $< -o $@ $(LOADER_ASFLAGS)

$(BUILD_DIR)/loader/%.c.o: loader/%.c
mkdir -p $(shell dirname $@)
$(CC) -c $< -o $@ $(LOADER_CFLAGS)


$(BUILD_DIR)/key.pub: $(BUILD_DIR)/tools/truesign
$(BUILD_DIR)/tools/truesign generate $(BUILD_DIR)/key.priv $@

include/truth/key.h: $(BUILD_DIR)/key.pub
$(BUILD_DIR)/tools/truesign header $(BUILD_DIR)/key.pub $@

$(BUILD_DIR)/symbols.o: $(OBJ) kernel/arch/$(ARCH)/link.ld
$(LD) -T kernel/arch/$(ARCH)/link.ld $(OBJ) -o $(KERNEL)64 $(LDFLAGS)
nm $(KERNEL)64 | $(PYTHON) build_symbol_table.py $(BUILD_DIR)/symbols.S
$(AS) -c $(BUILD_DIR)/symbols.S -o $@ $(ASFLAGS)

$(BUILD_DIR)/modules/%.ko: modules/% modules/link.ld $(BUILD_DIR)/key.pub
mkdir -p $(shell dirname $@)
$(MAKE) -C $< OUTFILE='../../$@' CFLAGS='$(MODULE_CFLAGS)' CC='$(MODULE_CC)' \
BUILD_DIR='../../$(BUILD_DIR)' LD='$(MODULE_LD)' \
AS='$(MODULE_AS)'

tags: kernel/arch/$(ARCH)/*.c kernel/core/*.c kernel/device/*.c \
include/arch/$(ARCH)/*.h include/truth/*.h
ctags -R kernel include
tags: kernel/arch/$(ARCH)/*.c kernel/core/*.c kernel/device/*.c include/arch/$(ARCH)/*.h include/truth/*.h loader/$(ARCH)/*.c
ctags -R kernel include loader

iso: $(BUILD_DIR)/truth.iso

tidy: kernel/arch/$(ARCH)/*.c kernel/core/*.c kernel/device/*.c include/arch/$(ARCH)/*.h include/truth/*.h loader/$(ARCH)/*.c
$(CLANG_TIDY) $^ --checks="*,-clang-diagnostic-incompatible-library-redeclaration" -- -I ./include $(MACROS) -D __C__ -D Boot_Compile_Random_Number=0

$(BUILD_DIR)/truth.iso: $(KERNEL) grub.cfg
mkdir -p $(BUILD_DIR)/isodir/boot/grub
cp $(KERNEL) $(BUILD_DIR)/isodir/boot/truth.elf
Expand All @@ -129,10 +153,10 @@ clean:
rm -rf $(BUILD_DIR)

start: debug
$(QEMU) -kernel $(KERNEL) $(QEMU_FLAGS) -monitor stdio
$(QEMU) -kernel $(LOADER) $(QEMU_FLAGS) -monitor stdio

start-log: debug
$(QEMU) -kernel $(KERNEL) -d in_asm,cpu_reset,exec,int,guest_errors,pcall \
$(QEMU) -kernel $(LOADER) -d in_asm,cpu_reset,exec,int,guest_errors,pcall \
-D $(BUILD_DIR)/qemu.log $(QEMU_FLAGS) -monitor stdio

-include $(OBJ:.o=.d)
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Kernel Features
- [x] Elf loader.
- [x] Loadable kernel modules.
- [x] 🔐 Kernel module Address Space Layout Randomization (ASLR) & signature verification.
- [x] 🔐 Kernel Address Space Layout Randomization (KASLR).
- [ ] Basic syscalls.
- [ ] POSIX syscall layer.
- [ ] EXT2 filesystem.
Expand Down
2 changes: 2 additions & 0 deletions build_symbol_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,6 @@ def write_assembly(symbols, file_name):
_, symbol_type, name = line.split()
if is_global_function(symbol_type):
symbols.append(name)

symbols = []
write_assembly(symbols, sys.argv[1])
3 changes: 3 additions & 0 deletions include/arch/x64/asm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#pragma once

#define Function(x) .global x; .type x, @function; x:
1 change: 1 addition & 0 deletions include/arch/x64/boot.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <truth/memory.h>
#include <arch/x64/segments.h>

#define Multiboot_Register_Magic 0x2badb002
#define MB_Magic 0x1badb002
#define MB_Alignment (1 << 1)
#define MB_Info (1 << 1)
Expand Down
2 changes: 1 addition & 1 deletion include/arch/x64/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ static inline void cpu_flags_clear_ac(void) {

static inline uint64_t cpu_get_ticks(void) {
uint32_t eax, edx;
__asm__ volatile ("rdtsc" : "=(eax)"(eax), "=(edx)"(edx)::);
__asm__ volatile ("rdtsc" : "=a"(eax), "=d"(edx)::);
return (((uint64_t)edx) << 32) | eax;
}

Expand Down
58 changes: 58 additions & 0 deletions include/arch/x64/segments.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,64 @@

#ifdef __C__

#include <truth/types.h>

void tss_set_stack(void *stack);

struct tss_entry {
uint32_t reserved0;
uint64_t stack0;
uint64_t stack1;
uint64_t stack2;
uint64_t reserved1;
uint64_t ist[7];
uint64_t reserved2;
uint16_t reserved3;
uint16_t iomap_base;
} pack;

struct gdt_entry {
uint16_t limit_low;
uint16_t base_low;
uint8_t base_middle;
uint8_t access;
uint8_t granularity;
uint8_t base_high;
};

struct gdt_register {
uint16_t limit;
uint64_t base;
} pack;


#define Gran_64_Bit_Mode (1 << 5)
#define Gran_32_Bit_Mode (1 << 6)
#define Gran_4_KB_Blocks (1 << 7)

#define gdt_entry(base, limit, access, granularity) \
{ (limit) & 0xffff, \
(uint16_t) ((base) >> 0 & 0xffff), \
(uint8_t) ((base) >> 16 & 0xff), \
(access) & 0xff, \
((limit) >> 16 & 0x0f) | ((granularity) & 0xf0), \
(uint8_t) ((base) >> 24 & 0xff), \
}

#define gdt_entry64(base, limit, access, granularity) \
{ (limit) & 0xffff, \
(uint16_t) ((base) >> 0 & 0xffff), \
(uint8_t) ((base) >> 16 & 0xff), \
(access) & 0xff, \
((limit) >> 16 & 0x0f) | ((granularity) & 0xf0), \
(uint8_t) ((base) >> 24 & 0xff), \
}, \
{ (uint16_t) ((base) >> 32 & 0xffff), \
(uint16_t) ((base) >> 48 & 0xffff), \
0, \
0, \
0, \
0, \
} \

#endif
7 changes: 7 additions & 0 deletions include/loader/allocator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#pragma once

#include <truth/types.h>


void *boot_allocator(size_t pages);
void boot_allocator_init(uint64_t kilobytes);
9 changes: 9 additions & 0 deletions include/loader/elf.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include <truth/elf.h>
#include <truth/types.h>

const void *boot_elf_get_section(const struct elf64_header *header, const size_t size, const char *name, size_t *section_size);
enum status boot_elf_relocate(void *kernel_start, size_t kernel_size);
enum status boot_elf_allocate_bss(void *kernel_start, phys_addr kernel_phys, size_t kernel_size, const void **bss_end);
enum status boot_elf_remap_section(void *kernel_start, phys_addr kernel_phys, size_t kernel_size, const void *virtual_base, phys_addr *section_phys, size_t *section_size, const char *section_name);
enum status boot_elf_kernel_enter(void *kernel_start, size_t kernel_size);
void *boot_elf_get_dynamic_symbol(void *kernel_start, size_t kernel_size, const char *name, size_t name_size);
3 changes: 3 additions & 0 deletions include/loader/halt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#pragma once

void boot_halt(void);
5 changes: 5 additions & 0 deletions include/loader/jitter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#pragma once

#include <truth/types.h>

uint64_t boot_memory_jitter_calculate(void);
6 changes: 6 additions & 0 deletions include/loader/log.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#pragma once

#include <truth/types.h>

void boot_vga_log64(const char *string);
void boot_log_number(uint64_t n);
9 changes: 9 additions & 0 deletions include/loader/paging.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#pragma once

#include <truth/types.h>
#include <truth/memory.h>

// Memory_Writable implies NX. We need this for higher levels of the page table.
#define Memory_Just_Writable (1 << 1)
#define invalid_phys_addr 0xfff
enum status boot_map_page(const void *virtual_address, phys_addr phys_address, enum memory_attributes permissions, bool force);
7 changes: 7 additions & 0 deletions include/loader/string.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#pragma once

#include <truth/types.h>

void *memset(void *b, int c, size_t len);
size_t strlen(const char *str);
int strncmp(const char *s1, const char *s2, size_t n);
19 changes: 19 additions & 0 deletions include/truth/boot.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#pragma once

#include <truth/types.h>
#include <external/multiboot.h>

struct boot_info {
const void *kernel;
phys_addr kernel_physical;
size_t kernel_size;
const void *strtab;
phys_addr strtab_physical;
size_t strtab_size;
const void *symtab;
phys_addr symtab_physical;
size_t symtab_size;
struct multiboot_info *multiboot_info;
};

#define Boot_Info_Name "Boot_Info"
8 changes: 5 additions & 3 deletions include/truth/elf.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#pragma once

#include <truth/types.h>

#define EI_CLASS 4
Expand Down Expand Up @@ -105,9 +107,9 @@ struct elf_symbol {
#define ELF32_ST_TYPE(i) ((i) & 0x0f)
#define ELF32_ST_INFO(b, t) (((b) << 4) + ((t) & 0x0f))

#define ELF64_ST_BIND ELF32_ST_BIND
#define ELF64_ST_TYPE ELF32_ST_TYPE
#define ELF64_ST_INFO ELF32_ST_INFO
#define ELF64_ST_BIND(x) ELF32_ST_BIND(x)
#define ELF64_ST_TYPE(x) ELF32_ST_TYPE(x)
#define ELF64_ST_INFO(b, t) ELF32_ST_INFO((b), (t))

#define STB_LOCAL 0
#define STB_GLOBAL 1
Expand Down
2 changes: 2 additions & 0 deletions include/truth/mt19937_64.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma once

#include <truth/types.h>

void mt19937_64_seed(uint64_t seed);

uint64_t mt19937_64_get_random_number(void);
10 changes: 8 additions & 2 deletions include/truth/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
#include <stdint.h>
#include <stddef.h>

#ifndef ATOMIC_INT_LOCK_FREE
#define ATOMIC_INT_LOCK_FREE (0)
#endif


typedef uint64_t phys_addr;

enum partial {
Expand Down Expand Up @@ -78,11 +83,12 @@ extern uint8_t __kernel_end;

#define container_of(child, parent_type, parent_entry) \
((parent_type)(child - &((parent_type)NULL)->parent_entry))
#define align_as(value, alignment) (value & ~(alignment - 1))
#define align_as(value, alignment) ((value) & ~((alignment) - 1))
#define is_power_of_two(value) ((((value) - 1) & value) == 0)
#define is_aligned(value, alignment) !(value & (alignment - 1))
#define is_aligned(value, alignment) !((value) & ((alignment) - 1))
#define round_next(x, y) (((x) + (y - 1)) & ~(y - 1))
#define static_array_count(x) (sizeof(x) / sizeof(x)[0])
#define min(x, y) ((x) < (y) ? (x) : (y))

#define check_format(x, y) __attribute__((format(printf, x, y)))
#define checked __attribute__((warn_unused_result))
Expand Down
Loading