Linux系统调用

4
我能够获取系统调用调用和内核中的处理执行。但是,还有一些事情不是很清楚。进入swi例程时,内核会将用户模式寄存器保存在堆栈上。问题是:
  1. 这是谁的堆栈?(因为swi处理和相应的系统调用例程需要堆栈框架来操作)
  2. 如果它是内核自己的堆栈,那么从哪里获得分配的堆栈? 它会开始使用当前的堆栈吗? 如果是,那么当前可以是任何可能正在内核中执行的进程。 这不会耗尽当前的堆栈吗?
  3. 如果它在swi处理程序中使用当前正在执行的用户进程的堆栈,则这将是内核现在将要访问的用户地址空间。 这是可能的吗? 因为内核可寻址内存在1GB内(如果在4GB RAM内存系统中使用1:3内核对用户地址空间比率)。
2个回答

5
大多数ARM模式都有独立的堆栈。这些堆栈通常在复位处理程序后不久设置。从arch/arm/kernel/setup.c代码中可以看到:
/*
 * setup stacks for re-entrant exception handlers
 */
__asm__ (
"msr    cpsr_c, %1\n\t"
"add    sp, %0, %2\n\t"
"msr    cpsr_c, %3\n\t"
"add    sp, %0, %4\n\t"
"msr    cpsr_c, %5\n\t"
"add    sp, %0, %6\n\t"
"msr    cpsr_c, %7"
    :
    : "r" (stk),
      "I" (PSR_F_BIT | PSR_I_BIT | IRQ_MODE),
      "I" (offsetof(struct stack, irq[0])),
      "I" (PSR_F_BIT | PSR_I_BIT | ABT_MODE),
      "I" (offsetof(struct stack, abt[0])),
      "I" (PSR_F_BIT | PSR_I_BIT | UND_MODE),
      "I" (offsetof(struct stack, und[0])),
      "I" (PSR_F_BIT | PSR_I_BIT | SVC_MODE)
    : "r14");

附言:SVC是曾经被称为SWI的当前名称。


谢谢,你说得对。用户模式的SP、LR在进入SWI处理程序时被保存。但是我可以从SWI处理程序堆栈中看到当前(即活动的Linux内核task_struct)信息。这怎么可能? - MS.

0

确实,堆栈是特定于ARM模式的。

这是快速系统调用返回路径。我们在这里尽可能少地执行操作,包括将r0保存回SVC堆栈中。

上述行在entry-common.S中引用。因此,堆栈是SVC堆栈。(注意:swi已被svc替换)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接