mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
x64 now compiles again and runs on real hardware.
A nasty bug was fixed that caused triple faults on systems with > 1 GiB RAM.
This commit is contained in:
parent
8c146f14c0
commit
0b1c2a77c9
15 changed files with 517 additions and 16 deletions
|
@ -29,10 +29,15 @@
|
|||
.type _start, @function
|
||||
_start:
|
||||
|
||||
pushq %rsi
|
||||
pushq %rdi
|
||||
|
||||
call initialize_standard_library
|
||||
|
||||
popq %rdi
|
||||
popq %rsi
|
||||
|
||||
# Run main
|
||||
# TODO: Sortix should set the initial values before this point!
|
||||
call main
|
||||
|
||||
# Terminate the process with main's exit code.
|
||||
|
|
|
@ -37,6 +37,7 @@ ifdef X86FAMILY
|
|||
$(CPU)/syscall.o \
|
||||
$(CPU)/thread.o \
|
||||
$(CPU)/scheduler.o \
|
||||
$(CPU)/process.o \
|
||||
x86-family/x86-family.o
|
||||
CPUFLAGS:=$(CPUFLAGS) -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow
|
||||
endif
|
||||
|
|
|
@ -214,10 +214,10 @@ namespace Sortix
|
|||
GDT::Init();
|
||||
|
||||
#ifdef PLATFORM_X64
|
||||
Log::Print("Halt: CPU X64 cannot boot because interrupts are not yet "
|
||||
Log::Print("Halt: CPU x64 cannot boot because interrupts are not yet "
|
||||
"supported under 64-bit Sortix.\n");
|
||||
Log::Print("Sorry, it simply isn't possible to fully boot Sortix in x64 mode yet.\n");
|
||||
Log::Print("X64 may be working when Sortix 0.5 comes out, or try the git master.\n");
|
||||
Log::Print("x64 may be working when Sortix 0.6 comes out, or try the git master.\n");
|
||||
while(true);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -273,8 +273,6 @@ namespace Sortix
|
|||
addr_t stackpos = CurrentThread()->stackpos + CurrentThread()->stacksize;
|
||||
addr_t argvpos = stackpos - sizeof(char*) * argc;
|
||||
char** stackargv = (char**) argvpos;
|
||||
regs->eax = argc;
|
||||
regs->ebx = argvpos;
|
||||
|
||||
size_t argvsize = 0;
|
||||
for ( int i = 0; i < argc; i++ )
|
||||
|
@ -288,9 +286,7 @@ namespace Sortix
|
|||
|
||||
stackpos = argvpos - argvsize;
|
||||
|
||||
regs->eip = entry;
|
||||
regs->useresp = stackpos;
|
||||
regs->ebp = stackpos;
|
||||
ExecuteCPU(argc, stackargv, stackpos, entry, regs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -101,6 +101,7 @@ namespace Sortix
|
|||
|
||||
private:
|
||||
Thread* ForkThreads(Process* processclone);
|
||||
void ExecuteCPU(int argc, char** argv, addr_t stackpos, addr_t entry, CPU::InterruptRegisters* regs);
|
||||
|
||||
public:
|
||||
void ResetForExecute();
|
||||
|
|
|
@ -106,5 +106,42 @@ namespace Sortix
|
|||
// up, the calling function will fill up the physical allocator with
|
||||
// plenty of nice physical pages. (see Page::InitPushRegion)
|
||||
}
|
||||
|
||||
// Please note that even if this function exists, you should still clean
|
||||
// up the address space of a process _before_ calling
|
||||
// DestroyAddressSpace. This is just a hack because it currently is
|
||||
// impossible to clean up PLM1's using the MM api!
|
||||
// ---
|
||||
// TODO: This function is duplicated in {x86,x64}/memorymanagement.cpp!
|
||||
// ---
|
||||
void RecursiveFreeUserspacePages(size_t level, size_t offset)
|
||||
{
|
||||
PML* pml = PMLS[level] + offset;
|
||||
for ( size_t i = 0; i < ENTRIES; i++ )
|
||||
{
|
||||
if ( !(pml->entry[i] & PML_PRESENT) ) { continue; }
|
||||
if ( !(pml->entry[i] & PML_USERSPACE) ) { continue; }
|
||||
if ( !(pml->entry[i] & PML_FORK) ) { continue; }
|
||||
if ( level > 1 ) { RecursiveFreeUserspacePages(level-1, offset * ENTRIES + i); }
|
||||
addr_t addr = pml->entry[i] & PML_ADDRESS;
|
||||
pml->entry[i] = 0;
|
||||
Page::Put(addr);
|
||||
}
|
||||
}
|
||||
|
||||
void DestroyAddressSpace()
|
||||
{
|
||||
// First let's do the safe part. Garbage collect any PML1/0's left
|
||||
// behind by user-space. These are completely safe to delete.
|
||||
RecursiveFreeUserspacePages(TOPPMLLEVEL, 0);
|
||||
|
||||
// TODO: Right now this just leaks memory.
|
||||
|
||||
// Switch to the address space from when the world was originally
|
||||
// created. It should contain the kernel, the whole kernel, and
|
||||
// nothing but the kernel.
|
||||
PML* const BOOTPML4 = (PML* const) 0x01000UL;
|
||||
SwitchAddressSpace((addr_t) BOOTPML4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
38
sortix/x64/process.cpp
Normal file
38
sortix/x64/process.cpp
Normal file
|
@ -0,0 +1,38 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of Sortix.
|
||||
|
||||
Sortix is free software: you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
Sortix is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
x64/process.cpp
|
||||
CPU-specific process code.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "platform.h"
|
||||
#include "process.h"
|
||||
|
||||
namespace Sortix
|
||||
{
|
||||
void Process::ExecuteCPU(int argc, char** argv, addr_t stackpos, addr_t entry, CPU::InterruptRegisters* regs)
|
||||
{
|
||||
regs->rdi = argc;
|
||||
regs->rsi = (size_t) argv;
|
||||
regs->rip = entry;
|
||||
regs->userrsp = stackpos;
|
||||
regs->rbp = stackpos;
|
||||
}
|
||||
}
|
52
sortix/x64/scheduler.cpp
Normal file
52
sortix/x64/scheduler.cpp
Normal file
|
@ -0,0 +1,52 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of Sortix.
|
||||
|
||||
Sortix is free software: you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
Sortix is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
x64/scheduler.cpp
|
||||
CPU specific things related to the scheduler.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "platform.h"
|
||||
#include "scheduler.h"
|
||||
#include "../memorymanagement.h"
|
||||
#include "descriptor_tables.h"
|
||||
|
||||
namespace Sortix
|
||||
{
|
||||
namespace Scheduler
|
||||
{
|
||||
const size_t KERNEL_STACK_SIZE = 256UL * 1024UL;
|
||||
const addr_t KERNEL_STACK_END = 0xFFFF800000001000UL;
|
||||
const addr_t KERNEL_STACK_START = KERNEL_STACK_END + KERNEL_STACK_SIZE;
|
||||
|
||||
void InitCPU()
|
||||
{
|
||||
// TODO: Prevent the kernel heap and other stuff from accidentally
|
||||
// also allocating this virtual memory region!
|
||||
|
||||
if ( !Memory::MapRangeKernel(KERNEL_STACK_END, KERNEL_STACK_SIZE) )
|
||||
{
|
||||
PanicF("could not create kernel stack (%zx to %zx)",
|
||||
KERNEL_STACK_END, KERNEL_STACK_START);
|
||||
}
|
||||
|
||||
GDT::SetKernelStack((size_t*) KERNEL_STACK_START);
|
||||
}
|
||||
}
|
||||
}
|
157
sortix/x64/syscall.s
Normal file
157
sortix/x64/syscall.s
Normal file
|
@ -0,0 +1,157 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of Sortix.
|
||||
|
||||
Sortix is free software: you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
Sortix is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
syscall.s
|
||||
An assembly stub that acts as glue for system calls.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
.global syscall_handler
|
||||
.global resume_syscall
|
||||
|
||||
.section .text
|
||||
.type syscall_handler, @function
|
||||
syscall_handler:
|
||||
cli
|
||||
|
||||
# Compabillity with InterruptRegisters.
|
||||
pushq $0x0
|
||||
pushq $0x80
|
||||
|
||||
pushq %r15
|
||||
pushq %r14
|
||||
pushq %r13
|
||||
pushq %r12
|
||||
pushq %r11
|
||||
pushq %r10
|
||||
pushq %r9
|
||||
pushq %r8
|
||||
pushq %rax
|
||||
pushq %rcx
|
||||
pushq %rdx
|
||||
pushq %rbx
|
||||
pushq %rsp
|
||||
pushq %rsi
|
||||
pushq %rdi
|
||||
|
||||
# Push the user-space data segment.
|
||||
movl %ds, %ebp
|
||||
pushq %rbp
|
||||
|
||||
# Load the kernel data segment.
|
||||
movw $0x10, %bp
|
||||
movl %ebp, %ds
|
||||
movl %ebp, %es
|
||||
movl %ebp, %fs
|
||||
movl %ebp, %gs
|
||||
|
||||
# Compabillity with InterruptRegisters.
|
||||
movq %cr2, %rbp
|
||||
pushq %rbp
|
||||
|
||||
# Store the state structure's pointer so the call can modify it if needed.
|
||||
movq %rsp, syscall_state_ptr
|
||||
|
||||
# By default, assume the system call was complete.
|
||||
movl $0, system_was_incomplete
|
||||
|
||||
# Reset the kernel errno.
|
||||
movl $0, errno
|
||||
|
||||
# Make sure the requested system call is valid.
|
||||
cmp SYSCALL_MAX, %rax
|
||||
jb valid_rax
|
||||
xorq %rax, %rax
|
||||
|
||||
valid_rax:
|
||||
# Read a system call function pointer.
|
||||
xorq %rbp, %rbp
|
||||
movq syscall_list(%rbp,%rax,4), %rax
|
||||
|
||||
# Oh how nice, user-space put the parameters in: rdi, rsi, rdx, rcx, r8, r9
|
||||
|
||||
# Call the system call.
|
||||
callq *%rax
|
||||
|
||||
# Test if the system call was incomplete
|
||||
movl system_was_incomplete, %ebx
|
||||
testl %ebx, %ebx
|
||||
|
||||
# If the system call was incomplete, the value in %eax is meaningless.
|
||||
jg return_to_userspace
|
||||
|
||||
# The system call was completed, so store the return value.
|
||||
movq %rax, 72(%rsp)
|
||||
|
||||
# Don't forget to update userspace's errno value.
|
||||
call update_userspace_errno
|
||||
|
||||
return_to_userspace:
|
||||
# Compabillity with InterruptRegisters.
|
||||
addq $8, %rsp
|
||||
|
||||
# Restore the user-space data segment.
|
||||
popq %rbp
|
||||
movl %ebp, %ds
|
||||
movl %ebp, %es
|
||||
movl %ebp, %fs
|
||||
movl %ebp, %gs
|
||||
|
||||
popq %rdi
|
||||
popq %rsi
|
||||
popq %rsp
|
||||
popq %rbx
|
||||
popq %rdx
|
||||
popq %rcx
|
||||
popq %rax
|
||||
popq %r8
|
||||
popq %r9
|
||||
popq %r10
|
||||
popq %r11
|
||||
popq %r12
|
||||
popq %r13
|
||||
popq %r14
|
||||
popq %r15
|
||||
|
||||
# Compabillity with InterruptRegisters.
|
||||
addq $16, %rsp
|
||||
|
||||
# Return to user-space.
|
||||
iretq
|
||||
|
||||
.type resume_syscall, @function
|
||||
resume_syscall:
|
||||
pushq %rbp
|
||||
movq %rsp, %rbp
|
||||
|
||||
movq %rdi, %rax
|
||||
movq %rsi, %r11
|
||||
|
||||
movq 0(%r11), %rdi
|
||||
movq 8(%r11), %rsi
|
||||
movq 16(%r11), %rdx
|
||||
movq 24(%r11), %rcx
|
||||
movq 32(%r11), %r8
|
||||
movq 40(%r11), %r9
|
||||
|
||||
callq *%rax
|
||||
|
||||
leaveq
|
||||
retq
|
||||
|
139
sortix/x64/thread.cpp
Normal file
139
sortix/x64/thread.cpp
Normal file
|
@ -0,0 +1,139 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of Sortix.
|
||||
|
||||
Sortix is free software: you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
Sortix is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
thread.cpp
|
||||
x64 specific parts of thread.cpp.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "platform.h"
|
||||
#include "thread.h"
|
||||
|
||||
namespace Sortix
|
||||
{
|
||||
void Thread::SaveRegisters(const CPU::InterruptRegisters* src)
|
||||
{
|
||||
registers.rip = src->rip;
|
||||
registers.userrsp = src->userrsp;
|
||||
registers.rax = src->rax;
|
||||
registers.rbx = src->rbx;
|
||||
registers.rcx = src->rcx;
|
||||
registers.rdx = src->rdx;
|
||||
registers.rdi = src->rdi;
|
||||
registers.rsi = src->rsi;
|
||||
registers.rbp = src->rbp;
|
||||
registers.r8 = src->r8;
|
||||
registers.r9 = src->r9;
|
||||
registers.r10 = src->r10;
|
||||
registers.r11 = src->r11;
|
||||
registers.r12 = src->r12;
|
||||
registers.r13 = src->r13;
|
||||
registers.r14 = src->r14;
|
||||
registers.r15 = src->r15;
|
||||
registers.cs = src->cs;
|
||||
registers.ds = src->ds;
|
||||
registers.ss = src->ss;
|
||||
registers.rflags = src->rflags;
|
||||
}
|
||||
|
||||
void Thread::LoadRegisters(CPU::InterruptRegisters* dest)
|
||||
{
|
||||
dest->rip = registers.rip;
|
||||
dest->userrsp = registers.userrsp;
|
||||
dest->rax = registers.rax;
|
||||
dest->rbx = registers.rbx;
|
||||
dest->rcx = registers.rcx;
|
||||
dest->rdx = registers.rdx;
|
||||
dest->rdi = registers.rdi;
|
||||
dest->rsi = registers.rsi;
|
||||
dest->rbp = registers.rbp;
|
||||
dest->r8 = registers.r8;
|
||||
dest->r9 = registers.r9;
|
||||
dest->r10 = registers.r10;
|
||||
dest->r11 = registers.r11;
|
||||
dest->r12 = registers.r12;
|
||||
dest->r13 = registers.r13;
|
||||
dest->r14 = registers.r14;
|
||||
dest->r15 = registers.r15;
|
||||
dest->cs = registers.cs;
|
||||
dest->ds = registers.ds;
|
||||
dest->ss = registers.ss;
|
||||
dest->rflags = registers.rflags;
|
||||
}
|
||||
|
||||
const size_t FLAGS_CARRY = (1<<0);
|
||||
const size_t FLAGS_RESERVED1 = (1<<1); /* read as one */
|
||||
const size_t FLAGS_PARITY = (1<<2);
|
||||
const size_t FLAGS_RESERVED2 = (1<<3);
|
||||
const size_t FLAGS_AUX = (1<<4);
|
||||
const size_t FLAGS_RESERVED3 = (1<<5);
|
||||
const size_t FLAGS_ZERO = (1<<6);
|
||||
const size_t FLAGS_SIGN = (1<<7);
|
||||
const size_t FLAGS_TRAP = (1<<8);
|
||||
const size_t FLAGS_INTERRUPT = (1<<9);
|
||||
const size_t FLAGS_DIRECTION = (1<<10);
|
||||
const size_t FLAGS_OVERFLOW = (1<<11);
|
||||
const size_t FLAGS_IOPRIVLEVEL = (1<<12) | (1<<13);
|
||||
const size_t FLAGS_NESTEDTASK = (1<<14);
|
||||
const size_t FLAGS_RESERVED4 = (1<<15);
|
||||
const size_t FLAGS_RESUME = (1<<16);
|
||||
const size_t FLAGS_VIRTUAL8086 = (1<<17);
|
||||
const size_t FLAGS_ALIGNCHECK = (1<<18);
|
||||
const size_t FLAGS_VIRTINTR = (1<<19);
|
||||
const size_t FLAGS_VIRTINTRPEND = (1<<20);
|
||||
const size_t FLAGS_ID = (1<<21);
|
||||
|
||||
void CreateThreadCPU(Thread* thread, addr_t entry)
|
||||
{
|
||||
const uint64_t CS = 0x18;
|
||||
const uint64_t DS = 0x20;
|
||||
const uint64_t RPL = 0x3;
|
||||
|
||||
CPU::InterruptRegisters regs;
|
||||
regs.rip = entry;
|
||||
regs.userrsp = thread->stackpos + thread->stacksize;
|
||||
regs.rax = 0;
|
||||
regs.rbx = 0;
|
||||
regs.rcx = 0;
|
||||
regs.rdx = 0;
|
||||
regs.rdi = 0;
|
||||
regs.rsi = 0;
|
||||
regs.rbp = thread->stackpos + thread->stacksize;
|
||||
regs.r8 = 0;
|
||||
regs.r9 = 0;
|
||||
regs.r10 = 0;
|
||||
regs.r11 = 0;
|
||||
regs.r12 = 0;
|
||||
regs.r13 = 0;
|
||||
regs.r14 = 0;
|
||||
regs.r15 = 0;
|
||||
regs.cs = CS | RPL;
|
||||
regs.ds = DS | RPL;
|
||||
regs.ss = DS | RPL;
|
||||
regs.rflags = FLAGS_RESERVED1 | FLAGS_INTERRUPT | FLAGS_ID;
|
||||
|
||||
thread->SaveRegisters(®s);
|
||||
}
|
||||
|
||||
void Thread::HandleSignalCPU(CPU::InterruptRegisters* regs)
|
||||
{
|
||||
regs->rdi = currentsignal->signum;
|
||||
regs->rip = (size_t) sighandler;
|
||||
}
|
||||
}
|
|
@ -24,10 +24,26 @@
|
|||
|
||||
#include <libmaxsi/platform.h>
|
||||
#include "x64.h"
|
||||
#include "log.h"
|
||||
|
||||
namespace Sortix
|
||||
{
|
||||
namespace X64
|
||||
{
|
||||
void InterruptRegisters::LogRegisters() const
|
||||
{
|
||||
Log::PrintF("[cr2=0x%zx,ds=0x%zx,rdi=0x%zx,rsi=0x%zx,rbp=0x%zx,"
|
||||
"rsp=0x%zx,rbx=0x%zx,rcx=0x%zx,rax=0x%zx,r8=0x%zx,"
|
||||
"r9=0x%zx,r10=0x%zx,r11=0x%zx,r12=0x%zx,r13=0x%zx,"
|
||||
"r14=0x%zx,r15=0x%zx,int_no=0x%zx,err_code=0x%zx,"
|
||||
"rip=0x%zx,cs=0x%zx,rflags=0x%zx,userrsp=0x%zx,"
|
||||
"ss=0x%zx]",
|
||||
cr2, ds, rdi, rsi, rbp,
|
||||
rsp, rbx, rcx, rax, r8,
|
||||
r9, r10, r11, r12, r13,
|
||||
r14, r15, int_no, err_code,
|
||||
rip, cs, rflags, userrsp,
|
||||
ss);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,10 +35,23 @@ namespace Sortix
|
|||
{
|
||||
uint64_t cr2;
|
||||
uint64_t ds; // Data segment selector
|
||||
uint64_t rdi, rsi, rbp, rsp, rbx, rdx, rcx, rax; // Pushed by pusha.
|
||||
uint64_t r8, r9, r10, r11, r12, r13, r14, r15; // Pushed by pusha.
|
||||
uint64_t rdi, rsi, rbp, rsp, rbx, rdx, rcx, rax;
|
||||
uint64_t r8, r9, r10, r11, r12, r13, r14, r15;
|
||||
uint64_t int_no, err_code; // Interrupt number and error code (if applicable)
|
||||
uint64_t eip, cs, eflags, useresp, ss; // Pushed by the processor automatically.
|
||||
uint64_t rip, cs, rflags, userrsp, ss; // Pushed by the processor automatically.
|
||||
|
||||
public:
|
||||
void LogRegisters() const;
|
||||
};
|
||||
|
||||
struct SyscallRegisters
|
||||
{
|
||||
uint64_t cr2; // For compabillity with above, may be removed soon.
|
||||
uint64_t ds;
|
||||
uint64_t di, si, bp, trash, b, d, c; union { uint64_t a; uint64_t result; };
|
||||
uint64_t r8, r9, r10, r11, r12, r13, r14, r15;
|
||||
uint64_t int_no, err_code; // Also compabillity.
|
||||
uint64_t ip, cs, flags, sp, ss;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,7 +115,7 @@ namespace Sortix
|
|||
// until the pebibyte era of RAM.
|
||||
if ( 0 < Page::pagesnotonstack )
|
||||
{
|
||||
Log::PrintF("%zu bytes of RAM aren't used due to technical"
|
||||
Log::PrintF("%zu bytes of RAM aren't used due to technical "
|
||||
"restrictions.\n", Page::pagesnotonstack * 0x1000UL);
|
||||
}
|
||||
|
||||
|
@ -178,7 +178,10 @@ namespace Sortix
|
|||
|
||||
// This call will also succeed, since there are plenty of physical
|
||||
// pages available and it might need some.
|
||||
Memory::MapKernel(page, (addr_t) (STACK + stacklength));
|
||||
if ( !Memory::MapKernel(page, (addr_t) (STACK + stacklength)) )
|
||||
{
|
||||
Panic("Unable to extend page stack, which should have worked");
|
||||
}
|
||||
|
||||
// TODO: This may not be needed during the boot process!
|
||||
//Memory::InvalidatePage((addr_t) (STACK + stacklength));
|
||||
|
@ -345,6 +348,9 @@ namespace Sortix
|
|||
|
||||
addr_t& entry = pml->entry[childid];
|
||||
|
||||
// Find the index of the next PML in the fractal mapped memory.
|
||||
size_t childoffset = offset * ENTRIES + childid;
|
||||
|
||||
if ( !(entry & PML_PRESENT) )
|
||||
{
|
||||
// TODO: Possible memory leak when page allocation fails.
|
||||
|
@ -353,7 +359,7 @@ namespace Sortix
|
|||
entry = page | flags;
|
||||
|
||||
// Invalidate the new PML and reset it to zeroes.
|
||||
addr_t pmladdr = (addr_t) (PMLS[i-1] + childid);
|
||||
addr_t pmladdr = (addr_t) (PMLS[i-1] + childoffset);
|
||||
InvalidatePage(pmladdr);
|
||||
Maxsi::Memory::Set((void*) pmladdr, 0, sizeof(PML));
|
||||
}
|
||||
|
@ -365,8 +371,7 @@ namespace Sortix
|
|||
"code calling this function", physical, mapto, i-1);
|
||||
}
|
||||
|
||||
// Find the index of the next PML in the fractal mapped memory.
|
||||
offset = offset * ENTRIES + childid;
|
||||
offset = childoffset;
|
||||
}
|
||||
|
||||
// Actually map the physical page to the virtual page.
|
||||
|
|
|
@ -106,6 +106,9 @@ namespace Sortix
|
|||
// up the address space of a process _before_ calling
|
||||
// DestroyAddressSpace. This is just a hack because it currently is
|
||||
// impossible to clean up PLM1's using the MM api!
|
||||
// ---
|
||||
// TODO: This function is duplicated in {x86,x64}/memorymanagement.cpp!
|
||||
// ---
|
||||
void RecursiveFreeUserspacePages(size_t level, size_t offset)
|
||||
{
|
||||
PML* pml = PMLS[level] + offset;
|
||||
|
|
38
sortix/x86/process.cpp
Normal file
38
sortix/x86/process.cpp
Normal file
|
@ -0,0 +1,38 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of Sortix.
|
||||
|
||||
Sortix is free software: you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
Sortix is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
x86/process.cpp
|
||||
CPU-specific process code.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "platform.h"
|
||||
#include "process.h"
|
||||
|
||||
namespace Sortix
|
||||
{
|
||||
void Process::ExecuteCPU(int argc, char** argv, addr_t stackpos, addr_t entry, CPU::InterruptRegisters* regs)
|
||||
{
|
||||
regs->eax = argc;
|
||||
regs->ebx = (size_t) argv;
|
||||
regs->eip = entry;
|
||||
regs->useresp = stackpos;
|
||||
regs->ebp = stackpos;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue