ARMProcess::ARMProcess(ProcessID id, Address entry, bool privileged) : Process(id, entry, privileged) { DEBUG("id =" << id << " entry =" << entry << " privileged = " << privileged); Size size = PAGEDIR_SIZE; BitAllocator *memory = Kernel::instance->getMemory(); Memory::Range range; Size framesize = (14+17)*sizeof(u32); // Allocate first level page table memory->allocate(&size, &m_pageDirectory, KiloByte(16)); // Initialize memory context Arch::Memory mem(m_pageDirectory, memory); mem.create(); // User stack. range.phys = 0; range.virt = mem.range(Memory::UserStack).virt; range.size = mem.range(Memory::UserStack).size; range.access = Memory::Present | Memory::User | Memory::Readable | Memory::Writable; mem.mapRange(&range); setUserStack(range.virt + range.size - MEMALIGN); // Kernel stack. range.phys = 0; range.virt = mem.range(Memory::KernelStack).virt; range.size = mem.range(Memory::KernelStack).size; range.access = Memory::Present | Memory::Readable | Memory::Writable; mem.mapRange(&range); setKernelStack(range.virt + range.size - MEMALIGN - framesize); // Map kernel stack. Arch::Memory local(0, memory); range.virt = local.findFree(range.size, Memory::KernelPrivate); local.mapRange(&range); Address *stack = (Address *) (range.virt + range.size - framesize - MEMALIGN); // Zero kernel stack MemoryBlock::set((void *)range.virt, 0, range.size); // restoreState: fill kernel register state stack[0] = (Address) loadCoreState0; /* restoreState: pop {lr} */ stack += 14; // loadCoreState0: fill user register state stack[0] = (privileged ? SYS_MODE : USR_MODE) | FIQ_BIT | IRQ_BIT; /* user program status (CPSR) */ stack++; stack[0] = m_userStack; /* user program SP */ stack[1] = 0; /* user program LR */ stack+=15; stack[0] = entry; /* user program entry (PC) */ local.unmapRange(&range); }
IntelProcess::IntelProcess(ProcessID id, Address entry, bool privileged) : Process(id, entry, privileged) { Address stack, stackBase, *pageDir; BitAllocator *memory = Kernel::instance->getMemory(); CPUState *regs; Arch::Memory local(0, memory); Arch::Memory::Range range; Size dirSize = PAGESIZE; u16 dataSel = privileged ? KERNEL_DS_SEL : USER_DS_SEL; u16 codeSel = privileged ? KERNEL_CS_SEL : USER_CS_SEL; // Allocate and map page directory memory->allocate(&dirSize, &m_pageDirectory); pageDir = (Address *) local.findFree(PAGESIZE, Memory::KernelPrivate); local.map(m_pageDirectory, (Address) pageDir, Arch::Memory::Present | Arch::Memory::Readable | Arch::Memory::Writable); // Initialize page directory for (Size i = 0; i < PAGEDIR_MAX; i++) pageDir[i] = 0; pageDir[0] = kernelPageDir[0]; // TODO: this should not be done here. Try to use libarch's Memory class. pageDir[DIRENTRY(PAGEDIR_LOCAL) ] = m_pageDirectory | PAGE_PRESENT | PAGE_USER; local.unmap((Address)pageDir); // Obtain memory mappings // TODO: use Memory::create() Arch::Memory mem(m_pageDirectory, memory); // User stack. range.phys = 0; range.virt = mem.range(Memory::UserStack).virt; range.size = mem.range(Memory::UserStack).size; range.access = Arch::Memory::Present | Arch::Memory::User | Arch::Memory::Readable | Arch::Memory::Writable; mem.mapRange(&range); setUserStack(range.virt + range.size - MEMALIGN); // Kernel stack. range.phys = 0; range.virt = mem.range(Memory::KernelStack).virt; range.size = mem.range(Memory::KernelStack).size; range.access = Arch::Memory::Present | Arch::Memory::Writable; mem.mapRange(&range); setKernelStack(range.virt + range.size - sizeof(CPUState) - sizeof(IRQRegs0) - sizeof(CPURegs)); // Map kernel stack range.virt = local.findFree(range.size, Memory::KernelPrivate); stack = range.virt; local.mapRange(&range); stackBase = stack + range.size; // loadCoreState: struct CPUState regs = (CPUState *) stackBase - 1; MemoryBlock::set(regs, 0, sizeof(CPUState)); regs->seg.ss0 = KERNEL_DS_SEL; regs->seg.fs = dataSel; regs->seg.gs = dataSel; regs->seg.es = dataSel; regs->seg.ds = dataSel; regs->regs.ebp = m_userStack; regs->regs.esp0 = m_kernelStack; regs->irq.eip = entry; regs->irq.cs = codeSel; regs->irq.eflags = INTEL_EFLAGS_DEFAULT | INTEL_EFLAGS_IRQ; regs->irq.esp3 = m_userStack; regs->irq.ss3 = dataSel; // restoreState: iret IRQRegs0 *irq = (IRQRegs0 *) regs - 1; irq->eip = (Address) loadCoreState; irq->cs = KERNEL_CS_SEL; irq->eflags = INTEL_EFLAGS_DEFAULT; // restoreState: popa CPURegs *pusha = (CPURegs *) irq - 1; MemoryBlock::set(pusha, 0, sizeof(CPURegs)); pusha->ebp = m_kernelStack - sizeof(CPURegs); pusha->esp0 = pusha->ebp; local.unmapRange(&range); }