gpt4 book ai didi

c - 使用我的字符驱动程序时出现段错误

转载 作者:太空宇宙 更新时间:2023-11-04 12:29:59 25 4
gpt4 key购买 nike

我正在尝试编写一个名为 my_module 的字符驱动程序。对于我想按以下方式操作的每台设备:

  • 如果我第一次打开设备的文件,我正在分配内存对于结构,设备文件中的“private_data”字段稍后将指向该结构。

  • 如果我之后打开设备的文件,我将继续使用“private_data”指向的相同结构

问题:当我第二次打开文件时,出现了段错误。如果我每次使用“打开”时都为结构重新分配内存,则没有错误。

我做错了什么?

/* my_module.c: Example char device module.
*
*/
/* Kernel Programming */
#define MODULE
#define LINUX
#define __KERNEL__

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <linux/errno.h>
#include<linux/slab.h> /* included for the purpose of using kmalloc and kfree */

#include "my_module.h"

#define CAN_READ 1

#define CANT_READ -1

#define CAN_WRITE 1

#define CANT_WRITE -1

#define MY_DEVICE "my_device"

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Anonymous");

#define BUF_LEN 4096


/* globals */
int my_major = 0; /* will hold the major # of my device driver */
int can_read = CANT_READ;
int can_write = CANT_WRITE;
char * buffp = NULL;




struct file_operations my_fops = {
.open = my_open,
.release = my_release,
.read = my_read,
.write = my_write,
.ioctl = my_ioctl,
.owner = THIS_MODULE
};

typedef struct driver_t {
int can_read;
int can_write;
int curr_index_write_d;
int curr_index_read_d;
char * d_ptr;
} Driver;



Driver * driverCreate( char * buffer, int can_read_arg, int can_write_arg ) {

Driver * driver = (Driver*)kmalloc(sizeof(*driver),GFP_KERNEL);

if(!driver){
return NULL;
}
driver->curr_index_write_d=0;
driver->curr_index_read_d=0;
driver->d_ptr=buffer;
driver->can_read=can_read_arg;
driver->can_write=can_write_arg;
return driver;
}










int init_module(void)
{
//printk(KERN_WARNING "start of module! ");
my_major = register_chrdev(my_major, MY_DEVICE, &my_fops);

if (my_major < 0)
{
//printk(KERN_WARNING "can't get dynamic major\n");
return my_major;
}

//
// do_init();
//
return 0;
}


void cleanup_module(void)
{
//printk(KERN_WARNING "end of module! ");
unregister_chrdev(my_major, MY_DEVICE);

//
// do clean_up();
//
return;
}


int my_open(struct inode *inode, struct file *filp)
{
if(MOD_IN_USE>1) {
return 0;
}
if (filp->f_mode & FMODE_READ)
{
can_read = CAN_READ;

}

if (filp->f_mode & FMODE_WRITE)
{
can_write = CAN_WRITE;
}
char * ptr = kmalloc(BUF_LEN, GFP_KERNEL);
if (!ptr) {
return my_major;
}
Driver * driver = driverCreate(ptr,can_read,can_write);
if (!driver) {
return my_major;
}
filp->private_data = driver;
MOD_INC_USE_COUNT;
return 0;
}










int my_release(struct inode *inode, struct file *filp)
{
/*
if(MOD_IN_USE>1) {
printk(KERN_WARNING "\nclose: MOD IN USE: %d\n", (int)MOD_IN_USE);
MOD_DEC_USE_COUNT;
return 0;
}
printk(KERN_WARNING "\nclose:(suupose to be 1) MOD IN USE: %d\n", (int)MOD_IN_USE);
Driver * d_ptr = (Driver*)(filp->private_data);
char * ptr = d_ptr->d_ptr;

if (filp->f_mode & FMODE_READ)
{
d_ptr->can_read = CANT_READ;
can_read = CANT_READ;
//
// handle read closing
//
}

if (filp->f_mode & FMODE_WRITE)
{
d_ptr->can_write = CANT_WRITE;
can_write = CANT_WRITE;
//
// handle write closing
//
}

if(ptr != NULL) {
kfree(ptr);
kfree(filp->private_data);
filp->private_data=NULL;
printk( KERN_WARNING "Memory is now free ");
}
else {
printk( KERN_WARNING "No memory to free ");
}
*/
return 0;
}












ssize_t my_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
{

Driver * d_ptr = (Driver*)(filp->private_data);
char * ptr = d_ptr->d_ptr;

int curr_index_write = d_ptr->curr_index_write_d;
int curr_index_read = d_ptr->curr_index_read_d;

if(d_ptr->can_read == CANT_READ) {
return 0;
}



if( curr_index_write - curr_index_read == 0 ) {

return 0;
}

int length = (count >= (curr_index_write - curr_index_read) ?
(curr_index_write - curr_index_read) : count );

copy_to_user((char*)buf,(ptr+curr_index_read),length);


d_ptr->curr_index_read_d = curr_index_write;


return length;
//
// Do read operation.
// Return number of bytes read.

}


ssize_t my_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos)
{
Driver * d_ptr = (Driver*)(filp->private_data);

int curr_index_write = d_ptr->curr_index_write_d;

char * ptr = d_ptr->d_ptr;

if(can_write == CANT_WRITE) {
return 0;
}

if( BUF_LEN < curr_index_write + count ) {
return -ENOMEM;
}

copy_from_user((ptr+curr_index_write),(char*)buf,count);

d_ptr->curr_index_write_d = curr_index_write + count;

return count;

//
// Do write operation.
// Return number of bytes written.
}


int my_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{

if(filp->private_data==NULL) {
return 0;
}
Driver * d_ptr = (Driver*)(filp->private_data);

switch(cmd)
{
case MY_RESET:

d_ptr->curr_index_write_d = 0;
d_ptr->curr_index_read_d = 0;
//
// handle OP 1.
//
break;
case MY_RESTART:

d_ptr->curr_index_read_d = 0;
//
// handle OP 1.
//
break;

default:
return -ENOTTY;
}

return 0;
}

最佳答案

代替这一行

  driver->d_ptr=buffer;

尝试

   driver->d_ptr=strdup(buffer);

记住 d_ptr 是指向 char 的指针。它需要先分配内存并复制到它。 strdup() 完成这项工作。

关于c - 使用我的字符驱动程序时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43546859/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com