Linux内核模块的面向对象设计

通过私有数据实现对象的继承或者关联

向子系统注新对象时,新对象的私有数据和框架层的基础对象复合成新对象。

基础架构一般会提供create方法,实现这个对象的创建并设置私有数据。

驱动模块得到创建的新对象之后进一步设置私有数据。

下面是一个虚拟无线网络设备的创建过程:


/* Function that creates wiphy context and net_device with wireless_dev.
 * wiphy/net_device/wireless_dev is basic interfaces for the kernel to interact with driver as wireless one.
 * It returns driver's main "navifly" context. */
static struct navifly_context *navifly_create_context(void) {
    struct navifly_context *ret = NULL;
    struct navifly_wiphy_priv_context *wiphy_data = NULL;
    struct navifly_ndev_priv_context *ndev_data = NULL;

    /* allocate for navifly context*/
    ret = kmalloc(sizeof(*ret), GFP_KERNEL);
    if (!ret) {
        goto l_error;
    }

    /* allocate wiphy context, also it possible just to use wiphy_new() function.
     * wiphy should represent physical FullMAC wireless device.
     * One wiphy can have serveral network interfaces - for that u need to implement add_virtual_intf() and co. from cfg80211_ops. */
    ret->wiphy = wiphy_new_nm(&nvf_cfg_ops, sizeof(struct navifly_wiphy_priv_context), WIPHY_NAME);
    if (ret->wiphy == NULL) {
        goto l_error_wiphy;
    }

    /* save navifly context in wiphy private data. */
    wiphy_data = wiphy_get_navi_context(ret->wiphy);
    wiphy_data->navi = ret;

    /* set device object as wiphy "parent", I dont have any device yet. */
    /* set_wiphy_dev(ret->wiphy, dev); */

    /* wiphy should determinate it type */
    /* add other required types like  "BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP)" etc. */
    ret->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);

    /* wiphy should have at least 1 band. */
    /* fill also NL80211_BAND_5GHZ if required, in this small example I use only 1 band with 1 "channel" */
    ret->wiphy->bands[NL80211_BAND_2GHZ] = &nf_band_2ghz;

    /* scan - if ur device supports "scan" u need to define max_scan_ssids at least. */
    ret->wiphy->max_scan_ssids = 69;

    /* register wiphy, if everything ok - there should be another wireless device in system.
     * use command:
     *     $ iw list
     *     Wiphy navifly
     *     ...
     * */
    if (wiphy_register(ret->wiphy) < 0) {
        goto l_error_wiphy_register;
    }

    /* allocate network device context. */
    ret->ndev = alloc_netdev(sizeof(*ndev_data), NDEV_NAME, NET_NAME_ENUM, ether_setup);
    if (ret->ndev == NULL) {
        goto l_error_alloc_ndev;
    }
    /* fill private data of network context.*/
    ndev_data = ndev_get_navi_context(ret->ndev);
    ndev_data->navi = ret;

    /* fill wireless_dev context.
     * wireless_dev with net_device can be represented as inherited class of single net_device. */
    ndev_data->wdev.wiphy = ret->wiphy;
    ndev_data->wdev.netdev = ret->ndev;
    ndev_data->wdev.iftype = NL80211_IFTYPE_STATION;
    ret->ndev->ieee80211_ptr = &ndev_data->wdev;

    /* set device object for net_device */
    /* SET_NETDEV_DEV(ret->ndev, wiphy_dev(ret->wiphy)); */

    /* set network device hooks. It should implement ndo_start_xmit() at least. */
    ret->ndev->netdev_ops = &nvf_ndev_ops;

    /* Add here proper net_device initialization. */

    /* register network device. If everything ok, there should be new network device:
     *     $ ip a
     *     ...
     *     4: navifly0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
     *         link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
     *     ...
     * */
    if (register_netdev(ret->ndev)) {
        goto l_error_ndev_register;
    }

    return ret;
    l_error_ndev_register:
    free_netdev(ret->ndev);
    l_error_alloc_ndev:
    wiphy_unregister(ret->wiphy);
    l_error_wiphy_register:
    wiphy_free(ret->wiphy);
    l_error_wiphy:
    kfree(ret);
    l_error:
    return NULL;
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值