uboot向linux内核传递启动参数_第1页
uboot向linux内核传递启动参数_第2页
uboot向linux内核传递启动参数_第3页
uboot向linux内核传递启动参数_第4页
uboot向linux内核传递启动参数_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、u-boot向linux内核传递启动参数(详细)U-BOOT在启动内核时,会向内核传递一些参数.BootLoader可以通过两种方法传递参数给内核,一种是旧的参数结构方式(parameter_struct),主要是2.6之前的内核使用的方式。另外一种就是现在的2.6内核在用的参数链表(taggedlist)方式。这些参数主要包括,系统的根设备标志,页面大小,内存的起始地址和大小,RAMDISK的起始地址和大小,压缩的RAMDISK根文件系统的起始地址和大小,当前内核命令参数等而这些参数是通过structtag来传递的。U-boot把要传递给kernel的东西保存在structtag数据结构中,

2、启动kernel时,把这个结构体的物理地址传给kernel;Linuxkernel通过这个地址分析出u-boot传递的参数。大家都知道U-Boot启动的时候会将启动参数的地址放入R2中,然后再启动内核。首先看两个重要的数据结构:第一个是global_data,定义在include/asm-arm/global_data.h文件中:typedefstructglobal_databd_t*bd;unsignedlongflags;unsignedlongbaudrate;unsignedlonghave_console;/*serial_init()wascalled*/unsignedlong

3、reloc_off;/*RelocationOffset*/unsignedlongenv_addr;/*AddressofEnvironmentstruct*/unsignedlongenv_valid;/*ChecksumofEnvironmentvalid?*/unsignedlongfb_base;/*baseaddressofframebuffer*/#ifdefCONFIG_VFDunsignedcharvfd_type;/*displaytype*/#endif#if0unsignedlongcpu_clk;/*CPUclockinHz!*/unsignedlongbus_clk

4、;unsignedlongram_size;/*RAMsize*/unsignedlongreset_status;/*resetstatusregisteratboot*/#endifvoid*jt;/*jumptable*/gd_t;在同一个文件中有如下定义:#defineDECLARE_GLOBAL_DATA_PTRregistervolatilegd_t*gdasm(r8)在需要使用gd指针的时候,只需要加入DECLARE_GLOBAL_DATA_PTR这句话就可以了。可以知道,gd指针始终是放在r8中的。其中的第一个变量,bd_t结构体,定义于include/asm-arm/u-bo

5、ot.h中:typedefstructbd_infointbi_baudrate;/*serialconsolebaudrate*/unsignedlongbi_ip_addr;/*IPAddress*/unsignedcharbi_enetaddr6;/*Ethernetadress*/structenvironment_s*bi_env;ulongbi_arch_number;/*uniqueidforthisboard*/ulongbi_boot_params;/*wherethisboardexpectsparams*/struct/*RAMconfiguration*/ulongst

6、art;ulongsize;bi_dramCONFIG_NR_DRAM_BANKS;#ifdefCONFIG_HAS_ETH1/*secondonboardethernetport*/unsignedcharbi_enet1addr6;#endifbd_t;bd_t中的变量bi_boot_params,表示传递给内核的参数的位置。然后看看gd和bd的初始化,在lib_arm/board.c中:gd=(gd_t*)(_armboot_start-CFG_MALLOC_LEN-sizeof(gd_t);memset(void*)gd,0,sizeof(gd_t);gd-bd=(bd_t*)(cha

