Linux Kernel Development – Creating a Proc file and Interfacing With User Space

On The first post we built a Simple Kernel Module with init and exit functions and covered the basic concepts in kernel programming

Next, We added a Kernel Module Parameters to configure the kernel module data

In this post, We will create the first interface to user space application using procfs (/proc) file

Proc File System

Proc is a pseudo file system for interfacing with the kernel internal data structures. As a user, you can use proc files for system diagnostics  – CPU, memory, Interrupts and many more. You can also configure a lot of parameters like scheduler parameters, kernel objects, memory and more

The common interaction with proc is using cat and echo from the shell. For example:

Creating a new Proc file

To create a proc file system we need to implement a simple interface – file_operation.

We can implement more than 20 functions but the common operations are read, write. To register the interface use the function proc_create

The basic structure is:

If you build and insert the module, you will see a new file /proc/mydev , You can test the read and write operations using cat and echo (only see the kernel log messages)


Implementing The Read Handler

The read handler receives 4 parameters:

  • File Object – per process structure with the opened file details (permission , position, etc.)
  • User space buffer
  • Buffer size
  • Requested position (in and out parameter)

To implement the read callback we need to:

  • Check the requested position
  • Fill the user buffer with a data (max size <= Buffer size) from the requested position
  • Return the number of bytes we filled.

For example, the user run the following code:

On the first call to read we get the user buffer, size = 100, position = 0 , we need to fill the buffer with up to 100 bytes from position 0, update the position and return the number of bytes we wrote. If we filled the buffer with 100 bytes and returned 100 the next call to read we get the user buffer, size=50 and position=100

Suppose we have 2 module parameters and we want to return their values on proc read handler we write the following:

This is a simple implementation, We check if this is the first time we call read (pos=0) and the user buffer size is bigger than BUFSIZE , otherwise we return 0 (end of file)

Then, we build the returned buffer, copy it to the user , update the position and return the number we wrote

Build and insert the module, you can test it with cat command:

Exchanging Data With User-Space

In the kernel code, you can’t just use memcpy between an address supplied by user-space and the address of a buffer in kernel-space:

  • Correspond to completely different address spaces (thanks to virtual memory).
  • The user-space address may be swapped out to disk.
  • The user-space address may be invalid (user space process trying to access unauthorized data).

You must use dedicated functions in your read and write file operations code:


Implementing the Write Handler

The write handler is similar to the read handler. The only difference is that the user buffer type  is a const char pointer. We need to copy the data from the user buffer to the requested position and return the number of bytes copied

In this example we want to set both values using a simple command:

The first value is the irq number and the second is the mode.

The code for the write handler:

Again, we check if this is the first time we call write (position 0) , then we use copy_from_user to memcpy the data from the user address space to the kernel address space. We extract the values, check for errors , update the position and return the number of bytes we received

The complete module code:

Note : to implement more complex proc entries , use the seq_file wrapper

User Space Application

You can open the file and use read/write functions to test the module. Don’t forget to move the position bask to 0 after each operation:


You can find the full source code here



Tagged ,

8 thoughts on “Linux Kernel Development – Creating a Proc file and Interfacing With User Space

  1. Malonu skaityti!

  2. please add a tutorial for INTERRUPT handling in linux device drivers also

  3. thanks a lot

  4. Fantastic!

    I had to replace line 6, from:


    1. from:


  5. I implemented a pretty similar module like this one (as I am practicing on one of the code projects in OS System Concepts book).
    But I got a problem with proc_write() function when I echo into /proc file, like this:

    echo “1234” > /proc/pid
    bash: /proc/pid: cannot overwrite existing file

    I also check the kernel log but only proc_read() was logged
    Please help me out of this!!!!

  6. Thank you for the clear and simple example for demonstrating the usage of the proc file system. The example works if it is tested with the included user mode application.I tried the example with Ubuntu 20.

    I got no output testing the driver with the console command sequence “cat /proc/mydev”. After some debugging, the count parameter value is 131702 when reading with the “cat” command. 131702 is greater than the 100 defined for the BUFSIZE causing the read function to return -EFAULT. I changed the logic to make sure there is enough space to hold the output for reading in ‘buf’ and only copy from ‘buf’ to ‘ubuf’ for no more than the count size. Both reading with the application and “cat” command delivers the same result with the new logic.

  7. Nice post, Thanks!

Leave a Reply

Your email address will not be published.