uClinux下移植Ne2000兼容的网卡驱动程序
2012-06-02

我是linux的新手,可以说从来没有在linux下写过程序,对于linux内核也是相当陌生,前一段时间,拿着tpu一个移植好了的uClinux在S3C44B0(ARM7TDMI核的嵌入式处理器)上的版本,把它成功的跑在了我自己的S3C44B0的板子上,这也就算是平生在uClinux下作的第一个工作吧。接下来就是添加网卡驱动,我用的是RTL8019AS--比较常用的ISA接口的以太网芯片。下面就从一个新手的角度来说说我的移植过程吧,其实很简单,我的整个摸索+移植的过程也就花了2天的时间,我尽量写的详细(罗嗦?)一点,希望对像我这样的新手入门有所帮助,错误之处在所难免,欢迎指正。

开始的时候,我也是摸不着头脑,不知道该从什么地方入手。用SoureInsight把整个uClinux内核的源码都添加进来,熟悉一下linux的内核(其实就是在里面瞎撞,也不怎么能看懂)。按照linux内核目录的分类,很自然的就找到Ne2000网卡的驱动就是./drivers/net/ne.c,和它相关的还有8390.h和8390.c。看看代码,逐渐的就明白了:

首先,在Ne.c中函数ne_probe就是网卡的检测函数,如果检测到Ne2000兼容的网卡就return 0。那个函数没有什么具体的工作,就是搭了一个架子。看的有前人在这个函数开始写到:

#if defined (CONFIG_NETtel) && defined (CONFIG_M5307)

…………

#elif defined(CONFIG_COLDFIRE)

static int once = 0;

if (once)

return -ENXIO;

if (base_addr == 0) {

dev->base_addr = base_addr = NE2000_ADDR;

dev->irq = NE2000_IRQ_VECTOR;

once++;

}

#endif

就明白了,可以把网卡的基地址、中断号都放到这里面定义。我也跟着照葫芦画瓢,添

加了一个:

#elif defined(CONFIG_ARCH_S3C44B0) //--by threewater

static int once = 0;

if (once)

return -ENXIO;

if (base_addr == 0) {

dev->base_addr = base_addr = ARM_NE2000_BASE;

dev->irq = ARM_NE2000_IRQ;

once++;

}

其中:ARM_NE2000_BASE和ARM_NE2000_IRQ是在配置内核的时候定义的,这个以后再说。

接下来,具体的工作就转移到了ne_probe1函数里面做。用SourceInight跟进来看(这个软件太好用了,忍不住在这里再坐一会广告)。Ne_probe1中,一开始就是

reg0 = inb_p(ioaddr);

if (reg0 == 0xFF) {

ret = -ENODEV;

goto err_out;

}

很容易理解,就是读一下网卡的基地址,对我来说也就是RTL8019的REG0,如果是0xff,说明没有检测到网卡,返回错误。好了,在下面添加一行

printk("begin find Ne2000 Net Card...\tbase address=0x%X\n",ioaddr);

//--add by threewater

来证明我们的想法是正确的,程序如果能读取8019的REG0,就应该显示出这一行。可是,那个ne_probe是谁调用的呢?还是用SourceInsight去找,用jamp to caller,哈哈,太容易了,立刻就看到了,网卡的检测是从./drivers/net/Space.c的ethif_probe函数

中实现的,关键代码:

if (probe_list(dev, eisa_probes) == 0)

return 0;

eisa_probes在前面定义成全局:

static struct devprobe eisa_probes[] __initdata = {

#ifdef CONFIG_DE4X5 /* DEC DE425, DE434, DE435 adapters */

{de4x5_probe, 0},

#endif

…………

{NULL, 0},

};

我也照着添加了:

if (probe_list(dev, arm_probes) == 0)

return 0;

并定义:

static struct devprobe arm_probes[] __initdata = {

#ifdef CONFIG_ARM

{ne_probe, 0},

#endif

{NULL, 0},

};

这样,编译内核启动,果然,显示出了输出结果。

共 3 页   123下一页
可能会用到的工具/仪表
本站简介 | 意见建议 | 免责声明 | 版权声明 | 联系我们
CopyRight@2024-2039 嵌入式资源网
蜀ICP备2021025729号