weiqi7777

cortex-a8 uboot系列:第十七章 uboot移植-网卡DM9000移植

0
阅读(1938)

一、  网卡基础知识

1.     网卡芯片与开发板的连接方式

总线式连接方式,使用SROM总线接口。

clip_image002

开发板核心板,使用SROM控制器的bank1。因此有效地址是0x8800_0000 – 0xffff_ffff

clip_image004

开发板上DM9000的连接。使用16-bit数据连接方式

clip_image006

网卡芯片有CS引脚,(CS就是chip_select,选线信号,主机向CS发送有效信号则从机芯片工作,主机向CS发送无效信号则从机芯片不工作)。这个引脚要接socsrom控制器的片选引脚。

主机s5pv210srom控制器每一个bank都有一个片选信号CSnn=0-5),这里接CSn1,说明DM9000接的是srombank1

所以,可以得到DM9000的总线基地址是0x8800_0000

 

DM9000CMD引脚,并接到了210ADDR2引脚上。为低,表示16位数据线上发送的是地址,为高,表示16位数据线上发送的数据。因此,地址和数据是复用的。

也就是如果要往 DM9000 0x04地址写入数据a。那么要执行以下两步

第一步:

ADDR2拉低,16位数据写0x04

也就是  *0x8800_0000 = 0x04

第二步:

ADDR2拉高,16位数据写a

也就是 *0x8800_0004 = a

 

DM9000的通过HR911105A接口与外部网线相连。

clip_image008

网线有8根线,但是实际只有4根有效通信线,另外4根都是GND,用来抗干扰的。4根通信线中管发送的是有2根(TX-TX+),管接收的2根(RX+RX-),因为网上传输的是差分信号。

210SROM控制器,

clip_image010

2.      SocSROM控制器

Bank和网卡芯片的CS引脚(SROM就是SRAM/ROM)。Socsrom控制器其实就是soc提供的对外总线式连接sram/rom的接口。如果soc要外部外接一些sram/rom类的存储芯片(或者伪装成srom接口的芯片,如网卡芯片)就要通过srom控制器来连接。

SROM控制器有6bank,地址和数据都是共有的,但是片选信号不是共用的。因此外部的SROM器件通过连接到自己的片选信号是否有效,从而决定地址和数据是否可用。

网卡接在srom中好处就是网卡芯片好像一个存储芯片一样,被扩展在soc的一个地址空间中,这样soc就可以直接用一个地址来访问网卡芯片的内部寄存器。

clip_image012

1)       网卡芯片内部寄存器使用相对地址访问

网卡芯片内部很多寄存器有一个地址,这个地址是从0x00开始的,但是实际上soc不能用0地址去访问这个网卡的芯片的内部寄存器。

所以soc访问网卡芯片0地址寄存器的地址应该是:起始地址 + 0x00。其中起始地址就是网卡芯片对应接在srom控制器的bankn对应的基地址。

如使用的九鼎开发板,网卡芯片接在bank0,基地址就是0x8000_0000。那么soc使用0x8000_0000访问网卡芯片的0地址寄存器,使用0x8000_0004访问4地址的寄存器。

2)       主机soc上网

其实就是操控网卡芯片内部的寄存器、缓冲区等资源来上网的。也就是soc是通过网卡芯片来间接上网的。

3)       总结

实际上也是一种总线式连接方式。优势是soc内部不需要内置网卡控制器,所有的SFR全都在外部网卡芯片中,而且还可以通过地址直接访问(IO与内存统一编址),不用像NAND/SD接口一样使用时序来访问。

从逻辑上看,网卡更像是soc内部串口等模块。

二、  Uboot中驱动文件

drivers/net目录下,有很多网卡驱动芯片,对于开发板使用的是DM9000,所以要查看dm9000.hdm9000.c。这些驱动代码来自于linux kernel源代码。

这个驱动代码是linux内核中设计好的,因此不用修改,在uboot中可以直接使用的。而且因为linux驱动设计的很合理(数据和代码是分开的,这样驱动主要是代码,数据是由硬件开发板中的接法决定,数据由一定的数据结构提供),所以驱动本身具有可移植性。

 

网卡移植的关键:初始化

Uboot在第二阶段init_sequences中进行了一系列的初始化,其中就有网卡芯片的初始化。这个初始化是关键,在这里的初始化中只要将网卡芯片正确的初始化了,则网卡芯片就能正常工作。

board/Samsung/smdkc110/smdkc110.c中的board_init函数,就对dm9000进行了初始化。

clip_image014

clip_image016

被注释掉的是三星提供的uboot中的代码,后面新增的是修改的代码。在三星原版中,使用的是SROMbank5,但是开发板使用的是bank1,因此要对SROM控制器的bank1进行初始化。

