写入设备文件打印“无效参数”

发布于 2025-02-13 09:24:00 字数 3404 浏览 1 评论 0原文

我目前正在使用设备驱动程序,在该驱动程序中我想为该驱动程序写一个句子并将其显示在内核中。读取内部缓冲区并用 cat 拨打驱动程序的工作状况非常好。但是,如果我尝试写入设备驱动程序,它将返回以下消息:

我为设备驱动程序有以下代码。我似乎找不到我在写功能中出错的地方...

#include "device_file.h"
#include <linux/fs.h>       /* file stuff */
#include <linux/kernel.h>   /* printk() */
#include <linux/errno.h>    /* error codes */
#include <linux/module.h>   /* THIS_MODULE */
#include <linux/cdev.h>     /* char device stuff */
#include <linux/uaccess.h>  /* copy_to_user() */

static const char g_s_Hello_World_string[] = "Hello from Job & Arief!\n\0";
static const ssize_t g_s_Hello_World_size = sizeof(g_s_Hello_World_string);
static char memory_buffer[500];

/*===============================================================================================*/
static ssize_t device_file_read(struct file *file_ptr, char __user *user_buffer, size_t count, loff_t *possition){

    printk( KERN_NOTICE "Kurniawan_Meulenbeld-driver: Device file is read at offset = %i, read bytes count = %u\n"
    , (int)*possition
    , (unsigned int)count );

    if( *possition >= g_s_Hello_World_size )
    return 0;

    if( *possition + count > g_s_Hello_World_size )
    count = g_s_Hello_World_size - *possition;

    if( copy_to_user(user_buffer, g_s_Hello_World_string + *possition, count) != 0 )
    return -EFAULT;

    *possition += count;
    return count;
}

/*===============================================================================================*/
static ssize_t memory_write( struct file *filp, const char *buf, size_t count, loff_t *f_pos) {
    const char *tmp;
    tmp=buf+count-1;

    if( copy_from_user(memory_buffer,tmp,1) != 0 )
        return -EFAULT;

    return count;
}
/*===============================================================================================*/
static struct file_operations Kurniawan_Meulenbeld_driver_fops =
        {
                .owner = THIS_MODULE,
                .read = device_file_read,
                .write =  memory_write,
        };

static int device_file_major_number = 0;
static const char device_name[] = "Kurniawan_Meulenbeld-driver";

/*===============================================================================================*/
int register_device(void)
{
    int result = 0;

    printk( KERN_NOTICE "Kurniawan_Meulenbeld-driver: register_device() is called.\n" );

    result = register_chrdev( 0, device_name, &Kurniawan_Meulenbeld_driver_fops );
    if( result < 0 )
    {
        printk( KERN_WARNING "Kurniawan_Meulenbeld-driver:  can\'t register character device with errorcode = %i\n", result );
        return result;
    }

    device_file_major_number = result;
    printk( KERN_NOTICE "Kurniawan_Meulenbeld-driver: registered character device with major number = %i and minor numbers 0...255\n"
            , device_file_major_number );

    return 0;
}

/*===============================================================================================*/
void unregister_device(void)
{
    printk( KERN_NOTICE "Kurniawan_Meulenbeld-driver: unregister_device() is called\n" );
    if(device_file_major_number != 0)
    {
        unregister_chrdev(device_file_major_number, device_name);
    }
}

I am currently working on a device driver where I want to write a sentence to that driver and display it in the kernel. Reading an internal buffer and calling the driver with cat works perfectly fine. However, if I try to write to the device driver it returns the following message:
enter image description here

I have the following code for my device driver. I can't seem to find where I went wrong in my write function...

#include "device_file.h"
#include <linux/fs.h>       /* file stuff */
#include <linux/kernel.h>   /* printk() */
#include <linux/errno.h>    /* error codes */
#include <linux/module.h>   /* THIS_MODULE */
#include <linux/cdev.h>     /* char device stuff */
#include <linux/uaccess.h>  /* copy_to_user() */

static const char g_s_Hello_World_string[] = "Hello from Job & Arief!\n\0";
static const ssize_t g_s_Hello_World_size = sizeof(g_s_Hello_World_string);
static char memory_buffer[500];

/*===============================================================================================*/
static ssize_t device_file_read(struct file *file_ptr, char __user *user_buffer, size_t count, loff_t *possition){

    printk( KERN_NOTICE "Kurniawan_Meulenbeld-driver: Device file is read at offset = %i, read bytes count = %u\n"
    , (int)*possition
    , (unsigned int)count );

    if( *possition >= g_s_Hello_World_size )
    return 0;

    if( *possition + count > g_s_Hello_World_size )
    count = g_s_Hello_World_size - *possition;

    if( copy_to_user(user_buffer, g_s_Hello_World_string + *possition, count) != 0 )
    return -EFAULT;

    *possition += count;
    return count;
}

/*===============================================================================================*/
static ssize_t memory_write( struct file *filp, const char *buf, size_t count, loff_t *f_pos) {
    const char *tmp;
    tmp=buf+count-1;

    if( copy_from_user(memory_buffer,tmp,1) != 0 )
        return -EFAULT;

    return count;
}
/*===============================================================================================*/
static struct file_operations Kurniawan_Meulenbeld_driver_fops =
        {
                .owner = THIS_MODULE,
                .read = device_file_read,
                .write =  memory_write,
        };

static int device_file_major_number = 0;
static const char device_name[] = "Kurniawan_Meulenbeld-driver";

/*===============================================================================================*/
int register_device(void)
{
    int result = 0;

    printk( KERN_NOTICE "Kurniawan_Meulenbeld-driver: register_device() is called.\n" );

    result = register_chrdev( 0, device_name, &Kurniawan_Meulenbeld_driver_fops );
    if( result < 0 )
    {
        printk( KERN_WARNING "Kurniawan_Meulenbeld-driver:  can\'t register character device with errorcode = %i\n", result );
        return result;
    }

    device_file_major_number = result;
    printk( KERN_NOTICE "Kurniawan_Meulenbeld-driver: registered character device with major number = %i and minor numbers 0...255\n"
            , device_file_major_number );

    return 0;
}

/*===============================================================================================*/
void unregister_device(void)
{
    printk( KERN_NOTICE "Kurniawan_Meulenbeld-driver: unregister_device() is called\n" );
    if(device_file_major_number != 0)
    {
        unregister_chrdev(device_file_major_number, device_name);
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

童话 2025-02-20 09:24:00

请注意,重定向&gt;/dev/my-driver是由当前用户下的shell在调用sudo之前完成的。 einval来自 含义 fd已连接到不适合编写的对象上。

尚不清楚Hello是文件还是字符串。 CAT期望它是文件。

要在设备中写下字符串 Hello 尝试:

echo "hello" | sudo tee /dev/my-driver

在设备中写文件 Hello 尝试:

cat hello | sudo tee /dev/my-driver
# or
sudo tee /dev/my-driver <hello

Note that redirection >/dev/my-driver is done by the shell under the current user before sudo is invoked. EINVAL from write means fd is attached to an object which is unsuitable for writing.

It is not clear whether hello is a file or a string. cat expects it to be a file.

To write string hello into your device try:

echo "hello" | sudo tee /dev/my-driver

To write file hello into your device try:

cat hello | sudo tee /dev/my-driver
# or
sudo tee /dev/my-driver <hello
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文