设备参数MAC地址在uboot和linux保持一致

来源:互联网 发布:文玩网络交易平台 编辑:程序博客网 时间:2024/05/22 14:57


《ARM Linux开发-warewin 2G/3G无线传输(DTU)和路由器—笔记》

Linux系统中,先启动UBOOT,后加载linux内核和应用程序。启动ubootuboot网卡驱动启动起来了,但是内核加载完后uboot不再起作用,Linux的网卡驱动开始起作用。这样因为是两个阶段的不同驱动,带来了MAC地址的不一致。

解决这个问题的思路:首先系统的MAC地址是可以通过linux程序(这里是web参数)设置进去的。Uboot能读取这个设置值,并能把设置值设置到网卡中,linux驱动运行时候就用网卡的设置。这样ubootlinux两个阶段都是用设置好的MAC地址。

linux程序保存的参数uboot如何能读出呢?在linux中直接使用MTD驱动在约定地址读写FLASH,uboot中没有文件系统启动,但可以直接读取flash数据,这样就解决了数据传递的问题。

1、uboot中读出MAC地址 

uboot中添加从nandflash0x80000位置读出MAC地址的值,在/u-boot-1.3.4/lib_arm/board.c的void start_armboot (void) 函数中添加以下红色处理代码:

/* MAC Address */

{

int i;

ulong reg;

char *s, *e;

char tmp[64];

i = getenv_r ("ethaddr", tmp, sizeof (tmp));

s = (i > 0) ? tmp : NULL;

for (reg = 0; reg < 6; ++reg) {

gd->bd->bi_enetaddr[reg] = s ? simple_strtoul (s, &e, 16) : 0;

if (s)

s = (*e) ? e + 1 : e;

}

................................

................................

memset(tmp, 0, 10);//  /dev/mtd2  

size = 6;

ret = nand_read(nand, 0x80000, &size, (u_char *)tmp);//0x80000 MAC地址所在if(ret == 0){//DATAFLASH_OK

printf("\nread MAC addr:");

for (reg = 0; reg < 6; ++reg) {

gd->bd->bi_enetaddr[reg] = tmp[reg];

printf(" %x", tmp[reg]);

}

#ifdef CONFIG_HAS_ETH1

2、ubootMAC地址的处理 ,把读出的MAC地址写到网卡寄存器中。

/u-boot-1.3.4/drivers/net/macb.c中static int macb_init(struct eth_device *netdev, bd_t *bd) 函数中添加以下红色字体:

macb_writel(macb, RBQP, macb->rx_ring_dma);

macb_writel(macb, TBQP, macb->tx_ring_dma);

//------------------------------------------------------------------

/* set hardware address                    设置MAC地址*/

if (is_zero_ether_addr(bd->bi_enetaddr) ||//检查是否全为

    is_multicast_ether_addr(bd->bi_enetaddr)) {

hwaddr_bottom = cpu_to_le32(*((u32 *)netdev->enetaddr));

macb_writel(macb, SA1B, hwaddr_bottom);

hwaddr_top = cpu_to_le16(*((u16 *)(netdev->enetaddr + 4)));

macb_writel(macb, SA1T, hwaddr_top);

}

//打印MAC  

printf("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", bd->bi_enetaddr[0],

       bd->bi_enetaddr[1], bd->bi_enetaddr[2], bd->bi_enetaddr[3],

       bd->bi_enetaddr[4], bd->bi_enetaddr[5]);

hwaddr_bottom = cpu_to_le32(*((u32 *)bd->bi_enetaddr));

macb_writel(macb, SA1B, hwaddr_bottom);

hwaddr_top = cpu_to_le16(*((u16 *)(bd->bi_enetaddr + 4)));

macb_writel(macb, SA1T, hwaddr_top);

//----------------------------------------------------------------

3、linux内核的读取,内核直接从网卡寄存器读出MAC

在linux内核中macb.c已经有了从控制器中读MAC,并有效性相关判断,不需要做任何改动,读取部分如以下代码所示:

.................................

static int __init macb_probe(struct platform_device *pdev)

macb_writel(bp, NCFGR, config);

macb_get_hwaddr(bp);//MAC  地址的判断

................................

4应用程序中的处理

linux应用程序中可调用MTD驱动MAC地址直接写到flash地址0x80000

5、编译及测试

1)编译uboot重新烧写,烧写linux内核

2)启动uboot 后调用saveenv命令一次,即可测试。

3)重新启动linux后用ifconfig 命令查看是否新的MAC地址与uboot打印的相对应;或在调试时可以看到如下信息:即正确

U-Boot 1.3.4 (Mar  7 2011 - 21:27:00)

DRAM:  64 MB

NAND:  256 MiB

*** Warning - bad CRC or NAND, using default environment

read MAC addr: 50 0 a8 c0 0 ffIn:    serial

Out:   serial

Err:   serial

Net:   macb0

MAC: 50:00:a8:c0:00:ff

macb0: Starting autonegotiation...

macb0: Autonegotiation complete

macb0: link up, 100Mbps full-duplex (lpa: 0x45e1)

Hit any key to stop autoboot:  0 

U-Boot> print

0 0
原创粉丝点击