SROM_BW设置SROM控制器的总配置。每4个位控制一个bank,对于使用的bank1,操作7-4位。因此要对这几位进行操作。

clip_image018

网卡工作在16-bit模式,所以  DataWidth11

原理图连接时,srom控制器的数据data15-0接到网卡的data15-0,所以是以字节对齐的,所以AddrMode1 1

至于第7位和第6位,和时序相关。这里都设置为1

SROM_BCx, 设置各个bank的时序信息。

clip_image020

MP0_1CON寄存器,配置SROM控制器的GPIO的片选功能。将7-4位设置为0x20,表示MP01_1管脚为srombank1的片选引脚。

clip_image022

照理来说,还需要设定SROM控制器的地址和数据的GPIO的功能,但是对应的GPIO功能默认为就是SROM的地址和数据功能,因此可以不用设置。

clip_image024

基地址的配置

smdkv210single.h中,关于DM9000有如下的宏定义。

clip_image026

表示基地址是0XA800_0000(因为使用的是bank5),CMD线接在了ADDR1

根据所用开发板,修改为如下

clip_image028

基地址为0x8800_0000bank1),CMD线接在了ADDR2,所以数据的地址是基地址+4

 

但是上面这样,是不工作的。

需要将CONFIG_DM9000_BASE 定义为 0x88000300

clip_image030

修改为88000300的原因,应该是和DM9000的芯片有关系,内部寄存器的偏移不是以0地址作为偏移,而是以0x300地址为偏移的。

 

Uboot中使用ping命令,测试网卡移植是否成功。

clip_image032

 

如果移植出现以下信息,说明SROM控制器的寄存器配置不正确。检查dm9000_pre_init函数(board/Samsung/smdkc110/smdkc110.c),寄存器设置是否正确。

clip_image034

 

三、  Linux网卡驱动的典型工作方式

linux系统中,网卡是一个设备,这个设备驱动工作后会生成一个设备名叫ethn(n012……),无线网卡名字一般叫wlan0wlan1……。

然后linux系统用一些专用命令来操作网卡,如ifconfig命令。

Linux下的应用程序如何使用网卡驱动来进行网络通信?最通用的方法就是socket借口。Linux系统中有一系列的API和库函数,提供了一个socket编程接口,linux下的应用程序都是通过socket来实现上网的,socket内部就是间接调用网卡驱动实现网络通信的。

Linux设计是非常完备的,应用层和驱动层是严格分离的。也就是说写网络编程应用层的人根本不用管驱动,只要会用socket接口即可;写底层驱动的人根本不用管应用层,只要面向linux的网络驱动框架模型即可。

Ping这样的命令实现的代码就是网络应用的应用程序,像dm9000.hdm9000.c这样的代码属于驱动程序。在uboot中应用是直接调用驱动实现的,也就是说ping命令内部是直接调用了dm9000的网卡驱动中的函数来实现。

1.    Ubootping命令实现

实现函数是do_ping,在common/cmd_net.c中。

clip_image036

使用string_to_ip函数将输入的ip地址转化为IPaddr_t类型值。

clip_image038

然后调用NetLoop函数(net\net.c中)

函数前面的部分,都是在构建ping的包。

构建好后,使用PingStart函数(net\net.c),准备发送ping包。

clip_image040

 

最后调用PingSend函数(net\net.c),将包发出去。

clip_image042

前面在构建数据,最后使用ArpRequest函数(net\net.c),将ARP包发送。因为ping使用的是ARP包。

clip_image044

函数在之前也在做数据的处理,最后调用eth_send函数(drivers/net/dm9000x.c中),将数据包发送出去。可以看出,这个函数是和具体的网卡芯片有关的。

clip_image046

这个函数,将指定的包,发送给DM9000网卡,网卡在将该包发送到网络中。

clip_image048

 

这样,就完成了pingARP包的发送。

剩下,就是要接收从网络回发的ARP包。

net_loop函数的后面,调用eth_rx函数(drivers/net/dm9000x.c中)对网络数据包进行接收。可以看出这个接收函数和具体网卡有关的。

clip_image050

四、  启动内核

使用tftp命令,将镜像下载到内存中,然后使用bootm命令运行内核。

但是要将串口改为串口2

而且启动参数设置要如下:

bootargs=console=ttySAC2,115200 root=/dev/mmcblk0p2 rw init=/linuxrc rootfstype=3

bootcmd=movi read kernel 30008000; movi read rootfs 30b00000 30000; bootm 30008000 30b00000

smdkv210single.h中要保证有如下宏,这样uboot才能给linux传递参数。启动内核才能成功。

clip_image051