Difference between revisions of "Embedded-Linux-Device-Driver/C3/Kernel-Memory-Allocation/English"

From Script | Spoken-Tutorial
Jump to: navigation, search
 
Line 68: Line 68:
 
Here, I have created a directory named '''MemoryAllocation.'''
 
Here, I have created a directory named '''MemoryAllocation.'''
  
In this directory, I have saved '''simple_driver dot c driver file, user dot c''' and '''Makefile.'''
+
In this directory, I have saved '''simple_driver dot c file, user dot c''' and '''Makefile.'''
  
 
I’ll use these files for demonstration.
 
I’ll use these files for demonstration.

Latest revision as of 10:30, 30 October 2020

Visual cue : Narration :
Slide 1:

Welcome slide:

Welcome to the spoken tutorial on Kernel Memory Allocation.
Slide 2:

Learning objectives:

In this tutorial, we will learn how to
  • Dynamically allocate the kernel memory using kmalloc() function and
  • kfree() function to free the memory allocated by kmalloc().
Slide 3:

System Requirements:

To record this tutorial, I am using,
  • VirtualBox 5.2.
  • Ubuntu Linux 18.04 LTS operating system.
  • Linux kernel version 5.0.0-31 generic.
  • gedit text editor.
Slide 4:

Prerequisites:

To follow this tutorial, you should be familiar with:
  • C programming language
  • Basics of Linux kernel

If not, then go through the C/C++ and Linux spoken tutorials on this website.

Slide 5:

Kernel Memory Allocation.

  • Linux handles memory allocation by creating a set of memory objects of fixed sizes
  • It will dynamically allocate portions of memory to programs at their request
  • When the memory is no longer needed,we have to free it for reuse
Let us see the commonly used kernels functions to allocate its memory.
Slide 6:

Kernel Memory Allocation functions.

  • kmalloc() and vmalloc() functions dynamically allocates the kernel memory.
  • kmalloc() is similar to the malloc function in c programs.
  • kmalloc() allocates contiguous physical memory and virtual memory.
  • vmalloc() allocates contiguous virtual memory but not the physical memory.
Point to the folder and file in Desktop

Point to the files.

Go to the DeviceDriver folder in the Desktop which we have created earlier.

Here, I have created a directory named MemoryAllocation.

In this directory, I have saved simple_driver dot c file, user dot c and Makefile.

I’ll use these files for demonstration.

Slide 7:

Code files:

  • The files used in this tutorial are available in the Code Files link on this tutorial page.
  • Please download and extract them
  • Make a copy and then use them while practising
Open the terminal

Type >> cd Desktop/DeviceDriver/ MemoryAllocation

Open the terminal by pressing ALT+Ctrl+T keys simultaneously.

Go to the directory where MemoryAllocation is saved on your system.

Press Enter key after every command.

Type >> gedit simple_driver.c Type gedit space simple driver dot c.

I have used the same file simple_driver dot c which we used earlier.

In this file, I have used the kmalloc() function to allocate the memory.

Let me explain the code.

Highlight <linux/slab.h>

static char *ptr

Here, we have to include the slab dot h kernel header file.

The kmalloc() function is declared in the slab dot h header file.

To use the string functions in the driver, include the string dot h header file.

Here, the ptr character pointer is defined with NULL value.

We will use it to store the address returned by the kmalloc() function.

Highlight init_function()

Highlight void *kmalloc(size_t size, int flags);

Highlight size

In the initialisation function, we have used the kmalloc() function.

Use the dynamic allocation way when you don’t know how much memory will be needed.

Now let us see the prototype of the kmalloc() function.

size specifies the size of memory to be allocated.

Highlight flag

Highlight GFP_ATOMIC.

Highlight void*

flag denotes the behavior of kmalloc call.

The two most widely used flags are GFP_KERNEL and GFP_ATOMIC.

It returns the virtual address of the first page allocated.

If there is any error, it returns NULL.

Highlight kmalloc()

Highlight GFP_ATOMIC

Here, kmalloc() dynamically allocates 8 bytes of the kernel memory.

We will use this allocated kernel memory space as a buffer.

It is also referred to as a virtual device.

GFP_ATOMIC flag will not put the current process in sleep state if memory is low.

This flag is mostly used in the interrupt handler to allocate memory.

Highlight char *

Highlight ptr

The kmalloc() returns an address which can be used to store any type of data.

Here, you can typecast it to store the data of respective data type.

I have typecast it as a character pointer to store a string in it.

The ptr contains the start address of the allocated kernel memory.

Highlight printk messages Depending upon its success or failure, the corresponding messages will be printed.
Highlight open()

