Sunday, Feb 05th

Last update12:13:00 PM GMT

Вы находитесь на: FreeBSD Запуск и выключение Базовые службы и память ядра

Базовые службы и память ядра

Прежде чем FreeBSD сможет делать какую-нибудь полезную работу, она должна установить некоторые базовые службы, которые используются всеми подсистемами внутри памяти ядра. Эти службы включают поддержку мьютексов, менеджер блокировок и менеджер памяти ядра. Все эти службы инициализируются в начале последовательности загрузки, чтобы их могла использовать оставшаяся часть ядра.

Базовые службы

Модуль

Первая процедура

SI_SUB_MTX_POOL_STATIC

mtx_pool_setup_static()

Sl_SUB_LOCKMGR

lockmgr_init()

SI_SUB_VM

vm_mem_init()

SI_SUB_KMEM

kmeminit()

SI_SUB_KVM_RSRC

vmmapentry_rsrc_init()

SI_SUB_WITNESS

witness_initialize()

SISUBMTXPOOLDYNAM

mtx_pool_setup_dynamic()

SI_SUB_LOCK

selectinitQ

SISUBEVENTHANDLER

eventhandler_init()

S1_SUB_KLD

linker_init()

SI_SUB_CPU

cpu_startup()

Мьютексы инициализируются двумя различными пулами: один статический, а другой динамический. Инициализация разделена, потому что динамические пулы используют распределитель памяти ядра, который должен быть установлен после статических мьютексов. Из-за тесной зависимости базовых служб памяти ядра друг от друга необходимо тщательно продумывать изменения порядка служб ядра.

Непосредственно после инициализации менеджера блокировок система включает систему виртуальной памяти ядра посредством вызова  базвовой службы vm_mem_init(). После завершения процедуры vm_mem_init() все выделения памяти ядром или процессами осуществляются для виртуальных адресов, которые преобразуются аппаратурой управления памятью в физические адреса. Когда работает система виртуальной памяти, ядро запускает свой собственный внутренний распределитель. Последней частью инициализации подсистемы памяти является наложение ограничений на ресурсы, используемые системой виртуальной памяти ядра, что выполняется процедурой vmmapentryrsrcJnit(). Модули ядра теперь могут запрашивать память, используя процедуру ядра malloc().

Переход от однопроцессорного ядра к ядру с поддержкой SMP потребовал блокировки структур данных ядра для нескольких независимых потоков. Отладка многопроцессорного кода достаточно трудна на уровне процессов, когда операционная система может предоставить программисту некоторую помощь. В ядре операционной системы эта проблема становится еще сложнее из-за того, что «рухнувшее» ядро тяжело отлаживать. Чтобы помочь в отладке ядра, FreeBSD добавила библиотеку ядра, которая может отслеживать все используемые и затем освобождаемые блокировки. Процедура witnessJnitialize() инстанциирует модуль SISUBWITNESS в качестве базовой службы для предоставления библиотеки модуля доказательств модулям, обрабатывающим блокировки.

Некоторые базовые службы требуют, чтобы их блокировки выделялись в виде части базовых служб. Системный вызов select и подсистема, обслуживающая объекты ядра, являются двумя такими службами. Модуль SI_SUB_LOCK предоставляет для служб место для регистрации того, что нужно каждый раз в начале последовательности загрузки вызывать их процедуры инициализации блокировок.

Модуль обработки событий позволяет различным службам регистрировать функции, вызываемые ядром при возникновении события. Служба обработки события интенсивно используется в последовательности выключения, но обрабатывает также такие разнообразные задачи, как клонирование устройства работа системы виртуальной памяти при нехватке памяти и разветвление, исполнение и завершение процессов. Модуль обработки событий SI_SUB_EVENTHANDLER запускается как часть базовых служб таким образом, чтобы другие модули могли его использовать при своем запуске.

Последней запускаемой службой является загрузчик модулей ядра, который загружает в систему динамические модули ядра при загрузке системы или в ходе ее работы. Процедура module_init() создает базовые структуры данных для обработки загрузки и выгрузки модуля, а также регистрации обработчика события для выгрузки всех модулей при выключении системы. Использование загрузчиком модулей ядра является причиной того, что этот модуль должен инициализироваться после только что обсужденного модуля обработчика событий.

Когда базовые службы запущены, ядро может теперь завершить установку процессора. Модуль SISUBCPU в действительности разделен на несколько подмодулей, которые отвечают за различные компоненты запуска системы. Первым подмодулем, который должен быть инициализирован, является расширенный программируемый контроллер прерываний (Advanced Programmable Interrupt Controller - APIC), который предоставляет поддержку аппаратных прерываний, а также координирует работу различных процессоров в системе SMP. Процедура apic_init() запускает устройство APIC, а затем зондирует наличие в системе других процессоров.

Без устройства APIC у нескольких процессоров в системе SMP не было бы способа координировать свою работу, поэтому этот шаг предпринимается в начале последовательности загрузки системы. Хотя система пока еще не готова запустить другие процессоры, она выделяет и инициализирует поддерживающие их структуры данных. Следующей подсистемой для запуска является сам центральный процессор. Хотя он уже работает, запущенный загрузочным кодом на языке ассемблера, в этот момент происходит несколько других частей инициализации.

Процедурой startclock() запускаются часы реального времени, и информация о процессоре выводится на консоли вместе со статистикой памяти. Модулем процессора запускается также система буферов, чтобы ядро могло читать данные с диска. FreeBSD сильно зависит от стабильного хранилища для памяти подкачки и для загрузки модулей ядра и программ. Поэтому система буферов устанавливается в начале последовательности загрузки, чтобы с самого начала дать ядру доступ к этим ресурсам.

В системах SMP после модулей APIC и процессора форсируется запуск модуля cpujnp, поскольку его аргумент порядка установлен в SIORDERSECOND, тогда как порядок и APIC, и процессора равен SIORDERFIRST. Поскольку в системе SMP контроллер APIC абсолютно необходим, то инициализация SMP должна быть произведена после инициализации APIC. Функция инициализации cpujnp, mp_start(), вызывает машинно-зависимые процедуры, которые выполняют фактическую работу по запуску других процессоров. Когда эта процедура завершается, все процессоры в SMP-системе активны, но не выполняют никакой работы до тех пор, пока не завершится вся последовательность запуска.

 


Похожие:
Еще по теме:
Советуем прочитать:

Сейчас 20 гостей онлайн

Реклама на сайте: