diff --git a/libmaxsi/x64/start.s b/libmaxsi/x64/start.s
index e3aeafda..bb2a5b48 100644
--- a/libmaxsi/x64/start.s
+++ b/libmaxsi/x64/start.s
@@ -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.
diff --git a/sortix/Makefile b/sortix/Makefile
index e2d5609c..d2079ef6 100644
--- a/sortix/Makefile
+++ b/sortix/Makefile
@@ -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
diff --git a/sortix/kernel.cpp b/sortix/kernel.cpp
index b7b8c5bb..07049700 100644
--- a/sortix/kernel.cpp
+++ b/sortix/kernel.cpp
@@ -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
diff --git a/sortix/process.cpp b/sortix/process.cpp
index c2f774fd..e4d6952a 100644
--- a/sortix/process.cpp
+++ b/sortix/process.cpp
@@ -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;
}
diff --git a/sortix/process.h b/sortix/process.h
index 25cd3bc1..b0d360dc 100644
--- a/sortix/process.h
+++ b/sortix/process.h
@@ -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();
diff --git a/sortix/x64/memorymanagement.cpp b/sortix/x64/memorymanagement.cpp
index f420addf..bacd2050 100644
--- a/sortix/x64/memorymanagement.cpp
+++ b/sortix/x64/memorymanagement.cpp
@@ -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);
+ }
}
}
diff --git a/sortix/x64/process.cpp b/sortix/x64/process.cpp
new file mode 100644
index 00000000..b08a2877
--- /dev/null
+++ b/sortix/x64/process.cpp
@@ -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 .
+
+ 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;
+ }
+}
diff --git a/sortix/x64/scheduler.cpp b/sortix/x64/scheduler.cpp
new file mode 100644
index 00000000..49b08b89
--- /dev/null
+++ b/sortix/x64/scheduler.cpp
@@ -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 .
+
+ 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);
+ }
+ }
+}
diff --git a/sortix/x64/syscall.s b/sortix/x64/syscall.s
new file mode 100644
index 00000000..c3dc44c6
--- /dev/null
+++ b/sortix/x64/syscall.s
@@ -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 .
+
+ 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
+
diff --git a/sortix/x64/thread.cpp b/sortix/x64/thread.cpp
new file mode 100644
index 00000000..9c63a9fc
--- /dev/null
+++ b/sortix/x64/thread.cpp
@@ -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 .
+
+ 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;
+ }
+}
diff --git a/sortix/x64/x64.cpp b/sortix/x64/x64.cpp
index f34d5db2..f102075e 100644
--- a/sortix/x64/x64.cpp
+++ b/sortix/x64/x64.cpp
@@ -24,10 +24,26 @@
#include
#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);
+ }
}
}
diff --git a/sortix/x64/x64.h b/sortix/x64/x64.h
index 17c6abb0..b7ad489b 100644
--- a/sortix/x64/x64.h
+++ b/sortix/x64/x64.h
@@ -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;
};
}
}
diff --git a/sortix/x86-family/memorymanagement.cpp b/sortix/x86-family/memorymanagement.cpp
index 9be88df5..cb3cb235 100644
--- a/sortix/x86-family/memorymanagement.cpp
+++ b/sortix/x86-family/memorymanagement.cpp
@@ -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.
diff --git a/sortix/x86/memorymanagement.cpp b/sortix/x86/memorymanagement.cpp
index a185512f..37fdddf9 100644
--- a/sortix/x86/memorymanagement.cpp
+++ b/sortix/x86/memorymanagement.cpp
@@ -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;
diff --git a/sortix/x86/process.cpp b/sortix/x86/process.cpp
new file mode 100644
index 00000000..0095e841
--- /dev/null
+++ b/sortix/x86/process.cpp
@@ -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 .
+
+ 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;
+ }
+}