注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

liuyue18301的个人主页

追逐梦想 光辉岁月

 
 
 

日志

 
 

Uboot通过bootm命令向内核传递MAC地址  

2009-10-30 11:29:20|  分类: uboot |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

 我们使用的系统中的CS8900a没有外接eeprom,所以在默认的情况,Linux下的CS8900a的驱动使用的是一个伪MAC地址。在单一的系统中,这是没有问题的,但是当我们在同一个子网中使用或测试多个设备是,就会产生冲突了。所以我们需要能够方便的改变网卡的MAC地址,而不是将MAC地址硬编码进内核中,每次修改都得重新编译内核。

一、内核参数的传递

       向Linux驱动传递参数的方式有两种,一为在系统启动的时候由bootloader传入,还有一种是将驱动编译成模块,将参数作为模块加载的参数传入。

       本系统使用的是由bootloader传入的方式。内核通过setup接口接受Bootloader传入的参数。方式如下:

static int __init param_mac_setup(char *str)

{

……

}

__setup("mac=", param_mac_setup);

这样,当在Bootloader中指定“mac=00:2E:79:38:6D:4E”,系统在加载这个模块的时候,就会执行相应的param_mac_setup()函数,而传入给它的参数就是等号后面的物理地址“00:2E:79:38:6D:4E”。这样,该函数就可以对它进行相应的处理。

二、bootm传递参数的方式

在bootm执行的流程图中,可以看到会调用do_bootm_linux()在执行Linux内核,内核的起始地址如下:

void (*theKernel)(int zero, int arch, uint params);

image_header_t *hdr = &header;

       theKernel = (void (*)(int, int, uint))ntohl(hdr->ih_ep);

header是uImage的头部,通过头部,得到内核映像起始的执行地址,标识为theKernel。从中也可以看到,内核接受三个参数,第一个为0,第二个为系统的ID号,第三个是传入内核的参数。

在do_bootm_linux()的最后,会跳到内核去执行:

       theKernel (0, bd->bi_arch_number, bd->bi_boot_params);

最后两个参数在board/smdk2410/smdk2410.c的board_init()中被初始化:

       /* arch number of SMDK2410-Board */

       gd->bd->bi_arch_number = MACH_TYPE_SMDK2410; /* 193 */

       /* adress of boot parameters */

       gd->bd->bi_boot_params = 0x30000100;

可以看到,uboot传给内核的参数表存放在内存中起始偏移0x100的位置,这里只是指定了“指针”的位置,但还没初始化其中的值,这是在do_bootm_linux()中跳到内核前去完成的。

值得注意的是, 内核的默认运行地址的0x30008000,前面就是留给参数用的。所以一般不要将内核下载到该地址之前,以免冲掉了传给内核的参数。

三、参数列表的构建

#if defined (CONFIG_SETUP_MEMORY_TAGS) || \

    defined (CONFIG_CMDLINE_TAG) || \

    defined (CONFIG_INITRD_TAG) || \

defined (CONFIG_SERIAL_TAG)

       setup_start_tag (bd);

#ifdef CONFIG_SERIAL_TAG

       setup_serial_tag (&params);

#endif

#ifdef CONFIG_REVISION_TAG

       setup_revision_tag (&params);

#endif

#ifdef CONFIG_SETUP_MEMORY_TAGS

       setup_memory_tags (bd);

#endif

#ifdef CONFIG_CMDLINE_TAG

       setup_commandline_tag (bd, commandline);

#endif

#ifdef CONFIG_INITRD_TAG

       if (initrd_start && initrd_end)

              setup_initrd_tag (bd, initrd_start, initrd_end);

#endif

#if defined (CONFIG_VFD) || defined (CONFIG_LCD)

       setup_videolfb_tag ((gd_t *) gd);

#endif

       setup_end_tag (bd);

#endif

四、将MAC地址参数传入命令行参数

       为了传入命令行参数,uboot所作的是:

              char *commandline = getenv ("bootargs");

              setup_commandline_tag (bd, commandline);

       现在想要把MAC地址也加入到命令行参数中,只需要实现:

char *commandline = getenv ("bootargs") + “ mac=” + getenv ("ethaddr");

setup_commandline_tag (bd, commandline);

即可。这样就不需要每次在命令行后面手工追加MAC地址参数了。

  评论这张
 
阅读(1730)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018