|
From: Daniel R. <co...@us...> - 2006-10-19 17:48:56
|
Update of /cvsroot/trion/trion v0.2/loader In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv11615 Modified Files: console.cpp console.hpp entry.asm heap_manager.cpp heap_manager.hpp main.cpp Log Message: no message Index: main.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/loader/main.cpp,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** main.cpp 24 Jun 2006 15:01:32 -0000 1.19 --- main.cpp 19 Oct 2006 17:48:52 -0000 1.20 *************** *** 41,96 **** #include <console.hpp> #include <heap_manager.hpp> ! #include <mp_detect.hpp> ! #include <hal_object.hpp> #include <mmu.hpp> - #include <idt.hpp> - #include <exception.hpp> - #include <apic_local.hpp> - #include <timer.hpp> - #include <irq.hpp> - #include <ipi.hpp> - #include <cpu_info.hpp> ! #include <gdt.hpp> ! #include <ports.hpp> ! #include <systemcall.hpp> ! #include <task_context.hpp> ! ! extern "C" u32b user_main() { ! asm("mov %ss, %eax\n" "mov %eax, %ds\n" "mov %eax, %es\n" ! "mov %eax, %fs\n" "mov %eax, %gs\n"); ! ! // Print a red 'A' in the upper-left corner of the screen ! char* vidmem = reinterpret_cast<char*>(0x2000); ! vidmem[(80+78)*2 + 0] = 'A'; ! vidmem[(80+78)*2 + 1] = 4; ! // Demonstrate the systemcall-mechanism ! asm("mov $(syscall_return - 0xE0000000), %edx\n" ! "push %ebp\n" ! "mov %esp, %ecx\n" ! "sysenter\n" ! "syscall_return: pop %ebp"); ! vidmem[(160+78)*2 + 0] = 'B'; ! vidmem[(160+78)*2 + 1] = 4; ! // Try accessing some I/O ports by moving the x86 hardware cursor ! asm("mov $0x0f, %al\n" "mov $0x3d4, %dx\n" "out %al, %dx\n"); ! asm("mov $0x9e, %al\n" "mov $0x3d5, %dx\n" "out %al, %dx\n"); ! asm("mov $0x0e, %al\n" "mov $0x3d4, %dx\n" "out %al, %dx\n"); ! asm("mov $0x00, %al\n" "mov $0x3d5, %dx\n" "out %al, %dx\n"); ! while(true); // Waiting for IRQs } ! extern "C" int main(u32b image_size, u32b processor, u32b magic, void* grub) ! { ! static u32b number_processors; if(processor == 0) --- 41,118 ---- #include <console.hpp> + #include <virtual_memory.hpp> + #include <physical_memory.hpp> + #include <heap_manager.hpp> ! // #include <mp_detect.hpp> ! #include <cpu_node.hpp> #include <mmu.hpp> ! extern "C" int main(u32b processor, u32b phys_addr, u32b virt_addr, u32b magic, u32b grub) { ! if(processor == 0) ! { ! // Enabling the console early allows us to print debug info during the start-up phase ! InitializeConsole(virt_addr - 4096); ! cout().ClearScreen(); ! cout() << "Welcome to Trion v0.2" << endl; ! CreateBspNode(); // Spawn local classes for the boot-strap processor ! // Initialize global memory management ! InitializePhysAllocator(phys_addr); ! InitializeVirtAllocator(virt_addr); ! InitializeHeapManager(); ! // Activate hyperthreading and boot all application processors ! } } ! /* ! node().memory(0x1000) = map(0x1000).Global().PAT(7); ! node().memory(0x1000) = map(0x1000) | map::Global() | map::PAT(7); ! node().memory(0x1000) = Physical(0x10000) | Global() | PAT(7); ! ! bool global = node().memory(0x1000).Global(); ! bool global = Global(node().memory(0x1000)); ! ! node(memory)(0x1000); ! */ ! ! // bool global = node(memory)[0x1000].Global(); ! // node(memory)[0x1000] = map(0x1000) | map::Global() | PAT(7); ! ! /* ! static u32b number_processors = 0; ! ! if(processor == 0) ! { ! // Create the global memory manager objects ! CreateVirtualAllocator(0xE0000000 + image_size + 0x2000); ! CreatePhysicalAllocator(0x00100000 + image_size + 0x5000); ! ! CreateHeapManager(0xE0000000 + image_size + 0x1000); ! ! // Enable the console and print a welcome message ! CreateConsole(); ! ! cout().ClearScreen(); ! cout() << "Welcome to Trion v0.2" << endl; ! ! // Spawn a set of local classes for this processor ! ! // Activate hyperthreading and boot all application processors ! } ! else ! { ! // ap_flag |= 2; // Indicates that the hal is fully initialized, next AP may get started ! ! while(true) asm("hlt"); ! } ! } if(processor == 0) *************** *** 191,192 **** --- 213,215 ---- } } + */ Index: console.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/loader/console.cpp,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** console.cpp 24 Jun 2006 15:01:32 -0000 1.10 --- console.cpp 19 Oct 2006 17:48:52 -0000 1.11 *************** *** 39,113 **** #include <console.hpp> - #include <hal_object.hpp> - char console::itoa_buffer[] = {'0', 'x', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; const char endl = '\n'; ! console::console() { ! window = heap().CreateObject<vRange>(0xB8000); ! x86_console = static_cast<u08b*>(window->GetVirtualBase()); ! x_offset = y_offset = 0; } ! void console::Clear() { ! EnterMutex(); ! memset(x86_console, &x86_console[80*50], u08b(0)); ! x_offset = y_offset = 0; ! ExitMutex(); } console& console::operator<<(const char* string) { ! EnterMutex(); ! u16b index = 0; ! while(true) { ! while(y_offset < 25) { ! while(x_offset < 80) { ! if(string[index] != 0) // Print text until the zero-termination is reached ! { ! if(string[index] == '\n') ! { ! x_offset=80; ! } ! else ! { ! x86_console[y_offset*160+x_offset*2+0] = string[index]; ! x86_console[y_offset*160+x_offset*2+1] = 9; ! x_offset++; ! } ! index++; ! } ! else ! { ! ExitMutex(); ! return *this; ! } } ! ! // End of line - next line ! x_offset = 0; ! y_offset++; } - - // End of the screen - move up one line - u16b source = 160; - u16b dest = 0; - - while(dest < 160*24) x86_console[dest++] = x86_console[source++]; - while(dest < 160*25) x86_console[dest++] = 0; - - x_offset = 0; - y_offset--; } - - ExitMutex(); return *this; } --- 39,88 ---- #include <console.hpp> const char endl = '\n'; ! console::console(u32b video_memory) { ! x86_console = reinterpret_cast<u16b*>(video_memory); ! ! SetPosition(0,0); // Upper left corner ! SetColour(0x900); // Dark Blue } ! void console::SetPosition(u08b x_position, u08b y_position) { ! if(x_position < 80 && y_position < 25) ! position = y_position*80 + x_position; ! } ! void console::ScrollScreen() ! { ! u16b* line00 = &x86_console[80*00], *line01 = &x86_console[80*01]; ! u16b* line24 = &x86_console[80*24], *line25 = &x86_console[80*25]; ! memcopy(line01, line25, line00); // Move up by a line ! memset (line24, line25, u16b(0)); // Clear the last line } console& console::operator<<(const char* string) { ! CriticalSection section(&mtx); ! for(u16b i=0; string[i] != 0; i++) { ! if(string[i] == '\n') { ! position = ((position + 79)/80)*80; ! } ! else ! { ! if(position == 2000) { ! SetPosition(0, 24); ! ScrollScreen(); } ! x86_console[position++] = u16b(string[i]) | colour; } } return *this; } *************** *** 115,132 **** console& console::operator<<(u32b number) { ! EnterMutex(); ! u08b base = 16; for(u08b index = sizeof(itoa_buffer)-3; index > 1; index--) { ! char digit = number%base; ! number = number/base; itoa_buffer[index] = (digit < 10) ? digit + '0' : digit - 10 + 'a'; } ! ExitMutex(); ! ! operator<<(itoa_buffer); ! return *this; } --- 90,103 ---- console& console::operator<<(u32b number) { ! char digit, itoa_buffer[12] = {'0', 'x', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; for(u08b index = sizeof(itoa_buffer)-3; index > 1; index--) { ! digit = number%16; ! number = number/16; itoa_buffer[index] = (digit < 10) ? digit + '0' : digit - 10 + 'a'; } ! return cout() << itoa_buffer; } *************** *** 134,145 **** { char dummy[] = { character , 0}; ! operator<<(dummy); ! return *this; } ! char console_reserved[sizeof(console)]; ! console& cout() { ! return (reinterpret_cast<console&>(console_reserved)); } --- 105,141 ---- { char dummy[] = { character , 0}; ! return cout() << dummy; } ! void console::SetColour(u16b screen_colour) ! { ! colour = screen_colour; ! } ! void console::ClearScreen() { ! CriticalSection section(&mtx); ! ! memset(x86_console, &x86_console[80*25], u16b(0)); ! position = 0; } + + void Assert(bool condition, const char* string) + { + if(!condition) + { + cout().SetColour(0xC00); + cout() << string; + + while(true); + } + } + + u08b console_reserved[sizeof(console)]; + console& cout() { return reinterpret_cast<console&>(console_reserved); } + + console& InitializeConsole(u32b video_memory) + { + new (console_reserved) console(video_memory); + return reinterpret_cast<console&>(console_reserved); + }; Index: console.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/loader/console.hpp,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** console.hpp 24 Jun 2006 15:01:32 -0000 1.8 --- console.hpp 19 Oct 2006 17:48:52 -0000 1.9 *************** *** 42,69 **** #include <std_types.hpp> - #include <heap_manager.hpp> #include <mutex.hpp> ! class console : private mutex { private: ! u08b x_offset, y_offset; ! u08b* x86_console; ! ! vRange* window; ! static char itoa_buffer[12]; public: ! console(); ! ! void Clear(); console& operator<<(const char* string); console& operator<<(char character); ! console& operator<<(u32b number); }; ! extern char console_reserved[]; console& cout(); --- 42,70 ---- #include <std_types.hpp> #include <mutex.hpp> ! void Assert(bool condition, const char* string); ! ! class console { private: ! u16b* x86_console, position, colour; ! mutex mtx; ! void SetPosition(u08b x_position, u08b y_position); ! void ScrollScreen(); public: ! console(u32b video_memory); console& operator<<(const char* string); console& operator<<(char character); ! console& operator<<(u32b number); ! ! void SetColour(u16b screen_colour); ! void ClearScreen(); }; ! console& InitializeConsole(u32b video_memory); console& cout(); Index: heap_manager.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/loader/heap_manager.hpp,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** heap_manager.hpp 24 Jun 2006 15:01:32 -0000 1.9 --- heap_manager.hpp 19 Oct 2006 17:48:52 -0000 1.10 *************** *** 42,70 **** #include <std_types.hpp> - #include <hal_object.hpp> - - extern "C" u32b heap_address; - extern "C" u32b sizeof_hobject_cpp; - - class memory_stack - { - private: - u32b stack[32]; - u16b stack_pointer, stack_underflow; - - public: - memory_stack(u32b heap_begin); - - u32b AllocatePage(); - void DelocatePage(u32b base_address); - }; class vRange { private: ! u32b page_base, page_size; public: ! vRange(u32b physical_base); ~vRange(); --- 42,53 ---- #include <std_types.hpp> class vRange { private: ! u32b range_base, range_size; public: ! vRange(u32b physical_base, u32b number_pages = 1); ~vRange(); *************** *** 77,107 **** private: u32b memory_base, memory_left; - - u32b GetStackBase(); void RefreshWindow(); public: ! heap_manager(u32b initial_heap); void* AllocateMemory(u32b size_bytes); void AllocateMpStack(); - - template<class T, class P> T* heap_manager::CreateObject(P parameter) - { return reinterpret_cast<T*>(new (AllocateMemory(sizeof(T))) T(parameter)); } - - template<class T> T* heap_manager::CreateObject() - { return reinterpret_cast<T*>(new (AllocateMemory(sizeof(T))) T()); } - - hal_object* CreateHalObject(u08b processor); }; ! extern char heap_manager_reserved[]; heap_manager& heap(); ! extern char virt_allocator_reserved[]; ! extern char phys_allocator_reserved[]; ! memory_stack& virtual_allocator(); ! memory_stack& physical_allocator(); #endif --- 60,86 ---- private: u32b memory_base, memory_left; void RefreshWindow(); public: ! heap_manager(); void* AllocateMemory(u32b size_bytes); void AllocateMpStack(); }; ! heap_manager& InitializeHeapManager(); heap_manager& heap(); ! template<class T, class P> T& CreateObject(P parameter) ! { ! void* memory = heap().AllocateMemory(sizeof(T)); ! return *(new (memory) T(parameter)); ! } ! template<class T> T& CreateObject() ! { ! void* memory = heap().AllocateMemory(sizeof(T)); ! return *(new (memory) T()); ! } #endif Index: heap_manager.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/loader/heap_manager.cpp,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** heap_manager.cpp 24 Jun 2006 15:01:32 -0000 1.12 --- heap_manager.cpp 19 Oct 2006 17:48:52 -0000 1.13 *************** *** 40,114 **** #include <heap_manager.hpp> ! #include <mmu.hpp> ! #include <console.hpp> ! memory_stack::memory_stack(u32b heap_begin) ! { ! // Initialize the stack with sequential addresses ! for(u08b i=0; i<32; i++) stack[i] = heap_begin + 4096*i; ! stack_pointer = 0; // first element ! stack_underflow = 32; // last + 1 ! } ! u32b memory_stack::AllocatePage() ! { ! if(stack_pointer == stack_underflow) ! { ! cout() << "Panic: Ran out of virtual memory"; ! while(true); ! } ! return stack[stack_pointer++]; ! } ! void memory_stack::DelocatePage(u32b base_address) { ! stack[--stack_pointer] = base_address; ! } ! vRange::vRange(u32b physical_base) ! { ! page_base = virtual_allocator().AllocatePage(); ! page_size = 4096; ! get_hal_object()(memory)(page_base) = memory_mapper::kernel_mode(physical_base); } vRange::~vRange() { ! get_hal_object()(memory)(page_base) -= map_item(0).Present(); ! virtual_allocator().DelocatePage(page_base); ! } ! ! void* vRange::GetVirtualBase() ! { ! return reinterpret_cast<void*>(page_base); ! } ! ! u32b vRange::GetLength() ! { ! return page_size; ! } ! heap_manager::heap_manager(u32b initial_heap) ! { ! memory_base = initial_heap; ! memory_left = 4096 - sizeof_hobject_cpp; } ! u32b heap_manager::GetStackBase() ! { ! u32b stack_base(0); ! asm("mov %%esp, %%eax" : "=a"(stack_base)); ! return (stack_base + 0xfff) &0xfffff000; ! } void heap_manager::RefreshWindow() { ! u32b phys_page = physical_allocator().AllocatePage(); ! u32b virt_page = virtual_allocator().AllocatePage(); ! get_hal_object()(memory)(virt_page) = memory_mapper::kernel_mode(phys_page); memory_base = virt_page; --- 40,84 ---- #include <heap_manager.hpp> ! #include <physical_memory.hpp> ! #include <virtual_memory.hpp> ! #include <console.hpp> ! #include <cpu_node.hpp> ! #include <mmu.hpp> ! extern "C" u32b stack_address; ! vRange::vRange(u32b physical_base, u32b number_pages) { ! range_base = virt_allocator().AllocatePage(number_pages); ! range_size = 4096*number_pages; ! Assert(range_base < 0xE0400000, "vRange passed the 4 MiB mark"); ! for(u32b i=0; i < number_pages; i++, physical_base += 4096, range_base += 4096) ! Node(Memory)(range_base) = map_item(physical_base); } vRange::~vRange() { ! virt_allocator().DelocatePage(range_base, range_size/4096); ! for(u32b i=0; i < range_size/4096; i++, range_base += 4096) ! Node(Memory)(range_base) = map_item(0); } ! void* vRange::GetVirtualBase() { return reinterpret_cast<void*>(range_base); } ! u32b vRange::GetLength() { return range_size; } ! heap_manager::heap_manager() : memory_base(0), memory_left(0) {} void heap_manager::RefreshWindow() { ! u32b phys_page = phys_allocator().AllocatePage(); ! u32b virt_page = virt_allocator().AllocatePage(); ! Assert(virt_page < 0xE0400000, "HeapManager passed 4 MiB mark"); ! Node(Memory)(virt_page) = map_item(phys_page); memory_base = virt_page; *************** *** 118,137 **** void* heap_manager::AllocateMemory(u32b size_bytes) { // Aligning the allocation size increases performance size_bytes = (size_bytes + 7) &0xFFFFFFF8; - if(size_bytes > 4096) - { - cout() << "Panic: heap-manager doesn't support allocations > 4096 byte"; - while(true); - } if(memory_left < size_bytes) RefreshWindow(); - void* tmp = reinterpret_cast<void*>(memory_base); - memory_base += size_bytes; memory_left -= size_bytes; ! return tmp; } --- 88,103 ---- void* heap_manager::AllocateMemory(u32b size_bytes) { + Assert(size_bytes <= 4096, "HeapManager can't allocate chunks greater than 4096 bytes"); + // Aligning the allocation size increases performance size_bytes = (size_bytes + 7) &0xFFFFFFF8; if(memory_left < size_bytes) RefreshWindow(); memory_base += size_bytes; memory_left -= size_bytes; ! ! return reinterpret_cast<void*>(memory_base - size_bytes); } *************** *** 139,175 **** { // Allocate a new page for the stack & map it in ! u32b phys_page = physical_allocator().AllocatePage(); ! u32b virt_page = virtual_allocator().AllocatePage(); ! ! get_hal_object()(memory)(virt_page) = memory_mapper::kernel_mode(phys_page); ! ! heap_address = virt_page + 4096; // Variable used by the loader ! } ! hal_object* heap_manager::CreateHalObject(u08b processor) ! { ! u32b hal_location = GetStackBase() - sizeof_hobject_cpp; ! new ((void*)hal_location) hal_object(processor, GetStackBase()); ! return reinterpret_cast<hal_object*>(hal_location); } char heap_manager_reserved[sizeof(heap_manager)]; ! char virt_allocator_reserved[sizeof(memory_stack)]; ! char phys_allocator_reserved[sizeof(memory_stack)]; ! ! heap_manager& heap() ! { ! return (reinterpret_cast<heap_manager&>(heap_manager_reserved)); ! } ! ! memory_stack& virtual_allocator() ! { ! return (reinterpret_cast<memory_stack&>(virt_allocator_reserved)); ! } ! memory_stack& physical_allocator() { ! return (reinterpret_cast<memory_stack&>(phys_allocator_reserved)); } --- 105,123 ---- { // Allocate a new page for the stack & map it in ! u32b phys_page = phys_allocator().AllocatePage(); ! u32b virt_page = virt_allocator().AllocatePage(); ! Node(Memory)(virt_page) = map_item(phys_page); ! stack_address = virt_page + 4096; // Use by the ASM code to setup the kernel stack } char heap_manager_reserved[sizeof(heap_manager)]; ! heap_manager& heap() { return reinterpret_cast<heap_manager&>(heap_manager_reserved); } ! heap_manager& InitializeHeapManager() { ! new (heap_manager_reserved) heap_manager(); ! return reinterpret_cast<heap_manager&>(heap_manager_reserved); } Index: entry.asm =================================================================== RCS file: /cvsroot/trion/trion v0.2/loader/entry.asm,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** entry.asm 24 Jun 2006 15:01:32 -0000 1.12 --- entry.asm 19 Oct 2006 17:48:52 -0000 1.13 *************** *** 40,53 **** extern main ; C++ entrypoint (loader/main.cpp) ! extern kernel_start ; Defined in the linker script extern kernel_end ; Always aligned to the next 4096 bytes boundary ! global heap_address ; Holds current heap address global cpu_id ; Number of the current processor ! global ap_code_start ; Helps relocating the entrypoint later ! global ap_code_end ; to boot the application cpus ! ! global sizeof_hobject_cpp section .text --- 40,51 ---- extern main ; C++ entrypoint (loader/main.cpp) ! extern kernel_start ; Symbols defined in the linker script extern kernel_end ; Always aligned to the next 4096 bytes boundary ! global stack_address ; Holds current stack address for APs global cpu_id ; Number of the current processor ! global ap_code_start ; Helps relocating the entrypoint later, ! global ap_code_end ; when booting the application processors section .text *************** *** 69,80 **** pepper equ 0xDFFF8000 ; As the kernel is linked to an address in high memory ! salt equ 0xDFF00000 ; all symboles have to be fixed until paging gets enabled: ! ; pepper = ap bootup (0x8000), salt = bsp code (0x100000) ! ; Addresses of the system tables relative to the current heap pointer ! stack_addr equ -(4096*1) ; The current cpu's stack gets created here ! hpagetable equ -(4096*2) ; High memory pagetable (0xE0000000) ! ipagetable equ -(4096*3) ; Idempotential pt needed for boot-up ! pagedirect equ -(4096*4) ; Initial pagedirectory ; Flags for the paging structures --- 67,77 ---- pepper equ 0xDFFF8000 ; As the kernel is linked to an address in high memory ! salt equ 0xDFF00000 ; all symboles must get fixed until paging is enabled: ! ; Addresses of the system tables relative to the end of the kernel image ! ipagetable equ 4096*3 - 0x10000 ; Idempotential page-table needed for boot-up ! hpagetable equ 4096*2 - 0x10000 ; High memory pagetable (0xE0000000) ! pagedirect equ 4096*1 - 0x10000 ; Initial pagedirectory ! boot_stack equ 4096*0 - 0x10000 ; The boot processor's stack ; Flags for the paging structures *************** *** 82,162 **** USER_MODE equ 7 ; ring3 | present | read&write - sizeof_hobject_asm equ 32*4 ; Assumed size (needed for memory reservation) - sizeof_hobject_cpp dd 32*4 - bsp_entrypoint: ! ; Set up a stack and reserve some memory for the hal-object ! mov esp, [heap_address - salt] ! add esp, stack_addr + 4096 ! sub esp, sizeof_hobject_asm ! ! ; Push the information passed to us by GRUB on the stack ! mov ecx, [cpu_id - salt] ! mov edx, kernel_end ! sub edx, kernel_start push ebx ; pointer to grub multiboot structure push eax ; magic - 0x2BADB002 - push ecx ; cpu# - push edx ; length of the kernel image - - ; Clear the region that will be used for the paging structures - xor eax, eax - mov edi, [heap_address - salt] - add edi, pagedirect - mov ecx, 1024*3 - rep stosd ! ; Map kernel to higher memory region ! mov edi, [heap_address - salt] ! add edi, pagedirect + 3584 ! mov eax, [heap_address - salt] ! add eax, hpagetable + SUPERVISOR ! stosd ! mov edi, [heap_address - salt] ! add edi, hpagetable ! mov eax, kernel_start - salt + SUPERVISOR ! mov edx, kernel_end sub edx, kernel_start - mov ecx, 12 - shr edx, cl ; eax = kernel_start | 3, edi = hpagetable - mov ecx, edx ; ecx = numbers of pages occupied by the nucleus stosd add eax, 4096 ! loop $-6 ! ; Append a page for the stack and another one for the heap at the end of the kernel ! mov eax, [heap_address - salt] ! add eax, stack_addr + SUPERVISOR stosd ! mov eax, [heap_address - salt] ! add eax, 0x00000000 + SUPERVISOR stosd ; Map the current code idempotentially ! mov edi, [heap_address - salt] ! add edi, pagedirect ! mov eax, [heap_address - salt] ! add eax, ipagetable + SUPERVISOR ! stosd ! mov edi, [heap_address - salt] ! add edi, ipagetable + 1024 ! mov eax, kernel_start - salt + SUPERVISOR ! stosd ! ; Allow the paging structs to be accessed though the last 4mb of the address-space ! mov edi, [heap_address - salt] ! add edi, pagedirect + 4092 ! mov eax, [heap_address - salt] ! add eax, pagedirect + SUPERVISOR ! stosd ; Enable paging ! mov eax, [heap_address - salt] ! add eax, pagedirect mov cr3, eax --- 79,134 ---- USER_MODE equ 7 ; ring3 | present | read&write bsp_entrypoint: ! ; Set up a stack and store the GRUB information on it ! mov eax, (kernel_end - salt) + boot_stack + 4096 ! mov esp, eax + push eax ; reserved memory for the node object pointer push ebx ; pointer to grub multiboot structure push eax ; magic - 0x2BADB002 ! ; Map kernel to higher memory region (3.5 GiB and above) ! mov ebx, (kernel_end - salt) + pagedirect + 3584 ! mov eax, (kernel_end - salt) + hpagetable + SUPERVISOR ! mov [ebx], eax ! mov edi, (kernel_end - salt) + hpagetable ! mov eax, (kernel_start - salt) + SUPERVISOR ! mov edx, kernel_end - 0x10000 sub edx, kernel_start + map_kernel: stosd + add eax, 4096 ! sub edx, 4096 ! test edx, edx ! jne map_kernel ! ! ; Append a page for the stack ! mov eax, (kernel_end - salt) + boot_stack + SUPERVISOR stosd ! ; Reserve another page for the console ! mov eax, 0xB8000 + SUPERVISOR stosd ; Map the current code idempotentially ! mov ebx, (kernel_end - salt) + pagedirect ! mov eax, (kernel_end - salt) + ipagetable + SUPERVISOR ! mov [ebx], eax ! mov ebx, (kernel_end - salt) + ipagetable + 1024 ! mov eax, (kernel_start - salt) + SUPERVISOR ! mov [ebx], eax ! ; Allow the paging structs to be accessed though the last 4 MiB of the address-space ! mov ebx, (kernel_end - salt) + pagedirect + 4092 ! mov eax, (kernel_end - salt) + pagedirect + SUPERVISOR ! mov [ebx], eax ; Enable paging ! mov eax, (kernel_end - salt) + pagedirect mov cr3, eax *************** *** 179,189 **** bsp_paging: ; Prepare the stack for virtual addressing ! mov eax, [heap_address] ! add eax, salt - 12288 mov ebp, eax ! sub eax, 16 + sizeof_hobject_asm mov esp, eax ! inc dword [cpu_id] call main ; Call the C++ entry point --- 151,164 ---- bsp_paging: ; Prepare the stack for virtual addressing ! mov eax, kernel_end + boot_stack + 4096 - 4 mov ebp, eax ! sub eax, 8 mov esp, eax ! push dword kernel_end - 0x10000 + 8192 ! push dword kernel_end - 0x10000 - salt + 12288 ! ! push dword [cpu_id] ! inc dword [cpu_id] call main ; Call the C++ entry point *************** *** 201,205 **** mov ds, ax ! lgdt [ap_gdt_selector - ap_code_start] ; Auto-relocatable since cs=ds, and AP's start at EIP=0 mov eax, cr0 --- 176,180 ---- mov ds, ax ! lgdt [ap_gdt_selector - ap_code_start] ; Auto-relocatable as CS=DS and APs start at IP=0 mov eax, cr0 *************** *** 217,222 **** ap_gdt_selector: ! dw (gdt_end - gdt_start) - 1 ! dd gdt_start - salt ap_code_end: --- 192,197 ---- ap_gdt_selector: ! dw (gdt_end - gdt_start) - 1 ! dd gdt_start - salt ap_code_end: *************** *** 225,229 **** bits 32 ap_pmode: ! mov eax, kernel_end - salt mov cr3, eax --- 200,204 ---- bits 32 ap_pmode: ! mov eax, (kernel_end - salt) + pagedirect mov cr3, eax *************** *** 238,257 **** ap_paging: ; Prepare the stack for virtual addressing ! mov eax, [heap_address] mov esp, eax - sub eax, sizeof_hobject_asm mov ebp, eax ! xor eax, eax ! mov ebx, [cpu_id] ! mov ecx, kernel_end ! sub ecx, kernel_start ! inc dword [cpu_id] ! push eax ; pointer to grub multiboot structure = 0 ! push eax ; magic = 0 ! push ebx ; cpu# ! push ecx ; length of the kernel image call main ; Call the C++ entry point --- 213,226 ---- ap_paging: ; Prepare the stack for virtual addressing ! mov eax, [stack_address] ! sub eax, 4 mov esp, eax mov ebp, eax ! mov eax, [cpu_id] inc dword [cpu_id] ! sub esp, 16 ; skip 4 parameters ! push eax ; cpu number call main ; Call the C++ entry point *************** *** 262,267 **** section .data ! heap_address dd (kernel_end - salt) + 4096*4 ; Holds address of the stack-end, initially ! cpu_id dd 0x0000000 ; kernel_end + sizeof(paging_structures + stack) gdt_selector: --- 231,236 ---- section .data ! stack_address dd 0 ; Holds address of AP's stack area (initialized by C++ kernel) ! cpu_id dd 0 gdt_selector: |