1. 程式人生 > >u-boot下網路驅動程式的修改

u-boot下網路驅動程式的修改

Eth.c工作之前的初始化

static struct eth_device *eth_devices, *eth_current;

Eth.c中有個eth_devices需要外部呼叫函式eth_register做初始化工作,其它函式(eth_initialize)都必須在這個初始化之後才能使用。

結構eth_devices是個迴圈連結串列,可包含多個eth_deviceeth_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_deviceseth_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陣列,可以在板子配置檔案中定義相應的巨集來定義相應的環境變數。