官方标准uboot2013移植10之环境变量和网卡的移植

1.iNand分区表检查-env究竟应该放在哪

1)测试环境变量是否可以保存,通过开机set设置环境变量然后save,然后关机后重启来测试环境变量的保存是否成功。

2)我们的环境变量究竟保存到哪里去了?这个就要去分析代码中的分区表。

3)环境变量应该被放在哪里?虽然无法确定ENV一定要放在哪里,但是有一些地方肯定是不能放的,否则将来会出问题。原则是同一个SD卡扇区只能放一种东西,不能叠加,否则就会被覆盖掉。uboot烧录时使用的扇区数是:SD2的扇区1-16和49-x(x-49大于等于uboot的大小)

4)从uboot的烧录情况来看,SD2的扇区0空闲,扇区1-16被uboot的BL1占用,扇区17-48空闲,扇区49-x被uboot的BL2占用。再往后就是内核、rootfs等镜像的分区了。系统移植工程师可以根据kernel镜像大小、rootfs大小等来自由给SD分区。

5)从uboot的分区情况来看,ENV不能往扇区1-16或者49-x中来放置,其他地方都可以商量。ENV的大小是16K字节也就是32个扇区。

2.环境变量相关代码浏览

1)目前情况是uboot在SD2中,而ENV在SD0中,所以现在ENV不管放在哪个扇区都能工作,不会有问题。但是我们还是得找到ENV分区所在并且改到不会和uboot冲突,因为将来部署系统时我们会将uboot和kernel、rootfs等都烧录到iNnand中去,那时候也要确保不会冲突。

2)static inline int write_env(struct mmc *mmc, unsigned long size,

                                unsigned long offset, const void *buffer)

类似于这种函数,在代码分析中,关键是弄明白各种参数的意义。mmc表示要写的mmc设备,size表示要写的大小,offset表示要写到SD卡的哪个扇区去,buffer是要写的内容。

3)CONFIG_ENV_OFFSET这个宏决定了我们的ENV在SD卡中相对SD卡扇区0的偏移量,也就是ENV写到SD卡的哪里去了。经过分析发现这个宏的值为0.所以我们的ENV被写到了0扇区开始的32个扇区中。

4)写到这里肯定不行,因为和uboot的BL1冲突了。解决方案是改变这个CONFIG_ENV_OFFSET的值,将ENV写到别的空闲扇区去。

#define MOVI_BL2_POS                ((eFUSE_SIZE / MOVI_BLKSIZE) + MOVI_BL1_BLKCNT + MOVI_ENV_BLKCNT)            后面这三个其实分别是1+16+32=49

其中的1就是扇区0(空闲的),16是就是扇区1-16(uboot的BL1),32就是扇区17-48(存放ENV的),49自然就是uboot的BL2开始扇区了。这种安排是三星移植的uboot版本中推荐的SD卡的分区方式,不一定是唯一的。

5)我们参考这个设计,即可实现环境变量不冲突。所以只要将ENV放到17扇区起始的地方即可。

3.环境变量的测试和配置移植

3.1如何测试环境变量的保存是否正确

1)程序修改重新编译后启动,启动后要注意iNand中本来有没有环境变量。为了保险起见对iNand的前49个扇区进行擦除,然后就可以确保里面没有之前保存过的环境变量了。使用命令:mmc write 0 30000000 0# 49来擦除SD0的扇区0-48,保证以前的环境变量都没有了。

2)重新开机后先set随便改一个环境变量作为标记然后saveenv然后重启。

3)测试方法是,使用:mmc read 0 30000000 17# 32命令将iNand的17开始的32个扇区读出来到内存30000000处,然后md查看。找到显示区域里面的各个环境变量,看读出来的和自己刚才修改的值是否一样。

3.2常用环境变量的配置移植

常用的环境变量就是网络相关的那几个,和CONFIG_BOOTCOMMAND、CONFIG_BOOTARGS等。

4.添加网络支持

1)uboot中对各种功能也是一个条件编译可以配置可以裁剪的设计(从linux内核学来的),默认情况下我们的uboot没有选择支持网络。

2)在配置头文件s5p_goni.h中添加一行 #define CONFIG_CMD_NET

3)添加了网络支持宏之后,在uboot初始化时就会执行eth_initialize函数,从而网络相关代码初始化就会被执行,将来网络就有可能能用。

官方标准uboot2013移植10之环境变量和网卡的移植_第1张图片

5.添加pingtftp命令

1)在linux系统中网络底层驱动被上层应用调用的接口是socket,是一个典型的分层结构,底层和上层是完全被socket接口隔离的。

2)但是在uboot中网络底层驱动和上层应用是黏在一起的,不分层。意思就是上层网络的每一个应用都是自己去调用底层驱动中的操作硬件的代码来实现的。

3)uboot中有很多预先设计的需要用到网络的命令,和我们直接相关的就是ping和tftp这两个命令。这两个命令在uboot中也是需要用相应的宏开关来打开或者关闭的。

4)经过代码检查,发现ping命令开关宏为CONFIG_CMD_PING,而tftp命令的开关为CONFIG_CMD_NET,确认添加。

5)代码实践。结果是ping和tftp命令都被识别了,但是都提示no ethernet found`````网络不通。为什么不通?因为还没做初始化等移植

官方标准uboot2013移植10之环境变量和网卡的移植_第2张图片

6.移植网卡初始化代码

实验现象分析

1)因为我们没有自定义的网卡初始化函数(board_eth_init或者cpu_eth_init),所以uboot启动时初始化网卡时打印:Net:   Net Initialization Skipped

2)eth.c中有2个很重要的全局变量:eth_devices(用来指向一个链表,这个链表中保存了当前系统中所有的网卡信息)和eth_current(eth_current指针指向当前我们正在操作的那个网卡)。

3)在linux的网卡驱动体系中,有一个数据结构(struct eth_device)用来表示(封装)一个网卡的所有信息,系统中注册一个网卡时就是要建立一个这个结构体的实例,然后填充这个实例中的各个元素,最后将这个结构体实例加入到eth_devices这个链表上,就完成了注册。了解了这些之后,你就明白了网卡驱动在初始化时必须负责将自己注册到系统的网卡驱动体系中(其实就是把自己的eth_device结构体实例添加到eth_devices链表中)。如果你不做这个过程就会出现:网卡找不到的错误。

4)分析当前的问题是:在305行判断eth_devices是否为NULL之前没有去做网卡驱动的注册,所以这里为NULL,所以打印出了“No ethernet found.”

7.DM9000驱动浏览

1)想解决这个问题,就是要在305行之前去注册网卡驱动。注册网卡驱动的代码不能随便乱写,一定要遵守linux网卡驱动架构的要求。这一块的代码一般属于网卡驱动的一部分,像这里就在dm9000x.c中。

2)dm9000x.c中的最后一个函数int dm9000_initialize(bd_t *bis),这个函数就是用来注册dm9000网卡驱动的。

8.问题修复

根据之前分析uboot函数,发现前面有2个函数预留的可以用来放网卡初始化函数的,经过对比感觉board_eth_init函数稍微合适点,于是乎去添加。

移植过来到eth.c ,然后屏蔽下面,一句话。

官方标准uboot2013移植10之环境变量和网卡的移植_第3张图片

9.结果

官方标准uboot2013移植10之环境变量和网卡的移植_第4张图片

你可能感兴趣的:(官方标准uboot2013移植10之环境变量和网卡的移植)