Что представляет собой состояние стека ядра ядра Linux при создании процесса?
Я не могу найти эту информацию нигде. Всюду, где я смотрю, я нахожу вещи, ссылаясь на то, как выглядит стек, когда вы нажимаете "главное" (независимо от вашей точки входа), которые будут аргументами программы и средой, но то, что я ищу, - это то, как система настраивается стек сотрудничать с макросом switch_to. При первом включении задачи необходимо будет иметь EFLAGS, EBP, регистры, которые сохраняет GCC, и адрес возврата из функции schedule() в стеке, на который указывает "tsk- > thread- > esp", но я не могу понять, как ядро устанавливает этот стек, поскольку он позволяет GCC сохранять регистры общего назначения (используя выходные параметры для встроенной сборки).
Я имею в виду только компьютеры x86. Я изучаю систему планировщика/процесса Linux для своего собственного небольшого ядра, которое я (пытаюсь) написать, и я не могу понять, что мне не хватает. Я знаю, что у меня что-то не хватает, поскольку тот факт, что Slackware работает на моем компьютере, свидетельствует о том, что планировщик работает: P
РЕДАКТИРОВАТЬ: Я, кажется, так плохо сформулировал это. Я ищу информацию о том, как устанавливаются задачи ядро , а не как задача задачи пользователя. Более конкретно, стек, на который указывает tsk- > thread- > esp, и что переключатель "switch_to" переключается на.
Ответы
Ответ 1
Начальный стек ядра для нового процесса устанавливается в copy_thread()
, который является функцией, специфичной для арки. Например, версия x86 начинается следующим образом:
int copy_thread(unsigned long clone_flags, unsigned long sp,
unsigned long unused,
struct task_struct *p, struct pt_regs *regs)
{
struct pt_regs *childregs;
struct task_struct *tsk;
int err;
childregs = task_pt_regs(p);
*childregs = *regs;
childregs->ax = 0;
childregs->sp = sp;
p->thread.sp = (unsigned long) childregs;
p->thread.sp0 = (unsigned long) (childregs+1);
p->thread.ip = (unsigned long) ret_from_fork;
p->thread.sp
и p->thread.ip
- новый указатель стека и указатель стека указателя соответственно.
Обратите внимание, что он не помещает сохраненные %eflags
, %ebp
и т.д. там, потому что, когда только что созданный поток выполнения сначала переключается на, он начинается с ret_from_fork
(здесь __switch_to()
возвращается для нового потока), что означает, что он не выполняет вторую половину подпрограммы switch_to()
.
Ответ 2
Состояние стека при создании процесса описано в X86-64 SVR4 ABI дополнение (для AMD64, то есть x86-64 64 бит машины). Эквивалент для 32-битного процессора Intel, вероятно, ABI i386. Я настоятельно рекомендую также читать Assembly HOWTO. И, конечно же, вы должны прочитать соответствующий файл ядра Linux.
Ответ 3
Google для "запуска процесса компоновки стека linux" дает эту ссылку: "Состояние запуска Linux/i386 ELF-двоичного кода", в котором описывается настроить, что ядро выполняет непосредственно перед передачей элемента управления в код запуска libc.