在上章-使內核支持燒寫yaffs2,裁剪內核並製作補丁了 本章,便開始移植以前2.6內核的驅動到3.4新內核 1.介紹 首先內核更新,有可能會重新定義新的巨集,去除以前的巨集,以前更改函數名等 所以移植驅動的過程如下: 1)編譯 2)解決錯誤 ->2.1)頭文件不對:去掉或改名 ->2.2)巨集不對:改名 ...
本章,便開始移植以前2.6內核的驅動到3.4新內核
1.介紹
首先內核更新,有可能會重新定義新的巨集,去除以前的巨集,以前更改函數名等
所以移植驅動的過程如下:
- 1)編譯
- 2)解決錯誤
- ->2.1)頭文件不對:去掉或改名
- ->2.2)巨集不對:改名使用新巨集
- ->2.3)有些函數沒有了:改名使用新函數
2.移植內核自帶的DM9000網卡驅動
machid=16a(mach-smdk2440.c)的內核下輸入ifconfig,發現該板卡的內核不支持DM9000,如下圖所示:
而在machid= 7cf(mach-mini2440.c)的內核下輸入ifconfig,卻能支持DM9000,如下圖所示:
2.1這是因為mach-mini2440.c單板文件里支持了內核自帶的DM9000網卡驅動
1)進入內核的驅動文件看看(位於drivers/net/ethernet/davicom/dm9000.c)
首先來看init入口函數,代碼如下:
static struct platform_driver dm9000_driver = { .driver = { .name = "dm9000", .owner = THIS_MODULE, .pm = &dm9000_drv_pm_ops, }, .probe = dm9000_probe, //.probe函數 .remove = __devexit_p(dm9000_drv_remove), }; static int __init dm9000_init(void) { printk(KERN_INFO "%s Ethernet Driver, V%s\n", CARDNAME, DRV_VERSION); return platform_driver_register(&dm9000_driver); //註冊平臺驅動 }
從上面代碼看到,內核會註冊一個"dm9000"平臺驅動,而再註冊個"dm9000"平臺設備時,內核便會調用上面的probe函數來註冊dm9000驅動.
2)然後再來看看mach-mini2440.c單板文件,是如何支持dm9000的,代碼如下:
static struct platform_device mini2440_device_eth = { .name = "dm9000", .id = -1, //id號,一個平臺驅動可以有多個平臺設備,-1表示只有一個平臺設備 .num_resources = ARRAY_SIZE(mini2440_dm9k_resource), .resource = mini2440_dm9k_resource, //資源,保存硬體相關 .dev = { .platform_data = &mini2440_dm9k_pdata, }, }; ... ... static struct platform_device *mini2440_devices[] __initdata = { &s3c_device_ohci, &s3c_device_wdt, &s3c_device_i2c0, &s3c_device_rtc, &s3c_device_usbgadget, &mini2440_device_eth //需要添加的DM9000平臺設備 ... ... }; ... ... static void __init mini2440_init(void) //init入口函數 { ... ... platform_add_devices(mini2440_devices, ARRAY_SIZE(mini2440_devices)); //註冊平臺設備 }
從上面代碼看到,由於mach-mini2440.c註冊了一個name為"dm9000"的平臺設備, 所以內核便會去匹配平臺驅動,從而支持DM9000.c(平臺設備一般保存的是硬體相關代碼,然後平臺驅動根據平臺設備的內容來註冊)
2.2然後參考上面平臺設備,修改mach-smdk2440.c(位於arch/arm/mach-s3c24xx/mach-smdk2440.c)
(使它也支持內核自帶的DM9000網卡驅動)
1)添加頭文件
#include <linux/dm9000.h>
2)添加全局變數:
#define MACH_SMDK2440_DM9K_BASE (S3C2410_CS4 + 0x300) static struct resource smdk2440_dm9k_resource[] = { [0] = { .start = MACH_SMDK2440_DM9K_BASE, .end = MACH_SMDK2440_DM9K_BASE + 3, .flags = IORESOURCE_MEM }, [1] = { .start = MACH_SMDK2440_DM9K_BASE + 4, .end = MACH_SMDK2440_DM9K_BASE + 7, .flags = IORESOURCE_MEM }, [2] = { .start = IRQ_EINT7, .end = IRQ_EINT7, .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, } }; /* * The DM9000 has no eeprom, and it's MAC address is set by * the bootloader before starting the kernel. */ static struct dm9000_plat_data SMDK2440_dm9k_pdata = { .flags = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM), }; static struct platform_device smdk2440_device_eth = { .name = "dm9000", .id = -1, .num_resources = ARRAY_SIZE(smdk2440_dm9k_resource), .resource = smdk2440_dm9k_resource, .dev = { .platform_data = &SMDK2440_dm9k_pdata, }, };
3)在smdk2440_devices[]數組下添加:
static struct platform_device *smdk2440_devices[] __initdata = { &s3c_device_ohci, &s3c_device_lcd, &s3c_device_wdt, &s3c_device_i2c0, &s3c_device_iis, &smdk2440_device_eth, //添加該句 };
2.3 然後編譯燒寫
在uboot下輸入:
nfs 30000000 192.168.2.106:/work/nfs_root/uImage //下載剛剛編譯好的uImage set machid 16a bootm 30000000
啟動內核後,便可以ping通,如下圖所示:
3.移植廠家提供的DM9000C驅動
3.1我們發現內核自帶的DM9000驅動版本只有1.31
如下圖所示(位於drivers/net/ethernet/davicom/dm9000.c):
而我們板子的網卡硬體比較新,已經是dm9000c了,所以我們去移植廠家提供的DM9000C驅動
在之前學習2.6內核的驅動時,我們便移植過了廠家提供的DM9000C驅動了,鏈接入口:http://www.cnblogs.com/lifexy/p/7777961.html
文件名為dm9dev9000c.c,由於2.6內核和3.4內核有很多不一樣的地方,所以編譯dm9dev9000c.c會出現很多錯誤,解決錯誤的具體辦法如下:
- 1)通過搜索,來閱讀錯誤的變數的用途,然後參考dm9000.c來修改dm9dev9000c.c
- 2)將只有定義而沒用到的錯誤變數,刪除掉
最終修改好的dm9dev9000c.c,鏈接入口:https://github.com/lifeyx/dm9000c
將修改好的dm9dev9000c.c也放在drivers/net/ethernet/davicom/目錄下
並修改Makefile:
#obj-$(CONFIG_DM9000) += dm9000.o
obj-$(CONFIG_DM9000) += dm9dev9000c.o
3.2編譯燒寫
1)啟動內核後,試驗,如下圖所示,可以ping通:
2)然後測試下使用nfs文件系統
在uboot設置bootargs參數:
set bootargs root=/dev/nfs console=ttySAC0,115200 nfsroot=192.168.2.106:/work/nfs_root/fs_mini_mdev_new ip=192.168.2.105:192.168.2.106:192.168.2.1:255.255.255.0::eth0:off
然後啟動nfs成功,如下圖所示:
未完待續,下章再來移植其它驅動~