《電子技術(shù)應(yīng)用》
您所在的位置:首頁 > 模擬設(shè)計(jì) > 設(shè)計(jì)應(yīng)用 > 嵌入式Linux網(wǎng)絡(luò)驅(qū)動(dòng)程序的體系結(jié)構(gòu)和實(shí)現(xiàn)原理
嵌入式Linux網(wǎng)絡(luò)驅(qū)動(dòng)程序的體系結(jié)構(gòu)和實(shí)現(xiàn)原理
摘要: 隨著人們對開放源代碼軟件熱情的日益增高,Linux作為一個(gè)功能強(qiáng)大而穩(wěn)定的開源操作系統(tǒng),越來越受到成千上萬的計(jì)算機(jī)專家和愛好者的青睞。
Abstract:
Key words :

  隨著人們對開放源代碼軟件熱情的日益增高,Linux作為一個(gè)功能強(qiáng)大而穩(wěn)定的開源操作系統(tǒng),越來越受到成千上萬的計(jì)算機(jī)專家和愛好者的青睞。在嵌入式領(lǐng)域,通過對Linux進(jìn)行小型化裁剪后,使其能夠固化在容量只有幾十兆字節(jié)的存儲(chǔ)器芯片或單片機(jī)中,成為應(yīng)用于特定場合的嵌入式Linux系統(tǒng)。Linux強(qiáng)大的網(wǎng)絡(luò)支持功能實(shí)現(xiàn)了對包括TCP/IP在內(nèi)的多種協(xié)議的支持,滿足了面向21世紀(jì)的嵌入式系統(tǒng)應(yīng)用聯(lián)網(wǎng)的需求。因此,在嵌入式系統(tǒng)開發(fā)調(diào)試時(shí),網(wǎng)絡(luò)接口幾乎成為不可或缺的模塊。

  1 嵌入式Linux網(wǎng)絡(luò)驅(qū)動(dòng)程序介紹

  Linux網(wǎng)絡(luò)驅(qū)動(dòng)程序作為Linux網(wǎng)絡(luò)子系統(tǒng)的一部分,位于TCP/IP網(wǎng)絡(luò)體系結(jié)構(gòu)的網(wǎng)絡(luò)接口層,主要實(shí)現(xiàn)上層協(xié)議棧與網(wǎng)絡(luò)設(shè)備的數(shù)據(jù)交換。Linux的網(wǎng)絡(luò)系統(tǒng)主要是基于BSD Unix的套接字(socket)機(jī)制,網(wǎng)絡(luò)設(shè)備與字符設(shè)備和塊設(shè)備不同,沒有對應(yīng)地映射到文件系統(tǒng)中的設(shè)備節(jié)點(diǎn)。

  通常,Linux驅(qū)動(dòng)程序有兩種加載方式:一種是靜態(tài)地編譯進(jìn)內(nèi)核,內(nèi)核啟動(dòng)時(shí)自動(dòng)加載;另一種是編寫為內(nèi)核模塊,使用insmod命令將模塊動(dòng)態(tài)加載到正在運(yùn)行的內(nèi)核,不需要時(shí)可用rmmod命令將模塊卸載。Linux 2.6內(nèi)核引入了kbuild機(jī)制,將外部內(nèi)核模塊的編譯同內(nèi)核源碼樹的編譯統(tǒng)一起來,大大簡化了特定的參數(shù)和宏的設(shè)置。這樣將編寫好的驅(qū)動(dòng)模塊加入內(nèi)核源碼樹,只需要修改相應(yīng)目錄的Kconfig文件,把新的驅(qū)動(dòng)加入內(nèi)核的配置菜單,然后需要修改相應(yīng)子目錄中與模塊編譯相關(guān)的Kbuild Makefile,即可使新的驅(qū)動(dòng)在內(nèi)核源碼樹中被編譯。在嵌入式系統(tǒng)驅(qū)動(dòng)開發(fā)時(shí),常常將驅(qū)動(dòng)程序編寫為內(nèi)核模塊,方便開發(fā)調(diào)試。調(diào)試完畢后,就可以將驅(qū)動(dòng)模塊編譯進(jìn)內(nèi)核,并重新編譯出支持特定物理設(shè)備的Linux內(nèi)核。

  2 嵌入式Linux網(wǎng)絡(luò)驅(qū)動(dòng)程序的體系結(jié)構(gòu)和實(shí)現(xiàn)原理

  2.1 Linux網(wǎng)絡(luò)設(shè)備驅(qū)動(dòng)的體系結(jié)構(gòu)

  如圖1所示,Linux網(wǎng)絡(luò)驅(qū)動(dòng)程序的體系結(jié)構(gòu)可劃分為4個(gè)層次。Linux內(nèi)核源代碼中提供了網(wǎng)絡(luò)設(shè)備接口及以上層次的代碼,因此移植特定網(wǎng)絡(luò)硬件的驅(qū)動(dòng)程序的主要工作就是完成設(shè)備驅(qū)動(dòng)功能層的相應(yīng)代碼,根據(jù)底層具體的硬件特性,定義網(wǎng)絡(luò)設(shè)備接口struct net_device類型的結(jié)構(gòu)體變量,并實(shí)現(xiàn)其中相應(yīng)的操作函數(shù)及中斷處理程序。

  

  Linux中所有的網(wǎng)絡(luò)設(shè)備都抽象為一個(gè)統(tǒng)一的接口,即網(wǎng)絡(luò)設(shè)備接口,通過struct net_device類型的結(jié)構(gòu)體變量表示網(wǎng)絡(luò)設(shè)備在內(nèi)核中的運(yùn)行情況,這里既包括回環(huán)(loopback)設(shè)備,也包括硬件網(wǎng)絡(luò)設(shè)備接口。內(nèi)核通過以dev_base為頭指針的設(shè)備鏈表來管理所有的網(wǎng)絡(luò)設(shè)備。

  2.2 net_device 數(shù)據(jù)結(jié)構(gòu)

  struct net_device結(jié)構(gòu)體是整個(gè)網(wǎng)絡(luò)驅(qū)動(dòng)結(jié)構(gòu)的核心,其中定義了很多供網(wǎng)絡(luò)協(xié)議接口層調(diào)用設(shè)備的標(biāo)準(zhǔn)方法,該結(jié)構(gòu)在2.6內(nèi)核源碼樹文件中定義,下面只列出其中主要的成員。

  2.2.1全局信息及底層硬件信息

  name:網(wǎng)絡(luò)設(shè)備名稱,默認(rèn)是以太網(wǎng);

  *next:指向全局鏈表下一個(gè)設(shè)備的指針,驅(qū)動(dòng)程序中不修改;

  mem_,rmem_:發(fā)送和接收緩沖區(qū)的起始,結(jié)束位置;

  base_addr,irq:網(wǎng)絡(luò)設(shè)備的I/O基地址,中斷號,ifconfig命令可顯示和修改;

  hard_header_len:硬件頭的長度,以太網(wǎng)中值為14;

  mtu:最大傳輸單元,以太網(wǎng)中值為1500B;

  dev_addr[MAX_ADDR_LEN]:硬件(MAC)地址長度及設(shè)備硬件地址,以太網(wǎng)地址長度是48bit,ether_setup會(huì)對其進(jìn)行正確的設(shè)置;

  隨著人們對開放源代碼軟件熱情的日益增高,Linux作為一個(gè)功能強(qiáng)大而穩(wěn)定的開源操作系統(tǒng),越來越受到成千上萬的計(jì)算機(jī)專家和愛好者的青睞。在嵌入式領(lǐng)域,通過對Linux進(jìn)行小型化裁剪后,使其能夠固化在容量只有幾十兆字節(jié)的存儲(chǔ)器芯片或單片機(jī)中,成為應(yīng)用于特定場合的嵌入式Linux系統(tǒng)。Linux強(qiáng)大的網(wǎng)絡(luò)支持功能實(shí)現(xiàn)了對包括TCP/IP在內(nèi)的多種協(xié)議的支持,滿足了面向21世紀(jì)的嵌入式系統(tǒng)應(yīng)用聯(lián)網(wǎng)的需求。因此,在嵌入式系統(tǒng)開發(fā)調(diào)試時(shí),網(wǎng)絡(luò)接口幾乎成為不可或缺的模塊。

  1 嵌入式Linux網(wǎng)絡(luò)驅(qū)動(dòng)程序介紹

  Linux網(wǎng)絡(luò)驅(qū)動(dòng)程序作為Linux網(wǎng)絡(luò)子系統(tǒng)的一部分,位于TCP/IP網(wǎng)絡(luò)體系結(jié)構(gòu)的網(wǎng)絡(luò)接口層,主要實(shí)現(xiàn)上層協(xié)議棧與網(wǎng)絡(luò)設(shè)備的數(shù)據(jù)交換。Linux的網(wǎng)絡(luò)系統(tǒng)主要是基于BSD Unix的套接字(socket)機(jī)制,網(wǎng)絡(luò)設(shè)備與字符設(shè)備和塊設(shè)備不同,沒有對應(yīng)地映射到文件系統(tǒng)中的設(shè)備節(jié)點(diǎn)。

  通常,Linux驅(qū)動(dòng)程序有兩種加載方式:一種是靜態(tài)地編譯進(jìn)內(nèi)核,內(nèi)核啟動(dòng)時(shí)自動(dòng)加載;另一種是編寫為內(nèi)核模塊,使用insmod命令將模塊動(dòng)態(tài)加載到正在運(yùn)行的內(nèi)核,不需要時(shí)可用rmmod命令將模塊卸載。Linux 2.6內(nèi)核引入了kbuild機(jī)制,將外部內(nèi)核模塊的編譯同內(nèi)核源碼樹的編譯統(tǒng)一起來,大大簡化了特定的參數(shù)和宏的設(shè)置。這樣將編寫好的驅(qū)動(dòng)模塊加入內(nèi)核源碼樹,只需要修改相應(yīng)目錄的Kconfig文件,把新的驅(qū)動(dòng)加入內(nèi)核的配置菜單,然后需要修改相應(yīng)子目錄中與模塊編譯相關(guān)的Kbuild Makefile,即可使新的驅(qū)動(dòng)在內(nèi)核源碼樹中被編譯。在嵌入式系統(tǒng)驅(qū)動(dòng)開發(fā)時(shí),常常將驅(qū)動(dòng)程序編寫為內(nèi)核模塊,方便開發(fā)調(diào)試。調(diào)試完畢后,就可以將驅(qū)動(dòng)模塊編譯進(jìn)內(nèi)核,并重新編譯出支持特定物理設(shè)備的Linux內(nèi)核。

  2 嵌入式Linux網(wǎng)絡(luò)驅(qū)動(dòng)程序的體系結(jié)構(gòu)和實(shí)現(xiàn)原理

  2.1 Linux網(wǎng)絡(luò)設(shè)備驅(qū)動(dòng)的體系結(jié)構(gòu)

  如圖1所示,Linux網(wǎng)絡(luò)驅(qū)動(dòng)程序的體系結(jié)構(gòu)可劃分為4個(gè)層次。Linux內(nèi)核源代碼中提供了網(wǎng)絡(luò)設(shè)備接口及以上層次的代碼,因此移植特定網(wǎng)絡(luò)硬件的驅(qū)動(dòng)程序的主要工作就是完成設(shè)備驅(qū)動(dòng)功能層的相應(yīng)代碼,根據(jù)底層具體的硬件特性,定義網(wǎng)絡(luò)設(shè)備接口struct net_device類型的結(jié)構(gòu)體變量,并實(shí)現(xiàn)其中相應(yīng)的操作函數(shù)及中斷處理程序。

  

  Linux中所有的網(wǎng)絡(luò)設(shè)備都抽象為一個(gè)統(tǒng)一的接口,即網(wǎng)絡(luò)設(shè)備接口,通過struct net_device類型的結(jié)構(gòu)體變量表示網(wǎng)絡(luò)設(shè)備在內(nèi)核中的運(yùn)行情況,這里既包括回環(huán)(loopback)設(shè)備,也包括硬件網(wǎng)絡(luò)設(shè)備接口。內(nèi)核通過以dev_base為頭指針的設(shè)備鏈表來管理所有的網(wǎng)絡(luò)設(shè)備。

  2.2 net_device 數(shù)據(jù)結(jié)構(gòu)

  struct net_device結(jié)構(gòu)體是整個(gè)網(wǎng)絡(luò)驅(qū)動(dòng)結(jié)構(gòu)的核心,其中定義了很多供網(wǎng)絡(luò)協(xié)議接口層調(diào)用設(shè)備的標(biāo)準(zhǔn)方法,該結(jié)構(gòu)在2.6內(nèi)核源碼樹文件中定義,下面只列出其中主要的成員。

  2.2.1全局信息及底層硬件信息

  name:網(wǎng)絡(luò)設(shè)備名稱,默認(rèn)是以太網(wǎng);

  *next:指向全局鏈表下一個(gè)設(shè)備的指針,驅(qū)動(dòng)程序中不修改;

  mem_,rmem_:發(fā)送和接收緩沖區(qū)的起始,結(jié)束位置;

  base_addr,irq:網(wǎng)絡(luò)設(shè)備的I/O基地址,中斷號,ifconfig命令可顯示和修改;

  hard_header_len:硬件頭的長度,以太網(wǎng)中值為14;

  mtu:最大傳輸單元,以太網(wǎng)中值為1500B;

  dev_addr[MAX_ADDR_LEN]:硬件(MAC)地址長度及設(shè)備硬件地址,以太網(wǎng)地址長度是48bit,ether_setup會(huì)對其進(jìn)行正確的設(shè)置;

  2.2.2 主要的操作方法

  int (*init)(struct net_device *dev); 設(shè)備初始化和向系統(tǒng)注冊的函數(shù),僅調(diào)用一次;

  int (*open)(struct net_device *dev);設(shè)備打開接口函數(shù),當(dāng)用ifconfig激活網(wǎng)絡(luò)設(shè)備時(shí)被調(diào)用,注冊所用的系統(tǒng)資源(I/O端口,IRQ,DMA等)同時(shí)激活硬件并增加使用計(jì)數(shù);

  int (*stop)(struct net_device *dev);執(zhí)行open方法的反操作;

  *hard_start_xmit;初始化數(shù)據(jù)包傳輸?shù)暮瘮?shù);

  *hard_header;該函數(shù)(在hard_start_xmit前被調(diào)用)根據(jù)先前檢索到的源和目標(biāo)硬件地址建立硬件頭。 eth_header是以太網(wǎng)類型接口的默認(rèn)函數(shù);

  2.3網(wǎng)絡(luò)驅(qū)動(dòng)程序的編寫及實(shí)現(xiàn)原理

  Linux網(wǎng)絡(luò)系統(tǒng)各個(gè)層次之間的數(shù)據(jù)傳送都是通過套接字緩沖區(qū)sk_buff完成的,sk_buff數(shù)據(jù)結(jié)構(gòu)是各層協(xié)議數(shù)據(jù)處理的對象。sk_buff是驅(qū)動(dòng)程序與網(wǎng)絡(luò)之間交換數(shù)據(jù)的媒介,驅(qū)動(dòng)程序向網(wǎng)絡(luò)發(fā)送數(shù)據(jù)時(shí),必須從其中獲取數(shù)據(jù)源和數(shù)據(jù)長度;驅(qū)動(dòng)程序從網(wǎng)絡(luò)上接收到數(shù)據(jù)后也要將數(shù)據(jù)保存到sk_buff中才能交給上層協(xié)議處理。

  對于實(shí)際開發(fā)以太網(wǎng)驅(qū)動(dòng)程序,可以參照內(nèi)核源碼樹中的相應(yīng)模板程序,重點(diǎn)理解網(wǎng)絡(luò)驅(qū)動(dòng)的實(shí)現(xiàn)原理和程序的結(jié)構(gòu)框架,然后針對開發(fā)的特定硬件改寫代碼,實(shí)現(xiàn)相應(yīng)的操作函數(shù)。下面結(jié)合作者利用Linux2.6.18內(nèi)核在深圳優(yōu)龍公司的FS2410開發(fā)板(SAMSUNG S3C2410處理器)上移植編寫嵌入式CS8900A網(wǎng)卡驅(qū)動(dòng)程序的實(shí)例,說明網(wǎng)絡(luò)驅(qū)動(dòng)程序的實(shí)現(xiàn)原理。

  2.3.1網(wǎng)絡(luò)設(shè)備初始化

  網(wǎng)絡(luò)設(shè)備的初始化是由net_device結(jié)構(gòu)中的init函數(shù)實(shí)現(xiàn)的,內(nèi)核加載網(wǎng)絡(luò)驅(qū)動(dòng)模塊后,就會(huì)調(diào)用初始化過程。實(shí)例中初始化函數(shù)_init cs8900_probe中主要完成的工作:

  a.調(diào)用內(nèi)核中通用的設(shè)置以太網(wǎng)接口的函數(shù)ether_setup();

  b.填充net_device結(jié)構(gòu)體變量dev中其它大部分成員;

  c.調(diào)用check_mem_region()檢測I/O地址空間,然后調(diào)用request_mem_region()申請以dev-》base_addr為起始地址的16個(gè)連續(xù)的 I/O地址空間;

  d.通過cs8900_read()探測網(wǎng)卡CS8900A,讀取ID信息;

  e.設(shè)置CS8900A的INTRQ0作為中斷信號輸出引腳;

  f.將MAC地址寫入CS8900A的IA寄存器中;

  g.通過register_netdev()將CS8900A注冊到Linux全局網(wǎng)絡(luò)設(shè)備鏈表中;

  2.3.2打開(或關(guān)閉)網(wǎng)絡(luò)設(shè)備

  系統(tǒng)響應(yīng)ifconfig命令時(shí),打開(關(guān)閉)一個(gè)網(wǎng)絡(luò)接口。ifconfig命令開始會(huì)調(diào)用ioctl(SIOCSIFADDR)來將地址賦予接口。響應(yīng)SIOCSIFADDR由內(nèi)核來完成,與設(shè)備無關(guān)。接著,ifconfig命令會(huì)調(diào)用ioctl(SIOCSIFFLAGS)設(shè)置dev-》flag的IFF_UP位來打開設(shè)備,這個(gè)調(diào)用會(huì)使設(shè)備的open方法得到調(diào)用。(當(dāng)ifconfig調(diào)用ioctl(SIOCSIFFLAGS)清除dev-》flag的IFF_UP位時(shí),設(shè)備的stop方法將被調(diào)用)

  實(shí)例中利用cs8900_start()函數(shù)打開網(wǎng)絡(luò)設(shè)備,主要完成的工作:

  a.通過set_irq_type()向內(nèi)核注冊網(wǎng)絡(luò)設(shè)備的中斷處理程序;

  b.通過cs8900_set()設(shè)置CS8900A網(wǎng)卡中各控制寄存器和配置寄存器;

  c.通過內(nèi)核中netif_start_queue()函數(shù)開啟網(wǎng)絡(luò)接口的數(shù)據(jù)傳輸隊(duì)列;

  2.3.3網(wǎng)絡(luò)數(shù)據(jù)包的發(fā)送

  數(shù)據(jù)包的發(fā)送和接收是網(wǎng)絡(luò)驅(qū)動(dòng)程序中實(shí)現(xiàn)的兩個(gè)最重要的任務(wù)。當(dāng)網(wǎng)絡(luò)設(shè)備被激活時(shí),net_device結(jié)構(gòu)中的open方法被調(diào)用,它負(fù)責(zé)打開設(shè)備并調(diào)用net_device結(jié)構(gòu)中的hard_header函數(shù)指針建立硬件幀頭信息。最后通過函數(shù)dev_queue_xmit()來調(diào)用net_device結(jié)構(gòu)中的hard_start_xmit方法把存放在sk_buff中的數(shù)據(jù)發(fā)送到網(wǎng)絡(luò)物理設(shè)備。如果發(fā)送成功,則在hard_start_xmit中釋放sk_buff并返回0;如果硬件設(shè)備忙暫時(shí)無法處理,則返回1。網(wǎng)絡(luò)硬件在發(fā)送完數(shù)據(jù)包后會(huì)產(chǎn)生中斷,把dev-》tbusy置0,通知系統(tǒng)可以再次發(fā)送。

  實(shí)例中,hard_start_xmit方法即為網(wǎng)絡(luò)設(shè)備數(shù)據(jù)發(fā)送函數(shù)cs8900_send_start(),該函數(shù)實(shí)現(xiàn)把數(shù)據(jù)發(fā)送到以太網(wǎng)上,由網(wǎng)絡(luò)協(xié)議接口層函數(shù)dev_queue_xmit()對其調(diào)用。cs8900_send_start()中主要完成的工作:

  a.發(fā)送數(shù)據(jù)前關(guān)閉中斷,中止網(wǎng)絡(luò)設(shè)備的數(shù)據(jù)傳輸隊(duì)列;

  b.向CS8900A寄存器TxCMD中寫入傳送數(shù)據(jù)命令控制字,向寄存器TxLength中寫入待發(fā)送數(shù)據(jù)幀長度;

  c.通過cs8900_read()反復(fù)讀取CS8900A總線狀態(tài)寄存器BusST信息,直到其已經(jīng)準(zhǔn)備好接收來自主機(jī)的數(shù)據(jù);

  d.調(diào)用cs8900_frame_write()將待發(fā)數(shù)據(jù)送入CS8900A的sk_buff中,硬件設(shè)備會(huì)將數(shù)據(jù)幀發(fā)送到以太網(wǎng)上;

  e.記錄數(shù)據(jù)幀的發(fā)送時(shí)刻,打開中斷,釋放sk_buff緩存,函數(shù)返回0;

  2.3.4網(wǎng)絡(luò)數(shù)據(jù)包的接收和中斷處理

  網(wǎng)絡(luò)設(shè)備是異步地接收外來的數(shù)據(jù)包并且主動(dòng)的“請求”將硬件獲得的數(shù)據(jù)包壓入內(nèi)核。網(wǎng)絡(luò)設(shè)備接收數(shù)據(jù)包是通過中斷實(shí)現(xiàn)的。對于網(wǎng)絡(luò)接口,接收到新數(shù)據(jù)包,發(fā)送完成或者報(bào)告錯(cuò)誤信息及連接狀態(tài)等都會(huì)觸發(fā)中斷,通常中斷處理程序通過檢測硬件狀態(tài)寄存器判斷是哪種情況。

  當(dāng)設(shè)備收到數(shù)據(jù)后會(huì)產(chǎn)生一個(gè)中斷,由硬件通知驅(qū)動(dòng)程序有數(shù)據(jù)包到達(dá)。在中斷處理程序中驅(qū)動(dòng)程序申請一塊sk_buff(一般定義為skb)緩沖區(qū),然后從硬件讀出數(shù)據(jù)放到申請好的緩沖區(qū)里,接下來填充sk_buff中的部分信息:包括接收到數(shù)據(jù)的設(shè)備結(jié)構(gòu)體指針填入skb-》dev;收到數(shù)據(jù)幀的類型填入skb-》protocol;把指針skb-》mac.raw指向硬件數(shù)據(jù)并丟棄硬件針頭(skb_pull);設(shè)置skb-》pkt_type,標(biāo)明鏈路層數(shù)據(jù)類型。最后調(diào)用協(xié)議接口層函數(shù)netif_rx() 把接收到的數(shù)據(jù)包傳輸?shù)骄W(wǎng)絡(luò)上層協(xié)議處理。這里,netif_rx()只是負(fù)責(zé)把數(shù)據(jù)放入工作隊(duì)列就返回,真正的處理是在中斷返回以后,這樣可減少中斷處理的時(shí)間。幾乎每個(gè)中斷處理程序的編寫都要涉及底半部機(jī)制,這樣可以保證中斷的高效處理。

  實(shí)例中數(shù)據(jù)接收函數(shù)cs8900_receive()由網(wǎng)絡(luò)驅(qū)動(dòng)的中斷處理函數(shù)調(diào)用,主要完成如下工作:

  a.通過從I/O口讀取RxStatus和RxLength的值,確定接收數(shù)據(jù)幀的狀態(tài)信息和長度;

  b.判斷接收數(shù)據(jù)幀的狀態(tài)是否正常,若異常則記錄相關(guān)錯(cuò)誤信息,然后函數(shù)返回;

  c.正常情況下,在內(nèi)存中申請一塊sk_buff緩存,并將數(shù)據(jù)從CS8900A的片內(nèi)存儲(chǔ)器傳送到sk_buff緩存中;d.從數(shù)據(jù)幀中獲取協(xié)議頭并賦給skb-》protocol;

  e.通過調(diào)用netif_rx()函數(shù)將接收到的數(shù)據(jù)送往上層協(xié)議棧進(jìn)行處理;

  f.記錄接收數(shù)據(jù)的時(shí)間并更新統(tǒng)計(jì)信息;

  3將設(shè)備驅(qū)動(dòng)模塊編譯進(jìn)內(nèi)核

  設(shè)計(jì)好模塊化的網(wǎng)絡(luò)驅(qū)動(dòng)程序后,我們就可以編譯這個(gè)內(nèi)核模塊,并將這個(gè)自定義的內(nèi)核模塊作為Linux系統(tǒng)源碼的一部分編譯出新的系統(tǒng)。下面介紹的內(nèi)容均在Linux2.6.18內(nèi)核上編譯通過,可以在2.6.x版本內(nèi)核中通用。如前所述,由于Linux2.6內(nèi)核引入了kbuild的新機(jī)制,使得編譯新的內(nèi)核模塊或者將自己編寫的內(nèi)核模塊集成到內(nèi)核源碼中都變得非常簡單了。

  Linux2.6內(nèi)核中,編譯內(nèi)核模塊首先要在/usr/src下正確配置和構(gòu)造內(nèi)核源碼樹,即把需要版本的內(nèi)核源碼解壓在/usr/src/,并在內(nèi)核源碼的主目錄下(這里為/usr/src/linux-2.6.18.3),使用make menuconfig或者make gconfig命令配置內(nèi)核,然后使用make all完整編譯內(nèi)核。

  下面以作者開發(fā)的CS8900A網(wǎng)卡驅(qū)動(dòng)為實(shí)例,介紹如何將網(wǎng)絡(luò)設(shè)備驅(qū)動(dòng)模塊編譯進(jìn)內(nèi)核。

  a.在系統(tǒng)源碼樹drivers目錄下創(chuàng)建新目錄Cs8900;

  b.將編寫好的文件cs8900.c和cs8900.h拷貝到drivers/Cs8900目錄下;

  c.在drivers/Cs8900目錄下,編寫Makefile文件:

 ?。akefile for CS8900A Network Driver

  obj -$(CONFIG_DRIVER_CS8900A) +=cs8900.o

  d.在drivers/Cs8900目錄下,編寫Kconfig文件:

 ?。ust for CS8900A Network Interface

  menu “CS8900A Network Interface support”

  config DRIVER_CS8900A

  tristate “CS8900A support”

  --------help--------

  This is a network driver module for CS8900A.

  endmenu

  e.在driver目錄下的Kconfig文件endmenu語句前,加入一行:

  source “drivers/Cs8900/Kconfig”

  這樣在內(nèi)核源碼樹的主目錄下,通過make menuconfig或者make gconfig命令就可以在Device Drivers選項(xiàng)的下面找到CS8900A Network Interface support選項(xiàng),并找到CS8900A support的選擇菜單,它有三種狀態(tài):未選中(不編譯)、選中(M)一編譯為模塊、選中(*)一編譯為新系統(tǒng)一部分。

  重新編譯內(nèi)核即可得到支持CS8900A網(wǎng)卡的內(nèi)核,然后將內(nèi)核下載到FS2410的開發(fā)板上,通過配置網(wǎng)絡(luò)參數(shù),就可以測試網(wǎng)卡驅(qū)動(dòng)程序的行為了。

  4 結(jié)束語

  在這個(gè)信息爆炸的時(shí)代,人們對于網(wǎng)絡(luò)的需求愈發(fā)強(qiáng)烈,越來越多的嵌入式設(shè)備都需要具有以太網(wǎng)的接入功能,因此開發(fā)網(wǎng)絡(luò)驅(qū)動(dòng)程序?qū)τ诤芏嗲度胧疆a(chǎn)品的研發(fā)至關(guān)重要。具體開發(fā)嵌入式Linux網(wǎng)絡(luò)驅(qū)動(dòng)程序時(shí),可以參照內(nèi)核中已經(jīng)支持的網(wǎng)絡(luò)驅(qū)動(dòng)源代碼,在重點(diǎn)理解Linux網(wǎng)絡(luò)驅(qū)動(dòng)實(shí)現(xiàn)原理的基礎(chǔ)上,按照模塊設(shè)計(jì)較為固定的開發(fā)模式,結(jié)合具體物理設(shè)備的硬件手冊,移植編寫需要的模塊化的網(wǎng)絡(luò)驅(qū)動(dòng)程序。

