Чтение онлайн

на главную

Жанры

Разработка ядра Linux
Шрифт:

 unsigned long zone_start_pfn;

 char *name;

 unsigned long spanned_pages;

 unsigned long present_pages;

};

Эта структура большая, но в системе всего три зоны и соответственно три такие структуры. Рассмотрим наиболее важные поля данной структуры.

Поле

lock
— это спин-блокировка, которая защищает структуру от параллельного доступа. Обратите внимание, что она защищает только структуру, а не страницы, которые принадлежат зоне. Для защиты отдельных страниц нет блокировок, хотя отдельные части кода могут блокировать данные, которые
могут оказаться в указанных страницах.

Поле

free_pages
— это количество свободных страниц в соответствующей зоне. Ядро старается поддерживать свободными хотя бы
pages_min
страниц зоны, если это возможно (например, с помощью вытеснения на диск).

Поле

name
 — это строка, оканчивающаяся нулем, которая содержит имя соответствующей зоны (что не удивительно). Ядро инициализирует указанное поле при загрузке системы с помощью кода, который описан n файле
mm/page_alloc.с.
Три зоны имеют имена "DMA", "Normal" и "HighMem".

Получение страниц памяти

Теперь, имея некоторое понятие о том, как ядро управляет памятью с помощью страниц, зон и так далее, давайте рассмотрим интерфейсы, которые реализованы в ядре для того, чтобы выделять и освобождать память внутри ядра. Ядро предоставляет один низкоуровневый интерфейс для выделения памяти и несколько интерфейсов для доступа к ней. Все эти интерфейсы выделяют память в объеме, кратном размеру страницы, и определены в файле

<linux/gfp.h>
. Основная функция выделения памяти следующая.

struct page * alloc_pages(unsigned int gfp_mask, unsigned int order);

Данная функция позволяет выделить 2

order
(т.е.
1 << order
) смежных страниц (один непрерывный участок) физической памяти и возвращает указатель на структуру
page
, которая соответствует первой выделенной странице памяти. В случае ошибки возвращается значение
NULL
. Параметр
gfp_mask
будет рассмотрен несколько позже. Полученную страницу памяти можно конвертировать в ее логический адрес с помощью следующей функции.

void *page_address(struct page *page);

Эта функция возвращает указатель на логический адрес, которому в данный момент соответствует начало указанной страницы физической памяти. Если нет необходимости в соответствующей структуре

struct page
, то можно использовать следующую функцию.

unsigned long __get_free_pages(unsigned int gfp_mask,

 unsigned int order);

Эта функция работает так же, как и функция

alloc_pages
, за исключением того, что она сразу возвращает логический адрес первой выделенной страницы памяти. Так как выделяются смежные страницы памяти, то другие страницы просто следуют за первой.

Если необходима всего одна страница памяти, то для этой цели определены следующие функции-оболочки, которые позволяют уменьшить количество работы по набору кода программы.

struct page * alloc_page(unsigned int gfp_mask);

unsigned long __get_free_page(unsigned int gfp_mask);

Эти функции работают так же, как и ранее описанные, по для них в качестве параметра

order
передается нуль (20 = одна страница памяти).

Получение страниц заполненных нулями

Для того чтобы получаемые страницы памяти были заполнены нулями, необходимо использовать следующую функцию.

unsigned long get_zeroed_page(unsigned int gfp_mask);

Эта

функция аналогична функции
__get_free_page
, за исключением того, что после выделения страницы памяти она заполняется нулями. Это полезно для страниц памяти, которые возвращаются в пространство пользователя, так как случайный "мусор", который находится в страницах памяти, может оказаться не совсем случайным и случайно может содержать некоторые (например, секретные) данные. Все данные необходимо обнулить или очистить каким-либо другим образом перед тем, как возвращать информацию в пространство пользователя, чтобы при этом не пострадала безопасность системы. В табл. 11.2 приведен список всех низкоуровневых средств выделения памяти.

Таблица 11.2. Низкоуровневые средства выделения памяти

