2015-10-31 9 views
1

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

+0

Изучите пейджинг: http://stackoverflow.com/questions/18431261/how-does-x86-paging-work и посмотрите некоторые минимальные примеры: https://github.com/cirosantilli/x86-bare-metal-examples /blob/d1f11492c2d2828c9c713d75b6f173da955aafc3/paging.S –

ответ

2

Есть несколько аспектов, которые следует рассмотреть отдельно:

  • Управление доступной физической памяти.
  • Управление памятью, требуемой ядром и его структурами данных.
  • Управление виртуальной памятью (пространством) каждого процесса.
  • Управление памятью, требуемой любым процессом, то есть malloc и free.

Чтобы иметь возможность управлять любыми другими требованиями к памяти, вам необходимо знать, сколько физической памяти у вас имеется и какие ее части доступны для вашего использования. Предполагая, что ваше ядро ​​загружено совместимым с несколькими загрузчиками загрузчиками, вы найдете эту информацию в multiboot header, которую вы передаете (в на x86, если я правильно помню) из загрузчика. Заголовок содержит структуру, описывающую, какие области памяти используются и которые являются свободными в использовании.

Вам также нужно как-то сохранить эту информацию и отслеживать, какая память распределена и освобождена. Легкий способ сделать это - поддерживать растровое изображение, где бит N указывает, используется ли или используется область памяти (фиксированный размер S) от N * S до (N + 1) * S - 1. Конечно, вы, вероятно, захотите использовать более сложные методы, такие как многоуровневые растровые изображения или бесплатные списки по мере продвижения ядра, но вы можете начать с простого растрового изображения, как указано выше.

Этот менеджер памяти обычно предоставляет только «большие» размеры памяти, обычно кратные 4KB. Это, конечно, бесполезно для динамического распределения памяти в стиле malloc и free, с которыми вы привыкли программировать приложения.

Поскольку динамическое распределение памяти значительно облегчит реализацию расширенных функций вашего ядра (многозадачность, взаимодействие между процессами, ...), вы обычно пишете диспетчер памяти, особенно для ядра. Он предоставляет средства для выделения (kalloc) и освобождения (kfree) произвольных размеров. Это память из пула (ов), которые распределяются с помощью диспетчера физической памяти сверху.

Все перечисленное происходит внутри ядра. Вероятно, вы также захотите предоставить приложения для динамического распределения памяти. Реализация этого очень похожа на концепцию управления физической памятью, как сделано выше:

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

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

Возможность размещения и освобождения страниц (4KB в основном), как и раньше, не помогает в управлении динамической памятью, но, как и раньше, это обычно обрабатывается каким-либо другим менеджером памяти, который использует эти большие куски памяти в качестве пула для обеспечения меньшего размера куски приложения. Важным примером является Doug Lea's allocator. Такие менеджеры памяти обычно реализуются как библиотека (скорее всего, это часть стандартной библиотеки), связанная с каждым приложением.

+0

Спасибо, что помогли. –