In order to switch tasks, I need to load new stack pointer, instruction pointer and PML4 pointer AT ONCE. I also need to restore process registers etc., but this can be done without involving any features designed to deal with task switching.
In protected mode it's easy (I think). You just fill TSS with these values. In long mode, however, TSS only holds stack pointers for each ring + interrupt stack table? I wonder how this works. How is it possible to load new rsp, rip and cr3 at oce in 64 bit mode?
Switching taks in 64 bit mode.
Re: Switching taks in 64 bit mode.
Why do you need to load them AT ONCE?
Re: Switching taks in 64 bit mode.
You don't have to load all of these at exactly the same time. You only have to make sure to do that inside one ISR. You update CR3 manually before returning from the ISR. Then you update RSP in assembler part of your ISR. All other general purpose registers are (presumably) reloaded by the rest of assembler part of your ISR. And finally, RFLAGS and RIP are reloaded by IRET instruction.
For this all to happen without crashing, you need at least your ISR code and both stacks mapped in both address spaces. Usually whole kernel space is common to all processes so this is not a problem.
Exact sequence may be different for your project, but general idea is something like presented above.
For this all to happen without crashing, you need at least your ISR code and both stacks mapped in both address spaces. Usually whole kernel space is common to all processes so this is not a problem.
Exact sequence may be different for your project, but general idea is something like presented above.
Re: Switching taks in 64 bit mode.
When I load programs, I set the virtual addresses of each segment as it's written in the header. These are some random (from kernel's point of view) addresses and may conflict with addresses in the kernel address space. That's why I make a new address space disjoint with kernel address space.
But here comes the problem - after loading new cr3 I can't execute any more instructions from kernel. Also, after jumping to entry point I can no longer do anything either, of course. In particular, usually even the rip is outside that address space, so even if I copied a little program doing what I want to that address space, I wouldn't have a way to jump to it.
But here comes the problem - after loading new cr3 I can't execute any more instructions from kernel. Also, after jumping to entry point I can no longer do anything either, of course. In particular, usually even the rip is outside that address space, so even if I copied a little program doing what I want to that address space, I wouldn't have a way to jump to it.
Re: Switching taks in 64 bit mode.
The conventional way of doing this is to reserve part of memory for the kernel and a separate part for the user program (all programs normally use the same virtual addresses, which are mapped to different physical addresses). The kernel address space is mapped the same in the page tables for all tasks, so the problems you mention don't arise.