Merge branch 'develop' of github.com:wichtounet/thor-os into develop

Conflicts:
	cpp.mk
This commit is contained in:
Baptiste Wicht 2014-01-28 08:05:54 +01:00
commit 3fb29dab1c
12 changed files with 188 additions and 49 deletions

View File

@ -20,6 +20,12 @@ programs/hello/a.out: force_look
programs/long/a.out: force_look
cd programs/long; ${MAKE} a.out
programs/longone/a.out: force_look
cd programs/longone; ${MAKE} a.out
programs/longtwo/a.out: force_look
cd programs/longtwo; ${MAKE} a.out
programs/loop/a.out: force_look
cd programs/loop; ${MAKE} a.out
@ -27,7 +33,7 @@ hdd.img:
dd if=/dev/zero of=hdd.img bs=516096c count=1000
(echo n; echo p; echo 1; echo ""; echo ""; echo t; echo c; echo a; echo 1; echo w;) | sudo fdisk -u -C1000 -S63 -H16 hdd.img
thor.flp: hdd.img bootloader/stage1.bin bootloader/stage2.bin kernel/kernel.bin programs/one/a.out programs/hello/a.out programs/long/a.out programs/loop/a.out
thor.flp: hdd.img bootloader/stage1.bin bootloader/stage2.bin kernel/kernel.bin programs/one/a.out programs/hello/a.out programs/long/a.out programs/loop/a.out programs/longone/a.out programs/longtwo/a.out
mkdir -p mnt/fake/
dd if=bootloader/stage1.bin of=hdd.img conv=notrunc
dd if=bootloader/stage2.bin of=hdd.img seek=1 conv=notrunc
@ -38,6 +44,8 @@ thor.flp: hdd.img bootloader/stage1.bin bootloader/stage2.bin kernel/kernel.bin
sudo /bin/cp programs/one/a.out mnt/fake/one
sudo /bin/cp programs/hello/a.out mnt/fake/hello
sudo /bin/cp programs/long/a.out mnt/fake/long
sudo /bin/cp programs/longone/a.out mnt/fake/longone
sudo /bin/cp programs/longtwo/a.out mnt/fake/longtwo
sudo /bin/cp programs/loop/a.out mnt/fake/loop
sleep 0.1
sudo /bin/umount mnt/fake/

2
cpp.mk
View File

@ -12,6 +12,6 @@ CPP_FLAGS_32=$(COMMON_CPP_FLAGS) $(CPP_FLAGS_LOW) -mpreferred-stack-boundary=4
CPP_FLAGS_64=$(COMMON_CPP_FLAGS) -mno-sse3 -mno-sse4 -mno-sse4.1 -mno-sse4.2
COMMON_LINK_FLAGS=-lgcc
PROGRAM_LINK_FLAGS=-z max-page-size=0x1000 $(COMMON_LINK_FLAGS) -T ../linker.ld
PROGRAM_LINK_FLAGS=$(COMMON_LINK_FLAGS) -z max-page-size=0x1000 -T ../linker.ld
PROGRAM_FLAGS=-I../../userlib/include/

View File

