版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、arm-linux 之 uboot 向内核传递参数 (setup_arch 分析)抛开uboot不谈,先看看uboot给内核传递的参数是什文件中的struct tag么样的东西, 在 arch/arm/kernel/setup.h结构体:struct tag struct tag_header hdr;union struct tag_corecore;struct tag_mem32mem;struct tag_videotextvideotext;struct tag_ramdiskramdisk;struct tag_initrd initrd;struct tag_serialnrse
2、rialnr;struct tag_revisionrevision;struct tag_videolfbvideolfb;struct tag_cmdlinecmdline;/* Acorn specific*/struct tag_acorn acorn;/* DC21285 specific*/struct tag_memclkmemclk;/* Marvell specific*/struct tag_mv_uboot mv_uboot;/ board infostruct tag_board_info board_info; u;Uboot传递给内核的参数,都是一些对一个个的设备参
3、数的 描述,用于对内核进行相应的初始化,参数的具体内容暂时 无需关心,有个大致印象就行,下面一步步看内核是怎么接 收uboot参数的,在setup_arch 函数中首先定义 struct tag * 型指针变量tags :struct tag *tags = (struct tag *)&init_tags;tags是重点,它就是内核接收uboot参数的东西!init_tags是个全局静态变量,就在本文件 (arch/arm/kernel/setup.c) 定义如下:static struct init_tags struct tag_header hdrl;struct tag_core c
4、ore;struct tag_header hdr2;struct tag_mem32 mem;struct tag_header hdr3; init_tags _initdata = tag_size(tag_core), ATAG_CORE , 1, PAGE_SIZE, 0 xff , tag_size(tag_mem32), ATAG_MEM , MEM_SIZE, PHYS_OFFSET , 0, ATAG_NONE ;在定义结构体init_tags的同时声明了静态全局变量init_tags ,记住这个静态全局变量不重要,继续往下看,还在setup_arch 函数中接下来几行:if
5、 (_atags_pointer)tags = phys_to_virt(_atags_pointer);else if (mdesc-boot_params)tags = phys_to_virt(mdesc-boot_params);这个是重点,这里根据情况判断tags接收uboot参数的来源,if中说明来源是uboot传递,else if说明是由内核部分的代码(即代码写死,不是从uboot),这个是重点:先看看这个 atags_pointer 是什么:_atags_pointer ,定义在汇编文件 arch/arm/kernel/head-common.S的_switch_data 子程
6、序(可参考“ AR牌构内核启动分析-head.S(1.4、stext分析之 打开MMU并跳到startkernel一贬,在内核代码源头 stext运行前,由arm寄存器R2保存要传递给内核的参数的地址,当stext运行到子程序_switch_data 时,定义变量_atags_pointer 保存这个地 址,即_atags_pointer保存了 uboot要传递给内核的参数的 地址,所以这里让tags获取_atags_pointer的转换后的虚 拟地址,即可访问。有的时候,可能不需要从uboot传递参数到内核,也就是说这些参数写死在内核里而不是在uboot里,那么就可以写死,写死是写死在 ma
7、chine_desc 变量的boot_params 成员,可 以把地址值赋给这个成员,即可访问。一般来说还是从atags_pointer传递,即从uboot传递的几 率比较大,我手头这个marvell设备就是如此,毕竟在内核代码的machine_desc变量写死本质还是 uboot里存放这些 参数的物理地址,一旦 uboot里这些参数的物理地址变动, 同时还要改 machine_desc 变量的这个值,不如自动传递方 便。搞明白了参数的传递,下面看内核代码如何使用这些参数, 接着setup_arch 函数往下看,如下:if (tags-hdr.tag != ATAG_CORE)convert_
8、to_tag_list(tags);if (tags-hdr.tag != ATAG_CORE)tags = (struct tag *)&init_tags;结合本文最前面的struct tags结构体,它的第一个成员如下: struct tag_header hdr记住,struct tag_header 的成员tag,如果不等于宏 ATAG_CORE 的值(在 arch/arm/kernel/setup.h定义),说明是旧式的参数,需要转换成新格式的参数,所以调用函数 convert_to_tag_list ;如果转换后依然是旧格式的,那么就没法使用这个参数了,改为使用默认参数,就是本文
9、开始时描 述的那个不重要的init_tags静态全局变量。convert_to_tag_list这个函数内容可以不看,因为一个正常 的uboot是不会传递旧格式的参数,这里重在理解道理即可。后面的fixup部分,其实可以不关注了, fixup用于内核代码 固定的写死 meminfo ,而不是由uboot传递参数配置 meminfo ,应该说很少有使用 fixup成员写死 meminfo的情 况。言归正传,看下面的代码:if (tags-hdr.tag = ATAG_CORE) if (meminfo.nr_banks != 0)squash_mem_tags(tags);save_atags(
10、tags);parse_tags(tags);)首先全局变量 meminfo在这时候还没有被初始化,其用于指示物理内存bank个数的成员nr_banks肯定为0,继续往下 看,save_atags将把tags里的内容拷贝给全局变量 atags_copy ,重点是下面的 parse_tags :观察parse_tags函数的实现,这时必须要搞懂tags指针变量里面的内容是什么了,tags指针变量实际上指向了多个的struct tags 型变量,观察 structtags结构体即可发现,它是一个 struct tags_header 加一个 联合的结构,这就很明确了,再看parse_tags的实现
11、,它就 是对每一个它指向的 struct tags型变量调用函数 parse_tag , 这个函数实际解析 structtags型变量,终于到重点了,看它的实现:static int _init parse_tag(const struct tag *tag)extern struct tagtable _tagtable_begin,_tagtable_end;struct tagtable *t;for (t = &_tagtable_begin; t hdr.tag = t-tag) t-parse(tag); break;return t &_tagtable_end; 先看 “ ex
12、tern struct tagtable _tagtable_begin,tagtable_end;可参考本人博客前面的描述内核汇编启动阶段的文章,可以立即感觉到这两个东西是在链接脚本 vmlinux.lds.S中定义的,并且是卡住莫一代码段便于给C函数调用;首先看这两个变量在哪里定义,卡住了哪部分内容:_tagtable_begin =.;*(.taglist.init)_tagtable_end =.;可见是卡住了 ” .taglist.init ”段的全部陶物段里是什么 东西呢?在这里,arch/include/asm/setup.h 文件中,有这么 些内容:#define _tag _
13、used_attribute_(_section_(.taglist.init)#define _tagtable(tag, fn) static struct tagtable _tagtable_#fn _tag = tag, fn 第一行的意思是:宏 tag ,定义为used _attribute_(_section_(.taglist.init);第二、三行的意思是:定义宏_tagtable(tag, fn)为staticstruct tagtable _tagtable_#fn _tag = tag, fn , 意思是:在”.taglist.init”段中,创建 struct tag
14、table的静态变量_tagtable_#fn(fn 是什么由参数指定, 后面的_tag起变量描述符的作用,它真正指定了这个静态 变量是在.taglist.init段中链接),并赋初值,赋的值就是宏 函数定义时的参数tag和fn。说白了就是,以 tagtable(tag, fn)形式定义的宏,实际是在 .taglist.init段中,创建 struct tagtable 的静态变量,并赋初 值给这个变量,赋的值就是这个宏的两个参数tag和fn。在 arch/arm/mach-XXX/core.c 、arch/arm/mm/init.c 、 arch/arm/kernel/setup.c 文件中
15、,定义了很多 _tagtable(XXX , XXX)这样的宏,这些宏干什么的?就是解 析uboot传递给内核的参数用的(当然不仅它们解析,后面还 有别的代码解析),现在回到parse_tag函数,应该很好理解 了,它对传递进来的参数,利用tagtable_begin和_tagtable_end ,使用所有定义的 _tagtable(tag,fn)对其进行遍历,一旦发现 tagtable(tag, fn)的tag和传递 进来的参数的参数头的 tag(即struct tags_header 的tag成 员)一样,就用该 tagtable(tag,fn)的fn即解析函数进行解析,这里的marvel
16、l设备的实现一共定义了 11个这样的tagtable(tag, fn),就不一列由了, 这里具体描述两个比较重要的:parse_tag_mem32这个是初始化 meminfo即让内核了解设备的物理内存情况的,它将调用函数 arm_add_memory ,参数就是uboot传递 的相应参数的 mem结构,包括start成员和size成员即物理 内存起始地址和内存大小,arm_add_memory 这个函数比较简单,它把这两个参数写进 meminfo的bank中,并更新benk 个数值nr_banks。对于很多小型 arm嵌入式应用,一般只 有一个物理内存,也就只调用该函数一次。重中之重的 mem
17、info就是在这里初始化的!parse_tag_cmdline它把uboot传递的“命令行参数”赋给静态全局变量 default_command_line ,这个变量是干什么用的?它很重要, 先看看这里的marvell设备的情况:ttyS0,115200 ubi.mtd=3 root=ubi0:rootfs rootfstype=ubifs mtdparts=nand_flash:0 x2000000 x0(uboot)ro,0 x200000 0 x200000(env)rw,0 x5000000 x400000(kernel0)ro,0 x2 8000000 x900000(rootfs0
18、)ro,0 x5000000 x3100000(ker nel1)ro,0 x28000000 x3600000(rootfs1)ro,0 x22000000 x5e00000(config)rwrw)想必会明白这个 default_command_line 是干什么的了,这里 只是拷贝到这个变量中去,后面还有其他代码进一步解析它。看完这一部分,接下来是另一部分的解析,接着 setup_arch函数往下看:parse_cmdline(cmdline_p, from);form指针变量在setup_arch函数一开始就指向了 default_command_line ,到这应该能感觉到现在要解析 default_command_line 了,看 parse_cmdline 的实现: 无需仔细看里边关于用空格定位每一个参数等细节,重点是看它是由谁来解析的,可以看到两个变量_early_begin和_early_end ,
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年智能安防工程调试合同协议
- 2026年外卖平台配送员合同
- 家用天然气安全培训总结课件
- 2026届新高考英语冲刺复习 应用文+如何介绍传统文化
- 园长开学培训
- 园林绿化造价培训课件
- 2024年平安创建汇报材料
- 华英公司安全培训课件
- 华晨培训安全b成绩查询课件
- 市事业单位202年急需紧缺人才引进工作实施方案
- 大气道狭窄护理课件
- 水电厂电气自动化监控系统功能分析
- DB11T 381-2023 既有居住建筑节能改造技术规程
- 计算机应用数学基础 教学 作者 王学军 计算机应用数学课件 第10章 图论
- DF6205电能量采集装置用户手册-2
- 电子电路基础-电子科技大学中国大学mooc课后章节答案期末考试题库2023年
- 四年级科学上册期末试卷及答案-苏教版
- 怀仁县肉牛养殖产业化项目可行性研究报告
- DB51T 2875-2022彩灯(自贡)工艺灯规范
- 主要负责人重大危险源安全检查表
- 《工程经济学》模拟试题答案 东北财经大学2023年春
评论
0/150
提交评论