Внутреннее устройство ядра Linux 2.4

       

первичный процессор проходит обычную последовательность


В случае SMP (многопроцессорной системы), первичный процессор проходит обычную последовательность - bootsector, setup и т.д., пока не встретится вызов функции start_kernel(), в которой стоит вызов функции smp_init(), откуда вызывается arch/i386/kernel/smpboot.c:smp_boot_cpus(). Функция smp_boot_cpus() в цикле (от 0 до NR_CPUS) вызывает do_boot_cpu() для каждого apicid. Функция do_boot_cpu() создает (т.е. fork_by_hand) фоновую задачу для указанного CPU и записывает, согласно спецификации Intel MP (в 0x467/0x469) трамплин-код, содержащийся в trampoline.S. Затем генерирует STARTUP IPI, заставляя вторичный процессор выполнить код из trampoline.S.

Ведущий процессор создает трамплин-код для каждого процессора в нижней памяти. Ведомый процессор, при исполнении "трамплина", записывает "магическое число", чтобы известить ведущий процессор, что код исполнен. Требование, по размещению трамплин-кода в нижней памяти, обусловлено спецификацией Intel MP.

Трамплин-код просто записывает 1 в %bx, переводит процессор в защищенный режим и передает управление на метку startup_32, которая является точкой входа в arch/i386/kernel/head.S.

При исполнении кода head.S, ведомый CPU обнаруживает, что он не является ведущим, перепрыгивает через очистку BSS и входит в initialize_secondary() которая переходит в фоновую задачу для данного CPU - минуя вызов init_tasks[cpu], поскольку она уже была проинициирована ведущим процессором при исполнении do_boot_cpu(cpu).

Характерно, что код init_task может использоваться совместно, но каждая фоновая задача должна иметь свой собственный TSS. Именно поэтому init_tss[NR_CPUS] является массивом.


Содержание раздела