1. 程式人生 > >linux網絡卡驅動

linux網絡卡驅動

1. 匯流排、裝置和驅動

    1.1 簡單介紹

     Linux裝置模型中三個很重要的概念就是匯流排、裝置和驅動,即bus,device和driver。它們分別對應的資料結構分別為struct bus_type,struct device和struct device_driver。

     匯流排是處理器與一個或多個裝置之間的通道,在裝置模型中,所有的裝置都通過匯流排相連。在最底層,Linux系統中的每一個裝置都用device結構的一個例項來表示。而驅動則是使總線上的裝置能夠完成它應該完成的功能。

     在系統中有多種匯流排,如PCI匯流排、SCSI匯流排等。系統中的多個裝置和驅動是通過匯流排讓它們聯絡起來的。在bus_type中兩個很重要的成員就是struct kset drivers和struct kset devices。它分別代表了連線在這個總線上的兩個鏈,一個是裝置連結串列,另一個則是裝置驅動連結串列。也就是說,通過一個匯流排描述符,就可以找到掛載到這條總線上的裝置,以及支援該匯流排的不同的裝置驅動程式。

    1.2 匯流排、裝置與驅動的繫結

     在系統啟動時,它會對每種型別的匯流排建立一個描述符,並將使用該匯流排的裝置連結到該匯流排描述符的devices鏈上來。也即是說在系統初始化時,它會掃描連線了哪些裝置,並且為每個裝置建立一個struce device變數,然後將該變數連結到這個裝置所連線的匯流排的描述符上去。另一方面,每當載入了一個裝置驅動,則系統也會準備一個struct device_driver結構的變數,然後再將這個變數也連結到它所在匯流排的描述符的drivers鏈上去。

     對於裝置來說,在結構體struct device中有兩個重要的成員,一個是struct bus_type *bus,另一個是struct device_driver *driver。bus成員就表示該裝置是連結到哪一個總線上的,而driver成員就表示當前裝置是由哪個驅動程式所驅動的。對於驅動程式來說,在結構體struct device_driver中也有兩個成員,struct bus_type *bus和struct list_head devices,這裡的bus成員也是指向這個驅動是連結到哪個總線上的,而devices這個連結串列則是表示當前這個驅動程式可以去進行驅動的那些裝置。一個驅動程式可以支援一個或多個裝置,而一個裝置則只會繫結給一個驅動程式。

     對於device與device_driver之間建立聯絡的方式,主要有兩種方式。第一種,在計算機啟動的時候,匯流排開始掃描連線在其上的裝置,為每個裝置建立一個struct device變數並連結到該匯流排的devices鏈上,然後開始初始化不同的驅動程式,驅動程式到它所在的匯流排的devices鏈上去遍歷每一個還沒有被繫結給某個驅動的裝置,然後再檢視是否能夠支援這種裝置,如果它能夠支援這種裝置,則將這個裝置與這個驅動聯絡起來。即,將這個裝置的device變數加到驅動的devices鏈上,同時讓struct device中的device_driver指向當前這個驅動。第二種則是熱插拔。也即是在系統執行時插入了裝置,此時核心會去查詢在該bus鏈上註冊了的device_driver,然後再將裝置與驅動聯絡起來。裝置與驅動根據什麼規則聯絡起來,它們是如何被聯絡起來的程式碼我們將在後面的章節進行詳細的描述。

    1.3 PCI匯流排

     PCI是一種在CPU與I/O裝置之間進行高速資料傳輸的一種匯流排。有很多裝置都是使用PCI匯流排的,網絡卡就是其中之一。我們在前面講了那些匯流排、裝置與驅動方面的知識,原因就在於網絡卡是連線到PCI總線上,所以PCI匯流排、網絡卡裝置以及網絡卡驅動就成了我們研究網絡卡的一個很重要的線索,尤其是在網路的鏈路層部分。下圖顯示了在一個系統中PCI裝置的一個框圖:

    

    圖1. PCI結構圖

     PCI子系統聲明瞭一個bus_type結構,為pci_bus_type。它就是PCI匯流排的描述符。在這個變數上,連結了PCI裝置以及支援PCI裝置的驅動程式。

    1.4 PCI裝置與驅動

     PCI裝置通常由一組引數唯一地標識,它們被vendorID,deviceID和class nodes所標識,即裝置廠商,型號等,這些引數儲存在pci_device_id結構中。每個PCI裝置都會被分配一個pci_dev變數,核心就用這個資料結構來表示一個PCI裝置。

     所有的PCI驅動程式都必須定義一個pci_driver結構變數,在該變數中包含了這個PCI驅動程式所提供的不同功能的函式,同時,在這個結構中也包含了一個device_driver結構,這個結構定義了PCI子系統與PCI裝置之間的介面。在註冊PCI驅動程式時,這個結構將被初始化,同時這個pci_driver變數會被連結到pci_bus_type中的驅動鏈上去。

     在pci_driver中有一個成員struct pci_device_id *id_table,它列出了這個裝置驅動程式所能夠處理的所有PCI裝置的ID值。

    1.5 PCI裝置與驅動的繫結過程

     下面描述一下對於PCI裝置與驅動繫結的過程。首先在系統啟動的時候,PCI匯流排會去掃描連線到這個總線上的裝置,同時為每一個裝置建立一個pci_dev結構,在這個結構中有一個device成員,並將這些pci_dev結構連結到PCI匯流排描述符上的devices鏈。如下圖所示:

    

    圖2. 將裝置連結到匯流排描述符上

     第二步是當PCI驅動被載入時,pci_driver結構體將被初始化,這一過程在函式pci_register_driver中:

     drv->driver.bus = &pci_bus_type;

     drv->driver.probe = pci_device_probe;

     最後會呼叫driver_register(&drv->driver)將這個PCI驅動掛載到匯流排描述符的驅動鏈上。同時在註冊的過程中,會根據pci_driver中的id_table中的ID值去檢視該驅動支援哪些裝置,將這些裝置掛載到pci_driver中的devices鏈中來。如下圖所示:

    

    圖3. 載入裝置驅動

     對於不同的裝置,可能驅動程式也不一樣,因此,對於上圖中的Dev3,可能就需要另外一個驅動程式來對其進行驅動。所以當載入了Dev3的驅動程式時,其示意圖如下圖所示:

    

    圖4. 不同的裝置驅動

     上面這三個示意圖就描述了匯流排、裝置以及驅動在系統中是如何進行相互聯絡的。前面對於驅動註冊這些函式的描述較為簡單,因為網絡卡是一個PCI裝置,因此在後面具體地講到網絡卡註冊時再來詳細地講解和PCI相關的註冊等函式。

    1.6 小結

     本部分主要講解了匯流排、裝置以及驅動方面的一些知識,由於網絡卡是一個PCI裝置,因此具體地講到了一點PCI匯流排、PCI裝置及相應的PCI驅動方面的知識,但是由於PCI本身就是很大的一個子系統,因此這裡不可能對其進行詳細地講解,在後面對網絡卡的分析中,將對網絡卡中涉及到的和PCI相關的部分進行講解。這一節還是起一個引子的作用。


 2. 網絡卡在PCI層的註冊

    2.1 資料結構

     前面第一章講了匯流排、裝置以及驅動方面的關係,也講到了大多數網絡卡裝置實際上是一個PCI裝置。因此,本章就講解網絡卡裝置在註冊時是如何註冊到PCI總線上去的。在這裡,以Intel的E100網絡卡驅動進行講解。

     前面講到每個PCI裝置都由一組引數唯一地標識,這些引數儲存在結構體pci_device_id中,如下所示:

    struct pci_device_id {

     __u32 vendor, device; /* Vendor and device ID or PCI_ANY_ID*/

     __u32 subvendor, subdevice; /* Subsystem ID's or PCI_ANY_ID */

     __u32 class, class_mask; /* (class,subclass,prog-if) triplet */

     kernel_ulong_t driver_data; /* Data private to the driver */

    };

     每個PCI裝置驅動都有一個pci_driver變數,它描述了一個PCI驅動的資訊,如下所示:

    struct pci_driver {

     struct list_head node;

     char *name;

     const struct pci_device_id *id_table; /* must be non-NULL for probe to be called */

     int (*probe) (struct pci_dev *dev, const struct pci_device_id *id); /* New device inserted */

     void (*remove) (struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */

     int (*suspend) (struct pci_dev *dev, pm_message_t state); /* Device suspended */

     int (*suspend_late) (struct pci_dev *dev, pm_message_t state);

     int (*resume_early) (struct pci_dev *dev);

     int (*resume) (struct pci_dev *dev); /* Device woken up */

     int (*enable_wake) (struct pci_dev *dev, pci_power_t state, int enable); /* Enable wake event */

     void (*shutdown) (struct pci_dev *dev);

     struct pci_error_handlers *err_handler;

     struct device_driver driver;

     struct pci_dynids dynids;

     int multithread_probe;

    };

     每個PCI驅動中都有一個id_table成員變數,記錄了當前這個驅動所能夠進行驅動的那些裝置的ID值。

     對於E100網絡卡驅動來說,它的pci_driver變數定義為:

    static struct pci_driver e100_driver = {

     .name = DRV_NAME,

     .id_table = e100_id_table,

     .probe = e100_probe,

     .remove = __devexit_p(e100_remove),

    #ifdef CONFIG_PM

     /* Power Management hooks */

     .suspend = e100_suspend,

     .resume = e100_resume,

    #endif

     .shutdown = e100_shutdown,

     .err_handler = &e100_err_handler,

    };

     裡面e100_id_table就表示該E100驅動所能夠支援的PCI裝置的ID號,其定義為:

    #define INTEL_8255X_ETHERNET_DEVICE(device_id, ich) {\

     PCI_VENDOR_ID_INTEL, device_id, PCI_ANY_ID, PCI_ANY_ID, \

     PCI_CLASS_NETWORK_ETHERNET

    static struct pci_device_id e100_id_table[] = {

     INTEL_8255X_ETHERNET_DEVICE(0x1029, 0),

     INTEL_8255X_ETHERNET_DEVICE(0x1030, 0),

     …

     { 0, }

    };

     當PCI層檢測到一個PCI裝置能夠被某PCI驅動所支援時(這是通過函式pci_match_one_device來進行檢測的),就會呼叫這個PCI驅動上的probe函式,在該函式中會對該特定的PCI裝置進行一些具體的初始化等操作。比如對於E100裝置驅動來說,其probe函式為e100_probe。在這個函式中,會對網絡卡裝置進行初始化。

     e100_probe主要就涉及到網絡卡裝置net_device的初始化,我們現在先來關注一下從網絡卡註冊一直到呼叫e100_probe這一個過程的整個流程。

    2.2 E100初始化

     E100驅動程式的初始化是在函式e100_init_module()中的,如下:

    static int __init e100_init_module(void)

    {

     if(((1

     printk(KERN_INFO PFX "%s, %s\n", DRV_DESCRIPTION, DRV_VERSION);

     printk(KERN_INFO PFX "%s\n", DRV_COPYRIGHT);

     }

     return pci_register_driver(&e100_driver);

    }

     在這個函式中,呼叫了pci_register_driver()函式,對e100_driver這個驅動進行註冊。

    2.3 PCI註冊

     在前面我們已經看到,PCI的註冊就是將PCI驅動程式掛載到其所在的匯流排的drivers鏈,同時掃描PCI裝置,將它能夠進行驅動的裝置掛載到driver上的devices連結串列上來,這裡,我們將詳細地檢視這整個流程的函式呼叫關係。

     pci_register_driver()->__pci_register_driver()

    /**

     * __pci_register_driver - register a new pci driver

     * @drv: the driver structure to register

     * @owner: owner module of drv

     * @mod_name: module name string

     *

     * Adds the driver structure to the list of registered drivers.

     * Returns a negative value on error, otherwise 0.

     * If no error occurred, the driver remains registered even if

     * no device was claimed during registration.

     */

    int __pci_register_driver(struct pci_driver *drv, struct module *owner, const char *mod_name);

     在函式中有幾個初始化語句:

     drv->driver.name = drv->name;

     drv->driver.bus = &pci_bus_type;

     drv->driver.owner = owner;

     drv->driver.mod_name = mod_name;

     即是將PCI裝置中的driver變數的匯流排指向pci_bus_type這個匯流排描述符,同時設定驅動的名字等。

     pci_bus_type定義如下:

    struct bus_type pci_bus_type = {

     .name = "pci",

     .match = pci_bus_match,

     .uevent = pci_uevent,

     .probe = pci_device_probe,

     .remove = pci_device_remove,

     .suspend = pci_device_suspend,

     .suspend_late = pci_device_suspend_late,

     .resume_early = pci_device_resume_early,

     .resume = pci_device_resume,

     .shutdown = pci_device_shutdown,

     .dev_attrs = pci_dev_attrs,

    };

     然後再呼叫函式driver_register(&drv->driver);通過這個函式將這個PCI驅動中的struct device_driver driver成員變數註冊到系統中去。

     pci_register_driver()->__pci_register_driver()->driver_register()

     driver_register()程式碼如下:

    /**

     * driver_register - register driver with bus

     * @drv: driver to register

     *

     * We pass off most of the work to the bus_add_driver() call,

     * since most of the things we have to do deal with the bus

     * structures.

     *

     * The one interesting aspect is that we setup @drv->unloaded

     * as a completion that gets complete when the driver reference

     * count reaches 0.

     */

    int driver_register(struct device_driver * drv)

    {

     if ((drv->bus->probe && drv->probe) ||

     (drv->bus->remove && drv->remove) ||

     (drv->bus->shutdown && drv->shutdown)) {

     printk(KERN_WARNING "Driver '%s' needs updating - please use bus_type methods\n", drv->name);

     }

     klist_init(&drv->klist_devices, NULL, NULL);

     init_completion(&drv->unloaded);

     return bus_add_driver(drv);

    }

     klist_init()是為裝置驅動的klist_devices成員進行初始化,這個klist_devices是一個對連結串列進行操作的包裹結構,它會連結這個驅動能夠支援的那些裝置。

     最後就呼叫bus_add_driver()函式。這個函式的功能就是將這個驅動加到其所在的匯流排的驅動鏈上。

     pci_register_driver()->__pci_register_driver()->driver_register()->bus_add_driver()->driver_attach()

     在bus_add_driver()函式中,最重要的是呼叫driver_attach()函式,其定義如下:

    /**

     * driver_attach - try to bind driver to devices.

     * @drv: driver.

     *

     * Walk the list of devices that the bus has on it and try to

     * match the driver with each one. If driver_probe_device()

     * returns 0 and the @dev->driver is set, we've found a

     * compatible pair.

     */

    int driver_attach(struct device_driver * drv)

    {

     return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);

    }

     該函式遍歷這個驅動所在的總線上的所有裝置,然後將這些裝置與當前驅動進行匹配,以檢測這個驅動是否能夠支援某個裝置,也即是將裝置與驅動聯絡起來。

     bus_for_each_dev函式是掃描在drv->bus這個總線上的所有裝置,然後將每個裝置以及當前驅動這兩個指標傳遞給__driver_attach函式。

     pci_register_driver()->__pci_register_driver()->driver_register()->bus_add_driver()->driver_attach()->__driver_attach()

     __driver_attach()函式是將驅動與裝置聯絡起來的函式。

    static int __driver_attach(struct device * dev, void * data)

    {

     struct device_driver * drv = data;

     /*

     * Lock device and try to bind to it. We drop the error

     * here and always return 0, because we need to keep trying

     * to bind to devices and some drivers will return an error

     * simply if it didn't support the device.

     *

     * driver_probe_device() will spit a warning if there

     * is an error.

     */

     if (dev->parent) /* Needed for USB */

     down(&dev->parent->sem);

     down(&dev->sem);

     if (!dev->driver)

     driver_probe_device(drv, dev);

     up(&dev->sem);

     if (dev->parent)

     up(&dev->parent->sem);

     return 0;

    }

     在函式中有兩條語句:

     if (!dev->driver)

     driver_probe_device(drv, dev);

     也即是判斷當前裝置是否已經註冊了一個驅動,如果沒有註冊驅動,則呼叫driver_probe_device()函式。

     pci_register_driver()->__pci_register_driver()->driver_register()->bus_add_driver()->driver_attach()->__driver_attach()->driver_probe_device()

     如下:

    /**

     * driver_probe_device - attempt to bind device & driver together

     * @drv: driver to bind a device to

     * @dev: device to try to bind to the driver

     *

     * First, we call the bus's match function, if one present, which should

     * compare the device IDs the driver supports with the device IDs of the

     * device. Note we don't do this ourselves because we don't know the

     * format of the ID structures, nor what is to be considered a match and

     * what is not.

     *

     * This function returns 1 if a match is found, an error if one occurs

     * (that is not -ENODEV or -ENXIO), and 0 otherwise.

     *

     * This function must be called with @dev->sem held. When called for a

     * USB interface, @dev->parent->sem must be held as well.

     */

    int driver_probe_device(struct device_driver * drv, struct device * dev)

    {

     struct stupid_thread_structure *data;

     struct task_struct *probe_task;

     int ret = 0;

     if (!device_is_registered(dev))

     return -ENODEV;

     if (drv->bus->match && !drv->bus->match(dev, drv))

     goto done;

     pr_debug("%s: Matched Device %s with Driver %s\n",

     drv->bus->name, dev->bus_id, drv->name);

     data = kmalloc(sizeof(*data), GFP_KERNEL);

     if (!data)

     return -ENOMEM;

     data->drv = drv;

     data->dev = dev;

     if (drv->multithread_probe) {

     probe_task = kthread_run(really_probe, data,

     "probe-%s", dev->bus_id);

     if (IS_ERR(probe_task))

     ret = really_probe(data);

     } else

     ret = really_probe(data);

    done:

     return ret;

    }

     該函式首先會呼叫總線上的match函式,以判斷當前的PCI驅動能否支援該PCI裝置,如果可以,則繼續往後面執行。

     drv->bus->match函式也即是pci_bus_type中的match成員變數,它為pci_bus_match函式。

     pci_register_driver()->__pci_register_driver()->driver_register()->bus_add_driver()->driver_attach()->__driver_attach()->driver_probe_device()->pci_bus_match()

    /**

     * pci_bus_match - Tell if a PCI device structure has a matching PCI device id structure

     * @dev: the PCI device structure to match against

     * @drv: the device driver to search for matching PCI device id structures

     *

     * Used by a driver to check whether a PCI device present in the

     * system is in its list of supported devices. Returns the matching

     * pci_device_id structure or %NULL if there is no match.

     */

    static int pci_bus_match(struct device *dev, struct device_driver *drv)

    {

     struct pci_dev *pci_dev = to_pci_dev(dev);

     struct pci_driver *pci_drv = to_pci_driver(drv);

     const struct pci_device_id *found_id;

     found_id = pci_match_device(pci_drv, pci_dev);

     if (found_id)

     return 1;

     return 0;

    }

     pci_bus_match函式的作用就是將PCI裝置與PCI驅動進行比較以檢查該驅動是否能夠支援這個裝置。在函式的最前面是兩個巨集to_pci_dev和to_pci_driver。因為在函式執行的過程中,雖然最開始傳進來的是pci_driver結構與pci_dev結構,但是在執行的時候卻取了這兩個結構體中的device_driver和device成員變數,所以現在就要通過這兩個成員變數找到之前對應的pci_driver和pci_dev結構的地址。

    #define to_pci_dev(n) container_of(n, struct pci_dev, dev)

    #define to_pci_driver(drv) container_of(drv,struct pci_driver, driver)

     這兩個巨集在 3rd書上有相應的講解,這裡也就是找到E100的pci_driver:e100_driver以及該網絡卡裝置的pci_dev結構。現在就要對它們進行比較以看它們之間是否能夠聯絡起來。這是通過函式pci_match_device實現的。

     pci_register_driver()->__pci_register_driver()->driver_register()->bus_add_driver()->driver_attach()->__driver_attach()->driver_probe_device()->pci_bus_match()->pci_match_device()

    /**

     * pci_match_device - Tell if a PCI device structure has a matching PCI device id structure

     * @drv: the PCI driver to match against

     * @dev: the PCI device structure to match against

     *

     * Used by a driver to check whether a PCI device present in the

     * system is in its list of supported devices. Returns the matching

     * pci_device_id structure or %NULL if there is no match.

     */

    const struct pci_device_id *pci_match_device(struct pci_driver *drv,

     struct pci_dev *dev)

    {

     struct pci_dynid *dynid;

     /* Look at the dynamic ids first, before the static ones */

     spin_lock(&drv->dynids.lock);

     list_for_each_entry(dynid, &drv->dynids.list, node) {

     if (pci_match_one_device(&dynid->id, dev)) {

     spin_unlock(&drv->dynids.lock);

     return &dynid->id;

     }

     }

     spin_unlock(&drv->dynids.lock);

     return pci_match_id(drv->id_table, dev);

相關推薦

Linux 驅動sk_buff核心原始碼隨筆

          這幾天在除錯有關網絡卡驅動的東西,有很多地方不清楚。而且網絡卡驅動主要有兩個很重要的結構體:struct net_device 和struct sk_buff。 驅動都是圍繞這兩個東西進行操作的,為了搞清楚該如何按協議棧處理資料包,週末閒來無事就看看核

Linux 驅動學習(二)(網路驅動介面小結)

【摘要】前文我們分析了一個虛擬硬體的網路驅動例子,從中我們看到了網路裝置的一些介面,其實網路裝置驅動和塊裝置驅動的功能比較類似,都是傳送和接收資料包(資料請求)。當然它們實際是有很多不同的。 1、引言 首先塊裝置在/dev目錄下有裝置節點,而網路裝置沒有

linux驅動

1. 匯流排、裝置和驅動     1.1 簡單介紹      Linux裝置模型中三個很重要的概念就是匯流排、裝置和驅動,即bus,device和driver。它們分別對應的資料結構分別為struct bus_type,struct device和struct de

嵌入式Linux——驅動(1):驅動框架介紹

宣告:文字是看完韋東山老師的視訊和看了一些文章後,所寫的總結。我會盡力將自己所瞭解的知識寫出來,但由於自己感覺並沒有學的很好,所以文中可能有錯的地方敬請指出,謝謝。         在介紹本文之前,我想先對前面的知識做一下總結,我們知道Linux系統的裝置分為字元裝置(ch

Linux 驅動學習(三)(net_device 等資料結構)

【摘要】前文對網路驅動例子進行一個簡單的梳理總結,本文貼出 net_device 的資料結構以及一些驅動中常用的資料結構。 1、網路裝置驅動結構 1)、網路協議介面層向網路層協議提供提供統一的資料包收發介面,不論上層協議為ARP還是IP,都通過dev_queue_xmi

學習筆記 --- LINUX驅動框架分析

網絡卡的驅動很簡單,就是填充net_device結構體,其應用層到網路協議層核心已經完成了,我們的工作就是填寫這個net_device,然後註冊就可以了。 修正一下:上面第三步應該是:register_netdev 下面程式碼實現一個虛擬網絡卡,這裡沒有實際的網絡卡,只是

linux驅動分析之probe函式

       從上面結果可以看出,該裝置使用了6個BAR中的2個BAR,即BAR0和BAR1,該裝置申請了兩塊IO記憶體,BAR0的範圍為:fea00000-fea1ffff,大小為128KB,用來對映裝置暫存器,BAR1的範圍為fea20000-fea23fff,大小為32KB,用來對映flash。裝置需要

l(轉)Linux DM9000驅動程式完全分析

[置頂] Linux DM9000網絡卡驅動程式完全分析 分類: Linux裝置驅動程式第三版學習筆記 2011-02-26 16:11 3513人閱讀 評論(34) 收藏 舉報 說明1:本文分析基於核心原始碼版本為linux-2

LINUX核心升級 - 更新驅動

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

初識Linux 驅動移植 之 dm9621驅動移植

概述 將kernel移植到開發板並能正常載入和啟動核心後,發現網絡卡並沒有工作,因此將網絡卡作為第一個移植的實踐。這篇文章用於記錄移植dm9621網絡卡過程中遇到的問題以及如何定位問題並嘗試解決。 配置核心 在找到dm9621網絡卡驅動的原始碼後,需要將其新增

新裝linux系統沒有驅動的解決方法

最近公司伺服器剛裝完centos6.0系統,發現只有一個lo網絡卡,沒有eth0也沒有ifcfg-eth0檔案,可以初步說明沒有網絡卡驅動 1.首先下載一個centos6.0的網絡卡驅動(舊版本的網絡卡驅動網上很難找,本人網上沒找到,最後通過客服人員才獲得,已經

Kali Linux ——在無網路情況下安裝無線驅動

1、背景:   今日剛剛開始學習kali linux,眾所周知,安裝完成後,系統是沒有無線網絡卡驅動的,這就對學生黨造成相當的困擾:校園網要連線有線是需要認證客戶端的,而認證客戶端只有windows端,如此一來,無線網也連不上,有線網也連不上,這就......很尷尬。   因此我走訪各大部落格,雖然沒能直接解

linux下編譯新核心,解決無法找到eth0裝置問題,安裝eth0驅動

由於我的blktrace執行時出現問題,只能對裝置測試一次,第二次的時候就會報如下錯誤:no such file or directory google瞭解決方案,很多都說是核心版本的問題,簡單的方法解決不了啊,測試不能不做啊,所以今天只能果斷換核心版本了(不過我想說每編一次核心,都會遇到新的

Kali linux下拓實N95外接驅動安裝教程

1.把linux系統這個資料夾複製到虛擬機器 2.已完成複製 3.開啟linux系統這個檔案 並在資料夾裡 點選右鍵打 然後在終端開啟 4.開的終端 5.輸入解壓命令tar -jxvf RT3070LinuxV2.5.0.

終於搞定了kali linux驅動問題

上一篇說我下了個1.0版本,結果放在VMware裡顯示grub無法安裝導致系統無法被引導,可能是因為低版本有專門為虛擬機器開發的VMware kali,而kali的官網上寫的是到kali2.0已結把虛擬機器版本結合到了

linux centos6.5 安裝驅動程式

網絡卡驅動安裝 檢視系統是否安裝了所需要的軟體包 系統已經安裝了該軟體包 系統已經安裝了gcc make 將下載的安裝包放在usr/local/src資料夾下 對壓縮檔案進行解壓 進入該目錄檢視 進入src目錄檢視 執行make install 進行安裝 進入

tiny4412學習(三)之移植linux-4.x驅動(1)支援驅動

一、思路 上一節我們通過DNW將核心、檔案系統、裝置樹檔案燒入到記憶體中,並使用bootm啟動核心:bootm0x40600000  0x41000000  0x42000000。因為此時核心並沒有S

Linux USB無線驅動相關資料收集

Linux下USB無線網絡卡驅動程式移植的實現 http://www.docin.com/p-297997312.html linux下安裝USB無線網絡卡驅動 http://wenku.baidu.com/view/fac9bb6da45177232f60a2e

linux上安裝驅動程式

                這篇日誌記錄在linux上安裝網絡卡驅動的過程。使用dell的optiplex 360或者opti

基於S3C2440的Linux-3.6.6移植——DM9000驅動移植

Linux-3.6.6很好的支援了DM9000,因此對於S3C2440晶片來說無需進行任何修改,甚至連menuconfig都已經預設配置了網絡卡驅動。但我們還需要設定網絡卡的MAC和IP等資訊。有許多方法可以實現網絡卡的設定,在這裡我們選擇一種比較簡單的方法——修改根檔案系