| 導購 | 订阅 | 在线投稿
分享
 
 
 

Linux kernel2.6.25 CS8900網卡驅動移植

來源:互聯網  2008-06-01 03:25:38  評論

一般來說,我們在編譯kernel時,設備驅動的選擇有兩種方式:一種是直接編譯到kernel裏,另一種是以模塊方式挂接。CS8900網卡驅動如果以模塊方式挂接,函數init_module就是入口;如果是直接編譯到kernel裏,那麽函數cs89x0_probe才是入口。在此入口函數中,將完成網卡驅動的各項初始化。如注冊虛擬地址,設備號,中斷號,以及各個相關寄存器的初始化。

cs89x0_probe函數裏會去調用真正的初始化函數cs89x0_probe1。下面說一下該初始化函數裏需要完成的幾個重要地方:

1、 注冊虛擬地址。

通過request_region函數注冊虛擬地址。在kenel裏面,我們所操作的寄存器的地址其實都是虛擬地址,但是每一個寄存器的虛擬地址都有唯一和其對應的物理地址,因爲在kernel裏面任何虛擬地址都會通過MMU轉化成物理地址。所以在kernel裏,定義完所要用到的寄存器後,都必須使用一個函數ioremap將我們所要用到的寄存器的物理地址轉換成爲在kernel裏可以操作的虛擬地址,然後才能將他們用以具體的操作,否則一切都是徒勞。

ioaddr = (int)ioremap(BASE_ADDR,16);

2、填充net_device結構體。

該結構體的成員都是和網絡設備有關的變量。其中比較重要的有兩個:dev_addr和open。dev_addr裏要存的是主機的MAC地址,一般都是從eeproom中讀出來再存放到該變量中,當然也可以根據自己的需要手動賦值。

for (i=0; i < ETH_ALEN/2; i++) {

unsigned int Addr;

Addr = readreg(dev, PP_IA+i*2);

dev->dev_addr[i*2] = Addr & 0xFF;

dev->dev_addr[i*2+1] = Addr >> 8;

}

Open是一個函數指針,需要把net_open函數賦值給他。net_open函數是一個專門用來注冊網絡設備中斷號的函數,輸入ifconfig命令時,最後就會調用到這個函數。在這個函數中要把中斷號設置一下。

writereg(dev, PP_BusCTL, ENABLE_IRQ | MEMORY_ON);

request_irq(dev->irq, &net_interrupt, 0, dev->name, dev);

3、 I/O端口的中斷請求設置。

網卡不可能也不需要時時刻刻都處于中斷狀態,合理的中斷觸發時機是一個必要條件。根據硬件電路圖的引腳可知,相對應的中斷請求寄存器是GPG1和EINT9。在GPG1寄存器裏面要把EINT9寄存器功能激活,而在EINT9寄存器裏面則要把中斷設置爲上跳沿觸發。

writel(readl(S 3C2410_GPGCON) | 0x8, S3C2410_GPGCON);

writel(readl(S3C2410_EXTINT1) | 0x40, S3C2410_EXTINT1);

還有一點要注意,CS8900網卡的寄存器都是16位的,所以在選擇讀寫函數時也必須選擇16位寄存器的讀寫函數。

static u16 readword(unsigned long base_addr, int portno)

{

return inw(base_addr + portno);

}

static void writeword(unsigned long base_addr, int portno, u16 value)

{

outw(value, base_addr + portno);

}

以上便是Linux kernel2.6.25 CS8900網卡驅動移植所需注意的內容。Kernel裏面涉及和兼容的東西非常多,去除容易産生沖突的部分,添加自己需要實現的功能,可以使得移植工作能夠順利進行。

一般來說,我們在編譯kernel時,設備驅動的選擇有兩種方式:一種是直接編譯到kernel裏,另一種是以模塊方式挂接。CS8900網卡驅動如果以模塊方式挂接,函數init_module就是入口;如果是直接編譯到kernel裏,那麽函數cs89x0_probe才是入口。在此入口函數中,將完成網卡驅動的各項初始化。如注冊虛擬地址,設備號,中斷號,以及各個相關寄存器的初始化。 cs89x0_probe函數裏會去調用真正的初始化函數cs89x0_probe1。下面說一下該初始化函數裏需要完成的幾個重要地方: 1、 注冊虛擬地址。 通過request_region函數注冊虛擬地址。在kenel裏面,我們所操作的寄存器的地址其實都是虛擬地址,但是每一個寄存器的虛擬地址都有唯一和其對應的物理地址,因爲在kernel裏面任何虛擬地址都會通過MMU轉化成物理地址。所以在kernel裏,定義完所要用到的寄存器後,都必須使用一個函數ioremap將我們所要用到的寄存器的物理地址轉換成爲在kernel裏可以操作的虛擬地址,然後才能將他們用以具體的操作,否則一切都是徒勞。 ioaddr = (int)ioremap(BASE_ADDR,16); 2、填充net_device結構體。 該結構體的成員都是和網絡設備有關的變量。其中比較重要的有兩個:dev_addr和open。dev_addr裏要存的是主機的MAC地址,一般都是從eeproom中讀出來再存放到該變量中,當然也可以根據自己的需要手動賦值。 for (i=0; i < ETH_ALEN/2; i++) {   unsigned int Addr;   Addr = readreg(dev, PP_IA+i*2);   dev->dev_addr[i*2] = Addr & 0xFF;   dev->dev_addr[i*2+1] = Addr >> 8; } Open是一個函數指針,需要把net_open函數賦值給他。net_open函數是一個專門用來注冊網絡設備中斷號的函數,輸入ifconfig命令時,最後就會調用到這個函數。在這個函數中要把中斷號設置一下。 writereg(dev, PP_BusCTL, ENABLE_IRQ | MEMORY_ON); request_irq(dev->irq, &net_interrupt, 0, dev->name, dev); 3、 I/O端口的中斷請求設置。 網卡不可能也不需要時時刻刻都處于中斷狀態,合理的中斷觸發時機是一個必要條件。根據硬件電路圖的引腳可知,相對應的中斷請求寄存器是GPG1和EINT9。在GPG1寄存器裏面要把EINT9寄存器功能激活,而在EINT9寄存器裏面則要把中斷設置爲上跳沿觸發。 writel(readl(S 3C2410_GPGCON) | 0x8, S3C2410_GPGCON); writel(readl(S3C2410_EXTINT1) | 0x40, S3C2410_EXTINT1); 還有一點要注意,CS8900網卡的寄存器都是16位的,所以在選擇讀寫函數時也必須選擇16位寄存器的讀寫函數。 static u16 readword(unsigned long base_addr, int portno) {   return inw(base_addr + portno);   }   static void writeword(unsigned long base_addr, int portno, u16 value) {   outw(value, base_addr + portno); } 以上便是Linux kernel2.6.25 CS8900網卡驅動移植所需注意的內容。Kernel裏面涉及和兼容的東西非常多,去除容易産生沖突的部分,添加自己需要實現的功能,可以使得移植工作能夠順利進行。
󰈣󰈤
王朝萬家燈火計劃
期待原創作者加盟
 
 
 
>>返回首頁<<
 
 
 
 
 熱帖排行
 
 
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有