Что представляет собой состояние стека ядра ядра 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.