1

我知道内核模式堆栈与 task_struct 结构的 thread_info 结构一起存储。但是用户模式堆栈存储在哪里。我想,它将作为内存区域存储在进程地址空间中,因为在页面错误期间内核会检查错误是否是由于用户堆栈扩展造成的。我需要有关用户堆栈的更多详细信息。ss(堆栈段寄存器)的目的是什么

4

1 回答 1

1

它存储在内核堆栈中。Linux 系统调用入口代码非常繁琐,尤其是现在它正在执行一些幽灵和崩溃缓解措施,但您可以查看entry_SYSCALL_64.

具体来说,这个序列将用户态线程的状态保存到内核堆栈。它正在构建结构的最后一部分,struct pt_regs稍后将传递给do_syscall_64.

/* Construct struct pt_regs on stack */
pushq   $__USER_DS              /* pt_regs->ss */
pushq   PER_CPU_VAR(cpu_tss_rw + TSS_sp2)   /* pt_regs->sp */ // This is where it's put on the stack.
pushq   %r11                    /* pt_regs->flags */
pushq   $__USER_CS              /* pt_regs->cs */
pushq   %rcx                    /* pt_regs->ip */
GLOBAL(entry_SYSCALL_64_after_hwframe)
pushq   %rax                    /* pt_regs->orig_ax */

PUSH_AND_CLEAR_REGS rax=$-ENOSYS

至于 ss 寄存器,在 x86 有虚拟内存之前,就有了段的概念。每个程序都存在于自己的一系列内存段中。每个段寄存器(ss、gs 等)都在全局描述符表中保存了一个索引,该索引确定了段的开始位置和它拥有的权限。ss 保存了堆栈的段。如果您尝试推送、弹出或调用,如果 esp 指向堆栈段之外,您将收到分段异常。如今,使用 x86_64 ss 和大多数其他分段寄存器大多是退化的,除了 fs 和 gs 分别用于访问用户空间和内核空间中的线程本地数据。

于 2018-11-02T23:57:00.833 回答