Linux kernel 我的平台驱动程序的rmmod导致内核死机?

Linux kernel 我的平台驱动程序的rmmod导致内核死机?,linux-kernel,linux-device-driver,embedded-linux,gpio,Linux Kernel,Linux Device Driver,Embedded Linux,Gpio,我已经编写了一个简单的GPIO sysfs驱动程序。然而,当我调用rmmod时,我的驱动程序正在崩溃。我不知道我错过了什么。我怀疑是我的probe()函数导致了此问题。我使用的是内核4.19版本。这是我的长代码: 设备id gpio系统匹配的结构[]{ {.compatible=“org,bone gpio sysfs”}, {}//NULL终止 }; ssize\u t direction\u show(结构设备*dev,结构设备属性*attr,char*buf) { 返回0; } ssize

我已经编写了一个简单的GPIO sysfs驱动程序。然而,当我调用
rmmod
时,我的驱动程序正在崩溃。我不知道我错过了什么。我怀疑是我的
probe()
函数导致了此问题。我使用的是内核4.19版本。这是我的长代码:

设备id gpio系统匹配的结构[]{
{.compatible=“org,bone gpio sysfs”},
{}//NULL终止
};
ssize\u t direction\u show(结构设备*dev,结构设备属性*attr,char*buf)
{
返回0;
}
ssize\u t direction\u存储(结构设备*dev,结构设备属性*attr,常量字符*buf,大小\u t计数)
{
返回0;
}
ssize_t value_show(结构设备*dev,结构设备属性*attr,char*buf)
{
返回0;
}
ssize_t value_store(结构设备*dev,结构设备属性*attr,常量字符*buf,大小计数)
{
返回0;
}
ssize_t label_show(结构设备*dev,结构设备属性*attr,char*buf)
{
返回0;
}
静态装置(方向);
静态设备属性(值);
静态设备属性(标签);
静态结构属性*gpio_属性[]={
&dev_attr_direction.attr,
&dev_attr_value.attr,
&dev_attr_label.attr,
无效的
};
静态结构属性\u组gpio\u组={
.attrs=gpio\U attrs,
};
常量结构属性组*gpio属性组[]=
{
&gpio_集团,
无效的
};
int gpio\U系统\平台\驱动程序\探针(结构平台\设备*pDev)
{   
结构设备节点*parent=pDev->dev.of\u节点;
结构设备_节点*子节点;
struct gpiodev_private_data*dev_data;
结构设备开发=pDev->dev;
常量字符*名称;
int i=0;
int ret;
gpiodrv_data.total_devices=子项计数(父项)的数量;
如果(!gpiodrv_data.total_devices){
dev_err(&dev,“错误-找不到设备\r\n”);
返回-艾因瓦尔;
}
dev_info(&dev,“子计数=%d\r\n”,gpiodrv_数据。设备总数);
gpiodrv_data.dev_sysfs=devm_kzalloc(&pDev->dev,sizeof(struct device*)*gpiodrv_data.total_devices,GFP_内核);
对于每个可用的子节点(父节点、子节点){
dev_data=devm_kzalloc(&dev,sizeof(struct gpiodev_private_data),GFP_内核);
如果(!dev_data){
pr_err(“无内存”);
return-ENOMEM;
}
if(属性的读取字符串(子项、标签和名称)){
pr_err(“缺少标签”);
snprintf(dev_数据->标签,sizeof(dev_数据->标签),“未知gpio-%d”,i);
}否则{
strcpy(开发数据->标签、名称);
开发信息(&dev,“GPIO标签=%s\n”,开发数据->标签);
}
dev_data->desc=dev_fwnode\u从子节点获取gpiod\u(&dev,“bone”和&child->fwnode,gpiod\u ASIS,dev_data->label);
如果(是错误(开发数据->描述)){
ret=PTR\u ERR(开发数据->描述);
如果(ret==-ENONET){
dev_err(&dev,“get-gpiod失败-找不到条目\r\n”);
}
返回ret;
}
/**gpio/gpio.txt**/
ret=gpiod\U方向\U输出(开发数据->描述,0);
如果(ret){
dev_err(&dev,“错误设置gpio方向失败=%d\r\n”,i);
返回ret;
}
gpiodrv_data.dev_sysfs[i]=使用组创建设备(gpiodrv_data.class_gpio,&dev,0,dev_数据,gpio_属性组,dev_数据->标签);
if(IS_ERR(gpiodrv_data.dev_sysfs[i])){
ret=PTR_ERR(gpiodrv_data.dev_sysfs[i]);
dev_err(&dev,“使用组创建设备时出错\r\n”);
返回ret;
}
i++;
}
返回0;
}
int gpio系统驱动程序删除(结构平台设备*pDev)
{ 
int i=0;
dev_info(&pDev->dev,“删除gpio syfs驱动程序\r\n”);
对于(i=0;i

当我调用我的驱动程序的
rmmod
时,问题就出现了。当我这样做时,我看到一个内核崩溃-指向平台驱动程序注销。我做错了什么?如果我对probe进行注释,那么我看不出这个问题。也许,探测器内部引入了一些问题。正如您所看到的,我使用的是托管资源API,所以我想,我不必调用
kfree()
,因为我使用的是
dev_kzalloc()

您是否检查了
class\u gpio
空指针或
平台驱动程序\u寄存器
失败?不确定是否相关,但我找不到
gpiodrv\u数据的定义。另外,发布内核紧急消息可能有助于使用局部变量
struct device dev=pDev->dev
和后续使用
&dev
看起来非常错误,因为
dev
变量在探测函数返回时不再存在。是否有任何原因导致您不能将
&dev
替换为
&pDev->dev
?您关心的是正确的-使用局部变量struct device dev=pDev->;随后使用&dev看起来非常错误,因为当probe函数返回时,dev变量就不存在了。。这就是问题所在,而且奏效了。