Драйвер что такое приоритет
Уровень IRQL, в котором выполняется подпрограмма драйвера, определяет, какие подпрограммы поддерживаются драйвером режима ядра, который он может вызывать. Например, для некоторых подпрограмм поддержки драйверов требуется, чтобы вызывающий объект выполнялся на уровне IRQL = DISPATCH_LEVEL. Другие не могут быть безопасно вызваны, если вызывающий объект работает на уровне IRQL выше, чем PASSIVE_LEVEL.
Ниже приведен список Ирклс, в которых вызываются наиболее распространенные стандартные подпрограммы драйверов. Ирклс перечислены от самого низкого до самого высокого приоритета.
PASSIVE_LEVEL
Прерывания маскированы — нет.
Подпрограммы драйвера, называемые в PASSIVE_LEVEL — DriverEntry, AddDevice, Повторная инициализация, подпрограммы выгрузки , большинство подпрограмм диспетчеризации, потоки, созданные драйвером, обратные вызовы рабочих потоков.
APC_LEVEL
Прерывания маскированы — APC_LEVEL прерывания маскируются.
Подпрограммы драйвера, называемые в APC_LEVEL — некоторые подпрограммы для диспетчеризации (см. раздел подпрограммы диспетчеризации и ирклс).
DISPATCH_LEVEL
Немаскированные прерывания — DISPATCH_LEVEL и APC_LEVEL прерывания отменяются. Возможны прерывания устройств, часов и сбоев питания.
Единственное различие между APC_LEVEL и PASSIVE_LEVEL заключается в том, что процесс, который выполняется в APC_LEVEL не может получить прерывания APC. Но оба Ирклс подразумевают контекст потока и оба подразумевают, что код может быть извлечен из страницы.
Драйверы самого низкого уровня обрабатывают IRP во время работы в одном из трех Ирклс:
PASSIVE_LEVEL без маскирования прерываний на процессоре, в подпрограммых диспетчеризации драйвера
Подпрограммы DriverEntry, AddDevice, Reinitializeи unload также выполняются на PASSIVE_LEVEL, как и любые системные потоки, созданные драйвером.
DISPATCH_LEVEL, с DISPATCH_LEVELми и APC_LEVEL прерываниями на процессоре, в подпрограммы стартио
Адаптерконтрол, адаптерлистконтрол, контроллерконтрол, иотимер, Cancel (хотя в нем удерживается превращение спин-блокировки), а подпрограммы кустомтимердпк также выполняются в DISPATCH_LEVEL, как и подпрограммы дпкфориср и CustomDpc .
IRQL устройства (ДИРКЛ) со всеми прерываниями, не превышающими синчронизеиркл объектов прерываний драйвера, замаскированных на процессор, в подпрограммах ISR и синчкритсектион
Большинство драйверов более высокого уровня обрабатывают IRP во время работы в одном из двух Ирклс:
PASSIVE_LEVEL без маскирования прерываний на процессоре, в подпрограммых диспетчеризации драйвера
Подпрограммы DriverEntry, Reinitialize, AddDeviceи unload также выполняются на PASSIVE_LEVEL, как и любые созданные драйверами системные потоки или подпрограммы обратного вызова рабочего потока или драйверы файловой системы.
DISPATCH_LEVEL с DISPATCH_LEVELными и APC_LEVEL прерываниями, перемаскированными на процессоре, в подпрограмме иокомплетион драйвера
Подпрограммы иотимер, Cancelи кустомтимердпк также выполняются на DISPATCH_LEVEL.
В некоторых случаях промежуточные и низкоуровневые драйверы устройств хранения данных вызываются на уровне IRQL APC_LEVEL. В частности, это может произойти при ошибке страницы, при которой драйвер файловой системы отправляет запрос IRP_MJ_READ для более низкого уровня драйверов.
Большинство стандартных подпрограмм драйверов выполняются на уровне IRQL, что позволяет им просто вызывать соответствующие подпрограммы поддержки. Например, драйвер устройства должен вызвать аллокатеадаптерчаннел при выполнении на уровне IRQL DISPATCH_LEVEL. Так как большинство драйверов устройств вызывают эти подпрограммы из подпрограммы стартио , обычно они работают в DISPATCH_LEVEL уже.
Обратите внимание, что драйвер устройства, не имеющий подпрограммы стартио , так как он настраивает и управляет своими очередями запросов IRP, не всегда запускается в DISPATCH_LEVEL IRQL, когда он должен вызвать аллокатеадаптерчаннел. Такой драйвер должен вкладывать свой вызов аллокатеадаптерчаннел между вызовами кераисеиркл и келовериркл , чтобы он выполнялся на требуемом уровне IRQL при вызове аллокатеадаптерчаннел и восстанавливает первоначальный уровень IRQL, когда вызывающая подпрограмма восстанавливает элемент управления.
При вызове подпрограмм поддержки драйверов необходимо учитывать следующее.
Вызов кераисеиркл с входным значением невиркл , меньшим, чем текущий уровень IRQL, приводит к неустранимой ошибке. Вызов келовериркл , за исключением восстановления исходного IRQL (т. е. После вызова кераисеиркл), также приводит к неустранимой ошибке.
При выполнении в режиме IRQL > = DISPATCH_LEVEL вызов подпрограммы kewaitforsingleobject или кеваитформултиплеобжектс для определенных ядром объектов Dispatcher для ожидания ненулевого интервала приводит к неустранимой ошибке.
Единственные подпрограммы драйвера, которые могут безопасно ожидать события, семафоры, мьютексы или таймеры, которые должны быть установлены в сигнальное состояние, — это те, которые выполняются в непроизвольном контексте потока на уровне IRQL PASSIVE_LEVEL, такие как созданные драйвером потоки, подпрограммы DriverEntry и Повторная инициализация , а также подпрограммы диспетчеризации для выполнения по сути синхронных операций ввода-вывода (например, большинство запросов управления операциями ввода-вывода).
Даже при выполнении на уровне IRQL PASSIVE_LEVEL код драйвера с подкачки не должен вызывать кесетевент, керелеасесемафореили керелеасемутекс с входным параметром Wait , имеющим значение true. Такой вызов может вызвать неустранимую ошибку страницы.
Любая подпрограмма, которая работает в более чем IRQL APC_LEVEL не может безопасно выделять память из выгружаемого пула и не обращаться к памяти выгружаемого пула. Если подпрограмма, выполняемая на уровне прерывания, превышающая APC_LEVEL вызывает ошибку страницы, это Неустранимая ошибка.
Драйвер не должен вызывать кеаккуиреспинлоккатдпклевел, керелеасеспинлоккфромдпклевел, кеаккуиреспинлоккили керелеасеспинлокк при выполнении на уровне IRQL > DISPATCH_LEVEL.
Вызов подпрограммы поддержки, использующей спин-блокировку, например подпрограмму Ексинтерлоккедxxx , приводит к возникновению IRQL на текущем процессоре как DISPATCH_LEVEL, так и диркл, если вызывающий объект еще не запущен на основе прерывания IRQL.
Код драйвера, выполняемый на уровне IRQL > PASSIVE_LEVEL, должен выполняться как можно быстрее. Чем выше уровень IRQL, в котором выполняется подпрограммы, тем более важным является обеспечение высокой общей производительности для выполнения этой подпрограммы как можно быстрее. Например, любой драйвер, вызывающий кераисеиркл , должен сделать обратный вызов келовериркл как можно скорее.
Дополнительные сведения об определении приоритетов см. в техническом документе о планировании, контексте потока и IRQL .
InDriver – популярный мобильный сервис заказа такси без оператора, это система взаимодействия водителя, пассажира без посредников. При этом для водителей выработана схема оценки, от которой зависит количество заказов, а также оплата за них. Рассмотрим, можно ли поднять приоритет автомобилиста в Индрайвере.
Что такое InDriver
InDriver – международная онлайн-система пассажирских перевозок. Сервис ведет работу более, чем в 70 городах четырех государств. Офис компании есть в Якутске, Москве. С 2014 года система начала работу на территории Казахстана. Список городов, где функционирует InDriver, постоянно растет.
Схема работы системы кардинально отличается от привычных сервисов такси. Основная идея в том, что здесь пассажир выбирает, с кем совершить поездку. А водители конкурируют за каждый заказ. Клиенты при выборе машины могут ориентироваться на степень удаленности, рейтинг сотрудника InDriver. Система оценки работает на основе отзывов пользователей, которые совершили поездку с конкретным автоводителем.
Что дает приоритет в InDriver
Приложение для гаджетов InDriver кардинально отличается от других сервисов пассажирских перевозок. Здесь пассажир сам определяет стоимость поездки. Фактически, эту систему нельзя отнести к такси, тут водители сами ведут борьбу за возможность взять пассажира, а клиент выбирает, с кем поехать. При этом для InDriver характерны такие особенности:
- нет необходимости звонить диспетчеру, этот факт существенно понижает цену поездки;
- заказ видят автомобилисты, работающие территориально максимально близко к местонахождению пассажира, этот фактор уменьшает время подачи транспорта;
- у пассажира есть возможность совершить звонок непосредственно водителю, который находится ближе всего;
- есть возможность отслеживать перемещение автоводителя по карте;
- разработана система оценок автомобилиста, клиенты могут оставлять отзывы после совершения поездки.
Важно! Сервис Индрайвер не повышает стоимость поездки для смартфона дорогой модели, постоянных пассажиров, или если телефон клиента имеет низкий заряд батареи.
Благодаря оценкам и отзывам клиентов, формируется рейтинг или приоритет водителей InDriver. Оценки отслеживает круглосуточный подраздел поддержки системы. Высокий приоритет гарантирует автомобилисту преимущество при получении заказов. Стоимость поездки находится под контролем пассажира, а не алгоритма сервиса.
Таким образом, положительные отзывы от клиентов оказывают прямое влияние на доходы лица, которое выполняет пассажирскую перевозку. Позитивная репутация дает водителю доступ к большему количеству заказов, клиенты охотнее будут отдавать предпочтение этому перевозчику. Автомобилисты заинтересованы постоянно повышать рейтинг.
Способы повысить свой приоритет
Система отзывов и оценок автомобилистов – эффективный, а также оперативный метод контроля качества предоставляемых услуг. Таким способом руководство сервиса отсеивает недобросовестных и нарушающих корпоративные регламенты работников. В результате пользователи получают доступ к системе с высоким качеством услуг по пассажирским перевозкам.
В сервисе могут работать только проверенные водители, поэтому, помимо оценки качества услуг, производится контроль документации, действует система юридической помощи, имеется поощрительная система для работников с лицензиями. Пользователи оценивают поездку и регулируют водительский приоритет по многим критериям:
- вежливость, с клиентом необходимо общаться культурно и тактично;
- если заказ был взят, то необходимо его выполнить, иначе может понизиться рейтинг;
- чистота автомобиля, необходимо следить за чистотой салона, не стоит курить и мусорить в машине;
- внешний вид водителя, безусловно, что пассажиру приятнее ехать с чистым и опрятным водителем, от которого хорошо пахнет;
- скорость подачи машины также оценивается;
- выполнение поездки, если доставлять пассажиров аккуратно и оперативно, то оценка перевозки будет высокая.
Водитель также имеет право выдвинуть к клиенту свои требования, к примеру, брать плату за слишком долгое ожидание, не разрешать курить в салоне автомобиля.
Как искусственно быстро поднять рейтинг
Возможность искусственно быстро повысить приоритет в InDriver не предусмотрена. Пассажир получает возможность оставлять отзыв и оценивать поездку только после того, как перевозка завершена, «накручивать» рейтинг в этой системе невозможно. Поэтому водителю требуется ответственно выполнять свою работу, и тем самым он сможет подымать приоритет в InDriver. При качественном исполнении своих должностных обязанностей рейтинг водителя будет стабильно подниматься.
Таким образом, для поднятия рейтинга водителя в сервисе InDriver ему потребуется, прежде всего, лояльное поведение по отношению к пассажирам. Чистая и отремонтированная машина, аккуратный внешний вид и соответствующее поведение. Ускоренный рост рейтинга обеспечен в сочетании с быстрой подачей машины и аналогичной доставкой клиента в конечную точку.
Чем выше расположена группа в этом списке, тем больше ее приоритет при загрузке.
Этот список, если возникнет большая необходимость, можно самостоятельно модифицировать: добавить новые группы, поменять порядок следования групп и т.д.
В данном примере драйвер PCI шины принадлежит группе драйверов "Boot Bus Extender".
Так, хорошо. С разделением на группы понятно: чем выше приоритет группы, тем ранше запустятся драйвера из этой группы.
А если рассмотреть два драйвера из одной группы, то какой из них будет загружен раньше ?
Очередность загрузки внутри групп определяется двоичным параметром " Tag ".
Если этот параметр отсутствует, то драйвер будет загружен в самую последнюю очередь.
Что можно сказать про параметр "Tag" ?
1. Обычно он представлен неким числом. Причем, если вдруг понадобится добавить тэг драйверу, у которого его нет, то значение этого тэга нельзя брать, что называется, "от балды". Но об этом дальше.
2. Руководствуясь только числовым значением параметра "Tag" нельзя судить о степени приоритетности драйвера.
Допустимые значения тэгов и их приоритет задаются двоичными переменными по названию группы драйверов в ветке:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GroupOrderList]
Пример ( для группы драйверов "Boot Bus Extender" ):
Двоичная переменная представляет из себя набор двойных слов (по 4 байта каждое).
Первое слово (выделено на рисунке красной рамкой) задает общую длину переменной (количество двойных слов)
Остальные двойные слова как раз и являются тэгами.
Тэг, равный единице, выделен зеленой рамкой, двойке -- синей.
Закономерность тут простая:
Чем левее расположен тэг тем выше его приоритет в группе.
Тем выше приоритет драйвера, у которого такой тэг имеется.
На приведенном выше рисунке видно, что приоритет тэга 01 выше, чем у тэга 02. Самым высоким приоритетом в этой группе обладает тэг 08 (выделен желтой рамкой).
Кстати, в группе драйверов могут встречаться драйвера с одинаковыми тэгами.
Как в таком случае определяется очередность -- мне не известно.
Итак.
Условно представим, что у нас есть:
1) драйвер A, принадлежащий группе драйверов Gr1
2) драйвер В, принадлежащий группе драйверов Gr2
3) приоритет Gr1 > Gr2
Из пункта (3) следует, что приоритет драйвера A выше, чем у B, т.е. драйвер A будет загружен раньше драйвера B.
Нам нужно добиться, чтобы драйвер B грузился раньше A.
Возможные варианты (первые два, пришедшие в голову):
1) изменить приоритет групп драйверов в списке ServiceGroupOrder > List
a) либо повысить приоритет Gr2 (сделать выше, чем у Gr1)
b) (зеркальный вариант) либо понизить приоритет Gr1 (сделать ниже, чем у Gr2)
Оба варианта одинаково плохи, особенно, если каждая из групп содержит больше одного драйвера. Ведь не всегда с уверенностью можно сказать, как на такое перемещение отреагируют остальные драйвера группы.
2) переместить один из драйверов в другую группу:
a) переместить драйвер B в группу Gr1 и присвоить ему более приоритетный Tag, чем у драйвера A.
b) (зеркальный вариант) переместить драйвер B в группу Gr2 и присвоить ему менее приоритетный Tag, чем у драйвера A.
ИМХО, самый оптимальный вариант 2a. Ему я и буду следовать на практике.
Настало время перейти к практике.
Как я уже упоминал в самом начале статьи, весь сыр-бор был затеян из-за того, что драйвера винды определяли IDE-контроллер раньше, чем драйвер WpcrSet успевал изменить его идентификационные регистры, что приводило к некоторым неудобствам.
Как оказалось, под термином " драйвера винды" скрывался вполне конкретный " Драйвер PCI шины". ( Вы, наверное, догадались, что не зря он присутствует почти на всех вышеприведенных скриншотах ;-) )
Иначе говоря, возникла острая необходимость в запуске драйвера WpcrSet раньше драйвера PCI.
Настройки драйвера PCI:
1. Драйвер принадлежит группе " Boot Bus Extender".
2. Параметр Tag у драйвера равен двум (02h).
Настройки драйвера WpcrSet по-умолчанию:
Видно, что:
1. Драйвер принадлежит группе " Extended Base".
2. У драйвера напрочь отсутствует параметр Tag, что говорит о его наименьшем приоритете даже в пределах родной группы.
На следующем этапе выясняем, приоретет какой группы (Boot Bus Extender / Extended Base) выше:
Видно, что группа Boot Bus Extender вторая от начала, а Extended Base -- третья с конца. Следовательно приоритет Boot Bus Extender гораздо выше.
Поэтому первым делом переносим драйвер WpcrSet в группу Boot Bus Extender. Для этого меняем параметр " Group" с Extended Base на Boot Bus Extender:
Теперь требуется выставить Tag для драйвера WpcrSet. Причем такой, чтобы его приоритет был выше приоритета тэга драйвера PCI (Tag=02h).
Для этого смотрим на содержимое переменной " Boot Bus Extender" в разделе [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GroupOrderList]
-
Note: На практике могла возникнуть ситуация, когда тэг драйвера PCI оказался бы наиболее приоритетным. т.е. самым левым в списке. Тогда перед ним нам пришлось бы добавить еще дополнительный тэг. При этом первое двойное слово в списке, задающее количество тэгов, пришлось бы увеличить на единицу.
Ну, вот и все. Настройки WpcrSet теперь выглядят так:
Теперь, перекрестясь , можно перезагружать компьютер и наблюдать за изменениями.
Note: Искренне надеюсь, что перед тем, как лезть в реестр, вы предварительно забакапились. Ибо еще раз повторяю: я снимаю с себя всю ответственность за то, что вы учините со своим компьютером, начитавшись моих "статей"!
Не знаю, как у Вас, а у меня все прошло просто замечательно. Драйвер WpcrSet стартовал раньше остальных драйверов и сделал свое черное дело точно и главное вовремя .
Так что на сегодняшний день вопрос о порядке старта драйверов в системе можно считать разрешенным.
-
NOTE: (для ленивых) описанные в статье манипуляции с реестром можно заменить одним REG-файлом следующего содержания:
реклама
Тем, кому интересно внутреннее устойство операционной системы Windows, предлагаю небольшое исследование. Мы попробуем выяснить, что отвечает за порядок загрузки драйверов и сервисов в Windows и можно ли этот порядок изменить.
Прежде всего посмотрим текущий порядок запуска системы с помощью программы LoadOrder от Sysinternals. Программа покажет нам, что и в каком порядке загружается при запуске операционной системы.
Как видно из рисунка, сначала загружаются драйверы устройств, необходимые для запуска системы, а потом различные Windows-сервисы. Поскольку между загрузкой сервисов и загрузкой драйверов есть некоторые различия, рассматривать их будем по отдельности.
В качестве подопытного возьмем драйвер Microsoft ACPI (Advanced Configuration and Power Interface), который отвечает за обнаружение аппаратного обеспечения и управление питанием. Задача ACPI — обеспечить взаимодействие между операционной системой и аппаратным обеспечением, поэтому драйвер ACPI загружается в самом начале.
Программа Loadorder предоставляет довольно ограниченную информацию о порядке загрузки, поэтому за более точными данными идем в реестр. У каждого драйвера и Windows-сервиса есть свой раздел в ветви реестра HKLM\SYSTEM\CurrentControlSet\Services. Названы разделы по имени драйвера\сервиса, соответственно нам нужен раздел ACPI.
За порядок загрузки драйвера отвечают три параметра реестра. Основной параметр Start — определяет тип запуска драйвера. Вот правила, по которым драйверы устанавливают значение своего параметра Start:
• Драйверы, которые должны загружаться системным загрузчиком при запуске операционной системы, указывают значение Start равное 0 ( запуск при загрузке системы ). Пример — драйверы системных шин и драйвер файловой системы, используемый при загрузке системы;
• Драйвер, который не требуется непосредственно для загрузки системы, указывает в Start значение, равное 1 ( запуск системой ). Пример — стандартный драйвер видеокарты (VgaSave);
• Драйвер, не обязательный для загрузки системы, устанавливает значение Start равным 2 ( автозапуск ). Пример — драйвер многосетевого UNC-npoвайдера (Multiple UNC Provider, MUP), поддерживающий UNC-имена удаленных ресурсов (типа \\Computer\Share);
• Драйверы, не обязательные для работы операционной системы (например, драйверы сетевых адаптеров), указывают значение Start равным 3 ( запуск по требованию ).
Также драйверы устройств могут использовать параметры Group и Tag для контроля порядка своей загрузки при запуске системы. Параметр Group драйверы\сервисы используют, чтобы указать группу, к которой они принадлежат, а порядок загрузки групп определяется параметром List, находящимся в разделе HKLM\SYSTEM\ CurrentControlSet\Control\ServiceGroupOrder\.
Кстати, параметр Group указывать не обязательно. Если драйвер\сервис не входит в какую либо группу, то он загружается в самом конце очереди.
Драйвер может еще больше детализировать порядок своей загрузки с помощью параметра Tag, который указывает конкретную позицию драйвера в группе. Диспетчер ввода-вывода сортирует драйверы в группе по значениям этого параметра, а драйверы, не имеющие параметра Tag, перемещаются в конец списка драйверов группы.
Посмотрев на порядок загрузки, можно подумать что сначала загружаются драйверы с меньшими значениями Tag, потом — с большими, но это не совсем так. Приоритет значений параметров Tag в рамках группы определяется в разделе HKLM\SYSTEM\CurrentControlSet\Control\GroupOrderList.
Для примера откроем двоичный параметр Boot Bus Extender, который соответствует одноименной группе, к которой относится и драйвер ACPI. Параметр представляет из себя набор двойных слов (по 4 байта каждое). Первое слово (выделено красным) задает общую длину переменной (количество двойных слов), в нашем примере 06. Остальные двойные слова как раз и являются тэгами. Драйверу ACPI соответствует тэг, равный 01 (выделен зеленым).
Приоритетность тега определяется не значением тега, а его положением: чем выше расположен тэг, тем выше его приоритет в группе, и тем выше приоритет драйвера, которому этот тэг соответствует. А поскольку 01 выше остальных тегов, то и драйвер ACPI загружается первым в группе.
Порядок загрузки Windows-сервисов несколько отличается от порядка загрузки драйверов. В качестве примера возьмем сервис aвтоматического обновления (wuauserv). Он не особо критичен для работы системы и поэтому грузится в последнюю очередь.
Опять идем в реестр. Параметры запуска сервиса находятся в разделе HKLM\SYSTEM\CurrentControlSet\Services\wuauserv. Я выделил два основных параметра, отвечающих за порядок загрузки данного сервиса.
Windows-сервисы запускаются диспетчером управления сервисами (Service Control Manager, SCM) в соответствии со значением параметра Start. Параметр этот для сервисов может принимать следующие значения:
• Авто запуск (2) — сервис запускается автоматически, сразу после запуска основного SCM-процесса Services.exe;
• Запуск по требованию (3) — сервис запускается при необходимости, по требованию какого либо сервиса или программы;
• Отключено (4) - сервис отключен и не запускается ни при каких условиях.
Значения 0 (запуск при загрузке системы) и 1 (запуск системой) для сервисов не могут быть указаны, только для драйверов устройств.
Кроме того, начиная с Windows Vista\Server 2008 для сервисов появился еще один режим запуска — отложенный автозапуск. Отвечает за него параметр DelayedAutoStart = 1, который который указывает SCM произвести автоматический старт данного сервиса с задержкой. SCM запускает службы, для которых выбран отложенный запуск, после загрузки сервисов, отмеченных для автозапуска.
Режимом запуска сервисов можно управлять не только из реестра, но и в графическом режиме, из консоли Службы (Services).
Так же как и драйверы, Windows-сервисы могут использовать параметр Group в своем разделе реестра, чтобы указать группу, к которой они принадлежат. Сейчас, для наглядности, возьмем наш сервис wuauserv, находящийся в самом конце списка загрузки. С помощью ключа Group поместим его в группу Event Log, перезагрузимся и посмотрим порядок загрузки в Loadorder. Как видите, порядок изменился и wuauserv поднялся с последнего места, загрузившись сразу после своего одногруппника — службы eventlog. Правда порядок размещения внутри группы изменить уже не получится, т.к. Tag для сервисов не используется.
И еще один параметр, который косвенно влияет на порядок загрузки сервисов — DependOnService. Он указывает, от каких сервисов зависит данный сервис. Соответственно сервис не загружается, пока не будут загружены сервисы, перечисленные в DependOnService.
Зависимости работают следующим образом — если сервисы находятся в одной группе, то зависимый сервис перемещается в конец списка и запускается после сервисов, от которых зависит. Если же группы разные, то сервис просто не запустится, а SCM выдаст ошибку.
Более наглядно это показано в оснастке Службы, где на вкладке Зависимости (Dependency) указаны как сервисы, от которых зависит данный сервис, так и сервисы, зависящие от него.
Тем, кому интересно внутреннее устойство операционной системы Windows, предлагаю небольшое исследование. Мы попробуем выяснить, что отвечает за порядок загрузки драйверов и сервисов в Windows и можно ли этот порядок изменить.
Прежде всего посмотрим текущий порядок запуска системы с помощью программы LoadOrder от Sysinternals. Программа покажет нам, что и в каком порядке загружается при запуске операционной системы.
Как видно из рисунка, сначала загружаются драйверы устройств, необходимые для запуска системы, а потом различные Windows-сервисы. Поскольку между загрузкой сервисов и загрузкой драйверов есть некоторые различия, рассматривать их будем по отдельности.
Драйверы
В качестве подопытного возьмем драйвер Microsoft ACPI (Advanced Configuration and Power Interface), который отвечает за обнаружение аппаратного обеспечения и управление питанием. Задача ACPI — обеспечить взаимодействие между операционной системой и аппаратным обеспечением, поэтому драйвер ACPI загружается в самом начале.
Программа Loadorder предоставляет довольно ограниченную информацию о порядке загрузки, поэтому за более точными данными идем в реестр. У каждого драйвера и Windows-сервиса есть свой раздел в ветви реестра HKLM\SYSTEM\CurrentControlSet\Services. Названы разделы по имени драйвера\сервиса, соответственно нам нужен раздел ACPI.
За порядок загрузки драйвера отвечают три параметра реестра. Основной параметр Start — определяет тип запуска драйвера. Вот правила, по которым драйверы устанавливают значение своего параметра Start:
• Драйверы, которые должны загружаться системным загрузчиком при запуске операционной системы, указывают значение Start равное 0 (запуск при загрузке системы). Пример — драйверы системных шин и драйвер файловой системы, используемый при загрузке системы;
• Драйвер, который не требуется непосредственно для загрузки системы, указывает в Start значение, равное 1 (запуск системой). Пример — стандартный драйвер видеокарты (VgaSave);
• Драйвер, не обязательный для загрузки системы, устанавливает значение Start равным 2 (автозапуск). Пример — драйвер многосетевого UNC-npoвайдера (Multiple UNC Provider, MUP), поддерживающий UNC-имена удаленных ресурсов (типа \\Computer\Share);
• Драйверы, не обязательные для работы операционной системы (например, драйверы сетевых адаптеров), указывают значение Start равным 3 (запуск по требованию).
Также драйверы устройств могут использовать параметры Group и Tag для контроля порядка своей загрузки при запуске системы. Параметр Group драйверы\сервисы используют, чтобы указать группу, к которой они принадлежат, а порядок загрузки групп определяется параметром List, находящимся в разделе HKLM\SYSTEM\ CurrentControlSet\Control\ServiceGroupOrder\.
Кстати, параметр Group указывать не обязательно. Если драйвер\сервис не входит в какую либо группу, то он загружается в самом конце очереди.
Драйвер может еще больше детализировать порядок своей загрузки с помощью параметра Tag, который указывает конкретную позицию драйвера в группе. Диспетчер ввода-вывода сортирует драйверы в группе по значениям этого параметра, а драйверы, не имеющие параметра Tag, перемещаются в конец списка драйверов группы.
Посмотрев на порядок загрузки, можно подумать что сначала загружаются драйверы с меньшими значениями Tag, потом — с большими, но это не совсем так. Приоритет значений параметров Tag в рамках группы определяется в разделе HKLM\SYSTEM\CurrentControlSet\Control\GroupOrderList.
Для примера откроем двоичный параметр Boot Bus Extender, который соответствует одноименной группе, к которой относится и драйвер ACPI. Параметр представляет из себя набор двойных слов (по 4 байта каждое). Первое слово (выделено красным) задает общую длину переменной (количество двойных слов), в нашем примере 06. Остальные двойные слова как раз и являются тэгами. Драйверу ACPI соответствует тэг, равный 01 (выделен зеленым).
Приоритетность тега определяется не значением тега, а его положением: чем выше расположен тэг, тем выше его приоритет в группе, и тем выше приоритет драйвера, которому этот тэг соответствует. А поскольку 01 выше остальных тегов, то и драйвер ACPI загружается первым в группе.
Сервисы
Порядок загрузки Windows-сервисов несколько отличается от порядка загрузки драйверов. В качестве примера возьмем сервис aвтоматического обновления (wuauserv). Он не особо критичен для работы системы и поэтому грузится в последнюю очередь.
Опять идем в реестр. Параметры запуска сервиса находятся в разделе HKLM\SYSTEM\CurrentControlSet\Services\wuauserv. Я выделил два основных параметра, отвечающих за порядок загрузки данного сервиса.
Windows-сервисы запускаются диспетчером управления сервисами (Service Control Manager, SCM) в соответствии со значением параметра Start. Параметр этот для сервисов может принимать следующие значения:
• Авто запуск (2) — сервис запускается автоматически, сразу после запуска основного SCM-процесса Services.exe;
• Запуск по требованию (3) — сервис запускается при необходимости, по требованию какого либо сервиса или программы;
• Отключено (4) — сервис отключен и не запускается ни при каких условиях.
Значения 0 (запуск при загрузке системы) и 1 (запуск системой) для сервисов не могут быть указаны, только для драйверов устройств.
Кроме того, начиная с Windows Vista\Server 2008 для сервисов появился еще один режим запуска — отложенный автозапуск. Отвечает за него параметр DelayedAutoStart = 1, который который указывает SCM произвести автоматический старт данного сервиса с задержкой. SCM запускает службы, для которых выбран отложенный запуск, после загрузки сервисов, отмеченных для автозапуска.
Режимом запуска сервисов можно управлять не только из реестра, но и в графическом режиме, из консоли Службы (Services).
Так же как и драйверы, Windows-сервисы могут использовать параметр Group в своем разделе реестра, чтобы указать группу, к которой они принадлежат. Сейчас, для наглядности, возьмем наш сервис wuauserv, находящийся в самом конце списка загрузки. С помощью ключа Group поместим его в группу Event Log, перезагрузимся и посмотрим порядок загрузки в Loadorder. Как видите, порядок изменился и wuauserv поднялся с последнего места, загрузившись сразу после своего одногруппника — службы eventlog. Правда порядок размещения внутри группы изменить уже не получится, т.к. Tag для сервисов не используется.
И еще один параметр, который косвенно влияет на порядок загрузки сервисов — DependOnService. Он указывает, от каких сервисов зависит данный сервис. Соответственно сервис не загружается, пока не будут загружены сервисы, перечисленные в DependOnService.
Зависимости работают следующим образом — если сервисы находятся в одной группе, то зависимый сервис перемещается в конец списка и запускается после сервисов, от которых зависит. Если же группы разные, то сервис просто не запустится, а SCM выдаст ошибку.
Более наглядно это показано в оснастке Службы, где на вкладке Зависимости (Dependency) указаны как сервисы, от которых зависит данный сервис, так и сервисы, зависящие от него.
Читайте также: