task_struct is used to store the status of CPU and trap frame does the same thing so how they differ? And trap frame is a data struct or a just and concept?
The cpu state - is about context switch, while trapframe holds userspace state saved in tcb after exception or irq have arised.
My explanation will be based on self-written OS for raspberry pi 2 (ARMv7)
Here is task struct, which stores context and trap frame:
class task {
private:
public:
uint32_t pid;
pde_t *pgd;
tstate state;
uint32_t *kstack;
context *ctx;
trapframe *tf;
task() {};
void init_vm();
int load_binary(char *binary_obj);
};
the context is a set of callee-saved registers, which represents state of the task before it was preempted by other task (context switch)
struct context {
uint32_t r4;
uint32_t r5;
uint32_t r6;
uint32_t r7;
uint32_t r8;
uint32_t r9;
uint32_t r10;
uint32_t r11;
uint32_t r12;
uint32_t lr;
};
when the context switch in scheduler is occured, current task saves its registers to *ctx in class task
, and new set of registers are loaded from next task:
Note that R0 in below example is THIS pointer, because we call method of a particular object. So the arguments are R1 and R2
void scheduler::swtch(struct context **oldctx, struct context *newctx)
{
/* r0-r3 are not preserved during call, no need to save them */
asm volatile("push {r4-r12, lr}");
/* save current kernel thread sp to oldctx */
asm volatile("str r13, [r1]");
/* Load newctx (new sp) to sp register */
asm volatile("mov r13, r2");
/* Load all other registers from new ctx,
* refer struct context format for details */
asm volatile("pop {r4-r12, lr}");
}
Now about trapframe:
struct trapframe {
uint32_t sp_usr; // user mode sp
uint32_t lr_usr; // user mode lr
uint32_t sp_svc;
uint32_t lr_svc;
uint32_t spsr;
uint32_t r[N_GEN_REGS];
uint32_t pc; // (lr on entry) instruction to resume execution
};
Trapframe stores register set which was saved during exception have arised, so using trapframe we can return back and proceed execution (when exception or irq will be handled)
To clarify, task_struct
contains information of a process, not a cpu. OS can manage multiple processes, thus there might be multiple instances of task_struct
Trapframe
saves userspace registers. It saves userspace registers when the cpu changes from user mode to kernel mode (ex. supervisor mode in xv6-riscv).
Of course trapframe is a data structure.
You can see how trapframe looks like at the link below, see proc.h
and proc.c
https://github.com/mit-pdos/xv6-public
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With