Ядро ОС Linux

       

Выделение памяти.


Выделение памяти в ядре отличается от выделения памяти на пользовательском уровне. Вместо функции malloc() выделяющее почти неограниченное количество памяти, существует kmalloc(), которая имеет некоторые отличия:

  • Память выделяется кусками размером степени 2, за исключением кусков больше 128 байтов, размер коих равен степени 2 за вычетом части под метку о размере. Вы можете запросить произвольный размер, однако это будет неэффективно, так как 31 байтового об'екта, к примеру, выделяется 32 байтовый кусок. Общий предел выделяемой памяти 131056 байт.
  • В качестве второго аргумента kmalloc() использует приоритет. Он используется в качестве аргумента функции get_free_page(), где он используется в качестве числа определяющего момент возврата. Обычно используемый приоритет - GFP_KERNEL. Если функция может быть вызвана с помощью прерывания используйте GFP_ATOMIC и приготовьтесь к тому, что функция может не работать. Это происходит из-за того, что при использовании GFP_KERNEL kmalloc() может не быть активным в любой момент времени, что не возможно при прерывании. Можно так же использовать опцию GFP_BUFFER, которая используется для выделения ядром области буфера. В драйверах устройств она не используется.

Для очистки памяти, выделенной kmalloc(), используйте функции kfree() и kfree_s(). Они также несколько отличаются от функции free() :

  • kfree() - это макрос, вызывающий kfree_s() и работающая как free() вне ядра.
  • Если вы знаете размеры об'екта, удаляемого из памяти, вы можете ускорить процесс, запуская сразу kfree_s(). У него существуют два аргумента : первым является аргумент kfree(), вторым - размер удаляемого об'екта.
  • См 2.6 для получения более подробной информации о kmalloc(), kfree() и о других полезных функциях.

    Другой способ сохранить память - выделение ее во время инициализации. Ваша инициализационная функция foo_init() в качестве аргумента использует указатель на текущий конец памяти.Она может взять столько памяти, сколько хочет сохранить указатель/указатели на эту память и возвратить указатель на новый конец памяти.Преимуществом этого метода является то, что при выделении большого буфера в случае, если foo - драйвер не находит foo- устройства, подключенного к компьютеру, память не тратится. Функция инициализации подробно обсуждается в части 2.3.6. Будьте предельно аккуратны при использовании kmalloc(), используйте его только в случае крайней необходимости. Помните, что память в ядре не своппится. Аккуратно выделяйте ее, а затем каждый раз очищайте ее функцией frее().

    ! Существует возможность выделения виртуальной памяти с помощью vmalloc(), однако это будет описано лишь в главе VMM во время ее написания. В данный момент вам придется изучать это самостоятельно.!



    Содержание раздела