乙太網驅動的流程淺析(一)-Ifconfig主要流程【原創】

来源:https://www.cnblogs.com/sky-heaven/archive/2019/11/27/11940638.html
-Advertisement-
Play Games

乙太網驅動的流程淺析(一) Ifconfig主要流程 Author:張昺華 Email:[email protected] Time:2019年3月23日星期六 此文也在我的個人公眾號以及《Linux內核之旅》上有發表: "乙太網驅動流程淺析(一) ifconfig主要流程" 很喜歡一群人在研究技術, ...


乙太網驅動的流程淺析(一)-Ifconfig主要流程

Author:張昺華
Email:[email protected]
Time:2019年3月23日星期六

此文也在我的個人公眾號以及《Linux內核之旅》上有發表:乙太網驅動流程淺析(一)-ifconfig主要流程

很喜歡一群人在研究技術,一起做有意思的東西,一起分享技術帶給我們的快樂,也希望中國有更多的人熱愛技術,喜歡一起研究、分享技術,然後可以一起用我們的技術來做一些好玩的東西,可以為這個社會創造一些東西來改善人們的生活。
如下是本人調試過程中的一點經驗分享,乙太網驅動架構畢竟涉及的東西太多,如下僅僅是針對載入流程和圍繞這個問題產生的分析過程和驅動載入流程部分,並不涉及乙太網協議層的數據流程分析。

【硬體環境】 Imx6ul

【Linux kernel版本】 Linux4.1.15

【乙太網phy】 Realtek8201f

一個乙太網的案例來講述Ifconfig

1. 問題描述

【問題】

機器通過usb方式下載了mac地址後,發現乙太網無法正常使用,敲命令 ifconfig eth0 up出現:ifconfig: SIOCSIFFLAGS: No such device,而對於沒有下載乙太網mac address的機器表現均正常。調試過程中發現在乙太網控制器代碼中加入一些printk,不正常的機器又正常了,列印的位置不同,機器的乙太網有時會正常,有時會異常,十分詭異。

2. 原因分析

【根本原因】

reset時序問題導致,phy reset的時間不滿足時序要求。如下圖,如果硬體接了reset引腳,應滿足時序要求在reset保持10ms有效電平後,還必須維持至少150ms才可以訪問phy register,也就是reset要在B點之後才可以正常通過MDC/MDIO來訪問phy register。如果是不使用硬體reset,使用軟體reset方式,那也要至少在A點,也就是在reset維持10ms有效電平後,再維持3.5個clk才能正常訪問phy register。

那為什麼下載了mac地址後才異常呢?不下載的又正常呢?

【原因分析】

freescale控制器獲取mac address流程如下:
1)模塊化參數設置,如果沒有跳到步驟2;
2)device tree中設置,如果沒有跳到步驟3;
3)from flash / fuse / via platform data,如果沒有跳到步驟4;
4)FEC mac registers set by bootloader===》即靠usb方式下載mac address ,如果沒有跳到步驟5;
5)靠kernel算一個隨機數mac address出來,然後寫入mac

那為什麼下載了mac地址後才異常呢?
下了mac後,會執行步驟4,不會執行步驟5,此時目前的代碼不滿足150ms的時序要求,無法訪問phy register,
導致phy_id獲取不到,因此phy_device也不會創建

那為什麼不下載的又正常呢?
不下載mac address,會執行步驟5 ,步驟5中調用了函數eth_hw_addr_random
剛好滿足了150ms的時序要求,所以才可以正常

跟入代碼eth_hw_addr_random看下

繼續看:

最終調用了kernel提供的獲取隨機數的一個函數,這塊代碼比較多就不繼續追下去了。

所以這塊步驟五的代碼剛剛好好在這個硬體條件下,恰巧滿足了150ms的reset時序要求,所以乙太網才可以正常。

3. 乙太網流程分析跟蹤

3.1 Ifconfig主要流程

回歸主題,根據這個ifconfig失敗的現象,我們追蹤一下code:
ifconfig: SIOCSIFFLAGS: No such device,既然出現了這個問題log,我們就從應用層的log入手,首先我們使用strace命令來追蹤下系統調用,以便於我們追蹤內核代碼實現。
strace ifconfig eth0 up跟蹤一下

可以發現主要是ioctl的操作,SIOCSIFFLAGS,然後我們需要瞭解下這個巨集的意思,說白了就是設置各種flag,靠ioctl第三個參數把所需要的動作flag傳入,比如說此時要對eth0進行up動作,那麼就傳入IFF_UP,例如:
struct ifreq ifr;


