首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >内核网络驱动程序中的netdev_alloc和netdev_priv问题

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

Stack Overflow用户
提问于 2014-03-07 23:20:40
回答 1查看 2K关注 0票数 1

我有一个自定义的FPGA逻辑,我已经为它实现了一个功能良好的char驱动程序,现在我也试图让它作为一个网络驱动程序来工作。我将尽我所能地使用LDD书籍、snull代码和环回.c、dumy.c以及内核中的其他驱动程序作为示例。

下面的代码(显然是从更大的文件中删除)是我到目前为止拥有的网络驱动程序代码;我可以成功地阻止它,并且"ifconfig optical0“显示我的MTU &标志是正确的,所以我知道它至少已经被注册了。

现在,我正在尝试实现struct _device的私有字段(void* priv),以便将统计数据和其他内容存储在其中,这会导致分段错误。以下是目前为止的代码:

代码语言:javascript
复制
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设备分配空间并初始化它(我知道它作为char驱动程序工作)。然后我调用optical_init,它分配、注册和配置serdes_dev->netdev。alloc_netdev也应该为(void*)priv字段分配空间,这也是传入sizeof(struct optical_priv)的原因。

其中的两个print语句不平滑后的输出如下所示:

代码语言:javascript
复制
priv is at address 0xdd2de500
priv is at 0x00000500
Done probing.

显然,在此之后,试图以任何方式访问priv会导致分段故障。我想我的困惑是为什么netdev_priv()在从两个不同的函数调用时返回两个不同的值--难道不应该在alloc_netdev之后的任何时候分配和纠正它吗?

e:我想我也混淆了我自己,在太多的驱动程序中寻找例子,来自太多的时代,沉浸在过去的硬件和内核API的历史中。如果有人对我有一个好的基本驱动程序的建议,我非常乐意阅读代码来学习。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-03-08 09:43:09

我认为问题在于:

代码语言:javascript
复制
err = optical_init(serdes_dev->netdev);

您正在传递指向netdev结构的无效指针。然后,在optical_init()中,用以下方法更改指针的本地值:

代码语言:javascript
复制
netdev = alloc_netdev(sizeof(struct optical_priv), "optical%d", optical_setup);

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

代码语言:javascript
复制
#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;
 }

产出如下:

代码语言:javascript
复制
before (nil)
while allocating 0x23ee030
after (nil)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22262624

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档