7、r*)gd-sizeof(bd_t);memset(gd-bd,0,sizeof(bd_t);说明这两个结构体在内存中的位置是在uboot的代码在往下的地址处,所以进行操作的时候不要覆盖了这个位置!在board/smdk2410/smdk2410.c中,有如下初始化:gd-bd-bi_boot_params=0 x30000100;说明参数位置在0 x30000100。现在,具体看看uboot是如何(按什么格式)把参数放入内存中。内核参数链表的格式和说明可以从内核源代码目录树中的include/asm-arm/setup.h中找到,参数链表必须以ATAG_CORE开始,以ATAG_NONE结束

8、。这里的ATAG_CORE,ATAG_NONE是各个参数的标记,本身是一个32位值,例如:ATAG_CORE=Ox5441OOO1。其它的参数标记还包括:ATAG_MEM32,ATAG_INITRD,ATAG_RAMDISK,ATAG_COMDLINE等。每个参数标记就代表一个参数结构体,由各个参数结构体构成了参数链表。参数结构体的定义如下:structtagstructtag_headerhdr;unionstructtag_corecore;structtag_mem32mem;structtag_videotextvideotext;structtag_ramdiskramdisk;st

9、ructtag_initrdinitrd;structtag_serialnrserialnr;structtag_revisionrevision;structtag_videolfbvideolfb;structtag_cmdlinecmdline;structtag_acornacorn;structtag_memclkmemclk;u;参数结构体包括两个部分,一个是tag_header结构体,一个是u联合体。tag_header结构体的定义如下:structtag_headeru32size;u32tag;其中size:表示整个tag结构体的大小(用字的个数来表示,而不是字节的个数),

10、等于tag_header的大小加上u联合体的大小,例如,参数结构体ATAG_CORE的size=(sizeof(tag-tag_header)+sizeof(tag-u.core)2,般通过函数tag_size(struct*tag_xxx)来获得每个参数结构体的size。其中tag:表示整个tag结构体的标记,如:ATAG_CORE等。联合体u包括了所有可选择的内核参数类型,包括:tag_core,tag_mem32,tag_ramdisk等。参数结构体之间的遍历是通过函数tag_next(struct*tag)来实现的。本系统参数链表包括的结构体有:ATAG_CORE,ATAG_MEM,A

11、TAG_RAMDISK,ATAG_INITRD32,ATAG_CMDLINE,ATAG_END。在整个参数链表中除了参数结构体ATAG_CORE和ATAG_END的位置固定以外,其他参数结构体的顺序是任意的。本BootLoader所传递的参数链表如下:第一个内核参数结构体,标记为ATAG_CORE,参数类型为tag_core。每个参数类型的定义请参考源代码文件。我们知道u-boot传递给内核的参数有很多个,如系统的根设备标志,页面大小,内存的起始地址和大小,RAMDISK的起始地址和大小,压缩的RAMDISK根文件系统的起始地址和大小等,而每个参数我们都是单独的采用一个structtag来标识

12、的,之前提到的参数标记如ATAG_MEM32,ATAG_INTRD等就是用来标识该tag结构是用来存放的哪种类型的参数。由于不同类型的参数传递的信息内容也不尽相同,为了综合不同参数的tag结构,所以在structtag结构中定义了一个联合体union,根据不同的参数标记符来选择联合体中不同的结构体来存储参数的内容,如参数标记若为ATAG_MEM32,则联合体中采用structtag_mem32来存储内存参数的内容。然而内核是如何从gd-bd-bi_boot_params指定的地址上知道参数从哪里开始以及到哪里结束呢?所以我们在构建各种参数tag时,在开始时先要构建一个参数标记为ATAG_COR

13、E的tag结构标示从这个tag结构开始接下来就是参数现来结合代码分析在u-boot中是如何来构建这多个参数的tag结构:/common/cmd_bootm.c文件中,bootm命令对应的do_bootm函数,当分析ulmage中信息发现OS是Linux时,调用./lib_arm/bootm.c文件中的do_bootm_linux函数来启动Linuxkernel。#ifdefined(CONFIG_SETUP_MEMORY_TAGS)|defined(CONFIG_CMDLINE_TAG)|defined(CONFIG_INITRD_TAG)|defined(CONFIG_SERIAL_TAG)

14、|defined(CONFIG_REVISION_TAG)|defined(CONFIG_LCD)|defined(CONFIG_VFD)setup_start_tag(bd);/通过bd结构体中参数在内存中的存放地址gd-bd-bi_boot_params来构建初始化的tag结构,表明参数结构的开始#ifdefCONFIG_SERIAL_TAGsetup_serial_tag(¶ms);/构建串口参数的tag结构#endif#ifdefCONFIG_REVISION_TAGsetup_revision_tag(¶ms);#endif#ifdefCONFIG_SETUP_MEM

15、ORY_TAGSsetup_memory_tags(bd);/构建内存参数的tag结构#endif#ifdefCONFIG_CMDLINE_TAGsetup_commandline_tag(bd,commandline);/构建命令行参数的tag结构#endif#ifdefCONFIG_INITRD_TAGif(initrd_start&initrd_end)setup_initrd_tag(bd,initrd_start,initrd_end);/构建ramdisk参数的tag结构#endif#ifdefined(CONFIG_VFD)|defined(CONFIG_LCD)setup_vi

16、deolfb_tag(gd_t*)gd);#endifsetup_end_tag(bd);/最后是构建参数tag结构结束的tag结构,标示参数已经结束,参数标记为ATAG_NONE#endif注意上面参数的tag结构的构建是有宏的约束的,再来看看具体是怎样构建每个tag结构的:#ifdefined(CONFIG_SETUP_MEMORY_TAGS)|defined(CONFIG_CMDLINE_TAG)|defined(CONFIG_INITRD_TAG)|defined(CONFIG_SERIAL_TAG)|defined(CONFIG_REVISION_TAG)|defined(CONFI

17、G_LCD)|defined(CONFIG_VFD)staticvoidsetup_start_tag(bd_t*bd)params=(structtag*)bd-bi_boot_params;/将指定的内存中存放参数列表的地址强制转化为structtag的结构,这样便于内核存取各个参数params-hdr.tag=ATAG_CORE;/标示这个tag结构是用来标示参数结构的开始params-hdr.size二tag_size(tag_core);/存放整个tag结构的大小params-u.core.flags=0;params-u.core.pagesize=0;params-u.core.