我們看這些主要是想知道為什麼會列印這個log:
ifconfig: SIOCSIFFLAGS: No such device
那麼內核中又是對ioctl做了什麼動作呢?因為strace命令讓我們知道了系統調用調用函數,我們可以在kernel中直接搜索SIOCSIFFLAGS,或者去乙太網驅動net目錄下直接搜索更快。最終我搜到了,路徑是:net/ipv4/devinet.c
我們可以看到內核的巨集定義:

查看devinet.c的代碼,我們找到了那個巨集,也就是做devinet_ioctl函數中,這也就是應用層的ioctl最終的實現函數,然後我們在裡面加一些列印,


通過列印結果我們可以確認是這個函數devinet_ioctl為應用層的ioctl的實現函數,因為你在kernel中搜SIOCSIFFLAGS巨集的話會有很多地方出現的,所以我們需要確認我們找的函數
沒問題:

看到這裡返回值ret是-19,那麼我們繼續順著追蹤下去,上代碼:
net/core/dev.c

繼續追蹤:net/core/dev.c

因此我們可以看到返回值-19就是如下代碼產生的

因此我們需要追蹤__dev_open函數,繼續看代碼:

通過調試,比如說加列印,或者是經驗我們可以推斷出是這裡返回的-19,那麼這個ndo_open又是在哪裡回調的呢?

我們可以看到ops這個結構的結構體
struct net_device dev
const struct net_device_ops
ops = dev->netdev_ops;

這裡熟悉驅動的朋友應該可以猜到這在在freescale的乙太網控制器驅動中一定有它的實現
net_device_ops就是kernel提供給drvier操作net_device的一些操作方法,具體實現自然由相應廠商的driver自己去實現。
路徑:drivers/net/Ethernet/freescale/fec_main.c

我們可以在這個fec_enet_open函數中加入dump_stack來看下整個調用情況
我們打出kernel的dump_stack信息來看:

這個調用過程就是應用層ioctl一直到kernel最底層fec_enet_open的過程。
應用代碼這樣:

總體流程:kill() -> kill.S -> swi陷入內核態 -> 從sys_call_table查看到sys_kill -> ret_fast_syscall -> 回到用戶態執行kill()下一行代碼
Ioctl《==ret_fast_syscall 《==SyS_ioctl《==do_vfs_ioctl《==vfs_ioctl《==sock_ioctl《==
devinet_ioctl《==dev_change_flags《==__dev_change_flags《==__dev_open《==fec_enet_open
我附上每個函數的代碼:
如果大家想看系統調用流程的話,參考這篇,我就不做這塊的說明瞭:
Linux系統調用(syscall)原理
http://gityuan.com/2016/05/21/syscall/
Arm Linux系統調用流程詳細解析
https://www.cnblogs.com/cslunatic/p/3655970.html

4. 網址分享

http://stackoverflow.com/questions/5308090/set-ip-address-using-siocsifaddr-ioctl
http://www.ibm.com/support/knowledgecenter/ssw_aix_72/com.ibm.aix.commtrf2/ioctl_socket_control_operations.htm
https://lkml.org/lkml/2017/2/3/396
linux PHY驅動
http://www.latelee.org/programming-under-linux/linux-phy-driver.html
Linux PHY幾個狀態的跟蹤
http://www.latelee.org/programming-under-linux/linux-phy-state.html
第十六章PHY -基於Linux3.10
https://blog.csdn.net/shichaog/article/details/44682931

