You are on page 1of 1

Running, Outdoor & All Day - On.

Women's Shoes
On AG

 Menu 

Home → Tutorials → Linux → Device Drivers →

Linux Device Driver Tutorial Part 9 – Procfs in

Linux

Linux Device Driver


Tutorial Part 9 – Procfs
in Linux
by SLR Character Device Driver , Device Driver ,
Linux , Tutorials Device Drivers

Villa Sha Cancun - Luxury Ocean


Front Villa
www.villasha.com/Luxury Villa/Cancun

Last Updated on: October 5th, 2022

This article is a continuation of the Series on

Linux Device Driver and carries the discussion

on Linux device drivers and their implementation.

The aim of this series is to provide easy and

practical examples that anyone can understand.

This is the ProcFS in Linux kernel driver tutorial –

Linux Device Driver Tutorial Part 9.

You can also read sysfs,

procfs, Workqueue, Completion, Softirq,

and threaded IRQ in the Linux device driver.

Table of Contents
1. Introduction
2. Procfs in Linux
2.1. Introduction
3. Creating procfs directory
4. Creating Procfs Entry
5. Procfs File System
6. Open and Release Function
7. Write Function
8. Read Function
9. Remove Proc Entry
10. Procfs in Linux – Complete Driver Source
Code
11. MakeFile
12. Building and Testing Driver

Introduction

The operating system segregates virtual memory

into kernel space and userspace. Kernel space

is strictly reserved for running the kernel, kernel

extensions, and most device drivers. In contrast,

user space is the memory area where all user-

mode applications work, and this memory can be

swapped out when necessary.

There are many ways to Communicate between

the Userspace and Kernel Space, they are:

IOCTL

Procfs

Sysfs

Configfs

Debugfs

Sysctl

UDP Sockets

Netlink Sockets

In this tutorial, we will see Procfs in Linux.

Procfs in Linux

Introduction

Many or most Linux users have at least heard of

proc. Some of you may wonder why this folder is

so important.

On the root, there is a folder titled “proc”. This

folder is not really on /dev/sda1 or where ever

you think the folder resides. This folder is a

mount point for the procfs (Process Filesystem)

which is a filesystem in memory. Many

processes store information about themselves on

this virtual filesystem. ProcFS also stores other

system information.

It can act as a bridge connecting the user space

and the kernel space. Userspace programs can

use proc files to read the information exported by

the kernel. Every entry in the proc file system

provides some information from the kernel.

A better trading experience - Fast,


Easy withdrawals
oqtimalp.com/Forex/Trading

The entry “meminfo” gives the details of the

memory being used in the system.

To read the data in this entry just run

cat /proc/meminfo

Similarly the “modules” entry gives details of all

the modules that are currently a part of the

kernel.

cat /proc/modules

It gives similar information as lsmod. Like this

more, proc entries are there.

/proc/devices — registered character

and block major numbers

/proc/iomem — on-system physical RAM

and bus device addresses

/proc/ioports — on-system I/O port

addresses (especially for x86 systems)

/proc/interrupts — registered

interrupt request numbers

/proc/softirqs — registered soft IRQs

/proc/swaps — currently active swaps

/proc/kallsyms — running kernel

symbols, including from loaded modules

/proc/partitions — currently

connected block devices and their

partitions

/proc/filesystems — currently active

filesystem drivers

/proc/cpuinfo — information about the

CPU(s) on the system

Most proc files are read-only and only expose

kernel information to user space programs.

proc files can also be used to control and modify

kernel behavior on the fly. The proc files need to

be writable in this case.

For example, to enable IP forwarding of

iptable, one can use the command below,

echo 1 > /proc/sys/net/ipv4/ip_forward

The proc file system is also very useful when we

want to debug a kernel module. While debugging

we might want to know the values of various

variables in the module or maybe the data that

the module is handling. In such situations, we

can create a proc entry for ourselves and dump

whatever data we want to look into in the entry.

We will be using the same example character

driver that we created in the previous post to

create the proc entry.

The proc entry can also be used to pass data to

the kernel by writing into the kernel, so there can

be two kinds of proc entries.

1. An entry that only reads data from the

kernel space.

2. An entry that reads as well as writes data

into and from kernel space.


Creating procfs directory
Table of Contents

