u-boot下网络驱动程序的修改
2016-05-17 22:07
501 查看
Eth.c工作之前的初始化
static struct eth_device *eth_devices, *eth_current;Eth.c中有个eth_devices需要外部调用函数eth_register做初始化工作,其它函数(除eth_initialize外)都必须在这个初始化之后才能使用。
结构eth_devices是个循环链表,可包含多个eth_device。eth_register每次调用添加一个结构,调用多次可生成循环链表。eth_devices指向链表的第1个元素。
at91sam9260ek中先调用eth_initialize,在此函数中调用Eth.c:eth_register:
board.c:调用Eth.c:eth_initialize()
调用at91sam9260ek.c: board_eth_init()
调用macb.c: macb_eth_initialize()
调用Eth.c: eth_register()。
int eth_register(struct eth_device* dev) { struct eth_device *d; if (!eth_devices) { eth_current = eth_devices = dev; #ifdef CONFIG_NET_MULTI /* update current ethernet name */ { char *act = getenv("ethact"); if (act == NULL || strcmp(act, eth_current->name) != 0) setenv("ethact", eth_current->name); } #endif } else { for (d=eth_devices; d->next!=eth_devices; d=d->next) ; d->next = dev; } dev->state = ETH_STATE_INIT; dev->next = eth_devices; return 0; } |
eth_initialize
int eth_initialize(bd_t *bis) { unsigned char env_enetaddr[6]; int eth_number = 0; eth_devices = NULL; eth_current = NULL; show_boot_progress (64); #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) miiphy_init(); #endif /* Try board-specific initialization first. If it fails or isn't * present, try the cpu-specific initialization */ if (board_eth_init(bis) < 0) //调用board_eth_init,此函数内部实现初始化eth_devices和eth_current,并调用eth_register(struct eth_device* dev)。 cpu_eth_init(bis); #if defined(CONFIG_DB64360) || defined(CONFIG_CPCI750) mv6436x_eth_initialize(bis); #endif #if defined(CONFIG_DB64460) || defined(CONFIG_P3Mx) mv6446x_eth_initialize(bis); #endif if (!eth_devices) { puts ("No ethernet found./n"); show_boot_progress (-64); } else { struct eth_device *dev = eth_devices; char *ethprime = getenv ("ethprime"); show_boot_progress (65); do { if (eth_number) puts (", "); printf("%s", dev->name); //如果找到环境变量”ethprime”,则将eth_current指向当前eth_device。 if (ethprime && strcmp (dev->name, ethprime) == 0) { eth_current = dev; puts (" [PRIME]"); } //读取环境变量“ethaddr”、“eth1addr”…设置的网络地址 eth_getenv_enetaddr_by_index(eth_number, env_enetaddr); //复制环境变量的网络地址到dev->enetadddr中。如果dev->write_hwaddr有效,写入到网卡的实际设备中。 if (memcmp(env_enetaddr, "/0/0/0/0/0/0", 6)) { if (memcmp(dev->enetaddr, "/0/0/0/0/0/0", 6) && memcmp(dev->enetaddr, env_enetaddr, 6)) { printf ("/nWarning: %s MAC addresses don't match:/n", dev->name); printf ("Address in SROM is %pM/n", dev->enetaddr); printf ("Address in environment is %pM/n", env_enetaddr); } memcpy(dev->enetaddr, env_enetaddr, 6); } if (dev->write_hwaddr && !eth_mac_skip(eth_number) && is_valid_ether_addr(dev->enetaddr)) { dev->write_hwaddr(dev); } eth_number++; dev = dev->next; } while(dev != eth_devices); #ifdef CONFIG_NET_MULTI /* update current ethernet name */ if (eth_current) { char *act = getenv("ethact"); if (act == NULL || strcmp(act, eth_current->name) != 0) setenv("ethact", eth_current->name); } else setenv("ethact", NULL); #endif putc ('/n'); } return eth_number; } |
eth_init函数
使用eth_init必须定义宏CONFIG_RESET_PHY_R。在board.c:start_armboot函数中它调用reset_phy,再调用eth_init。eth_init主要是要调用eth_current->init.
int eth_init(bd_t *bis) { int eth_number; struct eth_device *old_current, *dev; if (!eth_current) { puts ("No ethernet found./n"); return -1; } /* Sync environment with network devices */ eth_number = 0; dev = eth_devices; do { uchar env_enetaddr[6]; if (eth_getenv_enetaddr_by_index(eth_number, env_enetaddr)) memcpy(dev->enetaddr, env_enetaddr, 6); ++eth_number; dev = dev->next; } while (dev != eth_devices); old_current = eth_current; do { debug("Trying %s/n", eth_current->name); if (eth_current->init(eth_current,bis) >= 0) { eth_current->state = ETH_STATE_ACTIVE; return 0; } debug("FAIL/n"); eth_try_another(0); } while (old_current != eth_current); return -1; } |
NET有关的环境变量
(1) “ethaddr”表示网络地址,“eth1addr”、“eth2addr”表示第2个和第3个的网络地址;(2) "ethact"表示eth_current网络地址的名称,eth_current改变后重新写入此环境变量;
(3) "ethprime"表示上电后初始eth_current的名称;
Env_common.c中有一个default_environment数组,可以在板子配置文件中定义相应的宏来定义相应的环境变量。
相关文章推荐
- TCP核心概念-慢启动,ssthresh,拥塞避免,公平性的真实含义
- faster rcnn修改demo.py保存网络中间结果
- 可靠的传输层协议——TCP协议
- 深度学习——缩减+召回加速网络训练
- Socket TCP
- [原创]java WEB学习笔记08:HttpServletRequest & ServletRequest
- Python网络编程中的select 和 poll I/O复用的简单使用
- http post 请求数据格式选择
- AndroidStudio自定义属性xmlns无法识别问题解决in Gradle projects,always use http://schemas.android.com/apk/res-auto
- 网络流二十四题之十一 —— 航空路线问题(AIRL)
- 运输层的TCP协议
- BZOJ1001 狼抓兔子(裸网络流)
- Tcpdump抓取 Android 网络包
- TCP的连接建立与连接释放
- 网络 协议与分层结构 的学习心得
- Socket编程------模拟QQ聊天(TCP)
- 网络编程之FIFO
- https 常见问题一 PKIX path building failed
- TCP协议的建立与释放及TCP的有限状态基
- 关于Android6.0API,找不到org.apache.http.Header问题记录。