/* * Set up the a user mode thread. */ /*static*/ void Setup_User_Thread( struct Kernel_Thread* kthread, struct User_Context* userContext) { /* * Hints: * - Call Attach_User_Context() to attach the user context * to the Kernel_Thread * - Set up initial thread stack to make it appear that * the thread was interrupted while in user mode * just before the entry point instruction was executed * - The esi register should contain the address of * the argument block */ Attach_User_Context(kthread, userContext); /* ushort_t dsSelector */ Push(kthread, userContext->dsSelector); /* Stack pointer */ Push(kthread, (userContext->stackPointerAddr)); /* * The EFLAGS register will have all bits clear. * The important constraint is that we want to have the IF * bit clear, so that interrupts are disabled when the * thread starts. */ Push(kthread, 0UL); /* EFLAGS */ /* ushort_t csSelector */ Push(kthread, userContext->csSelector); /* Push the address of the start function. */ Push(kthread, userContext->entryAddr); /* Push fake error code and interrupt number. */ Push(kthread, 0UL); Push(kthread, 0UL); /* Push initial values for general-purpose registers. */ Push(kthread, 0UL); /* eax */ Push(kthread, 0UL); /* ebx */ Push(kthread, 0UL); /* ecx */ Push(kthread, 0UL); /* edx */ Push(kthread, userContext->argBlockAddr); /* esi */ Push(kthread, 0UL); /* edi */ Push(kthread, 0UL); /* ebp */ /* * Push values for saved segment registers. * Only the ds and es registers will contain valid selectors. */ Push(kthread, (ulong_t)userContext->dsSelector); /* ds */ Push(kthread, (ulong_t)userContext->dsSelector); /* es */ Push(kthread, (ulong_t)userContext->dsSelector); /* fs */ Push(kthread, (ulong_t)userContext->dsSelector); /* gs */ }
/* * Set up the a user mode thread. */ /*static*/ void Setup_User_Thread( struct Kernel_Thread* kthread, struct User_Context* userContext) { /* * Hints: * - Call Attach_User_Context() to attach the user context * to the Kernel_Thread * - Set up initial thread stack to make it appear that * the thread was interrupted while in user mode * just before the entry point instruction was executed * - The esi register should contain the address of * the argument block */ ulong_t ds = (ulong_t)(userContext->dsSelector); Attach_User_Context(kthread, userContext); Push(kthread, ds); // Data Selector Push(kthread, (ulong_t)(userContext->stackPointerAddr)); // Stack Pointer Push(kthread, EFLAGS_IF); /* EFLAGS */ Push(kthread, (ulong_t)(userContext->csSelector)); // Code Selector Push(kthread, (ulong_t)(userContext->entryAddr)); // Program Counter /* Push fake error code and interrupt number. */ Push(kthread, 0); Push(kthread, 0); /* Push initial values for general-purpose registers. */ Push(kthread, 0); /* eax */ Push(kthread, 0); /* ebx */ Push(kthread, 0); /* edx */ Push(kthread, 0); /* edx */ Push(kthread, (ulong_t)(userContext->argBlockAddr)); /* esi */ Push(kthread, 0); /* edi */ Push(kthread, 0); /* ebp */ /* * Push values for saved segment registers. * Only the ds and es registers will contain valid selectors. * The fs and gs registers are not used by any instruction * generated by gcc. */ Push(kthread, ds); /* ds */ Push(kthread, ds); /* es */ Push(kthread, ds); /* fs */ Push(kthread, ds); /* gs */ }
/* * Set up the a user mode thread. */ /*static*/ void Setup_User_Thread( struct Kernel_Thread* kthread, struct User_Context* userContext) { //lacki /* * Hints: * - Call Attach_User_Context() to attach the user context * to the Kernel_Thread * - Set up initial thread stack to make it appear that * the thread was interrupted while in user mode * just before the entry point instruction was executed * - The esi register should contain the address of * the argument block */ //TODO("Create a new thread to execute in user mode"); Attach_User_Context(kthread, userContext); /* data selector */ Push(kthread, (*userContext).dsSelector); /* stackPointer */ Push(kthread, (*userContext).stackPointerAddr); /* * EFLAGS_IF is a 32bit int with the 9th bit 1 and the other bits 0 * EFLAGS OR EFLAGS_IF return the EFLAGS with bit 9 set to 1 * EFLAGS_IF is defined in int.h */ //Print("original eflags: %lu \n", Get_Current_EFLAGS()); ulong_t eflags = Get_Current_EFLAGS() | EFLAGS_IF; //Print("current eflags: %lu \n", eflags); Push(kthread, eflags); /* code Selector */ Push(kthread, (*userContext).csSelector); /* code entry address */ Push(kthread, (*userContext).entryAddr); /* error code */ Push(kthread, 0); /* Interrupt Number */ Push(kthread, 0); /* EAX */ Push(kthread, 0); /* EBX */ Push(kthread, 0); /* ECX */ Push(kthread, 0); /* EDX */ Push(kthread, 0); /* esi */ Push(kthread, (*userContext).argBlockAddr); /* EDI */ Push(kthread, 0); /* EBP */ Push(kthread, 0); /* ds */ Push(kthread, (*userContext).dsSelector); /* es */ Push(kthread, (*userContext).dsSelector); /* fs */ Push(kthread, (*userContext).dsSelector); /* gs */ Push(kthread, (*userContext).dsSelector); }