You can create the directory under /proc/* using

the below API.

struct proc_dir_entry

*proc_mkdir(const char *name, struct

proc_dir_entry *parent)

where,

name: The name of the directory that will be

created under /proc.

parent: In case the folder needs to be

created in a subfolder under /proc a pointer

to the same is passed else it can be left as

NULL.

Creating Procfs Entry

The creation of proc entries has undergone a

considerable change in kernel version 3.10 and

above. In this post, we will see one of the

methods we can use in Linux kernel version

3.10. Let us see how we can create proc entries

in version 3.10.

struct proc_dir_entry *proc_create (

const char *name, umode_t mode,

struct proc_dir_entry *parent, const

struct file_operations *proc_fops )

The function is defined in proc_fs.h.

Where,

<name>: The name of the proc entry

<mode>: The access mode for proc entry

<parent>: The name of the parent directory

under /proc. If NULL is passed as a parent, the

/proc directory will be set as a parent.

<proc_fops>: The structure in which the file

operations for the proc entry will be created.

Note: The above proc_create is

valid in the Linux Kernel v3.10 to

v5.5. From v5.6, there is a change

in this API. The fourth argument

const struct file_operations

*proc_fops is changed to const

struct proc_ops *proc_ops.

For example to create a proc entry by the name

“etx_proc” under /proc the above function will be

defined as below,

1. proc_create("etx_proc",0666,NULL,&proc

Your guide to investing - Make


your money work
wallstreetlogic.com

This proc entry should be created in the Driver

init function.

If you are using the kernel version below 3.10,

please use the below functions to create proc

entry.

create_proc_read_entry()

create_proc_entry()

Both of these functions are defined in the

file linux/proc_fs.h.

The create_proc_entry is a generic function that

allows creating both the read as well as the write

entries.

create_proc_read_entry is a function specific

to create only read entries.

It is possible that most of the proc entries are

created to read data from the kernel space that is

why the kernel developers have provided a direct

function to create a read proc entry.

Procfs File System

Now we need to create file_operations structure

proc_fops in which we can map the read and

write functions for the proc entry.

1. static struct file_operations proc_fop


2. .open = open_proc,
3. .read = read_proc,
4. .write = write_proc,
5. .release = release_proc
6. };

This is like a device driver file system. We need

to register our proc entry filesystem. If you are

using the kernel version below 3.10, this will not

work. If you are using the Linux kernel v5.6 and

above, you should not use this structure. You

have to use struct proc_ops instead of

struct file_operationslike below.

1. static struct proc_ops proc_fops =


2. .proc_open = open_proc,
3. .proc_read = read_proc,
4. .proc_write = write_proc,
5. .proc_release = release_proc
6. };

Next, we need to add all functions to the driver.

Make your money


work - Your guide to
investing - ダンヒルの
カフスで⼈気上昇
wallstreetlogic.c…

Open and Release Function

These functions are optional.

1. static int open_proc(struct inode *ino


2. {
3. printk(KERN_INFO "proc file opend.
4. return 0;
5. }
6.
7. static int release_proc(struct inode *
8. {
9. printk(KERN_INFO "proc file releas
10. return 0;
11. }

Write Function

The write function will receive data from the user

space using the function copy_from_user into

an array “etx_array”.

Thus the write function will look as below.

1. static ssize_t write_proc(struct file


2. {
3. printk(KERN_INFO "proc file write.
4. copy_from_user(etx_array,buff,len
5. return len;
6. }

Read Function

Once data is written to the proc entry we can

read from the proc entry using a read function,

i.e transfer data to the user space using the

function copy_to_user function.

The read function can be as below.

static ssize_t read_proc(struct file *filp,


Copy Extern
{
printk(KERN_INFO "proc file read.....\n"
if(len)
len=0;
else{
len=1;
return 0;
}
copy_to_user(buffer,etx_array,20);

return length;;
}

Remove Proc Entry

Trade on the go - Fast, Easy


withdrawals
oqtimalp.com/Forex/Trading

Proc entry should be removed in the Driver exit

function using the below function.

void remove_proc_entry(const char

*name, struct proc_dir_entry *parent);

Example:

1. remove_proc_entry("etx_proc",NULL);

And you can remove the complete parent

directory using proc_remove(struct

proc_dir_entry *parent).

Procfs in Linux – Complete


Driver Source Code

As there are changes in the procfs file system in

the Linux kernel 3.10 and 5.6, we have added a

macro called LINUX_KERNEL_VERSION. You

have to mention your Linux kernel version.

Based on that, we will control the APIs in this

source code.

Note:

You can follow this format for this

LINUX_KERNEL_VERSION.

Example:

Your Linux
LINUX_KERNEL_VERSION
Kernel version

v3.10 310

v5.6 506

v5.10 510

[Get the Source code from the GitHub]

1. /*************************************
2. * \file driver.c
3. *
4. * \details Simple Linux device dri
5. *
6. * \author EmbeTronicX
7. *
8. * \Tested with Linux raspberrypi 5.10
9. *
10. * ************************************
11. #include <linux/kernel.h>
12. #include <linux/init.h>
13. #include <linux/module.h>
14. #include <linux/kdev_t.h>
15. #include <linux/fs.h>
16. #include <linux/cdev.h>
17. #include <linux/device.h>
18. #include<linux/slab.h>
19. #include<linux/uaccess.h>
20. #include <linux/ioctl.h>
21. #include<linux/proc_fs.h>
22. #include <linux/err.h>
23.
24. /*
25. ** I am using the kernel 5.10.27-v7l.
26. ** If you are using the kernel 3.10, t
27. ** and for kernel 5.1, set this as 501
28. ** changed in kernel above v5.5.
29. **
30. */
31. #define LINUX_KERNEL_VERSION 510
32.
33. #define WR_VALUE _IOW('a','a',int32_t*
34. #define RD_VALUE _IOR('a','b',int32_t*
35.
36. int32_t value = 0;
37. char etx_array[20]="try_proc_array\n"
38. static int len = 1;
39.
40.
41. dev_t dev = 0;
42. static struct class *dev_class;
43. static struct cdev etx_cdev;
44. static struct proc_dir_entry *parent;
45.
46. /*
47. ** Function Prototypes
48. */
49. static int __init etx_driver_init
50. static void __exit etx_driver_exit
51.
52. /*************** Driver Functions ****
53. static int etx_open(struct inode
54. static int etx_release(struct ino
55. static ssize_t etx_read(struct file *
56. static ssize_t etx_write(struct file
57. static long etx_ioctl(struct file
58.
59. /***************** Procfs Functions **
60. static int open_proc(struct inode
61. static int release_proc(struct in
62. static ssize_t read_proc(struct file
63. static ssize_t write_proc(struct file
64.
65. /*
66. ** File operation sturcture
67. */
68. static struct file_operations fops =
69. {
70. .owner = THIS_MODULE,
71. .read = etx_read,

You might also like