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
The Holidays Begin Here
SSSP
PPO OON
NNSSSO
O
ORR
REEED
D
DBB
BYYY D
D
DIIISSSN
N
NEEEYYYLLLA
A
ANN
NDD
D
Learn More
RRREEESSSO
O
ORR
RTTT
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.
___
Click Here for More Information
See More
Ad By Sponsor
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.
The Holidays Begin Here
SSSP
PPO OON
NNSSSO
O
ORR
REEED
D
DBB
BYYY D
D
DIIISSSN
N
NEEEYYYLLLA
A
ANN
NDD
D
Learn More
RRREEESSSO
O
ORR
RTTT
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,&pr
A better trading
experience - Start
with $20 USD only
oqtimalp.com/F…
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_f
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.
The Holidays Begin Here
SSSP
PPO OON
NNSSSO
O
ORR
REEED
D
DBB
BYYY D
D
DIIISSSN
N
NEEEYYYLLLA
A
ANN
NDD
D
Learn More
RRREEESSSO
O
ORR
RTTT
Open and Release Function
These functions are optional.
1. static int open_proc(struct inode *i
2. {
3. printk(KERN_INFO "proc file open
4. return 0;
5. }
6.
7. static int release_proc(struct inode
8. {
9. printk(KERN_INFO "proc file rele
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 fil
2. {
3. printk(KERN_INFO "proc file writ
4. copy_from_user(etx_array,buff,le
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.
1. static ssize_t read_proc(struct file
2. {
3. printk(KERN_INFO "proc file read
4. if(len)
5. len=0;
6. else{
7. len=1;
8. return 0;
9. }
10. copy_to_user(buffer,etx_array,20
11.
12. return length;;
13. }
Remove Proc Entry
___
Click Here for More Information
See More
Ad By Sponsor
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 d
5. *
6. * \author EmbeTronicX
7. *
8. * \Tested with Linux raspberrypi 5.
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,
27. ** and for kernel 5.1, set this as 5
28. ** changed in kernel above v5.5.
29. **
30. */
31. #define LINUX_KERNEL_VERSION 510
32.
33. #define WR_VALUE _IOW('a','a',int32_
34. #define RD_VALUE _IOR('a','b',int32_
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_in
50. static void __exit etx_driver_ex
51.
52. /*************** Driver Functions **
53. static int etx_open(struct inod
54. static int etx_release(struct i
55. static ssize_t etx_read(struct file
56. static ssize_t etx_write(struct fil
57. static long etx_ioctl(struct fil
58.
59. /***************** Procfs Functions
60. static int open_proc(struct ino
61. static int release_proc(struct
62. static ssize_t read_proc(struct fil
63. static ssize_t write_proc(struct fi
64.
65. /* The 2024 Niro EV
Available government
66. ** File operation
incentives of $5,000. sturcture
67. */
68. static struct file_operations fops =
69. {
70. .owner = THIS_MODUL
71. .read = etx_read,
Build and Price