雖然Linux驅(qū)動程序應(yīng)該是和具體的硬件平臺分離的,但是為了更好的理解DM9000的驅(qū)動程序,這里還是結(jié)合一下Mini2440開發(fā)板,這樣也可以更好的體會如何實(shí)現(xiàn)驅(qū)動和平臺分離。
本文分成以下幾個部分:
一、Mini2440開發(fā)板上DM9000的電氣連接和Mach-mini2440.c文件的關(guān)系。
二、兩個重要的結(jié)構(gòu)體介紹:sk_buff和net_device
三、具體代碼分析
一、Mini2440開發(fā)板上DM9000的電氣連接和Mach-mini2440.c文件的關(guān)系
Mini2440開發(fā)板上DM9000與S3C2440的連接關(guān)系如下:
這個DM9000平臺設(shè)備作為眾多平臺設(shè)備中的一個在扳子初始化的時候就被添加到了總線上。代碼清單如下:
其中片選信號AEN使用了nGCS4,所以網(wǎng)卡的內(nèi)存區(qū)域在BANK4,也就是從地址0x20000000開始。DM9000的TXD[2:0]作為strap pin在電路圖中是空接的,所以IO base是300H。中斷使用了EINT7。這些內(nèi)容在Mach文件中有如下體現(xiàn):
#define S3C2410_CS4 (0x20000000)
#define MACH_MINI2440_DM9K_BASE (S3C2410_CS4 + 0x300)
static struct resource mini2440_dm9k_resource[] __initdata = {
[0] = {
.start = MACH_MINI2440_DM9K_BASE,
.end = MACH_MINI2440_DM9K_BASE + 3,
.flags = IORESOURCE_MEM
},
[1] = {
.start = MACH_MINI2440_DM9K_BASE + 4,
.end = MACH_MINI2440_DM9K_BASE + 7,
.flags = IORESOURCE_MEM
},
[2] = {
.start = IRQ_EINT7,
.end = IRQ_EINT7,
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
}
};
另外在Mach文件中還定義了DM9000平臺設(shè)備,設(shè)備名稱為“dm9000”,設(shè)備資源就是上面定義的IO和中斷資源。代碼清單如下:
static struct dm9000_plat_data mini2440_dm9k_pdata __initdata = {
.flags = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
};
static struct platform_device mini2440_device_eth __initdata = {
.name = "dm9000",
.id = -1,
.num_resources = ARRAY_SIZE(mini2440_dm9k_resource),
.resource = mini2440_dm9k_resource,
.dev = {
.platform_data = &mini2440_dm9k_pdata,
},
};
MACHINE_START(MINI2440, "MINI2440")
/* Maintainer: Michel Pollet .phys_io = S3C2410_PA_UART, .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, .boot_params = S3C2410_SDRAM_PA + 0x100, .map_io = mini2440_map_io, .init_machine = mini2440_init, /*初始化函數(shù)*/ .init_irq = s3c24xx_init_irq, .timer = &s3c24xx_timer, MACHINE_END static void __init mini2440_init(void) { ... ... platform_add_devices(mini2440_devices, ARRAY_SIZE(mini2440_devices)); ... ... } static struct platform_device *mini2440_devices[] __initdata = { &s3c_device_usb, &s3c_device_wdt, /* &s3c_device_adc,*/ /* ADC doesn't like living with touchscreen ! */ &s3c_device_i2c0, &s3c_device_rtc, &s3c_device_usbgadget, &mini2440_device_eth, /*dm9000是眾多平臺設(shè)備中的一個*/ &mini2440_led1, &mini2440_led2, &mini2440_led3, &mini2440_led4, &mini2440_button_device, &s3c_device_nand, &s3c_device_sdi, &s3c_device_iis, &mini2440_audio, /* &s3c_device_timer[0],*/ /* buzzer pwm, no API for it */ /* remaining devices are optional */ }; 二、兩個重要的結(jié)構(gòu)體簡單介紹:sk_buff和net_device *sk_buff 如果把網(wǎng)絡(luò)傳輸看成是運(yùn)送貨物的話,那么sk_buff就是這個“貨物”了,所有經(jīng)手這個貨物的人都要干點(diǎn)什么事兒,要么加個包裝,要么印個戳兒等等。收貨的時候就要拆掉這些包裝,得到我們需要的貨物(payload data)。沒有貨物你還運(yùn)輸什么呢?由此可見sk_buff的重要性了。關(guān)于sk_buff的詳細(xì)介紹和幾個操作它的函數(shù),參考:“l(fā)inux內(nèi)核sk_buff的結(jié)構(gòu)分析” http://www.linuxidc.com/Linux/2011-07/39163.htm,寫得非常明白了。贊一個~ *net_device 又是一個龐大的結(jié)構(gòu)體。好吧,我承認(rèn)我從來就沒有看全過這個結(jié)構(gòu)體。它在內(nèi)核中就是指代了一個網(wǎng)絡(luò)設(shè)備。驅(qū)動程序需要在探測的時候分配并初始化這個結(jié)構(gòu)體,然后使用register_netdev來注冊它,這樣就可以把操作硬件的函數(shù)與內(nèi)核掛接在一起。 三、具體代碼的分析 在順序分析之前先看三個結(jié)構(gòu)體變量和一個自定義的結(jié)構(gòu)體。 * dm9000_driver變量。是platform_driver結(jié)構(gòu)體變量,其中包含了重要的:驅(qū)動的名字(用來match)和幾個重要操作函數(shù)。 static struct platform_driver dm9000_driver = { .driver = { .name = "dm9000", .owner = THIS_MODULE, }, .probe = dm9000_probe, .remove = __devexit_p(dm9000_drv_remove), .suspend = dm9000_drv_suspend, .resume = dm9000_drv_resume, }; * dm9000_netdev_ops變量。是net_device_ops結(jié)構(gòu)體變量, 其中定義了操作net_device的重要函數(shù),我們在驅(qū)動程序中根據(jù)需要的操作要填充這些函數(shù)。代碼清單如下: static const struct net_device_ops dm9000_netdev_ops = { .ndo_open = dm9000_open, .ndo_stop = dm9000_stop, .ndo_start_xmit = dm9000_start_xmit, .ndo_tx_timeout = dm9000_timeout, .ndo_set_multicast_list = dm9000_hash_table, .ndo_do_ioctl = dm9000_ioctl, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = dm9000_poll_controller, #endif }; * dm9000_ethtool_ops變量。是ethtool_ops結(jié)構(gòu)體變量,為了支持ethtool,其中的函數(shù)主要是用于查詢和設(shè)置網(wǎng)卡參數(shù)(當(dāng)然也有的驅(qū)動程序可能不支持ethtool)。代碼清單如下: static const struct ethtool_ops dm9000_ethtool_ops = { .get_drvinfo = dm9000_get_drvinfo, .get_settings = dm9000_get_settings, .set_settings = dm9000_set_settings, .get_msglevel = dm9000_get_msglevel, .set_msglevel = dm9000_set_msglevel, .nway_reset = dm9000_nway_reset, .get_link = dm9000_get_link, .get_eeprom_len = dm9000_get_eeprom_len, .get_eeprom = dm9000_get_eeprom, .set_eeprom = dm9000_set_eeprom, }; *board_info結(jié)構(gòu)體。用來保存芯片相關(guān)的一些私有信息。具體在代碼中分析。下面是這個結(jié)構(gòu)體的清單。 /* Structure/enum declaration ------------------------------- */ typedef struct board_info { void __iomem *io_addr; /* Register I/O base address */ void __iomem *io_data; /* Data I/O address */ u16 irq; /* IRQ */ u16 tx_pkt_cnt; u16 queue_pkt_len; u16 queue_start_addr; u16 dbug_cnt; u8 io_mode; /* 0:word, 2:byte */ u8 phy_addr; u8 imr_all;
上一篇:mini2440 dm9000 網(wǎng)卡驅(qū)動詳解 (二)
下一篇:mini2440 dm9000 網(wǎng)卡驅(qū)動詳解 (三)
- 熱門資源推薦
- 熱門放大器推薦
設(shè)計(jì)資源 培訓(xùn) 開發(fā)板 精華推薦
- MC34072ADR2G 有源高 Q 陷波濾波器運(yùn)算放大器的典型應(yīng)用
- STM32L552ZE MCU的評估板
- 具有 AVP 的 LTC1736 電流模式控制示例
- LTC3458EUE 演示板,1MHz 同步升壓型 DC/DC 轉(zhuǎn)換器,Vin = 2V-6V,Vout = 7V,Iout = 200-800mA
- LTC2945HUD 雙電源監(jiān)視器的典型應(yīng)用,具有用于電流隔離的通用光電耦合器
- DC941A,演示電路采用 LTC2482、16 位高性能 DS 模數(shù)轉(zhuǎn)換器
- 使用 TC7116 模數(shù)轉(zhuǎn)換器和 1.2 外部帶隙基準(zhǔn)(VIN - 連接到公共端)的典型應(yīng)用
- 基于VNI8200XP-32的八通道高端驅(qū)動器
- 使用 ROHM Semiconductor 的 BD4730 的參考設(shè)計(jì)
- LTC2355-14 演示板、14 位、1 通道 3.5Msps SAR ADC
- 半導(dǎo)體關(guān)稅可能會使您的下一輛汽車更加昂貴
- 潮起!人形機(jī)器人成本的20%-30%——靈巧手,國產(chǎn)3大廠商正快速產(chǎn)業(yè)化!
- AB Dynamics發(fā)布用于無人駕駛測試的物體檢測系統(tǒng)
- AI重構(gòu)出行:高階輔助駕駛的破局之路
- 廣汽即將發(fā)布全新星源增程技術(shù)
- Yole表示,到2030年,數(shù)據(jù)中心芯片市場規(guī)模將達(dá)到5000億美元
- 綠色節(jié)能趨勢下的延時繼電器發(fā)展:低功耗設(shè)計(jì)與環(huán)保材料應(yīng)用
- 國內(nèi)車企在固態(tài)電池領(lǐng)域的挑戰(zhàn)和技術(shù)方案
- 資本熱捧 + 政策護(hù)航,2025 人形機(jī)器人能否叩開 “量產(chǎn)元年” 大門?
- 耐世特推出用于智能運(yùn)動控制的 MotionIQ?軟件套件