unsigned long wait_table_size;
unsigned long wait_table_bits;
struct per_cpu_pageset pageset[NR_CPUS];
struct pglist_data *zone_pgdat;
struct page *zone_mem_map;
unsigned long zone_start_pfn;
char *name;
unsigned long spanned_pages;
unsigned long present_pages;
};
Эта структура большая, но в системе всего три зоны и соответственно три такие структуры. Рассмотрим наиболее важные поля данной структуры.
Поле lock
Поле free_pages
pages_min страниц зоны, если это возможно (например, с помощью вытеснения на диск).Поле name
mm/page_alloc.с. Три зоны имеют имена "DMA", "Normal" и "HighMem".Получение страниц памяти
Теперь, имея некоторое понятие о том, как ядро управляет памятью с помощью страниц, зон и так далее, давайте рассмотрим интерфейсы, которые реализованы в ядре для того, чтобы выделять и освобождать память внутри ядра. Ядро предоставляет один низкоуровневый интерфейс для выделения памяти и несколько интерфейсов для доступа к ней. Все эти интерфейсы выделяют память в объеме, кратном размеру страницы, и определены в файле
struct page * alloc_pages(unsigned int gfp_mask, unsigned int order);
Данная функция позволяет выделить 2order
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
Получение страниц заполненных нулями
Для того чтобы получаемые страницы памяти были заполнены нулями, необходимо использовать следующую функцию.
unsigned long get_zeroed_page(unsigned int gfp_mask);
Эта функция аналогична функции __get_free_page()
Таблица 11.2
. Низкоуровневые средства выделения памяти