0. 教程完整目录
- 00 - 嵌入式Linux系统中Bootloader的作用和基本运行原理
- 01 - 下载uboot源码并使用VSCode远程查看源码、编译uboot(2012.04.01版本)
- 02 - 详细探索uboot启动过程(基于S3C2410处理器)
- 03 - 初步移植uboot 2012.04到JZ2440(修改时钟,配置串口)
- 04 - 移植uboot 2012.04到JZ2440(支持Nor Flash读写)
- 05 - 移植uboot 2012.04到JZ2440(支持Nand Flash读写)
- 06 - 移植uboot 2012.04到JZ2440(支持DM9000C网卡)
- 07 - 移植uboot 2012.04到JZ2440(裁剪uboot大小)
- 08 - 移植uboot 2012.04到JZ2440(设置mtd分区表)
- 09 - 移植uboot 2012.04到JZ2440(设置默认环境变量参数)
- 10 - 移植uboot 2012.04到JZ2440(烧写Linux内核、烧写yaffs2文件系统)
- 11 - 移植uboot 2012.04到JZ2440(移植完成,制作uboot补丁)
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
编译通过,证明没有问题,将编译后的可执行文件下载到开发板中,查看输出信息:
6. 网卡功能测试
6.1. ping测试
首先设置网卡MAC地址和IP地址:
set ipaddr 192.168.0.106
set ethaddr 52:54:00:7c:df:b7
在此基础上进行 ping 局域网内主机测试:
ping 192.168.0.100
开发板所连接的路由器可以正常上网,接下来进行ping外网测试。
首先设置路由器的网关ip:
set gatewayip 192.168.0.1
然后ping一下我的服务器公网ip地址:
ping 122.51.89.94
只能ping ip地址,不能ping域名!
6.2. TFTP文件传输测试
uboot支持网络主要是为了进行TFTP文件传输,因为接下来uboot要启动内核,文件系统,而内核和文件系统的映像都比较大,如果使用串口接收文件或者USB接收文件比较慢,而网络可以瞬间迅速传输完成,非常方便。
TFTP全称 Trivial File Transfer Protocol,即简单文件传输协议,是TCP/IP协议族中的一个用来在客户机与服务器之间进行简单文件传输的协议,提供不复杂、开销不大的文件传输服务。端口号为69。
6.2.1 在Windows上建立Tftp服务器进行测试(局域网)
tftpf64工具在我的不限速下载站即可下载:
使用tftpd64工具在Windows上建立TFTP服务端,启动该软件之后就开启了Tftp服务,新建一个空文件夹tftp_root,作为服务端的根目录:
然后随便将Linux内核镜像文件放到文件夹tftp_root中:
在开发板的串口终端进行传输测试,首先设置Tftp服务器ip地址:
set serverip 192.168.0.100
然后使用Tftp命令get镜像文件:
tftp 30000000 uImage_4.3
接着,1806KB的内核文件,在几s之内就下载完成了,速度非常快:
之后,还可以使用uboot命令尝试启动刚刚下载的内核,看文件是否被正常下载:
bootm 30000000
可以看到内核被成功拉起,说明下载成功:
7. 烧写新方法
之前u-boot.bin文件都是通过下载器烧写的,太慢了,这里可以采用TFTP的方法烧写:
…… //使用tftp拉取u-boot.bin文件
protect off all
erase 0 3FFFF //u-boot.bin为217KB,所以擦除256KB即可
cp.b 30000000 0 40000 //从内存拷贝256KB数据
reset //复位开发板
甚至可以通过一行命令搞定:
protect off all;erase 0 3FFFF;cp.b 30000000 0 40000;
接收更多精彩文章及资源推送,欢迎订阅我的微信公众号:『mculover666』。