- •1. Определение и функции ос. Классификация многозадачных ос. Принципиальные отличия требований к системам реального времени и к обычными системами разделения времени.
- •1 Вопрос. Определение и функции ос.
- •2 Вопрос. Три подхода к определению ос:
- •3 Вопрос. Классификация многозадачных ос
- •2. Ядро ос. Подходы к определению ядра ос (классический и по Василенко). Причины неоднозначности. Режим ядра и режим пользователя. Системный вызов и его реализация (на примере любой ос/архитектуры).
- •4 Вопрос. Подходы к определению ядра ос
- •7 Вопрос. Понятие процесса. Адресное пространство процесса
- •8 Вопрос. Контекст процесса. Регистровый контекст
- •9 Вопрос. Системный контекст
- •10 Вопрос. Контекст процесса.
- •Создание и завершение процесса
- •11 Вопрос. Создание и завершение процесса
- •12 Вопрос. Граф состояний процесса. Причины перехода между состояниями.
- •Все возможные причины блокировки процесса
- •4. Вытесняющая многозадачность. Цели алгоритма планирования и их противоречивость. Основные алгоритмы планирования и их модификации.
- •13 Вопрос. Вытесняющая многозадачность
- •14 Вопрос. Задачи алгоритмов планирования
- •15 Вопрос. Планирование в системах пакетной обработки данных
- •17 Вопрос. Наименьшее оставшееся время выполнения. Трехуровневое планирование
- •18 Вопрос. Планирование в интерактивных системах
- •19 Вопрос. Несколько очередей. "Самый короткий процесс - следующий"
- •20 Вопрос. Гарантированное планирование. Лотерейное планирование. Справедливое планирование
- •21 Вопрос. Планирование в системах реального времени
- •22 Вопрос. Иерархия классов в Linux: rt, cfs, idle, stats.
- •23 Вопрос. Реальные алгоритмы планирования
- •24 Вопрос. Проблема балансировки нагрузки в smp-системах
- •Область применения нитей и процессов.
- •Реализация потоков в ядре
- •7. Синхронизация процессов и нитей (в т.Ч. Ядерных). Основные примитивы синхронизации. Различия семафоров и спин-блокировки. Ограничения использования семафоров в ядре (сюда же can_sleep()).
- •25 Вопрос. Примитивы межпроцессного взаимодействия
- •Спин-блокировки:
- •26 Вопрос. Семафоры
- •27 Вопрос. Мьютексы
- •[Крищенко: метода sys_linux]
- •28 Вопрос. Виртуальная память
- •Задачи, решаемые виртуальной памятью:
- •Вопросы из лекций:
- •29 Вопрос. Страничная организация виртуальной памяти
- •30 Вопрос. Сегментная и сегментно-страничная организации виртуальной памяти
- •31 Вопрос. Преобразование виртуального адреса в физический при страничном преобразовании
- •32 Вопрос. Tlb и его назначение. Моменты сброса tlb.
- •Адресное пространство процесса
- •Разделы адресного пространства процесса (32 разряда)
- •Выделение памяти процессу и освобождение им памяти. Связь функций выделения памятью стандартной библиотеки и системных вызовов, необходимость менеджера памяти режима пользователя
- •11. Виды межпроцессного взаимодействия и их классификация. Виды ipc в стандартах posix. Использование сокетов tcp/ip при большом количестве соединений Методы межпроцессного взаимодействия.
- •Виды ipc в стандартах posix
- •Использование сокетов tcp/ip при большом количестве соединений
- •32 Вопрос. Ввод-вывод и обработка прерываний.
- •33 Вопрос. Первичная и отложенная обработка прерываний, необходимость такого разделения. Реализация отложенной обработки.
- •13. Планировщик ввода-вывода для дисковых устройств. Алгоритмы планирования ввода-вывода для дискового устройства. Буферизация запросов.
- •34 Вопрос. Структура системы ввода-вывода
- •35 Вопрос. Алгоритмы планирования
- •36 Вопрос. Механизм ввода-вывода
- •36. Вопрос. Дескрипторы очереди запросов. Дескриптор запроса. Процесс планирования ввода-вывода
- •Процесс планирования ввода-вывода
- •14. Подсистема виртуальной фс в ядре ос. Кеширование. Ввод-вывод и прямой доступ к памяти на примере дискового устройства. Необходимость в уровне буферов (на примере Линукс)
- •Основные структуры
- •Уровень виртуальной файловой системы
- •Менеджер ввода-вывода
- •Стратегии организации ввода-вывода:
- •Ещё заметка про уровень буфферов
- •37 Вопрос. Основные структуры файловой системы.
- •Задачи файловой системы (from wiki)
- •38 Вопрос. Различные подходы к организации структур фс
- •39 Вопрос. Неразрывные файлы
- •40 Вопрос. Связанные списки. Связанные списки с индексацией
- •Связанные списки с индексацией
- •41 Вопрос. Индексные узлы
- •42 Вопрос. Реализация простой фс (предлагаю на примере minix file system).
- •43 Вопрос. Битовые карты, индексные узлы в minix 3
- •Индексные узлы
- •44 Вопрос. Журналируемые фс.
- •45 Вопрос. Физическая организация fat
- •46 Вопрос. Физическая организация s5 и ufs
- •47 Вопрос. Поиск адреса файла по его символьному имени
- •49 Вопрос. Физическая организация ntfs
- •50 Вопрос. Первый отрезок mft
- •51 Вопрос. Структура файлов ntfs
- •52 Вопрос. Виды файлов в ntfs
- •53 Вопрос. Каталоги ntfs
- •54 Вопрос. Файловые операции
- •55 Вопрос. Открытие файла
- •56 Вопрос. Обмен данными с файлом
- •57 Вопрос. Блокировки файлов
- •58 Вопрос. Стандартные файлы ввода и вывода, перенаправление вывода
- •59 Вопрос. Контроль доступа к файлам
- •60 Вопрос. Механизм контроля доступа
- •61 Вопрос. Организация контроля доступа в ос unix
- •62 Вопрос. Организация контроля доступа в ос Windows nt
- •63 Вопрос. Разрешения на доступ к каталогам и файлам
- •64 Вопрос. Встроенные группы пользователей и их права
- •65 Вопрос. Выводы
- •16. Сетевая подсистема ос и её функции. Причины включения tcp/ip в ядро ос. Реализация сетевых файловых систем.
- •Реализация сетевых файловых систем
- •Таненбаум Файловая система nfs
- •17. Идея микроядра. Недостатки и достоинства концепции микроядра (см. Qnx, Hurd, Minix, использование Mach в Mac os X). Идея микроядра
- •Достоинства:
- •Недостатки:
- •Более подробно о микроядре на примерах:
- •18. Идея ос на базе jit-vm. Недостатки, достоинства, ограничения концепции (смотреть, например, Singularity)
- •20. Существующие стандарты на интерфейсы ос. Группа стандартов Posix. Достоинства и недостатки реализации нестандартных интерфейсов (на примере WinApi). Реализация интерфейсов "чужеродных" ос.
- •Основные идеи стандарта posix
- •Api операционных систем. Проблемы, связанные с многообразием api (статья Wikipedia: Интерфейс программирования приложений)
- •21. Графическая подсистема и её место в ос на примере x11/Cocoa/WinApi. Достоинства и недостатки различных подходов.
18. Идея ос на базе jit-vm. Недостатки, достоинства, ограничения концепции (смотреть, например, Singularity)
Just-in-time compilation (JIT) - технология увеличения производительности программных систем, использующих байт-код, путём трансляции байт-кода в машинный код непосредственно во время работы программы. Т.о достигается высокая скорость выполнения (сравнимая с компилируемыми языками) за счёт увеличения потребления памяти (для хранения результатов компиляции) и затрат времени на компиляцию. JIT базируется на двух более ранних идеях, касающихся среды исполнения: компиляции байт-кода и динамической компиляции.
В языках, компилирующихся в байт-код, (таких как Perl, Java и пр), исходный код транслируется в одно из промежуточных представлений, известное как байт-код. Байт-код не является машинным кодом какого-либо компьютера и может портироваться на различные компьютерные архитектуры. Байт-код интерпретируется (исполняется) виртуальной машиной.
Концепция ОС на базе JIT-VM будет рассмотрена на примере ОС Singularity.
Singularity – это ОС, разрабатываемая как основа для более надежного системного и прикладного ПО. Singularity написана на Sing#, который является расширением языка С#. Архитектура ОС построена на основе 3 ключевых абстракций: ядра, SIP и каналов. Микроядро содержит основную функциональность системы, включая управление памятью, создание и завершение процессов, работу каналов, планирование (scheduling) и ввод/вывод. Как и в случае других микроядер, большая часть функциональности системы находится в процессах вне ядра. Ядро Singularity практически полностью состоит из безопасного (safe) кода, а остальная часть системы (включая все драйверы устройств, системные процессы и приложения), исполняемая в SIP, состоит только из безопасного кода.
Ключевой аспект Singularity – модель расширения, построенная на программно-изолированных процессах (Software-Isolated Process, SIP), которые инкапсулируют части приложения или системы и обеспечивают сокрытие информации, изоляцию сбоев и строго типизированный интерфейс. SIP используются в самой ОС и прикладном ПО. Весь код за пределами ядра исполняется в SIP-ах.
SIP-ы имеют различные объектные (а не адресные) пространства, т.е. два процесса не могут одновременно получить доступ к одному объекту. Процесс не может динамически загружать или генерировать код. SIP-ы не используют для изоляции аппаратное управление памятью, т.е в физическом или виртуальном адресном пространстве может находиться несколько SIP. Связь между SIP осуществляется через двунаправленные, строго типизированные высокоуровневые каналы. Накладные расходы на создание SIP-ы и коммуникацию между SIP-ами низки. SIP-ы создаются и уничтожаются операционной системой, поэтому при их уничтожении ресурсы, занятые SIP-ами гарантированно освобождаются.
Singularity запрещает совместное использование данных ядром и расширением (расширение ядра – это, например, модуль ядра в линуксе – мое примечание), что уменьшает кол-во ошибок. Singularity использует единый для всей системы механизм расширений, от драйверов устройств до приложений, вместо специализированного механизма расширений ядра.
Объектные пространства не могут совместно использовать указатели. Это 1) улучшает абстракцию данных и изоляцию процесса, скрывая детали реализации и предотвращая появление висячих указателей (dangling pointers) на выгруженные процессы; 2) ослабляет ограничения при реализации, позволяя процессам использовать разные исполняющие системы и их сборщики мусора; 3) делает прозрачными учет и восстановление ресурсов, благодаря однозначно монопольному использованию памяти процессом; 4) упрощает интерфейс ядра, устраняя потребность управлять множеством типов указателей и адресных пространств.
Недостатки и ограничения архитектуры
Сложность коммуникаций посредством передачи сообщений по сравнению с гибкостью совместного использования данных.
MMU (memory management unit) можно обойти с помощью DMA. В обычной ОС драйверы работают в режиме ядра и им доверяют, а в Singularity это проблема. Правда в новейших архитектурах процессоров доступ железа к пямяти контролируется.
(от меня:) скорость должна быть меньше – иначе где-то подвох. то есть система, основанная на jit, как риалтаймовая система по любому не прокатит)
Главные достоинства Singularity:
Конструкция системы и модель приложений, именуемая SIP, использующая проверенный безопасный код для реализации строгих границ между процессами без аппаратных механизмов. Поскольку SIP дешевле в создании и управлении, система и приложения могут поддерживать более строгую модель изоляции.
Непротиворечивая модель расширений системы и приложений, упрощающая модель безопасности, улучшает надежность и упрощает восстановление при сбоях, повышает оптимизацию кода и увеличивает эффективность программирования и тестирования.
Быстрый и поддающийся проверке механизм коммуникаций между процессами системы, не нарушающий независимости и изоляции процессов, но обеспечивающий корректную и недорогую связь между процессами.
Поддержка языка и компилятора для создания всей системы из безопасного кода и для проверки межпроцессных коммуникаций с явным управлением ресурсами.
Устранение различий между ОС и подсистемой исполнения безопасного языка, такой, как JVM или CLR.
Повсеместное использование спецификаций для описания, конфигурирования и проверки компонентов.
19. Внешний интерфейс ядра (совокупность системных вызовов). Интерфейс стандартной библиотеки Си и его взаимосвязь с системными вызовами. Разделение задач между ядром и стандартной библиотеки (на примере futex).
Интерфейс между операционной системой и программами пользователя определяется набором системных вызовов, предоставляемых операционной системой.
Практически все системные вызовы запускаются из программ с помощью вызова библиотечной процедуры с тем же именем, что и системный вызов.
Системные вызовы выполняются за серию шагов. Библиотечная процедура обычно помещает номер системного вызова туда, где его ожидает операционная система, например в регистр. Затем она выполняет команду TRAP (эмулированное прерывание) для переключения из пользовательского режима в режим ядра и начинает выполнение с фиксированного адреса внутри ядра. Запускаемая программа ядра проверяет номер системного вызова и затем отправляет его нужному обработчику, как правило, используя таблицу указателей на обработчики системных вызовов, индексированную по номерам вызовов. В этом месте начинает функционировать обработчик системных вызовов. Как только он завершает свою работу, управление может возвращаться в пространство пользователя к библиотечной процедуре, к команде, следующей за командой TRAP. Эта процедура в свою очередь передает управление программе пользователя обычным способом, которым производится возврат из вызванной процедуры.
Более подробно на примере Linux 2.4 и архитектуры i386:
Во время начальной загрузки системы вызывается функция arch/i386/kernel/traps.c:trap_init(), которая настраивает IDT (Interrupt Descriptor Table) так, чтобы вектор 0x80 указывал на точку входа system_call из arch/i386/kernel/entry.S.
Когда пользовательское приложение делает системный вызов, аргументы помещаются в регистры и приложение выполняет инструкцию int 0x80. В результате приложение переводится в привилегированный режим ядра и выполняется переход по адресу system_call в entry.S. Далее:
Сохраняются регистры.
В регистры ds и es заносится KERNEL_DS, так что теперь они ссылаются на адресное пространство ядра.
Если значение eax больше чем NR_syscalls, то возвращается код ошибки ENOSYS.
Если задача исполняется под трассировщиком (tsk->ptrace & PF_TRACESYS), то выполняется специальная обработка. Сделано это для поддержки программ типа strace и отладчиков.
Вызывается sys_call_table+4*(syscall_number из eax). Эта таблица инициализируется в том же файле (arch/i386/kernel/entry.S) и содержит указатели на отдельные обработчики системных вызовов, имена которых, в Linux, начинаются с префикса sys_, например sys_open, sys_exit, и т.п. Эти функции снимают со стека свои входные параметры, которые помещаются туда макросом SAVE_ALL.
Вход в 'system call return path'. Проверяется необходимость вызова планировщика (tsk->need_resched != 0) и имеются ли ожидающие сигналы.
Linux поддерживает до 6-ти входных аргументов в системных вызовах. Они передаются через регистры ebx, ecx, edx, esi, edi (и ebp для временного хранения). Номер системного вызова передается в регистре eax.
Интерфейс стандартной библиотеки языка C
Реальные машинные команды, которые требуются для активизации системных вызовов, естественно, отличаются от машины к машине, наряду со способом передачи параметров и результатов между вызывающей программой и ядром. Однако с точки зрения программиста на языке С использование системных вызовов ничем внешне не отличается от использования других функций стандартной ANSI библиотеки языка С. Стандартная библиотека обеспечивает C интерфейс к каждому системному вызову. Это приводит к тому, что системный вызов выглядит как функция на языке С для программиста. Это позволяет приложениям быть в некоторой степени переносимыми, т.е. необходимо скомпилировать код приложения на какой-нибудь системе и привязать к нему функции стандартной библиотеки, написанные и скомпилированные для этой системы.
Большинство системных вызовов, возвращающих целое значение, использует значение -1 при возникновении ошибки и значение большее или равное 0 при нормальном завершении. Системные вызовы, возвращающие указатели, обычно для идентификации ошибочной ситуации пользуются значением NULL. Для точного определения причины ошибки C-интерфейс предоставляет глобальную переменную errno, описанную в файле <errno.h> вместе с ее возможными значениями и их краткими определениями. Для получения символьной информации об ошибке на стандартном выводе программы для ошибок может применяться стандартная функция perror().
Разделение задач между ядром и стандартной библиотеки (на примере futex)
Ядро Linux обеспечивает работу с фьютексами (futex, 'Fast Userspace muTexes') как со строительным материалом для связей и семафоров пространства пользователя. Фьютекс идентифицируется блоком памяти, который может разделяться между разными процессами.
Любые операции фьютексов начинаются в пространстве пользователя, но также может быть нужно связываться с ядром, используя системный вызов.
Все операции с фьютексами практически полностью проводятся в пользовательском пространстве, соответствующие функции ядра задействуются лишь в ограниченном наборе случаев. Это позволяет повысить эффективность использования синхронизирующих примитивов, поскольку большинство операций не используют арбитраж, а значит и избежать использования относительно дорогостоящих системных вызовов.
Системный вызов sys_futex обеспечивает программный метод для ожидания изменения значения указанного адреса памяти и метод пробуждения всех ожидающих на определенном адресе. Когда операции futex заканчиваются без завершения спора в пространстве пользователя, должен быть сделан вызов к ядру для выноса решения. Вынос решения может означать как усыпление вызывающего процесса, так и наоборот – пробуждение ожидающего процесса.