Я знаю, что стек режима ядра хранится со структурой thread_info структуры task_struct. Но где хранится стек пользовательского режима. Я предполагаю, что он будет храниться в адресном пространстве процесса как область памяти, потому что во время ошибки страницы ядро проверяет, не была ли ошибка вызвана расширением пользовательского стека. Мне нужно больше информации о пользовательском стеке. И какова цель ss (регистр сегмента стека)
в Linux, где хранится стек пользовательского режима?
Ответы (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, которые используются для доступа к локальным данным потока в пространстве пользователя и пространстве ядра соответственно.