วิธีใช้ DebugFS blob wrapper ในโมดูลเคอร์เนล

ฉันกำลังพยายามค้นหาวิธีที่เร็วที่สุดในการย้ายข้อมูลขนาดใหญ่จากเคอร์เนลไปยังพื้นที่ผู้ใช้ ตอนนี้ฉันกำลังลองใช้การดีบักของ GKH แต่ฉันกำลังดิ้นรนเพื่อให้ blob wrapper ทำงาน

นี่คือสิ่งที่ฉันได้รับ:

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

มันสร้างขึ้น แต่ถ้าฉันรัน insmod อินสแตนซ์ qemu ของฉันก็ตายอย่างน่ากลัว

ไม่แน่ใจว่าทำไมถึงเป็นเช่นนั้น ฉันพลาดอะไรไป?


person user2036087    schedule 02.02.2013    source แหล่งที่มา
comment
สำหรับวิธีการถ่ายโอนข้อมูลจากพื้นที่เคอร์เนลไปยังพื้นที่ผู้ใช้คุณได้ลองใช้บัฟเฟอร์หรือ netlink mmapped แล้วหรือยัง? มักใช้เพื่อจุดประสงค์นี้ แม้ว่าอาจใช้ยากกว่าก็ตาม   -  person Eugene    schedule 03.02.2013
comment
มันตายยังไงกันแน่? คุณช่วยโพสต์รายงานเคอร์เนลโอ๊ะโอที่คุณได้รับที่นี่ได้ไหม (ถ้าเป็นโอ๊ะโอ) สำหรับโค้ด ฉันไม่เห็นว่าโครงสร้าง 'myblob' ชี้ไปที่ใดอย่างแน่นอน บางทีอาจเป็นเพราะการยกเลิกการอ้างอิงตัวชี้นี้ซึ่งทำให้เกิดความผิดพลาดใน my_init() และ BTW การส่งคืนค่าบวกจาก my_init() เมื่อเกิดข้อผิดพลาดอาจไม่ใช่ความคิดที่ดี IIRC ระบบจะถือว่า my_init() สำเร็จในกรณีนี้ วิธีปฏิบัติทั่วไปคือการส่งคืนรหัสข้อผิดพลาดเชิงลบ เช่น -EINVAL, -ENOMEM เป็นต้น   -  person Eugene    schedule 03.02.2013
comment
ดูเพิ่มเติมที่คำถามนี้และความคิดเห็นที่นั่นอาจเป็นประโยชน์   -  person Eugene    schedule 03.02.2013


คำตอบ (1)


ขอบคุณสำหรับความช่วยเหลือของคุณ. ฉันแค่ลืมรับ mem สำหรับ blob-struct ดังนั้นการตั้งค่าข้อมูลและตัวชี้ขนาดจึงฆ่ามันอย่างหลีกเลี่ยงไม่ได้

นี่คือเวอร์ชันที่ถูกต้องโดยสูบ u32 มูลค่า 32K 'จากเคอร์เนลไปยังพื้นที่ผู้ใช้ มันสร้างด้วยเคอร์เนล 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
ค่าความผิดพลาดใดจะเหมาะสมสำหรับกรณีสุดท้ายที่ไม่สามารถสร้างไฟล์ได้ - person user2036087; 03.02.2013
comment
ฟังก์ชัน debugfs_create_*() อาจล้มเหลวด้วยสาเหตุหลายประการ น่าเสียดายที่พวกเขาไม่ได้ส่งคืนรหัสข้อผิดพลาด ดังนั้นจึงไม่มีวิธีที่ง่ายในการระบุสาเหตุที่พวกเขาล้มเหลว และไม่มีรหัสข้อผิดพลาดที่ถูกต้องอย่างแน่นอนเพื่อให้ฟังก์ชัน init ของคุณส่งคืนเช่นกัน ฉันคิดว่ามันเป็นเรื่องปกติที่จะส่งข้อความเกี่ยวกับข้อผิดพลาดและส่งคืนบางอย่างเช่น -EINVAL หรือ -EPERM เหมือนที่คุณทำตอนนี้ - person Eugene; 03.02.2013
comment
หมายเหตุอีกประการหนึ่ง: เป็นการดีกว่าที่จะเพิ่มหน่วยความจำที่คุณจัดสรรก่อนที่ฟังก์ชัน init ของคุณจะออกพร้อมกับรหัสข้อผิดพลาด ในทั้งสองที่ในกรณีนี้ เคอร์เนลไม่สามารถจัดสรรคืนได้เอง ดังนั้นหน่วยความจำจะยังคงถูกจัดสรรและไม่พร้อมใช้งานสำหรับส่วนประกอบพื้นที่เคอร์เนลอื่นๆ จนกว่าระบบจะรีบูต - person Eugene; 03.02.2013
comment
ขอบคุณ ฉันจะจำไว้; ) - person user2036087; 03.02.2013