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

222 executables parse #224

Draft
wants to merge 15 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
20 changes: 14 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ ifeq ($(TOOLCHAIN), gcc)
else ifeq ($(TOOLCHAIN), clang)
X_CC = clang
X_LD = ld.lld
LD_FLAGS += -z lrodata-after-bss
else
$(error "Unknown compiler toolchain")
endif
Expand All @@ -42,9 +43,9 @@ ISO_IMAGE_FILENAME := $(IMAGE_BASE_NAME)-$(ARCH_PREFIX)-$(VERSION).iso

default: build

.PHONY: default build run clean debug tests gdb todolist
.PHONY: default build run clean debug tests gdb todolist examples

build: $(BUILD_FOLDER)/$(ISO_IMAGE_FILENAME)
build: examples $(BUILD_FOLDER)/$(ISO_IMAGE_FILENAME)

clean:
-rm -rf $(BUILD_FOLDER)
Expand All @@ -53,6 +54,13 @@ clean:
run: $(BUILD_FOLDER)/$(ISO_IMAGE_FILENAME)
$(QEMU_SYSTEM) -cdrom $(BUILD_FOLDER)/$(ISO_IMAGE_FILENAME)

examples:
echo "Building Examples"
mkdir -p $(BUILD_FOLDER)/examples
${ASM_COMPILER} -g -felf64 -Fdwarf examples/example_syscall.s -o $(BUILD_FOLDER)/examples/example_syscall.o
$(X_LD) -g $(BUILD_FOLDER)/examples/example_syscall.o -o $(BUILD_FOLDER)/examples/example_syscall.elf -e loop -T examples/linker_script_$(SMALL_PAGES).ld
#ld --section-alignment 0x200000 -g $(BUILD_FOLDER)/examples/example_syscall.o -o $(BUILD_FOLDER)/examples/example_syscall.elf -e loop

debug: DEBUG=1
debug: CFLAGS += $(C_DEBUG_FLAGS)
debug: ASM_FLAGS += $(ASM_DEBUG_FLAGS)
Expand All @@ -61,12 +69,12 @@ debug: $(BUILD_FOLDER)/$(ISO_IMAGE_FILENAME)
# qemu-system-x86_64 -monitor unix:qemu-monitor-socket,server,nowait -cpu qemu64,+x2apic -cdrom $(BUILD_FOLDER)/$(ISO_IMAGE_FILENAME) -serial file:dreamos64.log -m 1G -d int -no-reboot -no-shutdown
$(QEMU_SYSTEM) -monitor unix:qemu-monitor-socket,server,nowait -cpu qemu64,+x2apic -cdrom $(BUILD_FOLDER)/$(ISO_IMAGE_FILENAME) -serial stdio -m 2G -no-reboot -no-shutdown

$(BUILD_FOLDER)/$(ISO_IMAGE_FILENAME): $(BUILD_FOLDER)/kernel.bin grub.cfg
$(BUILD_FOLDER)/$(ISO_IMAGE_FILENAME): $(BUILD_FOLDER)/kernel.bin grub.cfg examples
mkdir -p $(BUILD_FOLDER)/isofiles/boot/grub
cp grub.cfg $(BUILD_FOLDER)/isofiles/boot/grub
cp $(BUILD_FOLDER)/kernel.bin $(BUILD_FOLDER)/isofiles/boot
cp $(BUILD_FOLDER)/kernel.map $(BUILD_FOLDER)/isofiles/boot
cp example.elf $(BUILD_FOLDER)/isofiles
cp $(BUILD_FOLDER)/examples/example_syscall.elf $(BUILD_FOLDER)/isofiles
grub-mkrescue -o $(BUILD_FOLDER)/$(ISO_IMAGE_FILENAME) $(BUILD_FOLDER)/isofiles

