Linux网络设备的系统调用

2023-11-15

转自: http://www.tuicool.com/articles/QJfmUr


在用户层上的程序, 建立本地socket后,使用ioctl读取phy芯片的寄存器。

ioctl(sockfd, SIOCGMIIREG, &ifr);

下面是linux的网络设备驱动程序响应用户层的ioctl命令过程间各个阶段的函数调用。


ioclt 系统调用层:

fs/ioctl.c

SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)
{ 
...
	error = do_vfs_ioctl(filp, fd, cmd, arg);
...
}

int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,                                                                    unsigned long arg)
{
	switch (cmd) {
...
	default:
       ...
            error = vfs_ioctl(filp, cmd, arg);

		
...
}

static long vfs_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg)
{ 
...
	*如果文件操作方法--无锁的的ioctl有对应实现函数(函数指针unlock_ioctl有被填充), 则调用unlcok_ioctl的实现函数
	*/
	if (filp->f_op->unlocked_ioctl) {
        error = filp->f_op->unlocked_ioctl(filp, cmd, arg);


...
}

unlock_ioctl 的实现层:


net/socket.c

static const struct file_operations socket_file_ops = {
...
    .unlocked_ioctl = sock_ioctl,
...
}

static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
{   
...
switch (cmd) {
...
 default:
            err = sock->ops->ioctl(sock, cmd, arg);
            if (err == -ENOIOCTLCMD)
                err = dev_ioctl(net, cmd, argp);

...
}


net/core/dev.c


//dev_ioctl :  network device ioctl
dev_ioctl(){
	switch (cmd) {
...
    case SIOCGMIIPHY:
    case SIOCGMIIREG:
    case SIOCSIFNAME:
        ret = dev_ifsioc(net, &ifr, cmd);



static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd)                                                             
{
	switch (cmd) {
...
    default:
            if (ops->ndo_do_ioctl) {
                if (netif_device_present(dev))
                    err = ops->ndo_do_ioctl(dev, ifr, cmd);

...
}

ndo_do_ioctl 的实现层:


drivers/net/octeon/octeon_mgmt.c


static int __init octeon_mgmt_mod_init(void)
{
    /* Force our mdiobus driver module to be loaded first. */
    octeon_mdiobus_force_mod_depencency();
    return platform_driver_register(&octeon_mgmt_driver);
}
 

static struct platform_driver octeon_mgmt_driver = {
    .driver = {
        .name       = "octeon_mgmt",
        .owner      = THIS_MODULE,
        .of_match_table = octeon_mgmt_match,
    },  
    .probe      = octeon_mgmt_probe,
    .remove     = __exit_p(octeon_mgmt_remove),
}; 


static struct of_device_id octeon_mgmt_match[] = {
    {
        .compatible = "cavium,octeon-5750-mix",

    },  
    {},  
};  
MODULE_DEVICE_TABLE(of, octeon_mgmt_match);

static int __init octeon_mgmt_probe(struct platform_device *pdev)
{  
 
...  
    netdev->netdev_ops = &octeon_mgmt_ops;
    netdev->ethtool_ops = &octeon_mgmt_ethtool_ops;
 ...   




static const struct net_device_ops octeon_mgmt_ops = {                                                                                         
    .ndo_open =         octeon_mgmt_open,
    .ndo_stop =         octeon_mgmt_stop,
    .ndo_start_xmit =       octeon_mgmt_xmit,
    .ndo_set_rx_mode =      octeon_mgmt_set_rx_filtering,
    .ndo_set_multicast_list =   octeon_mgmt_set_rx_filtering,
    .ndo_set_mac_address =      octeon_mgmt_set_mac_address,
    .ndo_do_ioctl =         octeon_mgmt_ioctl,
    .ndo_change_mtu =       octeon_mgmt_change_mtu,
#ifdef CONFIG_NET_POLL_CONTROLLER
    .ndo_poll_controller =      octeon_mgmt_poll_controller,
#endif
};
 
   
static int octeon_mgmt_ioctl(struct net_device *netdev,                                                                                        
                 struct ifreq *rq, int cmd)
{  
    default:
        if (p->phydev)
            return phy_mii_ioctl(p->phydev, if_mii(rq), cmd);

        return -EINVAL;
    }
}  


drivers/net/phy/phy.c

int phy_mii_ioctl(struct phy_device *phydev,
        struct mii_ioctl_data *mii_data, int cmd)
{  
    switch (cmd) {
    case SIOCGMIIPHY:
        mii_data->phy_id = phydev->addr;
    
    case SIOCGMIIREG:
        mii_data->val_out = phy_read(phydev, mii_data->reg_num);

        break;
    
...
}

include/linux/phy.h

static inline int phy_read(struct phy_device *phydev, u32 regnum)                                                                              
{
    return mdiobus_read(phydev->bus, phydev->addr, regnum);
}
  

drivers/net/phy/mdio_bus.c

int mdiobus_read(struct mii_bus *bus, int addr, u32 regnum)
{

    retval = bus->read(bus, addr, regnum);
...
}


bus->read 的实现层

drivers/net/phy/mdio-octeon.c

static int __init octeon_mdiobus_mod_init(void)
{  
    return platform_driver_register(&octeon_mdiobus_driver);
}  
  
   
static struct platform_driver octeon_mdiobus_driver = {
    .driver = {
        .name       = "mdio-octeon",
        .owner      = THIS_MODULE,
        .of_match_table = octeon_mdiobus_match,
    },
    .probe      = octeon_mdiobus_probe,

    .remove     = __exit_p(octeon_mdiobus_remove),
}; 
   
static struct of_device_id octeon_mdiobus_match[] = {
    {
        .compatible = "cavium,octeon-3860-mdio",

    },
    {},
};  
MODULE_DEVICE_TABLE(of, octeon_mdiobus_match);

static int __init octeon_mdiobus_probe(struct platform_device *pdev)
{  
...
    
    bus->mii_bus->read = octeon_mdiobus_read;

    bus->mii_bus->write = octeon_mdiobus_write;
 
...
}

octeon_mdiobus_read 是最底层的实现函数。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux网络设备的系统调用 的相关文章

  • 为什么使用 __get_free_pages() 进行顺序为 10 或 11 的页面分配通常会失败?

    我的系统内存充足 24GB的服务器 在我的系统中 内核空间分配了320MB和120MB用于崩溃内核 其余的内存用于其他目的 但是 当我使用 get free pages 分配顺序为 11 的连续页 内核无法分配 2 10 页 为什么 根据制
  • 抢占和上下文切换的区别

    一点介绍 我目前正在编写一个小型 读微型 RTOS 内核 它应该与内核中的大多数内容是一体的 然而 我找不到关于下面列出的一些事情的太多信息 这会很有帮助 除此之外 它实际上不是某种大学项目 而是我按照自己的意愿做的事情 回答所有问题的一个
  • Linux 内核驱动程序的探测函数何时被调用?

    我正在尝试更新Android的内核驱动程序 我添加了一些printk来调试它 调用了 init函数 但没有调用probe函数 我缺少什么 何时 如何调用探测函数 该代码可在以下位置获取 https github com lamegopint
  • 定义新的套接字选项以在 TCP 内核代码中使用

    我正在尝试向 TCP 内核代码添加一些功能 在tcp input c 我希望我实现的代码仅在某些情况下运行 我想添加一个控制标志 可以从用户空间应用程序设置它 我 认为我 需要添加一个新的套接字选项 以便我可以完成以下操作setsockop
  • 将 CPU 频率指定为 Linux 启动时的内核 CMD_LINE 参数?

    我将笔记本电脑的i5 CPU更换为i7 CPU 这样它可以运行得更快 但由于i7的功率更大 温度也比以前更高 所以我的笔记本经常死机 所以 我使用cpupower来指定CPU的最大频率 它起作用了 现在 我的问题是 有没有办法在启动时将CP
  • 如何在 OS161 中添加 open 系统调用的两个变体?

    从手册页OS161 Synopsis include
  • 在 Mac OS X 中创建虚拟 USB 设备

    我尝试以编程方式在 Mac OS 中添加带有驱动程序的虚拟 USB 设备 IOKit 文档说 传统上 虚拟设备的驱动程序在 IOResources 上匹配 因为虚拟设备不发布自己的 nub 此类驱动程序的另一个示例是 HelloIOKit
  • 如何显示 Jupyter 笔记本的版本并在 Jupyter 笔记本中运行单元?我收到错误:错误的解释器

    我已经安装了 Anaconda 并使用 conda 环境和 conda 命令来安装软件 当我输入 jupyter notebook version 我收到以下错误 zsh Users cr517 local bin jupyter bad
  • 转储 $mft 文件的内容

    对于一些商业的我正在做的项目我需要能够读取 mft 文件中存储的实际数据 我找到了一个gpl lib http www codeproject com KB files NTFSParseLib aspx artkw ntfs这可能会有所帮
  • Linux 中 NDIS 过滤器的类似物是什么?

    我正在研究一个as close to real time我在linux中尽可能地使用系统 并且需要在收到特定数据包后立即发送大约600 800字节的TCP数据包 为了获得最佳的延迟 我希望这个数据包直接从内核发送 而不是将接收到的数据包一直
  • Linux 源代码中的哪个位置会识别特定的 USB 设备?

    我有一个特定的 USB 设备 我想检查其 Linux 驱动程序源代码 我的理解是 USB 驱动程序执行的第一步是注册自己能够处理具有特定供应商 ID 和产品 ID 的设备 就我而言 供应商 ID 是0BDA产品 ID 是8187 有了这些信
  • 在中断时获取 current->pid

    我正在Linux调度程序上写一些东西 我需要知道在我的中断到来之前哪个进程正在运行 当前的结构可用吗 如果我在中断处理程序中执行 current gt pid 我是否可以获得我中断的进程的 pid 你可以 current gt pid存在并
  • 将 mmap 内核启动参数保留的内存映射到用户空间

    正如中所讨论的this https stackoverflow com q 1911473 143897问题 我在启动时使用内核启动参数保留一个内存块memmap 8G 64G 我写了一个字符驱动程序 http pete akeo ie 2
  • 内核与系统中的 Windows 进程

    我有一些与内核和用户模式下的 Windows 进程相关的问题 如果我有一个 hello world 应用程序和一个公开新系统调用 foo 的 hello world 驱动程序 我很好奇一旦处于内核模式 我能做什么和不能做什么 对于初学者来说
  • Linux 内核标识符中前导和尾随下划线的含义是什么?

    我不断遇到一些小约定 比如 KERNEL Are the 在这种情况下 是内核开发人员使用的命名约定 还是以这种方式命名宏的语法特定原因 整个代码中有很多这样的例子 例如 某些函数和变量以 甚至 这有什么具体原因吗 它似乎被广泛使用 我只需
  • 使用sk_buff添加以太网帧头

    我有一个捕获传出互联网流量的内核模块 Netfilter hook LOCAL OUT 在此挂钩处 仍然没有以太网标头 我构建了以太网头并且可以使用了 但是如何将其连接到skb这样我就可以将整个 skb 结构发送到dev queue xmi
  • 为什么这段代码会死锁?

    我在可加载模块中创建了 2 个 Linux 内核线程 并将它们绑定到在双核 Android 设备上运行的单独 CPU 内核 运行几次后 我注意到设备重新启动并重置了硬件看门狗定时器 我一直在解决这个问题 什么可能导致僵局 基本上 我需要做的
  • 在构建内核模块时为什么需要 /lib/modules? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 在Kbuild树中 当我们编写一个简单的hello ko程序时 为什么我们需要在构建规则中使用 C lib module 为什么需要这样做
  • Linux 上的“软/硬 nofile”是什么意思

    当我尝试在RedHat EL5上安装软件时 我得到了错误 软 硬nofile的期望值是4096 而默认值是1024 我设法增加了这个数字 但我不知道参数是什么 他们指的是软链接和硬链接吗 我改变的方法是 a 修改 etc security
  • Linux 内核中的 64 位 time_t

    我已经编译了内核 3 19 1 但仍然有问题time t 只是一个简单的程序cout lt lt sizeof time t 给出 4 个字节的大小 而不是我的意图的 8 个字节 我应该在 make menuconfig 期间打开特定选项吗

随机推荐

  • 避坑系列1 - 安装Ubuntu & Jenkins, 使用FinalShell

    2023年7月5日 我开始了实验室的工作 首先是要为主机安装Ubuntu 但仍然遇到了一些问题 我在想 今后会遇到许多错误 故障 在某些特定的情境下必然会遇到 比如 用rufus刷镜像时一定会遇到找不到设备的问题 我在网上找了一会才找到答案
  • 面试总结:html5的新特性(十大类)

    这里只以 根目录的方式来说明 详细的见如下连接 https www cnblogs com vicky1018 p 7705223 html 1 语义化标签 好处 1 使代码结构清晰 便于阅读2 便于SEO3 无障碍阅读4 便于后期的维护与
  • 下载多个ts文件,合并为一个mp4文件,并发送到微信

    1 使用internet download manager 来下载ts文件 2 使用tsMuxer来split ts文件 3 VLC media player convert ts to mp4 4 使用MP4Tools将两个ts文件合并
  • windows中的会话概念的总结

    转载请标明是引用于 http blog csdn net chenyujing1234 欢迎大家拍砖 一 参考 http blog csdn net zacklin article details 7579217 以前我一直不理解Windo
  • (三)无人机数据处理算法介绍——目标识别一

    无人机目标识别技术 1 几个相近的概念 图像分割 目标识别 模式识别 目标跟踪 图像分割 根据图像的像素统计特征来对图像进行分割 使得不同类的的图像分开 目标识别 范围广一点 所有的检测目标方法 都可以叫做目标识别 模式识别 当我们采用特定
  • c++ 独一无二的不可拷贝拷贝对象

    方法一 将类的拷贝构造函数和赋值函数只声明 不定义 并定义为 private class A private friend void copy one A const Uncopyable A operator const Uncopyab
  • 简单聊一聊 Spring 事务传播行为和事务隔离级别的那些事

    前言 Spring的事务 也就是数据库的事务操作 符合ACID标准 也具有标准的事务隔离级别 所以Spring的事务隔离级别和事务的传播行为是面试中经常考察的问题 下面简单做下总结 事务并发引发的问题 脏读 一个事务读取到了另一个事务修改但
  • Python记8(tkinter

    目录 1 参考 2 窗口 2 1 创建窗口 Tk 长宽geometry 屏幕宽高 拉伸窗口resizable 窗口名title 循环mainloop 获取窗口大小 2 2 窗口最大化 最小化 正常显示 state iconify attri
  • 知识分享系统

    开发工具 eclipse idea vscode等 数据库 sqlite mysql sqlserver等 功能模块 请用文字描述 至少200字
  • 一般数据库增量数据处理和数据仓库增量数据处理的几种策略

    开篇介绍 通常在数据量较少的情况下 我们从一个数据源将全部数据加载到目标数据库的时候可以采取的策略可以是 先将目标数据库的数据全部清空掉 然后全部重新从数据源加载进来 这是一个最简单并且最直观的并且不容易出错的一种解决方案 但是在很多时候会
  • MYSQL数据库--存储引擎

    前言 数据库存储引擎是数据库底层软件组件 数据库管理系统使用数据引擎进行创建 查询 更新和删除数据操作 简而言之 存储引擎就是指表的类型 数据库的存储引擎决定了表在计算机中的存储方式 不同的存储引擎提供不同的存储机制 索引技巧 锁定水平等功
  • HTTP和HTTPS协议

    HTTP协议 HTTP协议是一种应用层的协议 全称为超文本传输协议 URL URL值统一资源定位标志 也就是俗称的网址 协议方案名 http 表示的就是协议方案名 常用的协议有HTTP协议 HTTPS协议 FTP协议等 HTTPS协议是以H
  • iOS巅峰之点击UIAlertView的灰色部分也能dismiss消失

    UIAlertView alert UITapGestureRecognizer recognizerTap void viewDidLoad super viewDidLoad Do any additional setup after
  • This action could not be completed. Try again.

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 遇到this action could not be completed try again 22421 淡定 解决方法 确保网页上iTunes Connect已经remo
  • 快手投放广告,快手广告优势有哪些呢?

    快手在短视频领域已积累大量忠实用户 形成为独特的社区文化和 老铁经济 虽然商业化进程谨慎而缓慢 但从长远来看 兼顾用户体验的商业需求也许有利于平台商业化的持续发展 对于创作者来说 在入驻一个新平台之前 需要对平台的整体调性全面了解 快手是更
  • 软件工程第一节课 课程引言

    课程引言 一 需要网站系统开发需要掌握的技术 网站的开发技术有很多 主要包括CGI ASP PHP JSP ASP NET等 每一种技术都有其自身的特点与局限性 具体的网站开发技术要根据网站的功能需求 面对的受众 访问量 开发者熟悉的技术等
  • 开源协议说明LGPL

    文章目录 闭源程序 LGPL 闭源程序 不以某种形式开放源代码 也就是说 用户 包括其他开发者 不能获取其源代码的程序 LGPL LGPL协议是一个商业友好的协议 这里的含义是 你可以用 LGPL协议开发商业程序 当然也可以是非商业的闭源程
  • Android最常用八种加密算法

    原文链接 http blog csdn net smartbetter http blog csdn net u013718120 article details 56486408 项目地址 https github com Yalanti
  • 大一python字典作业

    1 字典操作综合练习一 定义一个字典 goods Apple 4999 华为 3600 Vivo 2999 OPPO 3200 三星 4300 向字典新增一个 小米 手机 价格为2800 将字典中 华为 品牌手机价格修改为3999 输入任一
  • Linux网络设备的系统调用

    转自 http www tuicool com articles QJfmUr 在用户层上的程序 建立本地socket后 使用ioctl读取phy芯片的寄存器 ioctl sockfd SIOCGMIIREG ifr 下面是linux的网络