Операционные системы - статьи


Как Linux работает с памятью.


Первая публикация данной статьи произошла на

Stanislav Ievlev,

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

Возникла мысль обратиться к прошлому, чтобы, по крайней мере, разобраться, как все это развивалось (с версии 0.1). Затея удалась... это помогло понять и современное ядро. В дальнейшем речь пойдет о ядрах серии 2.2, об изменениях в 2.4 будет сообщено особо.

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

Итак, в основе всего лежат страницы памяти. В ядре они описываются структурой mem_map_t.

typedef struct page { /* these must be first (free area handling) */ struct page *next; struct page *prev; struct inode *inode; unsigned long offset; struct page *next_hash; atomic_t count; unsigned long flags; /* atomic flags, some possibly updated asynchronously */ struct wait_queue *wait; struct page **pprev_hash; struct buffer_head * buffers; } mem_map_t;

Уже тут наблюдается определенная навороченность. Множество всяких ссылок. Вы не поверите, но все они используются. Одна страница может находиться в разных списках, например и в списке страниц в страничном кеше и в списке страниц относящихся к отображенному в память файлу (inode).В структуре, описывающей последний, можно найти и обратную ссылку, что очень удобно.

Все страницы адресуются глобальным указателем mem_map

mem_map_t * mem_map

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

static inline unsigned long page_address(struct page * page) { return PAGE_OFFSET + PAGE_SIZE * (page - mem_map); }




Начало  Назад  Вперед



Книжный магазин