linux – 什么是陷阱帧?陷阱框架和task_struct有什么区别?

task_struct用于存储CPU的状态和陷阱帧做同样的事情,它们如何区别?陷阱框架是数据结构还是公正和概念?

解决方法:

cpu状态 – 关于上下文切换,而trapframe保存在异常或irq出现之后保存在tcb中的用户空间状态.

我的解释将基于self-written OS for raspberry pi 2 (ARMv7)

这是task struct,它存储上下文和陷阱框架:

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);
};

上下文是一组被调用者保存的寄存器,表示任务在被其他任务(上下文切换)抢占之前的状态

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;
};

当调度程序中的上下文切换发生时,当前任务将其寄存器保存到类任务中的* ctx,并从下一个任务加载新的寄存器集:

注意下面例子中的R0是THIS指针,因为我们调用特定对象的方法.因此参数是R1和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}");
}

关于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存储在异常期间保存的寄存器集,因此使用trapframe我们可以返回并继续执行(当处理异常或irq时)

上一篇:Node.js进程与线程:下篇


下一篇:5年Android程序员面试字节跳动两轮后被完虐,请查收给你的面试指南