Highlight strcpy() and printk

open function will execute when a user program opens the device.

We will use a strcpy function to copy the data to the buffer.

Here, the strcpy() function will copy a string IITB to the buffer.

This message will be printed in the kernel log level.

Let us see the kernel function to release the dynamically allocated memory.
Highlight exit_function.

Highlight ptr

Highlight void kfree(const void *ptr)

As we allocated the kernel memory dynamically, it's our responsibility to release it.

We have to use the kfree() function in the exit function as shown here.

The kfree function is used to free the memory allocated by kmalloc().

ptr specifies the address returned by kmalloc().

It is mostly used in the cleanup function and avoids the leakage of memory.

Highlight kfree(ptr) Here, the kfree() function will release the memory whose address is stored in the pointer.

It will avoid the wastage of the kernel memory as its memory or stack is limited.

Highlight ptr

Highlight NULL

Now, ptr is a dangling pointer as it points to freed memory.

If you try to access it again, the program could crash and may lead to memory fault.

To avoid such problems, assign the NULL value to it, which is a valid address.

Save and close the file. Save and close the file.
Type >> gedit Makefile To compile the program, we have to create a Makefile.

Type gedit space Makefile.

Type the code as shown or you can use the downloaded Makefile.

Switchback to the terminal Save and close the file.

Now let us see a simple user program which will open and close a device.

Type >> gedit user.c

Highlight open() and close().

Save and close the file

Type >> clear

Type gedit space user dot c.

I have used the same user program user dot c which we used earlier.

This program opens and closes the new_device using respective system calls.

When the user program tries to open a device, the specified data will copy to the buffer.

Save and close the file.

Type >> sudo su

Type >> system password.

Type >> make all

Type >> clear

Type >> insmod simple_driver.ko

Type >> clear

Let us compile the driver.

Type sudo space su to be a superuser.

And then type the system password.

Type make space all.

Clear the screen.

Now load the driver into the kernel.

Type insmod space simple_driver dot ko.

Clear the screen.

Type >> dmesg | grep simple_driver

Highlight the output Highlight printk messages.

Type >> clear

Let’s see the loaded printk messages.

Type dmesg space pipe space grep space simple_driver.

Here, this message shows that the kmalloc() function executed successfully.

Clear the screen.

Now let us compile the user program to open the device.
Type >> gcc -c user.c

Type >> gcc -o user user.o

Type >> ./user

Highlight output.

Type >> clear

Type gcc space hyphen c space user dot c

Type gcc space hyphen o space user space user dot o

To execute the program type dot slash user.

The output shows that the device file opened and closed successfully.

Clear the screen.

Type >> dmesg | grep simple_driver

Highlight the output

Highlight printk message.

Type >> clear

Let’s see the printk messages from the open function of a driver.

Type dmesg space pipe space grep space simple_driver.

This message shows the IITB string is stored in the allocated kernels memory.

Clear the screen.

Type rmmod simple_driver

.ko

Type dmesg | grep simple_driver

Highlight the message

Type >> clear

Now let's unload the driver.

Type rmmod space simple_driver

dot ko

To see the unloaded printk messages type this dmesg command.

This message indicates that the kfree() function releases the memory.

Clear the screen.

With this, we come to the end of this tutorial. Let us summarise.
Slide :

Summary:

In this tutorial, we learnt how to
  • Dynamically allocate the kernel memory using kmalloc() function and
  • kfree() function to free the memory allocated by kmalloc().
Slide :

Assignment :

As an assignment:
  1. Open the simple_driver.c file
  2. Allocate the memory space using kmalloc in the driver as per your choice
  3. Store a different data to the kernel buffer
  4. Load the driver and then execute the user program
  5. See the output using dmesg command and then unload the driver.
Slide :

About Spoken Tutorial Project:

  • The video at the following link summarizes the Spoken Tutorial project.
  • Please download and watch it.
Slide :

Spoken Tutorial workshops :

The Spoken Tutorial Project Team conducts workshops and gives certificates.

For more details, please write to us.

Slide :

Forum questions :

Please post your timed queries in this forum
Slide :

Forum for specific questions :

  • Do you have any general or technical questions on Embedded Linux Device Driver?
  • Please visit the FOSSEE forum and post your question.
Slide :

Acknowledgment:

The Spoken Tutorial Project is funded by MHRD, Government of India.
Slide :

Thank you slide:

This tutorial has been contributed by FOSSEE and Spoken Tutorial Project, IIT Bombay.

This is Usha signing off. Thanks for watching.

Contributors and Content Editors

Nancyvarkey, Nirmala Venkat