Cara menggunakan pembungkus blob DebugFS dalam modul kernel

Saya mencoba menemukan cara tercepat untuk memindahkan data besar dari kernel ke ruang pengguna. Saat ini saya sedang mencoba debugf GKH, tetapi saya kesulitan untuk membuat pembungkus gumpalan berfungsi.

Inilah yang saya dapatkan sejauh ini:

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/debugfs.h>

MODULE_AUTHOR("CREED0R");
MODULE_LICENSE("GPL");


struct dentry *dfs;
struct debugfs_blob_wrapper *myblob;

int my_init(void)
{
    int stats[10];
    int i;

    for (i = 0; i < 10; i++)
        stats[i] = i;

    myblob->data = (void *) stats;
    myblob->size = (unsigned long) 10;

    dfs = debugfs_create_blob("test", 0644, NULL, myblob);

    if (dfs == NULL) {
        printk("Could not create debugfs blob\n");
        return 1;
    }

    printk("DebugFS file created\n");

    return 0;
}


void my_exit(void)
{
    printk("DebugFS file deleted\n\n");
    debugfs_remove(dfs);
}


module_init(my_init);
module_exit(my_exit);

Itu dibangun, tetapi jika saya menjalankan insmod, instance qemu saya mati secara mengerikan.

Tidak yakin kenapa seperti itu. Apa yang saya lewatkan?


person user2036087    schedule 02.02.2013    source sumber
comment
Adapun cara mentransfer data dari ruang kernel ke ruang pengguna, sudahkah Anda mencoba mmapped buffer atau netlink? Mereka sering digunakan untuk tujuan ini, meskipun mungkin lebih rumit untuk digunakan.   -  person Eugene    schedule 03.02.2013
comment
Bagaimana tepatnya cara matinya? Bisakah Anda memposting di sini laporan kernel oops yang Anda dapatkan (jika itu adalah oops)? Mengenai kodenya, saya tidak dapat melihat di mana tepatnya struktur 'myblob' dialokasikan. Mungkin, dereferensi penunjuk inilah yang menyebabkan kerusakan di my_init(). Dan BTW, mengembalikan nilai positif dari my_init() pada kesalahan mungkin bukan ide yang baik. IIRC, sistem akan menganggap bahwa my_init() berhasil dalam kasus ini. Praktik yang umum adalah mengembalikan kode kesalahan negatif, misalnya -EINVAL, -ENOMEM, dll.   -  person Eugene    schedule 03.02.2013
comment
Lihat juga pertanyaan ini dan komentar di sana, semoga bermanfaat.   -  person Eugene    schedule 03.02.2013


Jawaban (1)


terima kasih atas bantuan Anda. Saya hanya lupa mendapatkan mem untuk struktur gumpalan, jadi pengaturan data dan penunjuk ukuran pasti akan mematikannya.

Ini versi yang benar, memompa u32 senilai 32K dari kernel ke ruang pengguna. Itu dibangun dengan Kernel 2.6.32.38:

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/debugfs.h>

#define SIZE 8192

MODULE_AUTHOR("CREED0R");
MODULE_LICENSE("GPL");

struct dentry *dfs;
struct debugfs_blob_wrapper *myblob;

u32 *stats; /* our blob of data */

int my_init(void)
{
    int i;
    int stats_size;   /* size of our data */
    int struct_size;  /* size of the blob struct */

    struct_size = sizeof(struct debugfs_blob_wrapper);
    stats_size  = SIZE * sizeof(u32);


    /* get mem for data */
    stats = kmalloc(stats_size, GFP_KERNEL);

    if (stats == NULL) {
        printk("Could not allocate mem for data\n");
        return -ENOMEM;
    }


    /* fill datablob with dummy data */
    for (i = 0; i < SIZE; i++)
        stats[i] = i;


    /* get mem for blob struct and init */
    myblob = (struct debugfs_blob_wrapper *) kmalloc(struct_size, GFP_KERNEL);

    if (myblob == NULL) {
        printk("Could not allocate mem for blob\n");
        kfree(stats);
        return -ENOMEM;
    }


    /* only set data pointer and data size */
    myblob->data = (void *) stats;
    myblob->size = (unsigned long) stats_size;


    /* create pseudo file under /sys/kernel/debug/ with name 'test' */
    dfs = debugfs_create_blob("test", 0644, NULL, myblob);

    if (dfs == NULL) {
        printk("Could not create debugfs blob\n");
        kfree(stats);
        kfree(myblob);
        return -EINVAL;
    }

    printk("DebugFS file created\n");

    return 0;
}


void my_exit(void)
{
    printk("DebugFS file deleted\n\n");

    kfree(myblob);
    kfree(stats);

    debugfs_remove(dfs);
}


module_init(my_init);
module_exit(my_exit);
person user2036087    schedule 03.02.2013
comment
Nilai kesalahan apa yang sesuai untuk kasus terakhir ketika file tidak dapat dibuat? - person user2036087; 03.02.2013
comment
fungsi debugfs_create_*() mungkin gagal karena beberapa alasan. Sayangnya, mereka tidak mengembalikan kode kesalahan, jadi tidak ada cara mudah untuk menentukan mengapa mereka gagal dan tidak ada kode kesalahan yang benar-benar benar untuk mengembalikan fungsi init Anda. Saya kira, tidak masalah untuk mengeluarkan pesan tentang kesalahan dan mengembalikan sesuatu seperti -EINVAL atau -EPERM seperti yang Anda lakukan sekarang. - person Eugene; 03.02.2013
comment
Satu catatan lagi: lebih baik mengosongkan memori yang Anda alokasikan sebelum fungsi init Anda keluar dengan kode kesalahan, di kedua tempat dalam kasus ini. Kernel tidak dapat membatalkan alokasinya sendiri, sehingga memori akan tetap dialokasikan dan tidak tersedia untuk komponen ruang kernel lainnya hingga sistem di-boot ulang. - person Eugene; 03.02.2013
comment
Terima kasih, saya akan mengingatnya; ) - person user2036087; 03.02.2013