18、rootdev=0;params=tag_next(params);其中用到了一个重要的指针:params,这是一个指向structtag的指针,在文件的开始处声明,可以被这个文件中的所有函数访问:staticstructtag*params;tag和tag_header和内核中的结构一模一样。tag_header中的tag字段表示的是这个tag的类型,在内核和Bootloader中通过一些固定的整形常量来表示:#defineATAG_CORE0 x54410001#defineATAG_NONE0 x00000000#defineATAG_CORE0 x54410001#defineATAG

19、_MEM0 x54410002#defineATAG_VIDEOTEXT0 x54410003#defineATAG_RAMDISK0 x54410004#defineATAG_INITRD0 x54410005#defineATAG_INITRD20 x54420005#defineATAG_SERIAL0 x54410006#defineATAG_REVISION0 x54410007#defineATAG_VIDEOLFB0 x54410008#defineATAG_CMDLINE0 x54410009#defineATAG_ACORN0 x41000101#defineATAG_MEM

20、CLK0 x41000402上面是初始化tag链表(在SDRAM里),最后一句是作为链表的最关键部分,它的定义是:#definetag_next(t)(structtag*)(u32*)(t)+(t)-hdr.size)作用是指向下一个tag结构体。一般在每个参数的tag结构体的最后都要调用这个宏,内核在遇到这个宏就可以直接跳转到下一个参数tag结构体的地址上来存取。再来看看其他参数种类的tag结构的构建#ifdefCONFIG_SETUP_MEMORY_TAGSstaticvoidsetup_memory_tags(bd_t*bd)inti;for(i=0;ihdr.tag=ATAG_MEM

21、;params-hdr.size=tag_size(tag_mem32);params-u.mem.start=bd-bi_drami.start;params-u.mem.size=bd-bi_drami.size;params=tag_next(params);其中defined(CONFIG_SETUP_MEMORY_TAGS)和defined(CONFIG_CMDLINE_TAG)是必不可少的。前者是标记内存的信息,而后者是设置命令行标记(比如root=/dev/mtdblock2init=/linuxrcconsole=ttySACO”)到最后可以看到调用:theKernel(0,machid,bd-bi_boot_params);当然,有很多的宏来选择是否传递相应的tag到linuxkenel.实际是这些所以针对于bd-bi_boot_params这个变量.这个变量是个整形变量,代表存放所有tag的buffer的地址.例如,在smdk2410.c中的board_init()函数中,对于这个变量进行了如下赋值:gd-bd-bi_boot_params=0 x30000100;0 x30000100这个值可以随意指定,但是要保证和内核中相应的mach_type致.以smdk2410为例:在内核中始终这

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论