Иногда желательно ожидать наступления некоторого события schedule_timeout()
вместо функции schedule()
после того, как он поместил себя в очередь ожидания. Задание будет возвращено к выполнению, когда произойдет желаемое событие или пройдет указанный интервал времени. Код обязательно должен проверить,
Время вышло
В этой главе были рассмотрены понятия, связанные с представлением о времени в ядре и с тем, как при этом происходит управление абсолютным и относительным ходом времени. Были показаны отличия абсолютного и относительного времени, а также периодических и относительных событий. Далее были рассмотрены прерывания таймера, импульсы таймера, константа HZ
и переменная jiffies
.
После этого было рассказано о том, как реализованы таймеры ядра и как их можно использовать в собственном коде ядра. В конце главы были представлены другие методы, которые разработчики могут использовать для учета времени.
Большая часть кода ядра, который вам придется писать, требует понимания того, как время течет в ядре и как его отслеживать. С очень большой вероятностью, особенно при разработке драйверов, вам необходимо будет иметь дело с таймерами ядра. Материал этой главы принесет практическую пользу.
Глава 11
Управление памятью
Выделить память
В этой главе рассматриваются средства, которые предназначены для выделения памяти внутри ядра. Перед изучением интерфейсов, предназначенных для выделения памяти, необходимо рассмотреть, как ядро управляет памятью.
Страницы памяти
Ядро рассматривает страницы физической памяти как основные единицы управления памятью. Хотя наименьшая единица памяти, которую может адресовать процессор, — это машинное слово, модуль управления памятью (MMU, Memory Management Unit) — аппаратное устройство, которое управляет памятью и отвечает за трансляцию виртуальных адресов в физические — обычно работает со страницами. Поэтому модуль MMU управляет таблицами страниц на уровне страничной детализации (отсюда и название). С точки зрения виртуальной памяти, страница — это наименьшая значащая единица.
Как будет показано в главе 19, "Переносимость", каждая аппаратная платформа поддерживает свой характерный размер страницы. Многие аппаратные платформы поддерживают даже несколько разных размеров страниц. Большинство 32-разрядных платформ имеют размер страницы, равный 4 Кбайт, а большинство 64-разрядных платформ — 8 Кбайт. Это значит, что на машине, размер страницы которой равен 4 Кбайт, при объеме физической памяти, равном 1 Гбайт, эта физическая память разбивается на 262 144 страницы.
Ядро сопоставляет struct page
. Эта структура определена в файле
следующим образом.
struct page {
page_flags_t flags;
atomic_t _count;
atomic_t _mapcount;
unsigned long private;
struct address_space *mapping;
pgoff_t index;
struct list_head lru;
void *virtual;
};
Рассмотрим самые важные поля этой структуры. Поле flags
содержит состояние страницы. Это поле включает следующую информацию: является ли страница измененной (dirty) или заблокированной (locked) в памяти. Значение каждого флага представлено одним битом, поэтому всего может быть до 32 разных флагов. Значения флагов определены в файле
.