Функция Описание
alloc_page(gfp_mask)
Выделяет одну страницу памяти и возвращает указатель на соответствующую ей структуру
page
alloc_pages(gfp_mask, order)
Выделяет 2
order
страниц памяти и возвращает указатель на структуру
page
первой страницы
__get_free_page(gfp_mask)
Выделяет одну страницу памяти и возвращает указатель на ее логический адрес
__get_free_pages(gfp_mask, order)
Выделяет 2
order
страниц памяти и возвращает указатель на логический адрес первой страницы
get_zeroed_page(gfp_mask)
Выделяет одну страницу памяти, обнуляет ее содержимое и возвращает указатель на ее логический адрес

Освобождение страниц

Для освобождения страниц, которые больше не нужны, можно использовать следующие функции.

void __free_pages(struct page *page, unsigned int order);

void free_pages(unsigned long addr, unsigned int order);

void free_page(unsigned long addr);

Необходимо быть внимательными и освобождать только те страницы памяти, которые вам выделены. Передача неправильного значения параметра

page
,
addr
или
order
может привести к порче данных. Следует помнить, что ядро доверяет себе. В отличие от пространства пользователя, ядро с удовольствием зависнет, если вы попросите. Рассмотрим пример. Мы хотим выделить 8 страниц памяти.

page = __get_free_pages(GFP_KERNEL, 3);

if (!page) {

 /* недостаточно памяти: эту ошибку необходимо обработать самим! */

 return -ENOMEM;

}

/* переменная 'page' теперь содержит адрес

первой из восьми страниц памяти */

free_pages(page, 3);

/*

* наши страницы памяти теперь освобождены и нам больше нельзя

Поделиться:
Популярные книги

Генерал Империи

Ланцов Михаил Алексеевич
4. Безумный Макс
Фантастика:
альтернативная история
5.62
рейтинг книги
Генерал Империи

Отмороженный 9.0

Гарцевич Евгений Александрович
9. Отмороженный
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Отмороженный 9.0

Под знаменем пророчества

Зыков Виталий Валерьевич
3. Дорога домой
Фантастика:
фэнтези
боевая фантастика
9.51
рейтинг книги
Под знаменем пророчества

Возвышение Меркурия. Книга 16

Кронос Александр
16. Меркурий
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 16

Дядя самых честных правил 8

Горбов Александр Михайлович
8. Дядя самых честных правил
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Дядя самых честных правил 8

Para bellum

Ланцов Михаил Алексеевич
4. Фрунзе
Фантастика:
попаданцы
альтернативная история
6.60
рейтинг книги
Para bellum

Идеальный мир для Лекаря 5

Сапфир Олег
5. Лекарь
Фантастика:
фэнтези
юмористическая фантастика
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 5

Покоритель Звездных врат

Карелин Сергей Витальевич
1. Повелитель звездных врат
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Покоритель Звездных врат

Отборная бабушка

Мягкова Нинель
Фантастика:
фэнтези
юмористическая фантастика
7.74
рейтинг книги
Отборная бабушка

Жестокая свадьба

Тоцка Тала
Любовные романы:
современные любовные романы
4.87
рейтинг книги
Жестокая свадьба

Смертник из рода Валевских. Книга 1

Маханенко Василий Михайлович
1. Смертник из рода Валевских
Фантастика:
фэнтези
рпг
аниме
5.40
рейтинг книги
Смертник из рода Валевских. Книга 1

Сердце Дракона. Том 11

Клеванский Кирилл Сергеевич
11. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
6.50
рейтинг книги
Сердце Дракона. Том 11

Тройняшки не по плану. Идеальный генофонд

Лесневская Вероника
Роковые подмены
Любовные романы:
современные любовные романы
6.80
рейтинг книги
Тройняшки не по плану. Идеальный генофонд

Возвращение Низвергнутого

Михайлов Дем Алексеевич
5. Изгой
Фантастика:
фэнтези
9.40
рейтинг книги
Возвращение Низвергнутого