此內(nèi)容為AET網(wǎng)站原創(chuàng),未經(jīng)授權(quán)禁止轉(zhuǎn)載。
亚洲一区二区欧美_亚洲丝袜一区_99re亚洲国产精品_日韩亚洲一区二区
国产精品日本精品| 亚洲国产精品一区| 卡一卡二国产精品| 久久xxxx| 亚洲欧美视频一区二区三区| 亚洲视频www| 亚洲美女淫视频| 亚洲日本成人网| 亚洲国产精品悠悠久久琪琪| 久久国产精品色婷婷| 欧美一区二区播放| 亚洲欧美日韩精品久久奇米色影视| 日韩午夜电影av| 亚洲免费观看| 亚洲精品资源美女情侣酒店| 亚洲美女91| 99精品国产福利在线观看免费| 999在线观看精品免费不卡网站| 亚洲精品男同| 亚洲免费激情| 日韩一区二区电影网| 一本色道久久综合狠狠躁篇的优点| 亚洲美女免费精品视频在线观看| 亚洲美女av在线播放| 日韩一区二区高清| 一区二区三区蜜桃网| 一区二区三区精品视频| 亚洲一区二区三区乱码aⅴ| 亚洲在线中文字幕| 欧美亚洲色图校园春色| 欧美在线网址| 亚洲清纯自拍| 在线一区二区日韩| 亚洲欧美日韩在线综合| 欧美在线免费观看视频| 久久久久九九视频| 奶水喷射视频一区| 欧美日韩精品伦理作品在线免费观看| 欧美日韩蜜桃| 国产精品亚洲产品| 黑人巨大精品欧美一区二区小视频| 永久免费毛片在线播放不卡| 亚洲精品女人| 午夜激情一区| 91久久久久久| 亚洲一区二区三区中文字幕| 欧美在线观看视频在线| 美女亚洲精品| 欧美日韩精品免费观看| 国产精品一区二区久久国产| 国产一区二区三区四区| 亚洲欧洲精品天堂一级| 亚洲亚洲精品在线观看 | 国产欧美日韩精品a在线观看| 国产一区二区三区在线观看免费| 亚洲第一福利视频| 一本久道久久综合狠狠爱| 先锋影音一区二区三区| 亚洲欧洲日本一区二区三区| 亚洲综合成人婷婷小说| 久久五月天婷婷| 欧美日韩一区二区三区视频 | 国产精品99久久久久久有的能看| 久久国产加勒比精品无码| 一区二区三区 在线观看视频| 久久精品理论片| 欧美日韩国产小视频| 国产毛片一区二区| 亚洲黄色成人| 羞羞视频在线观看欧美| 99在线精品免费视频九九视| 久久久久久久激情视频| 欧美日韩免费| 在线播放中文一区| 午夜激情久久久| 在线视频一区观看| 久久午夜精品一区二区| 国产精品国产三级欧美二区| 亚洲电影第1页| 香蕉成人啪国产精品视频综合网| 一区二区三区精品视频在线观看| 毛片一区二区| 国产一区二区成人| 亚洲视频在线二区| 亚洲美女一区| 久热成人在线视频| 国产日产欧产精品推荐色| 日韩亚洲国产欧美| 亚洲人成亚洲人成在线观看| 久久精品一区蜜桃臀影院| 国产精品久久久久久户外露出| 最新中文字幕一区二区三区| 亚洲福利视频专区| 欧美在线视频免费| 国产精品黄页免费高清在线观看| 亚洲黄色小视频| 久久精品一区| 久久精品二区亚洲w码| 国产精品捆绑调教| 99精品国产热久久91蜜凸| 日韩一级欧洲| 欧美经典一区二区| 亚洲国产精品va在线看黑人动漫| 久久激情五月丁香伊人| 久久精品视频播放| 国产午夜亚洲精品理论片色戒| 亚洲午夜在线视频| 亚洲欧美国产一区二区三区| 欧美少妇一区二区| 99精品欧美一区二区三区综合在线| 亚洲裸体视频| 欧美精品v日韩精品v韩国精品v | 午夜精品久久| 国产精品人成在线观看免费| 日韩一区二区精品| 中文一区在线| 国产精品地址| 中文欧美字幕免费| 亚洲欧美久久| 国产精品外国| 亚洲欧美日韩一区二区| 欧美一区二区成人| 国产欧美日韩一区二区三区在线观看 | 亚洲午夜国产成人av电影男同| 日韩视频在线播放| 欧美噜噜久久久xxx| 亚洲欧洲日韩在线| 99亚洲一区二区| 欧美四级电影网站| 亚洲网站在线| 久久se精品一区精品二区| 国内一区二区在线视频观看| 久久精品国产99国产精品澳门| 免费一级欧美片在线播放| 亚洲国产婷婷综合在线精品 | 亚洲国产精品传媒在线观看| 久久综合给合久久狠狠狠97色69| 一区二区三区我不卡| 91久久国产综合久久| 欧美精品不卡| 一区二区三区欧美日韩| 午夜日韩福利| 国产综合第一页| 亚洲黄色三级| 欧美日韩日韩| 亚洲欧美日韩在线播放| 久久久久成人精品免费播放动漫| 在线观看日韩www视频免费| 99视频在线精品国自产拍免费观看| 国产精品成人国产乱一区| 亚洲资源在线观看| 久久在线视频| 99pao成人国产永久免费视频| 欧美在线日韩在线| 亚洲高清在线观看| 亚洲一区二区精品| 国产区精品视频| 亚洲激情黄色| 国产精品国产a| 久久精品99久久香蕉国产色戒| 欧美国产先锋| 亚洲伊人伊色伊影伊综合网| 久久影视三级福利片| 一本色道久久综合亚洲精品不| 久久精品国产免费| 亚洲精品欧美极品| 欧美一区二区| 亚洲欧洲一二三| 午夜精品久久| 亚洲激精日韩激精欧美精品| 亚洲欧美在线另类| 亚洲国产成人久久综合| 午夜精品久久久久久久男人的天堂 | 一区二区欧美日韩| 国产亚洲欧美一区在线观看| 亚洲精品视频免费| 国产精品视频免费一区| 亚洲第一在线| 国产精品mm| 亚洲国产电影| 国产精品毛片一区二区三区| 91久久精品国产91久久性色tv | 久久久高清一区二区三区| 亚洲欧洲免费视频| 久久精品国产综合精品| 日韩亚洲欧美综合| 麻豆精品视频在线观看| 亚洲一区二区三区乱码aⅴ| 欧美成人一区二区在线| 欧美亚洲一区三区| 欧美视频在线观看免费网址| 亚洲高清激情| 国产欧美日韩一区二区三区| 一区二区日本视频| 有码中文亚洲精品| 久久精品五月| 亚洲伊人观看| 欧美视频在线免费| 亚洲精品一二| 伊人成人在线|