您的位置:首页 > 理论基础 > 计算机网络

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;

}

如果移植新的网卡驱动的话,应在board_eth_init中初始dev并调用eth_register。

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数组,可以在板子配置文件中定义相应的宏来定义相应的环境变量。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: