Aprendiendo sobre proc en el kernel

Aprendizaje de la programación proc en linux kernel 5.8

Frente al archivo de encabezado proc_fs.h, un poco de aprendizaje

Vea la primera estructura en el archivo de encabezado, la estructura de operación del directorio / proc

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;

Mira las funciones importantes en el archivo de encabezado

extern struct proc_dir_entry *proc_create_data(const char *, umode_t,
                                               struct proc_dir_entry *,
                                               const struct proc_ops *,
                                               void *);

De acuerdo, escribe la primera demostración

#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

Ejecutando una orden

sudo make
sudo insmod proc.ko
sudo rmmod proc.ko

Bien, todo el directorio proc colapsó

ls /proc

Toda la línea de comando de la computadora se bloquea, haga clic en el botón de apagado, la máquina se congela. . . . . .

¿Cuál es la razón para esto? Me hizo pensar

El archivo de encabezado de vim prc_fs.h, creo que encontré la razón

#define remove_proc_entry(name, parent) do {} while (0)

Esta función está comentada, lo que significa que ya no funciona, y la función proc_remove se encuentra en el código fuente,
pero la implementación no parece funcionar porque no hay nada en el código de implementación.

static inline void proc_remove(struct proc_dir_entry *de) {}

Luego modifique la demostración nuevamente

#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);

Ejecute el comando nuevamente

sudo make
sudo insmod proc.ko
cat /proc/our_proc
dmesg

Visto en el búfer de anillo de depuración

[ 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

Desinstalar el controlador

sudo rmmod proc.ko

Al ver que / proc / our_proc se ha ido, todo vuelve a la normalidad

Esta es la nueva función api de proc, que se usa principalmente para consultar dinámicamente la información del controlador. Por supuesto, llamamos a la
API clásica glibc read write ioctl lseek y así sucesivamente activará el gancho correspondiente

Supongo que te gusta

Origin blog.csdn.net/qq_32783703/article/details/113090611
Recomendado
Clasificación