$(BUILD_FOLDER)/%.o: src/%.s
Expand All @@ -88,7 +96,7 @@ $(BUILD_FOLDER)/kernel.bin: $(OBJ_ASM_FILE) $(OBJ_C_FILE) $(OBJ_FONT_FILE) src/l
echo $(OBJ_ASM_FILE)
echo $(OBJ_FONT_FILE)
echo $(IS_WORKFLOW)
$(X_LD) -n -o $(BUILD_FOLDER)/kernel.bin -T src/linker.ld $(OBJ_ASM_FILE) $(OBJ_C_FILE) $(OBJ_FONT_FILE) -Map $(BUILD_FOLDER)/kernel.map
$(X_LD) $(LD_FLAGS) -n -o $(BUILD_FOLDER)/kernel.bin -T src/linker.ld $(OBJ_ASM_FILE) $(OBJ_C_FILE) $(OBJ_FONT_FILE) -Map $(BUILD_FOLDER)/kernel.map

gdb: DEBUG=1
gdb: CFLAGS += $(C_DEBUG_FLAGS)
Expand All @@ -103,7 +111,7 @@ tests:
${TOOLCHAIN} ${TESTFLAGS} tests/test_kheap.c tests/test_common.c src/kernel/mem/kheap.c src/kernel/mem/bitmap.c src/kernel/mem/pmm.c src/kernel/mem/mmap.c src/kernel/mem/vmm_util.c -o tests/test_kheap.o
${TOOLCHAIN} ${TESTFLAGS} tests/test_vm.c tests/test_common.c src/kernel/arch/x86_64/system/vm.c src/kernel/mem/vmm_util.c -o tests/test_vm.o
${TOOLCHAIN} ${TESTFLAGS} tests/test_vfs.c tests/test_common.c src/fs/vfs.c src/drivers/fs/ustar.c -o tests/test_vfs.o
${TOOLCHAIN} ${TESTFLAGS} tests/test_utils.c src/kernel/mem/vmm_util.c -o tests/test_utils.o
${TOOLCHAIN} ${TESTFLAGS} tests/test_utils.c tests/test_common.c src/kernel/mem/vmm_util.c -o tests/test_utils.o
${TOOLCHAIN} ${TESTFLAGS} tests/test_window.c tests/test_common.c src/kernel/graphics/window.c -o tests/test_window.o
./tests/test_mem.o && ./tests/test_kheap.o && ./tests/test_number_conversion.o && ./tests/test_vm.o && ./tests/test_vfs.o && ./tests/test_utils.o && ./tests/test_window.o

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ But at kernel level several things have been implemented:
* Basic Virtual Memory implementation
* Initial Userspace support (so far can run only an idle userspace thread)
* Basic syscall mechanism (altough no real syscalls are implemented, just one that prints the string "example")
* Initial basic ELF support (from kernel module)

## Prerequisites:

Expand Down
4 changes: 4 additions & 0 deletions build/Common.mk
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ CFLAGS := -std=gnu99 \
-mno-red-zone \
-mno-sse \
-mcmodel=large \
-fno-pie \
-fno-pic \
-fno-stack-protector

CFLAGS += $(DEF_FLAGS)
Expand All @@ -46,5 +48,7 @@ TESTFLAGS := -std=gnu99 \
-DSMALL_PAGES=0 \
-D_TEST_=1

LD_FLAGS :=

PRJ_FOLDERS := src
TEST_FOLDER := tests
2 changes: 1 addition & 1 deletion docs/kernel/Syscalls.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ The syscalls are called using the interrupt vector `0x80`. Arguments depend on t

# Syscalls List

## 0x01 TEST
## 0x00 TEST

The first syscall is reserved for test purpose, and it should be never used.

Expand Down
Binary file removed example.elf
Binary file not shown.
7 changes: 7 additions & 0 deletions examples/example_syscall.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
extern loop
[bits 64]
loop:
mov rdi, 0x63
mov rsi, 0x1
int 0x80
jmp loop
31 changes: 31 additions & 0 deletions examples/linker_script_0.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
ENTRY(loop)

