forked from mizabrik/acos-notes
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathkernel.tex
More file actions
128 lines (122 loc) · 11.8 KB
/
kernel.tex
File metadata and controls
128 lines (122 loc) · 11.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
\documentclass[main]{subfiles}
\begin{document}
Ядро --- это тот код, который загружается загрузчиков в начале работы ПК
и работает в привилегированном режиме. Оно настраивает все структуры, и с
этой точки зрения есть несколько взглядов, как его организовывать.
\begin{description}
\item[Монолитное ядро] весь код компилируется сразу и ядро обрабатыевает
все случаи, в чистом виде не встречается. Основное преимущество ---
быстродействие, так как происходит меньше переключений контекстов
(что дорого, ведь нам нужно сохранить значения всех регистров в оперативную
память для одного процесса, заргузить для другого и т. д.)
и ко всем ресурсам ядра можно получить доступ быстро и просто.
С другой стороны, ошибка в одном логическом компоненте приводит к нарушении
работы всего ядра. Более того, возможно, оно даже не сможет уведомить об этом
пользователя (не удастся даже вывести kernel panic / BSOD с отладочной
информацией). Это, в свою очередь, повышает требования к качеству кода.
\item[Расширяемое ядро] Весь код работает в привилегированном режиме, но
отдельные компоненты (обычно, модули) можно загружать и выгружать по мере
необходимости. В UNIX-подобных системах есть несколько утилит для работы с
модулями:
\begin{description}
\item[insmod] Установка модуля. На вход принимает объектный файл с расширением
.ko. он
компонуется дополнительно, добавляется мета-информация (например, имя модуля)
\item[modprobe] Ищет файл указанного модуля (обычно, в каталоге
/lib/modules/VERSION) и загружает (или выгружает) его в соответствии с modules.map. В этом
файле указывается, где находятся модули и какие у них есть зависимости
(например, модуль работы с жёстким диском требует модуля работы с SATA).
В современных дистрибутивах монолитными остались только обработчики прерываний,
некоторые драйвера для работы с шинами (PCIe, но не *ATA, например).
Поверх монолитной части наслаиваются модули менее обязательные, на них ещё
и т. д. В итоге, modprobe обычно загружает очень много зависимостей.
\item[lsmod] Отображает загруженные модули.
\item[rmmod] Выгружает модуль.
\end{description}
\item[Микроядро] Само ядро ужимается до минимального размера, а весь код,
который можно вынести из ядра, выносится из ядра в отдельный процесс. Обычно
в ядре остаётся механизм запуска/остановки процессов, механизм передачи
сообщений между процессами (IPC) и интерфейсы для работы с железом.
Микроядра гораздо безопаснее, т. к. критичным остаётся очень мало кода, и
отдельные компоненты проще разрабатывать без оглядки на остальные.
С другой стороны, такой подход влечёт частые переключение контекстов и
большие нагрузки на систему IPC.
Пример микроядра --- GNU HURD.
\end{description}
\section{Модули Linux}
Обязательными компонентами модуля являются две функции: функция инициализации
module\_init(...), которая вызывается при загрузке модуля в ядро (и может
завершиться неудачей) и module\_destroy --- функция, вызываемая при завершении
работы модуля и освобождающая его ресурсы (обязана завершиться).
Всё остальное --- необязательно и зависит от предназначения модуля.
\section{Файловая система в UNIX}
Файловая система, в простом варианте, представляет собой дерево, вершины
которого --- файлы и каталоги (файлы бывают только листьями).
Отсюда --- названия каталога / корнем, т. к. он не имеет родителей.
С помощью chroot для процесса можно подменить корень файловой системы
на другой каталог.
\section{Процессы}
Процессы --- это механизм разграничения ресурсов.
У каждого процесса есть свой контекст, который состоит из следующих составляющих:
\begin{description}
\item[Аппаратная] Состояние регистров, таблица страниц, таблица сегментов (LDT)
т. е. всё, что непосредственно необходимо аппаратуре для его исполнения.
\item[Пользовательская] Сами данные процесса --- его код, данные в памяти
и т. д.
\item[Системная] Информация о процессе, храняшяяся в ОС (не обязательна для
непосредственного испольнения кода). В UNIX-подобных системах это:
\begin{description}
\item идентификатор процесса (pid), идентификатор родительского процесса (ppid),
владелец и группа процесса (uid и gid), пользователь и группа, чьими
правами обладает процесс(euid и egid), таблица файловых дескрипторов
(список открытых файлов), корень ФС (используется для chroot),
терминал процесса (некоторое абстрактное устройство, на которое можно выводить
текст и считывать некоторый ввод в последовательном режиме; раньше их представляли
принтерами, позднее ими стали мониторы с клавиатурами, также могут быть удалёнными;
может отстутсвовать, тогда он называется демоном) группа процесса (pgid),
идентифиф
\item[sid] Идентфикатор сессии, сессия завершается целиком.
\item[cgroup] Разделяет процессы на группы, каждая из которых обладает своим
набором прав (специфично для Linux).
\item[nice] Приоритет, которым обладает процесс в глазах планировщика процессов.
Задаётся целым числом, чем ниже его значение, тем чаще будет выполняться процесс. Может быть
изменён утилитой renice. Приоритет делится на динамическую часть (меньше у детей,
увеличивается из-за долгого простоя и т. д.) и статическую часть:
ядерную (назначается рядром; например, даёт больший приоритет ядерным процессам)
и пользовательскую (назначается пользователем, позволяет указать приоритеты, но в
границах, установленных пользователем).
\item[Ограничения] Различные лимиты: максимально число откытых файлов,
ограничение исплользуемой оперативной памяти и т. д. Могут быть отображены
с помощью утилиты ulimit. Отменить их нельзя. Делятся на жёсткие (неизмениямые)
и мягкие (можно менять, но в рамках жёсткого).
\item[Сигнальная маса]
\item[Очередь сигналов]
\item[Список IPC объектов]
\item[Состояние]
\item[Exit status] То, как завершился процесс. В том числе, код возврата.
\end{description}
\end{description}
\subsection{Квант времени}
Квант времени --- время, которое выполняется процесс без переключения контекста.
Большие кванты времени уменьшают частоту переключений контекстов, что даёт
повышение быстродействия. С другой стороны, это может вызвать задержки между,
например, вводом пользователя и его передаче заинтересованному процессу.
\subsection{Состояния процесса}
Из-за псевдо-многозадачности, каждый процесс может выполняться или ожидать
выполнения в каждый момент времени, это и называется его состоянием.
На самом деле, их немного больше и это зависит от ОС. Например, в Linux
существуют следующие состояния процессов:
\begin{description}
\item[Выполнение] Процесс, собственно, исполняется: его код выполняется
процессором.
\item[Готов к выполнению] Процесс приостановлен планировщиком, но может
продолжить исполнение в любой момент.
\item[Блокирован IO] Процесс не может быть выполнен, т. к. он ожидает
завершения некоторой операции вовода-вывода.
\item[Приостановлен]
\item[Не выполняется, но не трогайте] Не может быть убит.
\item[Зомби] Процесс уже завершил свою работу, но родительский процессс
ещё не узнал его exit status. Будет удалён ОС после вызова
wait или waitpid родителем процесса.
\end{description}
\end{document}