Learning of proc programming in linux kernel 5.8
Facing the proc_fs.h header file, a little bit of learning
See the first structure in the header file, the operation structure of the /proc directory
struct proc_ops {
unsigned int proc_flags;
int (*proc_open)(struct inode *, struct file *);
ssize_t (*proc_read)(struct file *, char __user *, size_t, loff_t *);
ssize_t (*proc_write)(struct file *, const char __user *, size_t, loff_t *);
loff_t (*proc_lseek)(struct file *, loff_t, int);
int (*proc_release)(struct inode *, struct file *);
__poll_t (*proc_poll)(struct file *, struct poll_table_struct *);
long (*proc_ioctl)(struct file *, unsigned int, unsigned long);
#ifdef CONFIG_COMPAT
long (*proc_compat_ioctl)(struct file *, unsigned int, unsigned long);
#endif
int (*proc_mmap)(struct file *, struct vm_area_struct *);
unsigned long (*proc_get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
} __randomize_layout;
Look at the important functions in the header file
extern struct proc_dir_entry *proc_create_data(const char *, umode_t,
struct proc_dir_entry *,
const struct proc_ops *,
void *);
Okay, write down the first demo
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/uaccess.h> /* copy_*_user */
#include <linux/slab.h>
int our_proc_open(struct inode *, struct file *);
ssize_t our_proc_read(struct file *, char __user *, size_t, loff_t *);
struct proc_ops ops = {
.proc_open = our_proc_open,
.proc_read = our_proc_read
};
int our_proc_open(struct inode *inode, struct file *file)
{
return 0;
};
ssize_t our_proc_read(struct file *file, char __user * buffer, size_t size, loff_t *off_t)
{
printk(KERN_ALERT "HELLO,our_proc_read\n");
return 0;
};
static int __init our_proc_init(void)
{
printk(KERN_ALERT "HELLO,KERNEL\n");
//挂载proc
proc_create_data("our_proc", 0644, NULL, &ops, NULL);
return 0;
}
static void __exit our_proc_exit(void)
{
printk(KERN_ALERT "HELLO,KERNEL BYE BYE\n");
remove_proc_entry("our_proc", NULL);
}
module_init(our_proc_init);
module_exit(our_proc_exit);
Makefile
obj-m:=proc.o
KERNELBUILD := /lib/modules/$(shell uname -r)/build
default:
make -C $(KERNELBUILD) M=$(shell pwd) modules
clean:
rm -rf *.o *.ko
Excuting an order
sudo make
sudo insmod proc.ko
sudo rmmod proc.ko
Okay, the entire proc directory collapsed
ls /proc
The entire command line of the computer crashes, click the shutdown button, the machine freezes. . . . . .
What is the reason for this? Caused me to think
The header file of vim prc_fs.h, I think I found the reason
#define remove_proc_entry(name, parent) do {} while (0)
This function is commented out, which means it doesn’t work anymore, and the proc_remove function is found in the source code,
but the implementation does not seem to work because there is nothing in the implementation code.
static inline void proc_remove(struct proc_dir_entry *de) {}
Then modify the demo again
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/uaccess.h> /* copy_*_user */
#include <linux/slab.h>
#define MODULE_NAME "our_proc"
struct proc_dir_entry* proc_handle = NULL;
int our_proc_open(struct inode *, struct file *);
ssize_t our_proc_read(struct file *, char __user *, size_t, loff_t *);
struct proc_ops ops = {
.proc_open = our_proc_open,
.proc_read = our_proc_read
};
int our_proc_open(struct inode *inode, struct file *file)
{
return 0;
};
ssize_t our_proc_read(struct file *file, char __user * buffer, size_t size, loff_t *off_t)
{
printk(KERN_ALERT "HELLO,our_proc_read\n");
return 0;
};
static int __init our_proc_init(void)
{
printk(KERN_ALERT "HELLO,KERNEL\n");
//挂载proc
proc_handle = proc_create_data(MODULE_NAME, 0644, NULL, &ops, NULL);
return 0;
}
static void __exit our_proc_exit(void)
{
printk(KERN_ALERT "HELLO,KERNEL BYE BYE\n");
if (proc_handle) {
proc_remove(proc_handle);
}
}
module_init(our_proc_init);
module_exit(our_proc_exit);
Execute the command again
sudo make
sudo insmod proc.ko
cat /proc/our_proc
dmesg
Seen in the debug ring buffer
[ 1212.214871] HELLO,KERNEL
[ 1227.271966] HELLO,our_proc_read
[ 1250.484078] HELLO,KERNEL BYE BYE
[ 1305.898772] HELLO,KERNEL
[ 1342.722686] HELLO,KERNEL BYE BYE
[ 1649.965351] HELLO,KERNEL
[ 1656.079254] HELLO,our_proc_read
[ 1657.011422] HELLO,our_proc_read
Uninstall the driver
sudo rmmod proc.ko
Seeing that /proc/our_proc is gone, everything is back to normal
This is the new function api of proc, which is mainly used to dynamically query drive information. Of course, we call the
glibc classic api read write ioctl lseek and so on, which will trigger the corresponding hook