Next: Character vs. block devices
Up: Device Driver Basics
Previous: Namespace
Memory allocation in the kernel is a little different from memory
allocation in normal user-level programs. Instead of having a
malloc() capable of delivering almost unlimited amounts of memory,
there is a kmalloc() function that is a bit different:
- Memory is provided in pieces whose size is a power of 2, except
that pieces larger than 128 bytes are allocated in blocks whose size
is a power of 2 minus some small amount for overhead.
You can request any odd size, but memory will not be used any more
efficiently if you request a 31-byte piece than it will if you request
a 32 byte piece. Also, there is a limit to the amount of memory that
can be allocated, which is currently 131056 bytes.
- kmalloc() takes a second argument, the priority. This is
used as an argument to the get_free_page() function, where it
is used to determine when to return. The usual priority is
GFP_KERNEL. If it may be called from within an interrupt, use
GFP_ATOMIC and be truly prepared for it to fail (i.e. don't panic).
This is because if you specify GFP_KERNEL, kmalloc() may
sleep, which cannot be done on an interrupt. The other option is
GFP_BUFFER, which is used only when the kernel is allocating buffer
space, and never in device drivers.
To free memory allocated with kmalloc(), use one of two
functions: kfree() or kfree_s(). These differ from free()
in a few ways as well:
- kfree() is a macro which calls kfree_s() and acts
like the standard free() outside the kernel.
- If you know what size object you are freeing, you can speed
things up by calling kfree_s() directly. It takes two
arguments: the first is the pointer that you are freeing, as in the
single argument to kfree(), and the second is the size of the
object being freed.
See section for more information on
kmalloc(), kfree(), and other useful functions.
The other way to acquire memory is to allocate it at initialization time.
Your initialization function, foo_init(), takes one argument,
a pointer to the current end of memory. It can take as much memory as
it wants to, save a pointer or pointers to that memory, and return a
pointer to the new end of memory. The advantage of this over
statically allocating large buffers (char bar[20000]) is that if
the foo driver detects that the foo device is not attached to the
computer, the memory is not wasted. The init() function is
discussed in Section .
Be gentle when you use kmalloc. Use only what you have to. Remember
that kernel memory is unswappable, and thus allocating extra memory in
the kernel is a far worse thing to do in the kernel than in a
user-level program. Take only what you need, and free it when you are
done, unless you are going to use it right away again.
[I believe that it is possible to allocate swappable memory with
the vmalloc function, but that will be documented in the VMM section
when it gets written. In the meantime, enterprising hackers are
encouraged to look it up themselves.]
Next: Character vs. block devices
Up: Device Driver Basics
Previous: Namespace
Converted on:
Mon Apr 1 10:20:16 EST 1996