SECTIONS {

. = 8M;

.text : ALIGN (2M)
{
*(.text)
*(.text.*)
}

.rodata : ALIGN (2M)
{
*(.rodata)
*(.rodata.*)
}

.data : ALIGN (2M)
{
*(.data)
*(.data.*)
}

.bss : ALIGN (2M)
{
*(.bss)
}

}

31 changes: 31 additions & 0 deletions examples/linker_script_1.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
ENTRY(loop)

SECTIONS {

. = 4M;

.text : ALIGN (4K)
{
*(.text)
*(.text.*)
}

.rodata : ALIGN (4K)
{
*(.rodata)
*(.rodata.*)
}

.data : ALIGN (4K)
{
*(.data)
*(.data.*)
}

.bss : ALIGN (4K)
{
*(.bss)
}

}

2 changes: 1 addition & 1 deletion grub.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ set default=0

menuentry "DreamOs64" {
multiboot2 /boot/kernel.bin // Path to the loader executable
module2 /example.elf
module2 /example_syscall.elf
boot
// More modules may be added here in the form 'module <path> "<cmdline>"'
}
2 changes: 2 additions & 0 deletions src/include/kernel/loaders/elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,5 +87,7 @@ void load_elf(uintptr_t elf_start, uint64_t size);
bool parse_section_header(Elf64_Ehdr *elf_start, uint64_t size, executable_loader_type type);

Elf64_Half loop_phdrs(Elf64_Ehdr* e_phdr, Elf64_Half phdr_entries);
Elf64_Phdr *read_phdr(Elf64_Ehdr* e_hdr, Elf64_Half phdr_entry_number);

uint64_t elf_flags_to_memory_flags(Elf64_Word flags);
#endif
1 change: 1 addition & 0 deletions src/include/kernel/mem/hh_direct_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
void early_map_physical_memory(uint64_t end_of_reserved_area);

void *hhdm_get_variable ( uintptr_t phys_address );
void *hhdm_get_phys_address(uintptr_t hhdm_address);
void hhdm_map_physical_memory();

#endif
1 change: 1 addition & 0 deletions src/include/kernel/mem/vmm_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
size_t get_number_of_pages_from_size(size_t size);
size_t align_value_to_page(size_t value);
size_t align_up(size_t value, size_t alignment);
size_t align_down(size_t value, size_t alignment);
bool is_address_aligned(size_t value, size_t alignment);

size_t vm_parse_flags( size_t flags );
Expand Down
2 changes: 1 addition & 1 deletion src/include/kernel/scheduling/scheduler.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#ifndef _SCHEDULER_H_
#define _SCHEDULER_H_

#include <cpu.h>
#include <stdint.h>
#include <thread.h>
#include <task.h>
#include <cpu.h>

#define SCHEDULER_NUMBER_OF_TICKS 0x200
#define SCHEDULER_MAX_THREAD_NUMBER 0x10
Expand Down
12 changes: 10 additions & 2 deletions src/include/kernel/scheduling/task.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef _TASK_H
#define _TASK_H