```

End


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • crontab 預設編輯器為vi,不支持foldenable 將預設編輯器改為vim即可解決 將這句話加入/root/.bashrc ...
  • 故障現象 解決方案(失敗) 無效,date命令顯示正常,但是放在腳本中的date命令依然報錯,並且日誌時間依然延後8小時 無效 依然沒有什麼鳥用 最後網上看了一篇文章大概是說可能是升級libc.so.6導致,嘗試以下方法總算成功了 解決方案(成功!) ...
  • 常見的FTP伺服器程式 IIS、Serv-U (windwards中) wu-ftpd(淘汰了)、Proftpd (Linux中) vsftpd(Very Secure FTP Daemon) (Linux中) 安裝 yum install vsftp –y 相關文件 主配置文件 /etc/vsft ...
  • 乙太網驅動流程淺析(三) ifconfig的 19錯誤最底層分析 Author:張昺華 Email:[email protected] Time:2019年3月23日星期六 此文也在我的個人公眾號以及《Linux內核之旅》上有發表: "乙太網驅動流程淺析(三) ifconfig的 19錯誤最底層分析" ...
  • 乙太網驅動的流程淺析(四) 乙太網驅動probe流程 Author:張昺華 Email:[email protected] Time:2019年3月23日星期六 此文也在我的個人公眾號以及《Linux內核之旅》上有發表: "乙太網驅動的流程淺析(四) 乙太網驅動probe流程" 乙太網驅動probe流 ...
  • CentOS8 配置軟體源 在 CentOS8 中、使用了基於DNF技術(YUM v4)的 YUM 工具。 YUM v4 與之前在 CentOS7 上使用的 YUM v3 相比具有以下優點: 提高性能 支持模塊化內容 設計良好的用於與工具集成的穩定API 詳情參考官網:https://dnf.rea ...
  • 1、簡介與原理 互聯網誕生之初就存在三大服務:WWW、FTP、郵件 FTP主要針對企業級,可以設置許可權,對不同等級的資料針對不同許可權人員顯示。 但是像網盤這樣的基本沒有許可權劃分。 簡介: FTP(File Transfer Protocol)文件傳輸協議,用於網上的控制文件的雙向傳輸。 “下載”文件 ...
  • 2、DHCP伺服器相關文件 安裝SHCP伺服器 yum install dhcp 對應的埠 埠號: ipv4 udp67、udp68(不推薦改埠) ipv6 udp546、udp547(暫時還沒生效) 2、相關文件 服務名:dhcpd (d:daeman守護進程) 主配置文件:/etc/dhc ...
一周排行
    -Advertisement-
    Play Games
  • 前言 在我們開發過程中基本上不可或缺的用到一些敏感機密數據,比如SQL伺服器的連接串或者是OAuth2的Secret等,這些敏感數據在代碼中是不太安全的,我們不應該在源代碼中存儲密碼和其他的敏感數據,一種推薦的方式是通過Asp.Net Core的機密管理器。 機密管理器 在 ASP.NET Core ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 順序棧的介面程式 目錄順序棧的介面程式頭文件創建順序棧入棧出棧利用棧將10進位轉16進位數驗證 頭文件 #include <stdio.h> #include <stdbool.h> #include <stdlib.h> 創建順序棧 // 指的是順序棧中的元素的數據類型,用戶可以根據需要進行修改 ...
  • 前言 整理這個官方翻譯的系列,原因是網上大部分的 tomcat 版本比較舊,此版本為 v11 最新的版本。 開源項目 從零手寫實現 tomcat minicat 別稱【嗅虎】心有猛虎,輕嗅薔薇。 系列文章 web server apache tomcat11-01-官方文檔入門介紹 web serv ...
  • C總結與剖析:關鍵字篇 -- <<C語言深度解剖>> 目錄C總結與剖析:關鍵字篇 -- <<C語言深度解剖>>程式的本質:二進位文件變數1.變數:記憶體上的某個位置開闢的空間2.變數的初始化3.為什麼要有變數4.局部變數與全局變數5.變數的大小由類型決定6.任何一個變數,記憶體賦值都是從低地址開始往高地 ...
  • 如果讓你來做一個有狀態流式應用的故障恢復,你會如何來做呢? 單機和多機會遇到什麼不同的問題? Flink Checkpoint 是做什麼用的?原理是什麼? ...
  • C++ 多級繼承 多級繼承是一種面向對象編程(OOP)特性,允許一個類從多個基類繼承屬性和方法。它使代碼更易於組織和維護,並促進代碼重用。 多級繼承的語法 在 C++ 中,使用 : 符號來指定繼承關係。多級繼承的語法如下: class DerivedClass : public BaseClass1 ...
  • 前言 什麼是SpringCloud? Spring Cloud 是一系列框架的有序集合,它利用 Spring Boot 的開發便利性簡化了分散式系統的開發,比如服務註冊、服務發現、網關、路由、鏈路追蹤等。Spring Cloud 並不是重覆造輪子,而是將市面上開發得比較好的模塊集成進去,進行封裝,從 ...
  • class_template 類模板和函數模板的定義和使用類似,我們已經進行了介紹。有時,有兩個或多個類,其功能是相同的,僅僅是數據類型不同。類模板用於實現類所需數據的類型參數化 template<class NameType, class AgeType> class Person { publi ...
  • 目錄system v IPC簡介共用記憶體需要用到的函數介面shmget函數--獲取對象IDshmat函數--獲得映射空間shmctl函數--釋放資源共用記憶體實現思路註意 system v IPC簡介 消息隊列、共用記憶體和信號量統稱為system v IPC(進程間通信機制),V是羅馬數字5,是UNI ...