GNU/Linux >> Linux Esercitazione >  >> Linux

Come creare file Proc Linux nel programma C usando LKM

Il file system Proc riflette lo stato corrente del kernel Linux.

Lo stato attuale del kernel potrebbe rappresentare varie informazioni come i processi in esecuzione su di esso, le informazioni sull'hardware, le informazioni di rete ecc. Quindi questo sistema è progettato in modo tale che tutte queste informazioni possano essere facilmente accessibili dai processi a livello di utente.

Diciamo anche che un file system proc è uno pseudo file system. Questo perché i file in questo file system vengono caricati con informazioni quando si accede a questi file e questo è il motivo per cui i file in questo file system di solito mostrano una dimensione zero.

Esegui un ls /proc sul tuo sistema e noterai qualcosa di simile al seguente:

$ ls /proc
1  15  1681  1719 35 60  713  878 cgroups filesystems kpageflags pagetypeinfo sysrq-trigger ....

Quindi vediamo che questo file system contiene file e directory. I nomi dei file o delle directory sono alfabetici o numerici. I nomi di file o directory numerici corrispondono principalmente ai processi in esecuzione sul sistema e il numero rappresenta l'ID processo del processo. Quindi è molto facile conoscere le informazioni a livello di kernel su qualsiasi processo usando il suo ID processo e aprendo il file corrispondente.

In questo articolo approfondiremo la nostra conoscenza dei moduli del kernel caricabili (LKM) e discuteremo come vengono creati, letti e scritti questi file proc.

Fare riferimento al nostro precedente articolo sul file system proc Linux per comprendere i vari file che si trovano in /proc.

Creazione di file Proc

Nell'articolo sui moduli del kernel Linux, abbiamo discusso su come creare, caricare e scaricare LKM. Questo era il concetto di base per aggiungere più funzionalità al kernel Linux in fase di esecuzione. I file Proc funzionano secondo lo stesso principio. Ogni file proc viene creato, caricato e scaricato sotto forma di LKM.

Nel codice seguente, proviamo a creare un file proc e a definirne le capacità di lettura e scrittura.

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <linux/string.h>
#include <linux/vmalloc.h>
#include <asm/uaccess.h>

#define MAX_LEN       4096
int read_info( char *page, char **start, off_t off,int count, int *eof, void *data );
ssize_t write_info( struct file *filp, const char __user *buff,unsigned long len, void *data );

static struct proc_dir_entry *proc_entry;
static char *info;
static int write_index;
static int read_index;

int init_module( void )
{
    int ret = 0;
    info = (char *)vmalloc( MAX_LEN );
    memset( info, 0, MAX_LEN );
    proc_entry = create_proc_entry( "procEntry123", 0644, NULL );

    if (proc_entry == NULL)
    {
        ret = -1;
        vfree(info);
        printk(KERN_INFO "procEntry123 could not be created\n");
    }
    else
    {
        write_index = 0;
        read_index = 0;
        proc_entry->read_proc = read_info;
        proc_entry->write_proc = write_info;
        printk(KERN_INFO "procEntry123 created.\n");
    }

    return ret;
}

void cleanup_module( void )
{
    remove_proc_entry("procEntry123", proc_entry);
    printk(KERN_INFO "procEntry123 unloaded.\n");
    vfree(info);
}

ssize_t write_info( struct file *filp, const char __user *buff, unsigned long len, void *data )
{
    int capacity = (MAX_LEN-write_index)+1;
    if (len > capacity)
    {
        printk(KERN_INFO "No space to write in procEntry123!\n");
        return -1;
    }
    if (copy_from_user( &info[write_index], buff, len ))
    {
        return -2;
    }

    write_index += len;
    info[write_index-1] = 0;
    return len;
}

int read_info( char *page, char **start, off_t off, int count, int *eof, void *data )
{
    int len;
    if (off > 0)
    {
        *eof = 1;
        return 0;
    }

    if (read_index >= write_index)
    read_index = 0;

    len = sprintf(page, "%s\n", &info[read_index]);
    read_index += len;
    return len;
}

Nel codice sopra :

  • Nella funzione init_module abbiamo usato la funzione 'create_proc_entry' per creare un file proc chiamato 'procEntry123'
  • Il file viene creato con privilegi adeguati come descritto dal secondo argomento della funzione create_proc_entry.
  • Due funzioni read_info e write_info vengono utilizzate durante la lettura e la scrittura del file proc.
  • L'indirizzo di queste due funzioni è assegnato ai membri della struttura proc_dir_entry.
  • Il passaggio precedente è stato eseguito affinché il codice sapesse quale funzione chiamare quando il file proc viene letto e scritto.
  • Nella funzione write_info, se c'è capacità di scrivere nel buffer, la funzione copy_from_user viene utilizzata per copiare la stringa dallo spazio utente al buffer di memoria allocato del modulo del kernel.
  • Nella funzione read_info, le informazioni presenti nel buffer vengono rispedite allo spazio utente.

Il Makefile per il codice sopra è simile a:

$ cat Makefile
obj-m += proc.o
all:
        sudo make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
        sudo make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

Ora, quando il codice sopra è compilato, vediamo :

$ make
sudo make -C /lib/modules/2.6.32-21-generic/build M=/home/himanshu modules
make: Entering directory `/usr/src/linux-headers-2.6.32-21-generic'
CC [M]  /home/himanshu/proc.o
/home/himanshu/proc.c: In function ‘init_module’:
/home/himanshu/proc.c:33: warning: assignment from incompatible pointer type
Building modules, stage 2.
MODPOST 1 modules
LD [M]  /home/himanshu/proc.ko
make: Leaving directory `/usr/src/linux-headers-2.6.32-21-generic'

Una volta che il codice è stato compilato correttamente, il modulo viene inserito e caricato dal seguente comando:

$ sudo insmod proc.ko

E dopo aver inserito se vediamo la directory proc, troviamo una voce 'procEntry123'

$ ls /proc/procEntry123
/proc/procEntry123

Ora, se proviamo a scrivere e leggere da esso:

$ echo "TGS" > /proc/procEntry123
$ cat /proc/procEntry123
TGS

Quindi vediamo che siamo in grado di leggere e scrivere il file proc. Allo stesso modo vengono implementati tutti i file di proc standard.


Linux
  1. Come creare uno scambio in Linux

  2. Come creare un file di scambio in Linux

  3. Come creare un utente Linux usando Ansible

  4. Crea file utilizzando la riga di comando in Linux

  5. Come creare file sparsi in Linux usando il comando 'dd'

Come creare un file in Linux usando Cat Command

Come creare un file in Linux usando Terminal

Come creare un file in Ubuntu Linux usando comando e GUI

/proc/cpuinfo e /proc/meminfo in Linux

Come comprimere un file in Linux

Come creare file zip o directory protetti da password in Linux