Commit d7aa43cf12f9172a743c37c4b30fd48522eb006d
- Diff rendering mode:
- inline
- side by side
kernel/kernel.cc
(1 / 1)
|   | |||
| 104 | 104 | fs_root = initrd::initialise(initrd_address); | |
| 105 | 105 | ||
| 106 | 106 | // Start multitasking | |
| 107 | multitasking::initialise(); | ||
| 107 | //multitasking::initialise(); | ||
| 108 | 108 | } | |
| 109 | 109 | ||
| 110 | 110 | void start_error() |
|   | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008 Stephen Gentle | ||
| 3 | * | ||
| 4 | * Permission to use, copy, modify, and distribute this software for any | ||
| 5 | * purpose with or without fee is hereby granted, provided that the above | ||
| 6 | * copyright notice and this permission notice appear in all copies. | ||
| 7 | * | ||
| 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include "virtual_address_space.h" | ||
| 18 | #include "common.h" | ||
| 19 | |||
| 20 | virtual_address_space::virtual_address_space() | ||
| 21 | { | ||
| 22 | } | ||
| 23 | |||
| 24 | virtual_address_space::virtual_address_space(paging::page_directory_t * dir, heap::heap * addr_heap) | ||
| 25 | : m_page_directory(dir), m_heap(addr_heap) | ||
| 26 | { | ||
| 27 | } | ||
| 28 | |||
| 29 | virtual_address_space::~virtual_address_space() | ||
| 30 | { | ||
| 31 | } |
|   | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008 Stephen Gentle | ||
| 3 | * | ||
| 4 | * Permission to use, copy, modify, and distribute this software for any | ||
| 5 | * purpose with or without fee is hereby granted, provided that the above | ||
| 6 | * copyright notice and this permission notice appear in all copies. | ||
| 7 | * | ||
| 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #ifndef ADDRESS_SPACE_H | ||
| 18 | #define ADDRESS_SPACE_H | ||
| 19 | |||
| 20 | #include "common.h" | ||
| 21 | #include "paging.h" | ||
| 22 | |||
| 23 | #include "mm/kheap.h" | ||
| 24 | |||
| 25 | class virtual_address_space | ||
| 26 | { | ||
| 27 | public: | ||
| 28 | // Default constructor | ||
| 29 | virtual_address_space(); | ||
| 30 | |||
| 31 | // Constructor that sets page directory and heap | ||
| 32 | virtual_address_space(paging::page_directory_t * dir, heap::heap * addr_heap); | ||
| 33 | |||
| 34 | // Deconstructor | ||
| 35 | ~virtual_address_space(); | ||
| 36 | |||
| 37 | // Set the page directory of this address space to an existing one | ||
| 38 | void set_page_directory(paging::page_directory_t * directory) | ||
| 39 | { | ||
| 40 | m_page_directory = directory; | ||
| 41 | } | ||
| 42 | |||
| 43 | paging::page_directory * get_page_directory() | ||
| 44 | { | ||
| 45 | return m_page_directory; | ||
| 46 | } | ||
| 47 | |||
| 48 | private: | ||
| 49 | // This address space's page directory | ||
| 50 | paging::page_directory_t * m_page_directory; | ||
| 51 | |||
| 52 | // This address space's heap | ||
| 53 | heap::heap * m_heap; | ||
| 54 | }; | ||
| 55 | |||
| 56 | |||
| 57 | #endif |
kernel/process/process.cc
(15 / 6)
|   | |||
| 17 | 17 | #include "process/process.h" | |
| 18 | 18 | #include "process/scheduler.h" | |
| 19 | 19 | ||
| 20 | Process::Process() | ||
| 20 | process::process() | ||
| 21 | 21 | : m_id(0), m_threads(), m_desc() | |
| 22 | 22 | { | |
| 23 | 23 | m_id = scheduler::add_process(this); | |
| 24 | 24 | } | |
| 25 | 25 | ||
| 26 | Process::Process(Process * parent) | ||
| 26 | process::process(process * parent) | ||
| 27 | 27 | : m_id(0), m_threads(), m_desc() | |
| 28 | 28 | { | |
| 29 | 29 | m_id = scheduler::add_process(this); | |
| … | … | ||
| 32 | 32 | m_desc = parent->m_desc;// + "[F]"; | |
| 33 | 33 | } | |
| 34 | 34 | ||
| 35 | Process::~Process() | ||
| 35 | process::~process() | ||
| 36 | 36 | { | |
| 37 | 37 | scheduler::remove_process(this); | |
| 38 | 38 | } | |
| 39 | 39 | ||
| 40 | size_t Process::add_thread(Thread * t) | ||
| 40 | size_t process::add_thread(thread * t) | ||
| 41 | 41 | { | |
| 42 | 42 | // Add the thread onto the thread vector | |
| 43 | 43 | m_threads.push_back(t); | |
| 44 | 44 | ||
| 45 | // Add the thread to the scheduler's queue | ||
| 46 | scheduler::add_thread(t); | ||
| 47 | |||
| 45 | 48 | // Return the thread's ID | |
| 46 | 49 | return t->get_id(); | |
| 47 | 50 | } | |
| 48 | 51 | ||
| 49 | void Process::remove_thread(Thread * t) | ||
| 52 | void process::remove_thread(thread * t) | ||
| 50 | 53 | { | |
| 51 | if(t != NULL) | ||
| 54 | // Check that t is not null | ||
| 55 | if(t == NULL) | ||
| 56 | { | ||
| 52 | 57 | return; | |
| 58 | } | ||
| 59 | |||
| 60 | // Remove the thread from the scheduler | ||
| 61 | scheduler::remove_thread(t); | ||
| 53 | 62 | } |
kernel/process/process.h
(25 / 9)
|   | |||
| 20 | 20 | #include "common.h" | |
| 21 | 21 | #include "string.h" | |
| 22 | 22 | #include "vector.h" | |
| 23 | |||
| 23 | 24 | #include "process/thread.h" | |
| 25 | #include "mm/virtual_address_space.h" | ||
| 24 | 26 | ||
| 25 | 27 | using namespace std; | |
| 26 | 28 | ||
| 27 | class Process | ||
| 29 | class process | ||
| 28 | 30 | { | |
| 29 | 31 | public: | |
| 30 | 32 | // Create a normal process | |
| 31 | Process(); | ||
| 33 | process(); | ||
| 32 | 34 | ||
| 33 | 35 | // Fork a process from another | |
| 34 | Process(Process * parent); | ||
| 36 | process(process * parent); | ||
| 35 | 37 | ||
| 36 | 38 | // Destroy this process and remove it from the scheduler | |
| 37 | ~Process(); | ||
| 39 | ~process(); | ||
| 38 | 40 | ||
| 39 | 41 | // Add a thread to this process. Returns ID assigned to thread | |
| 40 | size_t add_thread(Thread * t); | ||
| 42 | size_t add_thread(thread * t); | ||
| 41 | 43 | ||
| 42 | 44 | // Remove a thread from this process | |
| 43 | void remove_thread(Thread * t); | ||
| 45 | void remove_thread(thread * t); | ||
| 44 | 46 | ||
| 45 | 47 | // Kill the process | |
| 46 | 48 | void kill(); | |
| … | … | ||
| 51 | 51 | size_t get_id() { return m_id; }; | |
| 52 | 52 | ||
| 53 | 53 | // Get this thread's parent | |
| 54 | Process * get_parent() { return m_parent; }; | ||
| 54 | process * get_parent() { return m_parent; }; | ||
| 55 | 55 | ||
| 56 | // Return this process' virtual address space | ||
| 57 | virtual_address_space * get_address_space() | ||
| 58 | { | ||
| 59 | return m_address_space; | ||
| 60 | } | ||
| 61 | |||
| 62 | void set_address_space(virtual_address_space * addr) | ||
| 63 | { | ||
| 64 | m_address_space = addr; | ||
| 65 | } | ||
| 66 | |||
| 56 | 67 | private: | |
| 57 | 68 | // The process ID | |
| 58 | 69 | size_t m_id; | |
| 59 | 70 | ||
| 71 | // This process' address space | ||
| 72 | virtual_address_space * m_address_space; | ||
| 73 | |||
| 60 | 74 | // The threads that this process contains | |
| 61 | vector<Thread *> m_threads; | ||
| 75 | vector<thread *> m_threads; | ||
| 62 | 76 | ||
| 63 | 77 | // The parent of this process | |
| 64 | Process * m_parent; | ||
| 78 | process * m_parent; | ||
| 65 | 79 | ||
| 66 | 80 | // Description of this process | |
| 67 | 81 | std::string m_desc; |
kernel/process/scheduler.cc
(47 / 10)
|   | |||
| 15 | 15 | */ | |
| 16 | 16 | ||
| 17 | 17 | #include "scheduler.h" | |
| 18 | #include "task.h" | ||
| 18 | 19 | #include "timer.h" | |
| 19 | 20 | ||
| 21 | // The current thread. | ||
| 22 | thread * current_thread = NULL; | ||
| 23 | |||
| 20 | 24 | namespace scheduler | |
| 21 | 25 | { | |
| 22 | vector<Process *> m_processes; | ||
| 23 | vector<Thread *> m_threads; | ||
| 26 | // Vectors for storing the threads and processes the scheduler will use | ||
| 27 | vector<process *> m_processes; | ||
| 28 | vector<thread *> m_threads; | ||
| 24 | 29 | ||
| 30 | // Keep track of process IDs | ||
| 31 | size_t process_id = 0; | ||
| 32 | |||
| 25 | 33 | void schedule() | |
| 26 | 34 | { | |
| 27 | // TODO: Implement | ||
| 35 | // If we haven't set up multitasking yet, just exit early | ||
| 36 | if(current_thread == NULL) | ||
| 37 | { | ||
| 38 | return; | ||
| 39 | } | ||
| 40 | |||
| 41 | // Read the esp, ebp registers | ||
| 42 | uintptr esp, ebp, eip; | ||
| 43 | |||
| 44 | esp = multitasking::read_esp(); | ||
| 45 | ebp = multitasking::read_ebp(); | ||
| 46 | |||
| 47 | // Get the current instruction pointer. | ||
| 48 | eip = read_eip(); | ||
| 49 | |||
| 50 | // If we just executed read_eip, then eip will contain the correct value. We may | ||
| 51 | // have just switched tasks though, and jumped to this address, and in that case | ||
| 52 | // we would have just executed switch_task. We'll set the value to 0x12345 later | ||
| 53 | // on so we know what is happenning now | ||
| 54 | if(eip == 0x12345) | ||
| 55 | { | ||
| 56 | return; | ||
| 57 | } | ||
| 58 | |||
| 59 | // Save the registers | ||
| 60 | current_thread->set_eip(eip); | ||
| 61 | current_thread->set_stack_ptr(esp, ebp); | ||
| 62 | |||
| 63 | // TODO: Get next task in vector | ||
| 64 | |||
| 65 | // Switch tasks | ||
| 66 | multitasking::switch_tasks(eip, esp, ebp, current_thread->get_parent()->get_address_space()); | ||
| 28 | 67 | } | |
| 29 | 68 | ||
| 30 | size_t add_process(Process * p) | ||
| 69 | size_t add_process(process * p) | ||
| 31 | 70 | { | |
| 32 | 71 | // Make sure [p] is not null | |
| 33 | 72 | if(p == NULL) | |
| … | … | ||
| 77 | 77 | // Add the process to the scheduler's vector | |
| 78 | 78 | m_processes.push_back(p); | |
| 79 | 79 | ||
| 80 | // TODO: Assign thread ID? | ||
| 81 | |||
| 82 | return p->get_id(); | ||
| 80 | return ++process_id; | ||
| 83 | 81 | } | |
| 84 | 82 | ||
| 85 | void remove_process(Process * p) | ||
| 83 | void remove_process(process * p) | ||
| 86 | 84 | { | |
| 87 | 85 | // Make sure [p] is not null | |
| 88 | 86 | if(p == NULL) | |
| … | … | ||
| 91 | 91 | // TODO: Implement | |
| 92 | 92 | } | |
| 93 | 93 | ||
| 94 | void add_thread(Thread * t) | ||
| 94 | void add_thread(thread * t) | ||
| 95 | 95 | { | |
| 96 | 96 | // Check that [t] is not null | |
| 97 | 97 | if(t == NULL) | |
| … | … | ||
| 103 | 103 | m_threads.push_back(t); | |
| 104 | 104 | } | |
| 105 | 105 | ||
| 106 | void remove_thread(Thread * t) | ||
| 106 | void remove_thread(thread * t) | ||
| 107 | 107 | { | |
| 108 | 108 | // Check [t] is not null | |
| 109 | 109 | if(t == NULL) |
kernel/process/scheduler.h
(4 / 4)
|   | |||
| 26 | 26 | void schedule(); | |
| 27 | 27 | ||
| 28 | 28 | // Add a process to the scheduler and return its pid | |
| 29 | size_t add_process(Process * p); | ||
| 29 | size_t add_process(process * p); | ||
| 30 | 30 | ||
| 31 | 31 | // Remove a process from the scheduler | |
| 32 | void remove_process(Process * p); | ||
| 32 | void remove_process(process * p); | ||
| 33 | 33 | ||
| 34 | 34 | // Add a thread to the scheduler | |
| 35 | void add_thread(Thread * t); | ||
| 35 | void add_thread(thread * t); | ||
| 36 | 36 | ||
| 37 | 37 | // Remove a thread from the scheduler | |
| 38 | void remove_thread(Thread * t); | ||
| 38 | void remove_thread(thread * t); | ||
| 39 | 39 | ||
| 40 | 40 | // Sleep the current task for a certian amount of time | |
| 41 | 41 | void sleep(size_t t); |
kernel/process/task.cc
(26 / 7)
|   | |||
| 22 | 22 | ||
| 23 | 23 | extern uintptr initial_esp; | |
| 24 | 24 | extern paging::page_directory_t * current_directory; | |
| 25 | extern heap::heap * kheap; | ||
| 26 | extern thread * current_thread; | ||
| 25 | 27 | ||
| 26 | 28 | namespace multitasking | |
| 27 | { | ||
| 29 | { | ||
| 28 | 30 | void move_stack(void * new_stack_start, size_t size); | |
| 29 | 31 | ||
| 30 | 32 | void initialise() | |
| 31 | 33 | { | |
| 32 | debug::startup_message("Starting Multitasking"); | ||
| 34 | debug::startup_message("Starting Scheduler"); | ||
| 33 | 35 | ||
| 34 | // Relocate the stack to a known location | ||
| 36 | // Disable interrupts while we start multitasking | ||
| 37 | disable(); | ||
| 38 | |||
| 39 | // Relocate the stack to a known location | ||
| 35 | 40 | move_stack((void *)0xE0000000, 0x2000); | |
| 36 | 41 | ||
| 37 | debug::startup_status(false); | ||
| 42 | // Make a new process for the kernel | ||
| 43 | process * kernel_process = new process(); | ||
| 44 | |||
| 45 | // Make a virtual address space object that points to the kernel's virtual memory | ||
| 46 | virtual_address_space * addr = new virtual_address_space(current_directory, kheap); | ||
| 47 | kernel_process->set_address_space(addr); | ||
| 48 | |||
| 49 | current_thread = new thread(kernel_process); | ||
| 50 | |||
| 51 | // Re-enable interrupts, starting the scheduler | ||
| 52 | enable(); | ||
| 53 | |||
| 54 | debug::startup_status(true); | ||
| 38 | 55 | } | |
| 39 | 56 | ||
| 57 | // Move the initial kernel stack that Grub leaves us with to [new_stack_start] | ||
| 40 | 58 | void move_stack(void * new_stack_start, size_t size) | |
| 41 | 59 | { | |
| 42 | 60 | // Allocate space for the new stack | |
| … | … | ||
| 75 | 75 | // Retrieve the old stack and base pointers | |
| 76 | 76 | asm volatile("mov %%esp, %0" : "=r" (old_stack_pointer)); | |
| 77 | 77 | asm volatile("mov %%ebp, %0" : "=r" (old_base_pointer)); | |
| 78 | |||
| 78 | |||
| 79 | 79 | // Calculate offset and stack and base pointers to our new stack | |
| 80 | 80 | uintptr offset = (uintptr)new_stack_start - initial_esp; | |
| 81 | 81 | uintptr new_stack_pointer = old_stack_pointer + offset; | |
| … | … | ||
| 88 | 88 | for(uintptr i = (uintptr)new_stack_start; i < (uintptr)new_stack_start - size; i -= 4) | |
| 89 | 89 | { | |
| 90 | 90 | uintptr temp = *(uintptr *)i; | |
| 91 | |||
| 91 | |||
| 92 | 92 | // Assume that temp is a base pointer if it is in the range of the old stack, and | |
| 93 | 93 | // translate it to our new stack location. | |
| 94 | 94 | // This will also remap any other pointers that coincidentally fall in this range. | |
| … | … | ||
| 99 | 99 | *temp2 = temp; | |
| 100 | 100 | } | |
| 101 | 101 | }; | |
| 102 | |||
| 102 | |||
| 103 | 103 | // Switch to the new stack | |
| 104 | 104 | asm volatile("mov %0, %%esp" : : "r" (new_stack_pointer)); | |
| 105 | 105 | asm volatile("mov %0, %%ebp" : : "r" (new_base_pointer)); | |
| 106 | 106 | } | |
| 107 | |||
| 107 | 108 | } |
kernel/process/task.h
(8 / 0)
|   | |||
| 20 | 20 | #include "common.h" | |
| 21 | 21 | #include "scheduler.h" | |
| 22 | 22 | ||
| 23 | extern "C" uintptr read_eip(); | ||
| 24 | |||
| 23 | 25 | namespace multitasking | |
| 24 | 26 | { | |
| 25 | 27 | void initialise(); | |
| 28 | |||
| 29 | // Defined in platform specific task.cc | ||
| 30 | uintptr read_esp(); | ||
| 31 | uintptr read_ebp(); | ||
| 32 | |||
| 33 | void switch_tasks(uintptr eip, uintptr esp, uintptr ebp, virtual_address_space * addr); | ||
| 26 | 34 | } | |
| 27 | 35 | ||
| 28 | 36 | #endif |
kernel/process/thread.cc
(4 / 6)
|   | |||
| 17 | 17 | #include "process/process.h" | |
| 18 | 18 | #include "process/thread.h" | |
| 19 | 19 | ||
| 20 | |||
| 21 | Thread::Thread(Process * parent) : | ||
| 22 | m_parent(parent) | ||
| 20 | thread::thread(process * parent) | ||
| 21 | : m_parent(parent), m_eip(0), m_esp(0), m_ebp(0) | ||
| 23 | 22 | { | |
| 24 | |||
| 25 | // TODO: Implement | ||
| 23 | parent->add_thread(this); | ||
| 26 | 24 | } | |
| 27 | 25 | ||
| 28 | Thread::~Thread() | ||
| 26 | thread::~thread() | ||
| 29 | 27 | { | |
| 30 | 28 | m_parent->remove_thread(this); | |
| 31 | 29 | } |
kernel/process/thread.h
(23 / 13)
|   | |||
| 20 | 20 | ||
| 21 | 21 | #include "common.h" | |
| 22 | 22 | ||
| 23 | // Forward declaration of process class so this will compile | ||
| 24 | class Process; | ||
| 23 | // Forward declarations of process class | ||
| 24 | class process; | ||
| 25 | 25 | ||
| 26 | class Thread | ||
| 26 | class thread | ||
| 27 | 27 | { | |
| 28 | 28 | public: | |
| 29 | enum Status | ||
| 29 | enum status | ||
| 30 | 30 | { | |
| 31 | 31 | Ready, | |
| 32 | 32 | Running, | |
| … | … | ||
| 37 | 37 | typedef int (* ThreadStart)(void *); | |
| 38 | 38 | ||
| 39 | 39 | // Make a normal thread | |
| 40 | Thread(Process * parent, ThreadStart start_function, void * param); | ||
| 40 | thread(process * parent, ThreadStart start_function, void * param); | ||
| 41 | 41 | ||
| 42 | Thread(Process * parent); | ||
| 42 | thread(process * parent); | ||
| 43 | 43 | ||
| 44 | 44 | // Remove this thread | |
| 45 | ~Thread(); | ||
| 45 | ~thread(); | ||
| 46 | 46 | ||
| 47 | 47 | // Accessor functions to get and set information about the thread | |
| 48 | 48 | size_t get_id() { return m_id; }; | |
| 49 | 49 | size_t get_errno() { return m_errno; }; | |
| 50 | Process * get_parent() { return m_parent; }; | ||
| 51 | Status get_status() { return m_status; }; | ||
| 50 | process * get_parent() { return m_parent; }; | ||
| 51 | status get_status() { return m_status; }; | ||
| 52 | 52 | ||
| 53 | void set_status(Status s) { m_status = s; }; | ||
| 54 | void set_errno(size_t n) { m_errno = n; }; | ||
| 53 | void set_status(status s) { m_status = s; }; | ||
| 54 | void set_errno(size_t n) { m_errno = n; }; | ||
| 55 | void set_eip(uintptr eip) { m_eip = eip; }; | ||
| 55 | 56 | ||
| 57 | void set_stack_ptr(uintptr esp, uintptr ebp) { m_esp = esp; m_ebp = ebp; }; | ||
| 58 | |||
| 56 | 59 | private: | |
| 57 | 60 | // This thread's parent process | |
| 58 | Process * m_parent; | ||
| 61 | process * m_parent; | ||
| 59 | 62 | ||
| 63 | // This thread's instruction pointer | ||
| 64 | uintptr m_eip; | ||
| 65 | |||
| 66 | // This thread's stack | ||
| 67 | //stack * m_stack; | ||
| 68 | uintptr m_esp, m_ebp; | ||
| 69 | |||
| 60 | 70 | // The status of this thread | |
| 61 | Status m_status; | ||
| 71 | status m_status; | ||
| 62 | 72 | ||
| 63 | 73 | // The thread's last error | |
| 64 | 74 | size_t m_errno; |

