Commit b31d98675726045c6d2bda1096424185e54bb020

Move the stack to a known location
  
2525#include "acpi.h"
2626#include "paging.h"
2727#include "fs/initrd.h"
28#include "fs/vfs.h"
2928#include "exec/elf32.h"
29#include "process/task.h"
3030
3131// Symmetry Kernel
3232
3535// Show messages on startup?
3636bool quiet_boot = false;
3737
38u32int initial_esp;
38uintptr initial_esp;
3939
4040
4141// This is the main function of the kernel - after the bootloader
4444// Although this currently just does a few tests and waits for interrupts
4545// after initialising everything, this will eventually just initialise and
4646// then start the init process.
47extern "C" void _main(struct multiboot * mboot_ptr, u32int initial_stack)
47extern "C" void _main(struct multiboot * mboot_ptr, uintptr initial_stack)
4848{
4949 // Execute static constructors
5050 construct();
102102
103103 // Mount the initial ramdisk
104104 fs_root = initrd::initialise(initrd_address);
105
106 // Start multitasking
107 multitasking::initialise();
105108 }
106109
107110 void start_error()
  
1818#include "iostream.h"
1919#include "scheduler.h"
2020#include "task.h"
21#include "paging.h"
2122
23extern uintptr initial_esp;
24extern paging::page_directory_t * current_directory;
25
2226namespace multitasking
2327{
28 void move_stack(void * new_stack_start, size_t size);
29
2430 void initialise()
2531 {
2632 debug::startup_message("Starting Multitasking");
2733
34 // Relocate the stack to a known location
35 move_stack((void *)0xE0000000, 0x2000);
2836
29 debug::startup_status(true);
37 debug::startup_status(false);
38 }
39
40 void move_stack(void * new_stack_start, size_t size)
41 {
42 // Allocate space for the new stack
43 for(uintptr i = (uintptr)new_stack_start; i >= ((uintptr)new_stack_start - size); i -= PAGE_SIZE)
44 {
45 // The stack should be user mode and writable
46 paging::allocate_frame(paging::get_page(i, true, current_directory), false, true);
47 }
48
49 // Flush the TLB by reading and writing the directory address
50 uintptr pd_addr;
51 asm volatile("mov %%cr3, %0" : "=r" (pd_addr));
52 asm volatile("mov %0, %%cr3" : : "r" (pd_addr));
53
54 uintptr old_stack_pointer;
55 uintptr old_base_pointer;
56
57 // Retrieve the old stack and base pointers
58 asm volatile("mov %%esp, %0" : "=r" (old_stack_pointer));
59 asm volatile("mov %%ebp, %0" : "=r" (old_base_pointer));
60
61 // Calculate offset and stack and base pointers to our new stack
62 uintptr offset = (uintptr)new_stack_start - initial_esp;
63 uintptr new_stack_pointer = old_stack_pointer + offset;
64 uintptr new_base_pointer = old_base_pointer + offset;
65
66 // Copy the old stack to our net stack location
67 memcpy((void *)new_stack_pointer, (void *)old_stack_pointer, initial_esp - old_stack_pointer);
68
69 // Recurse through all the values in the new stack
70 for(uintptr i = (uintptr)new_stack_start; i < (uintptr)new_stack_start - size; i -= 4)
71 {
72 uintptr temp = *(uintptr *)i;
73
74 // Assume that temp is a base pointer if it is in the range of the old stack, and
75 // translate it to our new stack location.
76 // This will also remap any other pointers that coincidentally fall in this range.
77 if((old_stack_pointer < temp) && (temp < initial_esp))
78 {
79 temp = temp + offset;
80 uintptr * temp2 = (uintptr *)i;
81 *temp2 = temp;
82 }
83 };
84
85 // Switch to the new stack
86 asm volatile("mov %0, %%esp" : : "r" (new_stack_pointer));
87 asm volatile("mov %0, %%ebp" : : "r" (new_base_pointer));
3088 }
3189}