#include <elf.h>
#include <stddef.h>
#include <stdbool.h>
#include <thread.h>
Expand All @@ -27,14 +28,21 @@ struct task_t {

extern size_t next_task_id;

task_t* create_task( char *name, void (*_entry_point)(void *), void *args, bool is_supervisor );
task_t* create_task( char *name, bool is_supervisor );
task_t *create_task_from_func(char *name, void (*_entry_point)(void *), void *args, bool is_supervisor);
task_t *create_task_from_elf(char *name, void *args, Elf64_Ehdr *elf_header);

task_t* get_task( size_t task_id );

bool add_thread_to_task_by_id( size_t task_id, thread_t* thread );
bool add_thread_to_task( task_t* task, thread_t* thread );

bool delete_thread_from_task( size_t thread_id, task_t *task );
void prepare_virtual_memory_environment( task_t* task );

void prepare_virtual_memory_environment(task_t* task);

void print_thread_list( size_t task_id );

bool remove_thread_from_task(size_t thread_id, task_t *task);

#endif
2 changes: 1 addition & 1 deletion src/include/kernel/scheduling/thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ struct thread_t {
extern size_t next_thread_id;


thread_t* create_thread(char* thread_name, void (*_entry_point)(void *) , void* arg, struct task_t* parent_task, bool is_supervisor);
thread_t* create_thread(char* thread_name, void (*_entry_point)(void *) , void* arg, struct task_t* parent_task, bool is_supervisor, bool is_elf);
void thread_execution_wrapper( void (*)(void *), void*);
void thread_suicide_trap();
void thread_sleep(size_t millis);
Expand Down
10 changes: 5 additions & 5 deletions src/kernel/arch/x86_64/mem/vmm_mapping.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ void *map_phys_to_virt_addr_hh(void* physical_address, void* address, size_t fla
uint8_t user_mode_status = 0;

if ( !is_address_higher_half((uint64_t) address) ) {
pretty_log(Verbose, "address is in lower half");
pretty_logf(Verbose, "address is in lower half: 0x%x", address);
flags = flags | VMM_FLAGS_USER_LEVEL;
user_mode_status = VMM_FLAGS_USER_LEVEL;
}
Expand All @@ -47,7 +47,7 @@ void *map_phys_to_virt_addr_hh(void* physical_address, void* address, size_t fla
clean_new_table(new_table_hhdm);
pdpr_root = new_table_hhdm;
} else {
pretty_log(Verbose, "No need to allocate pml4");
//pretty_log(Verbose, "No need to allocate pml4");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of commenting these out, why not remove them? can always re-add them later if needed

pdpr_root = (uint64_t *) hhdm_get_variable((uintptr_t) pml4_root[pml4_e] & VM_PAGE_TABLE_BASE_ADDRESS_MASK);
}

Expand All @@ -59,7 +59,7 @@ void *map_phys_to_virt_addr_hh(void* physical_address, void* address, size_t fla
clean_new_table(new_table_hhdm);
pd_root = new_table_hhdm;
} else {
pretty_log(Verbose, "No need to allocate pdpr");
//pretty_log(Verbose, "No need to allocate pdpr");
pd_root = (uint64_t *) hhdm_get_variable((uintptr_t) pdpr_root[pdpr_e] & VM_PAGE_TABLE_BASE_ADDRESS_MASK);
}

Expand All @@ -72,7 +72,7 @@ void *map_phys_to_virt_addr_hh(void* physical_address, void* address, size_t fla
clean_new_table(new_table_hhdm);
pt_table = new_table_hhdm;
} else {
pretty_log(Verbose, "No need to allocate pd");
//pretty_log(Verbose, "No need to allocate pd");
pt_table = (uint64_t *) hhdm_get_variable((uintptr_t) pd_root[pd_e] & VM_PAGE_TABLE_BASE_ADDRESS_MASK);
}

Expand All @@ -84,7 +84,7 @@ void *map_phys_to_virt_addr_hh(void* physical_address, void* address, size_t fla
}
#elif SMALL_PAGES == 0
pd_root[pd_e] = (uint64_t) (physical_address) | HUGEPAGE_BIT | flags | user_mode_status;
pretty_logf(Verbose, " PD Flags: 0x%x entry value pd_root[0x%x]: 0x%x", flags, pd_e, pd_root[pd_e]);
pretty_logf(Verbose, " PD Flags: 0x%x entry value pd_root[0x%x]: 0x%x - address: 0x%x", flags, pd_e, pd_root[pd_e], address);
return address;
}
#endif
Expand Down
34 changes: 32 additions & 2 deletions src/kernel/loaders/elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,14 @@ void load_elf(uintptr_t elf_start, uint64_t size) {
Elf64_Half phdr_entsize = elf_header->e_phentsize;
pretty_logf(Verbose, " Number of PHDR entries: 0x%x", phdr_entries);
pretty_logf(Verbose, " PHDR Entry Size: 0x%x", phdr_entsize );
pretty_logf(Verbose, " ELF Entry point: 0x%x", elf_header->e_entry);
Elf64_Half result = loop_phdrs(elf_header, phdr_entries);
if (result > 0) {
pretty_logf(Verbose, " Number of PT_LOAD entries: %d", result);
Elf64_Phdr *cur_phdr = read_phdr(elf_header, 0);
pretty_logf(Verbose, "\t[cur_phdr]: Type: 0x%x, Flags: 0x%x - Vaddr: 0x%x - aligned: 0x%x - p_align: 0x%x - p_memsz: 0%x - p_offset: 0x%x", cur_phdr->p_type, cur_phdr->p_flags, cur_phdr->p_vaddr, align_value_to_page(cur_phdr->p_vaddr), cur_phdr->p_align, cur_phdr->p_memsz, cur_phdr->p_offset);
cur_phdr = read_phdr(elf_header, 1);
//pretty_logf(Verbose, "\t[cur_phdr]: Type: 0x%x, Flags: 0x%x - Vaddr: 0x%x - aligned: 0x%x - p_align: 0x%x - p_memsz: 0%x - p_offset: 0x%x", cur_phdr->p_type, cur_phdr->p_flags, cur_phdr->p_vaddr, align_value_to_page(cur_phdr->p_vaddr), cur_phdr->p_align, cur_phdr->p_memsz, cur_phdr->p_offset);
}
}
}
Expand All @@ -28,7 +33,7 @@ Elf64_Half loop_phdrs(Elf64_Ehdr* e_hdr, Elf64_Half phdr_entries) {
Elf64_Half number_of_pt_loads = 0;
for (size_t i = 0; i < phdr_entries; i++) {
Elf64_Phdr phdr = phdr_list[i];
pretty_logf(Verbose, "\t[%d]: Type: 0x%x, Flags: 0x%x - Vaddr: 0x%x - aligned: 0x%x ", i, phdr.p_type, phdr.p_flags, phdr.p_vaddr, align_value_to_page(phdr.p_vaddr));
pretty_logf(Verbose, "\t[%d]: Type: 0x%x, Flags: 0x%x - Vaddr: 0x%x - aligned: 0x%x - offset: 0x%x ", i, phdr.p_type, phdr.p_flags, phdr.p_vaddr, align_value_to_page(phdr.p_vaddr), phdr.p_offset);
if ( is_address_aligned(phdr.p_vaddr, PAGE_SIZE_IN_BYTES) ) {
pretty_log(Verbose, "\tThe address is aligned");
} else {
Expand All @@ -39,6 +44,14 @@ Elf64_Half loop_phdrs(Elf64_Ehdr* e_hdr, Elf64_Half phdr_entries) {
return number_of_pt_loads;
}

/**
* This function return the phdr entry at the pdhrd_entry_number provided.
*
*
* @param e_hdr the elf header
* @param phdr_entry_number the entry number we want to read
* @return Elf64_Phdr * the selected P_hdr or NULL if not found.
*/
Elf64_Phdr *read_phdr(Elf64_Ehdr* e_hdr, Elf64_Half phdr_entry_number) {
Elf64_Half phdr_entries = e_hdr->e_phnum;

Expand All @@ -48,7 +61,6 @@ Elf64_Phdr *read_phdr(Elf64_Ehdr* e_hdr, Elf64_Half phdr_entry_number) {
}

return NULL;

}


Expand Down Expand Up @@ -91,3 +103,21 @@ bool parse_section_header(Elf64_Ehdr *elf_start, uint64_t size, executable_loade
}
return false;
}

/**
* This function given an elf p_hdr flag returns the architecture dependent vmm flags
*
*
* @param flags elf flags
* @return architecture dependant flags
*/
uint64_t elf_flags_to_memory_flags(Elf64_Word flags) {
// This function will be movede into the arch dependant code
// Elf flags:
// 1 = Read
// 2 = Write
// 4 = Execute
// They can be mixed.
uint64_t flags_to_return = (flags & 0b10);
return flags_to_return;
}
Loading
Loading