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数组,可以在板子配置文件中定义相应的宏来定义相应的环境变量。

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值