/proc is one of the most popular kernel to user-space interface which you can leverage to add an interface to your Kernel code such as Kernel modules, Kernel Device Drivers, etc. Personally I prefer /proc interface than other alternatives such as /sysfs, ioctl() and so on for my personal Kernel modules/stack.
So here is my detailed multi-episode YouTube video series on /proc Interface.
/* proc_example.c
* Author: Kiran Kankipati
* Updated: 22-feb-2017
*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/skbuff.h>
#include <linux/udp.h>
#include <linux/ip.h>
#include <linux/in.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/net.h>
#include <linux/netdevice.h>
#include <linux/socket.h>
#include <linux/sockios.h>
#include <linux/inet.h>
#include <linux/inetdevice.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/if_arp.h>
#include <linux/icmp.h>
#include <linux/proc_fs.h>
#include <linux/netlink.h>
#include <linux/mroute.h>
#include <net/checksum.h>
#include <net/inet_ecn.h>
#include <net/xfrm.h>
#include <net/route.h>
#include <net/sock.h>
#include <net/ip.h>
#include <net/tcp.h>
#include <net/arp.h>
#include <net/udp.h>
#include <net/icmp.h>
#include <net/inetpeer.h>
#include <net/protocol.h>
#include <net/flow.h>
#include <asm/types.h>
struct proc_dir_entry *tlc_proc_a;
static ssize_t tlc_proc_a_read(struct file *fp, char *buf, size_t len, loff_t * off)
{ static int finished=0; if(finished) {finished=0;return 0;} finished=1;
//int abc=100;
//strcpy(buf, "abc: %d\n", abc);
//sprintf(buf, "abc: %d\n", abc);
memset(buf,0xaa,10);
//return strlen(buf);
return 10;
}
static struct file_operations tlc_proc_a_fops = { .owner=THIS_MODULE, .read=tlc_proc_a_read, };
static int hello_init(void)
{
tlc_proc_a = proc_create( "tlc_proc_a", 0444, NULL, &tlc_proc_a_fops);
if(tlc_proc_a==NULL) { printk(KERN_ALERT "Error: Could not initialize %s\n", "tlc_proc_a"); }
return 0;
}
static void hello_exit(void)
{ remove_proc_entry("tlc_proc_a", NULL);
}
module_init(hello_init);
module_exit(hello_exit);
Its makefile:
obj-m += proc_example.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
IMPORTANT NOTE: None of these sample code published in the below episodes will no longer work in a modern recent kernel versions (i.e especially those which are released after 2019 or so). So here are my video episodes performing a live kernel module code porting of episode – 191 Linux Kernel /proc Interface – create and read /proc file. If you want to make the other episode sample demo code to work then you just follow and repeat these steps.
Download this episode my entire kernel module sample code, make file, clean script which I hosted in my GitHub Repo. And here is the source code for a quick reference.
/* proc_example.c
* Author: Kiran Kankipati
* Updated: 03-Mar-2021
* Release notes: this is my updated (ported) code of my earlier (22-feb-2017) Kernel module code
which creates a sample /proc file and allows us to read its contents from the user-space.
*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/skbuff.h>
#include <linux/udp.h>
#include <linux/ip.h>
#include <linux/in.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/net.h>
#include <linux/netdevice.h>
#include <linux/socket.h>
#include <linux/sockios.h>
#include <linux/inet.h>
#include <linux/inetdevice.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/if_arp.h>
#include <linux/icmp.h>
#include <linux/proc_fs.h>
#include <linux/netlink.h>
#include <linux/mroute.h>
#include <net/checksum.h>
#include <net/inet_ecn.h>
#include <net/xfrm.h>
#include <net/route.h>
#include <net/sock.h>
#include <net/ip.h>
#include <net/tcp.h>
#include <net/arp.h>
#include <net/udp.h>
#include <net/icmp.h>
#include <net/inetpeer.h>
#include <net/protocol.h>
#include <net/flow.h>
#include <asm/types.h>
struct proc_dir_entry *tlc_proc_a;
static ssize_t tlc_proc_a_read(struct file *fp, char *buf, size_t len, loff_t * off)
{ static int finished=0; if(finished) {finished=0;return 0;} finished=1;
//int abc=100;
//strcpy(buf, "abc: %d\n", abc);
//sprintf(buf, "abc: %d\n", abc);
memset(buf,0xaa,10);
//return strlen(buf);
return 10;
}
static struct proc_ops tlc_proc_a_fops = { .proc_read=tlc_proc_a_read, };
static int hello_init(void)
{
tlc_proc_a = proc_create( "tlc_proc_a", 0444, NULL, &tlc_proc_a_fops);
if(tlc_proc_a==NULL) { printk(KERN_ALERT "Error: Could not initialize %s\n", "tlc_proc_a"); }
return 0;
}
static void hello_exit(void)
{ remove_proc_entry("tlc_proc_a", NULL);
}
module_init(hello_init);
module_exit(hello_exit);
Download this episode my entire kernel module sample code, make file, clean script which I hosted in my GitHub Repo. And here is the source code for a quick reference.
/* proc_example.c
* Author: Kiran Kankipati
* Updated: 03-Mar-2021
* Release notes: this is my updated (ported) code of my earlier (22-feb-2017) Kernel module code
which creates a sample /proc file and allows us to read its contents from the user-space.
*
* Updated: 28-Apr-2022
* Release notes: added the module license and metadata.
* compatible with: 5.13.0-41-generic (Ubuntu 21.10) - as well tested with: 5.15.0-27-generic (Ubuntu 22.04 LTS)
*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/skbuff.h>
#include <linux/udp.h>
#include <linux/ip.h>
#include <linux/in.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/net.h>
#include <linux/netdevice.h>
#include <linux/socket.h>
#include <linux/sockios.h>
#include <linux/inet.h>
#include <linux/inetdevice.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/if_arp.h>
#include <linux/icmp.h>
#include <linux/proc_fs.h>
#include <linux/netlink.h>
#include <linux/mroute.h>
#include <net/checksum.h>
#include <net/inet_ecn.h>
#include <net/xfrm.h>
#include <net/route.h>
#include <net/sock.h>
#include <net/ip.h>
#include <net/tcp.h>
#include <net/arp.h>
#include <net/udp.h>
#include <net/icmp.h>
#include <net/inetpeer.h>
#include <net/protocol.h>
#include <net/flow.h>
#include <asm/types.h>
struct proc_dir_entry *tlc_proc_a;
static ssize_t tlc_proc_a_read(struct file *fp, char *buf, size_t len, loff_t * off)
{ static int finished=0; if(finished) {finished=0;return 0;} finished=1;
//int abc=100;
//strcpy(buf, "abc: %d\n", abc);
//sprintf(buf, "abc: %d\n", abc);
memset(buf,0xaa,10);
//return strlen(buf);
return 10;
}
static struct proc_ops tlc_proc_a_fops = { .proc_read=tlc_proc_a_read, };
static int hello_init(void)
{
tlc_proc_a = proc_create( "tlc_proc_a", 0444, NULL, &tlc_proc_a_fops);
if(tlc_proc_a==NULL) { printk(KERN_ALERT "Error: Could not initialize %s\n", "tlc_proc_a"); }
return 0;
}
static void hello_exit(void)
{ remove_proc_entry("tlc_proc_a", NULL);
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_DESCRIPTION("Sample /proc read access file");
MODULE_AUTHOR("Copyright(c) 2022 - Kiran Kankipati");
MODULE_LICENSE("GPL v2");
I also conduct sessions/classes on Systems and Network Software Programming, Linux Kernel Programming and Architecture. If you are interested, click HERE for more details.
If you have any queries or anything to discuss further on Linux Kernel Programming and writing Kernel modules kindly feel free to contact me.