@ -12,6 +12,7 @@
#include "stl/vector.hpp"
#include "paging.hpp"
#include "interrupts.hpp"
namespace scheduler {
@ -25,19 +26,16 @@ struct process_t {
bool system;
size_t code_selector;
size_t data_selector;
size_t physical_cr3;
size_t paging_size;
size_t physical_user_stack;
size_t physical_kernel_stack;
size_t rip;
size_t user_rsp;
size_t kernel_rsp;
interrupt::syscall_regs regs;
std::vector<segment_t> segments;
std::vector<size_t> physical_paging;
};

View File

@ -16,7 +16,7 @@ namespace scheduler {
void init();
void start();
void kill_current_process();
void kill_current_process(const interrupt::syscall_regs& regs);
void reschedule(const interrupt::syscall_regs& regs);

View File

@ -200,15 +200,25 @@ void init_head(){
malloc_head->prev_ref() = malloc_head;
}
void expand_heap(malloc_header_chunk* current){
void expand_heap(malloc_header_chunk* current, size_t bytes = 0){
auto blocks = MIN_BLOCKS;
if(bytes){
auto necessary_blocks = ((bytes + META_SIZE) / BLOCK_SIZE) + 1;
if(necessary_blocks > blocks){
blocks = necessary_blocks;
}
}
//Allocate a new block of memory
uint64_t* block = allocate_block(MIN_BLOCKS);
uint64_t* block = allocate_block(blocks);
//Transform it into a malloc chunk
auto header = reinterpret_cast<malloc_header_chunk*>(block);
//Update the sizes
header->size() = MIN_BLOCKS * BLOCK_SIZE - META_SIZE;
header->size() = blocks * BLOCK_SIZE - META_SIZE;
header->footer()->size() = header->size();
//Insert the new block into the free list
@ -301,7 +311,7 @@ void* malloc::k_malloc(uint64_t bytes){
if(current == malloc_head){
//There are no blocks big enough to hold this request
//So expand the heap
expand_heap(current);
expand_heap(current, bytes);
} else if(current->size() >= bytes){
//This block is big enough

View File

@ -45,19 +45,19 @@ void create_idle_task(){
idle_process.physical_user_stack = 0;
idle_process.physical_kernel_stack = 0;
idle_process.rip = reinterpret_cast<size_t>(&idle_task);
idle_process.user_rsp = reinterpret_cast<size_t>(&idle_stack[63]);
idle_process.regs.rflags = 0x200;
idle_process.regs.rip = reinterpret_cast<size_t>(&idle_task);
idle_process.regs.rsp = reinterpret_cast<size_t>(&idle_stack[63]);
idle_process.kernel_rsp = reinterpret_cast<size_t>(&idle_kernel_stack[4095]);
idle_process.code_selector = gdt::LONG_SELECTOR;
idle_process.data_selector = gdt::DATA_SELECTOR;
idle_process.regs.cs = gdt::LONG_SELECTOR;
idle_process.regs.ds = gdt::DATA_SELECTOR;
processes.push_back(std::move(idle_process));
rounds.push_back(0);
}
void switch_to_process(size_t index) __attribute__((noreturn));
void switch_to_process(size_t index){
void switch_to_process(const interrupt::syscall_regs& regs, size_t index){
current_index = index;
k_printf("Switched to %u\n", index);
@ -67,7 +67,29 @@ void switch_to_process(size_t index){
gdt::tss.rsp0_low = process.kernel_rsp & 0xFFFFFFFF;
gdt::tss.rsp0_high = process.kernel_rsp >> 32;
asm volatile("mov rax, %0; mov ds, ax; mov es, ax; mov fs, ax; mov gs, ax;"
auto stack_pointer = reinterpret_cast<uint64_t*>(regs.placeholder);
*(stack_pointer + 4) = process.regs.ds;
*(stack_pointer + 3) = process.regs.rsp;
*(stack_pointer + 2) = process.regs.rflags;
*(stack_pointer + 1) = process.regs.cs;
*(stack_pointer + 0) = process.regs.rip;
*(stack_pointer - 3) = process.regs.r12;
*(stack_pointer - 4) = process.regs.r11;
*(stack_pointer - 5) = process.regs.r10;
*(stack_pointer - 6) = process.regs.r9;
*(stack_pointer - 7) = process.regs.r8;
*(stack_pointer - 8) = process.regs.rdi;
*(stack_pointer - 9) = process.regs.rsi;
*(stack_pointer - 10) = process.regs.rdx;
*(stack_pointer - 11) = process.regs.rcx;
*(stack_pointer - 12) = process.regs.rbx;
*(stack_pointer - 13) = process.regs.rax;
*(stack_pointer - 14) = process.regs.ds;
asm volatile("mov cr3, %0" : : "r" (process.physical_cr3) : "memory");
/*asm volatile("mov rax, %0; mov ds, ax; mov es, ax; mov fs, ax; mov gs, ax;"
: //No outputs
: "r" (process.data_selector)
: "rax");
@ -77,9 +99,7 @@ void switch_to_process(size_t index){
asm volatile("push %0; push %1; pushfq; pop rax; or rax, 0x200; push rax; push %2; push %3; iretq"
: //No outputs
: "r" (process.data_selector), "r" (process.user_rsp), "r" (process.code_selector), "r" (process.rip)
: "rax", "memory");
__builtin_unreachable();
: "rax", "memory");*/
}
size_t select_next_process(){
@ -89,8 +109,7 @@ size_t select_next_process(){
void save_context(const interrupt::syscall_regs& regs){
auto& process = processes[current_index];
process.user_rsp = regs.rsp;
process.rip = regs.rip;
process.regs = regs;
}
} //end of anonymous namespace
@ -105,10 +124,16 @@ void scheduler::start(){
started = true;
switch_to_process(processes.size() - 1);
current_index = 0;
rounds[current_index] = TURNOVER;
//Wait for the next interrupt
while(true){
asm volatile ("nop; nop; nop; nop");
}
}
void scheduler::kill_current_process(){
void scheduler::kill_current_process(const interrupt::syscall_regs& regs){
k_printf("Kill %u\n", current_index);
processes.erase(current_index);
@ -121,7 +146,7 @@ void scheduler::kill_current_process(){
//Select the next process and switch to it
auto index = select_next_process();
switch_to_process(index);
switch_to_process(regs, index);
}
void scheduler::reschedule(const interrupt::syscall_regs& regs){
@ -141,7 +166,7 @@ void scheduler::reschedule(const interrupt::syscall_regs& regs){
save_context(regs);
switch_to_process(index);
switch_to_process(regs, index);
} else {
++rounds[current_index];
}

View File

@ -809,7 +809,7 @@ bool create_paging(char* buffer, scheduler::process_t& process){
//2.1 Allocate user stack
allocate_user_memory(process, scheduler::user_stack_start, scheduler::user_stack_size, process.physical_user_stack);
process.user_rsp = scheduler::user_rsp;
process.regs.rsp = scheduler::user_rsp;
//2.2 Allocate all user segments
@ -865,22 +865,8 @@ bool create_paging(char* buffer, scheduler::process_t& process){
return true;
}
void exec_command(const std::vector<std::string>& params){
if(params.size() < 2){
k_print_line("exec: Need the name of the executable to read");
return;
}
if(!disks::mounted_partition() || !disks::mounted_disk()){
k_print_line("Nothing is mounted");
return;
}
scheduler::init();
auto content = read_elf_file(params[1], "exec");
void queue_process(const std::string& file){
auto content = read_elf_file(file, "exec");
if(!content){
return;
@ -896,12 +882,34 @@ void exec_command(const std::vector<std::string>& params){
return;
}
process.rip = header->e_entry;
process.regs.rip = header->e_entry;
process.code_selector = gdt::USER_CODE_SELECTOR + 3;
process.data_selector = gdt::USER_DATA_SELECTOR + 3;
process.regs.cs = gdt::USER_CODE_SELECTOR + 3;
process.regs.ds = gdt::USER_DATA_SELECTOR + 3;
process.regs.rflags = 0x200;
scheduler::queue_process(std::move(process));
}
void exec_command(const std::vector<std::string>& params){
if(params.size() < 2){
k_print_line("exec: Need the name of the executable to read");
return;
}
if(!disks::mounted_partition() || !disks::mounted_disk()){
k_print_line("Nothing is mounted");
return;
}
scheduler::init();
for(size_t i = 1; i < params.size(); ++i){
queue_process(params[i]);
}
scheduler::start();
}

View File

@ -42,7 +42,7 @@ void system_call_entry(const interrupt::syscall_regs& regs){
break;
case 0x666:
scheduler::kill_current_process();
scheduler::kill_current_process(regs);
break;
default:

15
programs/longone/Makefile Normal file
View File

@ -0,0 +1,15 @@
.PHONY: default clean
default: a.out
include ../../cpp.mk
%.cpp.o: src/%.cpp
$(CC) $(PROGRAM_FLAGS) $(CPP_FLAGS_64) $(WARNING_FLAGS) -c $< -o $@
a.out: main.cpp.o
$(CC) $(PROGRAM_LINK_FLAGS) $(CPP_FLAGS_64) -o a.out main.cpp.o
clean:
rm *.cpp.o
rm -rf a.out

View File

@ -0,0 +1,30 @@
//=======================================================================
// Copyright Baptiste Wicht 2013-2014.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================
#include <print.hpp>
#include <system.hpp>
volatile uint64_t current = 45;
uint64_t fibonacci_slow(uint64_t s){
if(s == 1 || s == 2){
return current;
}
return fibonacci_slow(s - 1) + fibonacci_slow(s - 2);
}
auto message = "I'm one";
int main(){
while(true){
fibonacci_slow(current);
print_line(message);
}
exit(0);
}

15
programs/longtwo/Makefile Normal file
View File

@ -0,0 +1,15 @@
.PHONY: default clean
default: a.out
include ../../cpp.mk
%.cpp.o: src/%.cpp
$(CC) $(PROGRAM_FLAGS) $(CPP_FLAGS_64) $(WARNING_FLAGS) -c $< -o $@
a.out: main.cpp.o
$(CC) $(PROGRAM_LINK_FLAGS) $(CPP_FLAGS_64) -o a.out main.cpp.o
clean:
rm *.cpp.o
rm -rf a.out

View File

@ -0,0 +1,30 @@
//=======================================================================
// Copyright Baptiste Wicht 2013-2014.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================
#include <print.hpp>
#include <system.hpp>
volatile uint64_t current = 45;
uint64_t fibonacci_slow(uint64_t s){
if(s == 1 || s == 2){
return current;
}
return fibonacci_slow(s - 1) + fibonacci_slow(s - 2);
}
auto message = "I'm two";
int main(){
while(true){
fibonacci_slow(current);
print_line(message);
}
exit(0);
}