1. JZ2440开发板上的网卡
JZ2440开发板板载DM9000C网卡,原理图如图:
2. 添加uboot中已有的驱动文件到工程中
2.1. 添加宏定义
uboot自带的驱动文件夹中已经包含有DM9000的文件:
- drivers/net/dm9000x.c
- drivers/net/dm9000x.h
接下来查看此目录(net目录)下的makefile文件,将DM9000的这两个文件加入工程:
从makefille中可以看到,只需要配置 CONFIG_DRIVER_DM9000 这个宏定义,dm9000的相关文件就会被加入到工程。
根据经验,需要配置的肯定不止一个宏定义这么简单,全局搜索一下此宏定义,参考别的单板文件,比如:
果然,除了 CONFIG_DRIVER_DM9000 宏定义之外,还有三个地址相关的配置宏定义。
仿照这个配置,在自己的单板配置文件中添加include/configs/smdk2440.h
,并将原有CS8900网卡驱动的配置去掉:
2.2. 修改宏定义
三个地址相关宏定义是参考别的单板配置复制过来的,肯定不能用,查看S3C2440芯片手册和原理图,确定这三个地址。
首先是基地址CONFIG_DM9000_BASE
,在原理图中可以看到DM9000是接在内存控制器上的BANK4上的,由nGCS4控制,进而在S3C2440芯片手册查找BANK4对应的基地址为0x20000000
:
DM9000_IO默认配置的是基地址CONFIG_DM9000_BASE,不用修改。
DM9000的地址线和数据线是分离的,但是数据线上可以传输命令或者数据,需要使用信号线CMD区分,查看原理图,方便起见将 LADDR2 信号线接到 CMD 引脚上,当作控制信号来用。
所以当发出的地址中 bit2 为0时,表示数据线上传输的命令,当发出地址中 bit 2 为1时,表示传输的是数据,DM9000_DATA宏定义就表示发数据时地址应该有什么变化,将bit 2置为1即可:
#define DM9000_DATA (CONFIG_DM9000_BASE + 4)
综合以上修改,最后修改结果如图:
这个时候编译没有问题,但是运行的结果还是会出现net 网卡找不到的日志,接着进行修改。
3. 设置内存控制器
根据原理图,网卡DM9000是接到内存控制器的BANK4的,所以需要设置内存控制器中BANK4的位宽参数和时序参数。
3.1. 内存控制器BANK4的设置
通过内存控制器的 BWSCON 寄存器来设置数据总线位宽:
其中BANK位宽设置如下:
通过内存控制器的 BANKCON4 来设置 BANK4 的时序参数:
根据DM9000的时序性能,此寄存器的值可以设置为0x00000740
。
3.2. 在uboot中修改内存控制器的设置
在之前分析SDRAM移植的时候已经详细分析了内存控制器的设置位置,这里不再赘述。
内存控制器设置在board/samsung/smdk2440/lowlevel_init.S
文件中的 lowlevel_init 函数中,接下来开始修改。
B4_BWSCON寄存器的设置是DW16,和DM9000一致,不用修改:
时序参数宏定义中只需要修改一处即可:
设置完成。
编译之后,结果还是不符合预期,提示找不到网卡,根据启动过程进行错误分析。
4. 修改初始化函数
在uboot启动的第二阶段board_init_r函数中,网卡初始化调用的是eth_initialize
函数:
eth_initialize 函数在net/eth.c
文件中,其中又调用了 board_eth_init 函数:
board_eth_init 函数在board/samsung/smdk2440/smdk2410.c
文件中,实现如下:
可以看到,当定义CONFIG_CS8900时,会调用其初始化函数,但是此处我们定义的是DM9000,所以无任何操作。
修改此函数实现:
编译,下载到开发板中,在串口终端中查看结果:
5. 优化
在这里发现一个不影响功能的小问题,顺手优化一下,在smdk2440文件夹下,smdk2410.c文件名没有修改:
修改文件名为smdk2440.c:
然后修改此目录下的makefile,将smdk2440.c文件加入工程:
重新编译:
make distclean
make smdk2440_config
make
编译通过,证明没有问题,将编译后的可执行文件下载到开发板中,查看输出信息: