gpt4 book ai didi

c - 内核网络驱动程序中 netdev_alloc 和 netdev_priv 的问题

转载 作者:太空宇宙 更新时间:2023-11-04 04:44:53 27 4
gpt4 key购买 nike

我有一个自定义的 FPGA 逻辑,我已经为其实现了一个功能性的字符驱动程序,现在我正试图让它作为一个网络驱动程序工作。我尽可能使用 LDD 书、snull 代码和 loopback.c、dummy.c 以及内核中的其他驱动程序作为示例。

我在下面得到的代码(显然是从较大的文件中删除的)是我目前拥有的网络驱动程序代码;我可以成功 insmod,并且“ifconfig optical0”显示我的 MTU 和标志是正确的,所以我知道至少它正在注册。

现在我正在尝试实现 struct net_device 的私有(private)字段 (void* priv) 来存储统计信息和其他内容,这会导致段错误。到目前为止,这是代码:

struct serdes_device {
struct serdes_regs __iomem *regs;
struct serdes_dma *tx_dma,
*rx_dma;

struct device *dev;
struct net_device *netdev;
struct resource serdes_res;
struct cdev cdev;
int major, minor;

int tx_kbps;
int rx_kbps;
};

struct optical_priv {
struct serdes_device *serdes_dev;
struct net_device_stats stats;
};

static const struct net_device_ops optical_netdev_ops = {
.ndo_get_stats = optical_stats,
.ndo_start_xmit = optical_xmit,
/* and so on, not including the ops functions for brevity */
};

void optical_setup(struct net_device *dev)
{
dev->netdev_ops = &optical_netdev_ops;
dev->destructor = free_netdev;

dev->tx_queue_len = 1;
dev->type = ARPHRD_NONE;
dev->hard_header_len = SERDES_FRAME_HEADER_LENGTH;
dev->mtu = SERDES_FRAME_TOTAL_LENGTH;
dev->addr_len = 0;

dev->flags &= ~IFF_BROADCAST;
/* more flags & features cut */
}

static int optical_init(struct net_device *netdev)
{
int err;
struct optical_priv *priv;

netdev = alloc_netdev(sizeof(struct optical_priv), "optical%d", optical_setup);
if (!netdev)
return -ENOMEM;

err = register_netdev(netdev);
if (err < 0)
goto err;

priv = netdev_priv(netdev);
printk(KERN_WARNING "priv is at address 0x%p\n", priv);

return 0;

err:
free_netdev(netdev);
return err;
}

static int serdes_of_probe(struct platform_device *op)
{
struct serdes_device *serdes_dev;
struct optical_priv *priv;
int err = 0;

serdes_dev = kzalloc(sizeof(struct serdes_device), GFP_KERNEL);

/* A bunch of unrelated openfirmware & cdev code removed. */

err = optical_init(serdes_dev->netdev);
if (err < 0)
dev_err(serdes_dev->dev, "Error %d initing optical link\n", err);

priv = netdev_priv(serdes_dev->netdev);
if (!priv)
dev_err(serdes_dev->dev, "priv is null... \n");

dev_info(serdes_dev->dev, "priv is at 0x%p\n", priv);
dev_info(&op->dev, "Done probing.\n");

return 0;

out_free_serdes:
kfree(serdes_dev);

out_return:
return err;
}

因此,据我所知,我正在为我的 serdes 设备(我知道它用作字符驱动程序)分配空间并进行初始化。然后我调用 optical_init 来分配、注册和配置 serdes_dev->netdev。 alloc_netdev 应该也为 (void *)priv 字段分配空间,这就是传入 sizeof(struct optical_priv) 的原因。

里面两条print语句insmod后的输出是这样的:

priv is at address 0xdd2de500
priv is at 0x00000500
Done probing.

并且显然在这之后尝试以任何方式访问 priv 会导致段错误。我想我的困惑是为什么当从两个不同的函数调用时 netdev_priv() 返回两个不同的值——它不应该在 alloc_netdev 之后随时分配和更正吗?

e:我想我也在为太多的驱动程序寻找例子而感到困惑,这些驱动程序来自太多的时代,沉浸在过去的硬件和内核 API 的历史中......如果有人能为我推荐一个好的基本驱动程序首先,我非常乐意阅读代码来学习。

最佳答案

我认为问题出在这里:

err = optical_init(serdes_dev->netdev);

您正在传递一个指向 netdev 结构的无效指针。然后在 optical_init() 中更改指针的本地值:

netdev = alloc_netdev(sizeof(struct optical_priv), "optical%d", optical_setup);

现在您有一个指向 struct net_device 的有效指针。但此指针值不适用于 serdes_dev->netdev 变量,而仅适用于 optical_init() 的本地。因此,指向 priv 的指针也是无效的。这里有一个显示问题的小例子:

#include <stdio.h>
#include <stdlib.h>

struct test {
int first;
int *second;
};

void allocate_memory(int *ptr)
{
ptr = malloc(10);
printf("while allocating %p\n", ptr);
}

int main(void) {
struct test *p1;

p1= malloc(sizeof(struct test));

printf("before %p\n", p1->second);
allocate_memory(p1->second);
printf("after %p\n", p1->second);

free(p1);
free(p2);

return EXIT_SUCCESS;
}

输出是:

before (nil)
while allocating 0x23ee030
after (nil)

关于c - 内核网络驱动程序中 netdev_alloc 和 netdev_priv 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22262624/

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