Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is trap frame? And what is difference between trap frame and task_struct?

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?

like image 312
Tarak Patel Avatar asked Dec 17 '17 03:12

Tarak Patel


2 Answers

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)

like image 178
Alex Hoppus Avatar answered Sep 18 '22 12:09

Alex Hoppus


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

like image 22
koo Avatar answered Sep 20 '22 12:09

koo