ImageVerifierCode 换一换
格式:DOCX , 页数:20 ,大小:36.71KB ,
资源ID:6099279      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/6099279.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(如何启动内核vivi与Linux kernel的参数传递情景分析.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

如何启动内核vivi与Linux kernel的参数传递情景分析.docx

1、如何启动内核vivi与Linux kernel的参数传递情景分析vivi开发笔记(十七):vivi与Linux kernel的参数传递情景分析(上)在上一部分提到过了,vivi作为bootloader,向内核传递启动参数是其本职工作之一。要把这个情景分析清楚,不仅仅需要分析vivi的参数机制,而且要分析Linux kernel的接收机制。因为这是一个简单的通信过程,比起本科所学习的TCP/IP来简单的多,但是因为简单,所以在协议上并不规范,理解上反而不如TCP/IP协议。下面就分为两个方面对此情景分析。一、综述内核参数传递机制 现在内核参数传递机制有两种:一种是基于struct param_s

2、truct,这种已经比较老了。缺点是该结构每个成员的位置是固定的,受限比较大。另外一种就是新的struct tag way。说新是相对的,Linux kernel 2.4.x都希望采用这种tag的方式。关于这方面的资料,可以有如下参考(所给出的目录是基于linux-2.4.18的内核,以顶层Makefile所在目录为当前目录。这里基于ARM架构的S3C2410,其他的SoC可以类比很容易得到):1、关于bootloader的理解-【Documentation/arm/booting】 此文档详细的讲述了bootloader的作用,具体内容如下:armlinuxlqm arm$ cat Boot

3、ing Booting ARM Linux =Author: Russell KingDate : 18 May 2002The following documentation is relevant to 2.4.18-rmk6 and beyond.In order to boot ARM Linux, you require a boot loader, which is a smallprogram that runs before the main kernel. The boot loader is expectedto initialise various devices, an

4、d eventually call the Linux kernel,passing information to the kernel.Essentially, the boot loader should provide (as a minimum) thefollowing:1. Setup and initialise the RAM.2. Initialise one serial port.3. Detect the machine type.4. Setup the kernel tagged list.5. Call the kernel image.1. Setup and

5、initialise RAM-Existing boot loaders: MANDATORYNew boot loaders: MANDATORYThe boot loader is expected to find and initialise all RAM that thekernel will use for volatile data storage in the system. It performsthis in a machine dependent manner. (It may use internal algorithmsto automatically locate

6、and size all RAM, or it may use knowledge ofthe RAM in the machine, or any other method the boot loader designersees fit.)2. Initialise one serial port-Existing boot loaders: OPTIONAL, RECOMMENDEDNew boot loaders: OPTIONAL, RECOMMENDEDThe boot loader should initialise and enable one serial port on t

7、hetarget. This allows the kernel serial driver to automatically detectwhich serial port it should use for the kernel console (generallyused for debugging purposes, or communication with the target.)As an alternative, the boot loader can pass the relevant console=option to the kernel via the tagged l

8、ists specifing the port, andserial format options as described in linux/Documentation/kernel-parameters.txt.3. Detect the machine type-Existing boot loaders: OPTIONALNew boot loaders: MANDATORYThe boot loader should detect the machine type its running on by somemethod. Whether this is a hard coded v

9、alue or some algorithm thatlooks at the connected hardware is beyond the scope of this document.The boot loader must ultimately be able to provide a MACH_TYPE_xxxvalue to the kernel. (see linux/arch/arm/tools/mach-types).4. Setup the kernel tagged list-Existing boot loaders: OPTIONAL, HIGHLY RECOMME

10、NDEDNew boot loaders: MANDATORYThe boot loader must create and initialise the kernel tagged list.A valid tagged list starts with ATAG_CORE and ends with ATAG_NONE.The ATAG_CORE tag may or may not be empty. An empty ATAG_CORE taghas the size field set to 2 (0x00000002). The ATAG_NONE must setthe size

11、 field to zero.Any number of tags can be placed in the list. It is undefinedwhether a repeated tag appends to the information carried by theprevious tag, or whether it replaces the information in itsentirety; some tags behave as the former, others the latter.The boot loader must pass at a minimum th

12、e size and location ofthe system memory, and root filesystem location. Therefore, theminimum tagged list should look: +-+base - | ATAG_CORE | | +-+ | | ATAG_MEM | | increasing address +-+ | | ATAG_NONE | | +-+ vThe tagged list should be stored in system RAM.The tagged list must be placed in a region

13、 of memory where neitherthe kernel decompressor nor initrd bootp program will overwriteit. The recommended placement is in the first 16KiB of RAM.5. Calling the kernel image-Existing boot loaders: MANDATORYNew boot loaders: MANDATORYThere are two options for calling the kernel zImage. If the zImagei

14、s stored in flash, and is linked correctly to be run from flash,then it is legal for the boot loader to call the zImage in flashdirectly.The zImage may also be placed in system RAM (at any location) andcalled there. Note that the kernel uses 16K of RAM below the imageto store page tables. The recomm

15、ended placement is 32KiB into RAM.In either case, the following conditions must be met:- CPU register settingsr0 = 0,r1 = machine type number discovered in (3) above.r2 = physical address of tagged list in system RAM.- CPU modeAll forms of interrupts must be disabled (IRQs and FIQs)The CPU must be i

16、n SVC mode. (A special exception exists for Angel)- Caches, MMUsThe MMU must be off.Instruction cache may be on or off.Data cache must be off.- The boot loader is expected to call the kernel image by jumpingdirectly to the first instruction of the kernel image. 可以看出bootloader最少具备5项功能,上面比较清晰。可以看出,现在2

17、.4的内核都是希望采用tagged list的方式来进行传递的,这里没有提到比较老的方式。这里要特别注意的是,r2 = physical address of tagged list in system RAM.,这里的“必须”是针对于tagged list而言的,如果采用param_struct,则并没有这个限制。这在后面将会详细分析,而这正是可能导致疑惑的地方。2、参数传递数据结构的定义位置【include/asm/setup.h】,在这里就可以看到两种参数传递方式了。可以说,现在bootloader和Linux kernel约定的参数传递机制就是这两种,必须严格按照这两种机制进行传输,否

18、则的话,kernel可能因为无法识别bootloader传递过来的参数而导致无法启动。关于这两种方式,在这里还有说明:/* linux/include/asm/setup.h* Copyright (C) 1997-1999 Russell King* This program is free software; you can redistribute it and/or modify* it under the terms of the GNU General Public License version 2 as* published by the Free Software Found

19、ation.* Structure passed to kernel to tell it about the* hardware its running on. See linux/Documentation/arm/Setup* for more info.* NOTE:* This file contains two ways to pass information from the boot* loader to the kernel. The old struct param_struct is deprecated,* but it will be kept in the kern

20、el for 5 years from now* (2001). This will allow boot loaders to convert to the new struct* tag way.*/ 这说明,现在参数传递必须要采用tag方式,因为现在新的kernel已经不支持param_struct方式了。不幸的是,vivi还是采用的param_struct方式。这里暂时以param_struct为主分析,考虑以后更新为tag方式。在这里你也可以参考【Documentation/arm/setup】,里面有关于选项具体含义的详细说明。(在这里多说几句。Linux的Documentatio

21、n是一个很好的学习库,几乎所有的问题在这里都能有初步的解答。如果要想继续深入,那么就要读源代码了。学习上,先看README,然后翻阅Documentation,无疑是一条捷径。而且,是否有完备的文档,也是判断这个软件是否优秀的重要标准。)二、vivi设置Linux参数分析 上面对bootloader与Linux kernel之间参数传递的两种方式已经有了一个总体的理解。下面就来先看vivi部分如何设置Linux参数。【init/main.c】boot_or_vivi()-run_autoboot()-exec_string(boot) 到此,也就是要执行boot命令。与命令相关部分都在【lib

22、/command.c】中,找到boot_cmd,然后跟踪至【lib/boot_kernel.c】,boot的执行行为函数为command_boot(),继续分析:【lib/boot_kernel.c】command_boot()-主要就是三步工作。 获取media_type。media_type = get_param_value(media_type, &ret); media_type是重要的,因为对于不同的存储介质,底层的驱动函数是不同的。通过media_type这个顶层抽象,实现了与底层驱动的联系。armlinuxlqm include$ cat boot_kernel.h #ifnd

23、ef _VIVI_BOOT_KERNEL_H_#define _VIVI_BOOT_KERNEL_H_/* * Media Type: A type of storage device that contains the linux kernel* +-+-+* | Value(Integer) | Type |* +-+-+* | 0 | UNKNOWN | * | 1 | RAM |* | 2 | NOR Flash Memory |* | 3 | SMC (NAND Flash Memory) on the S3C2410 |* +-+-+*/enum MT_UNKNOWN = 0, M

24、T_RAM, MT_NOR_FLASH, MT_SMC_S3C2410;#endif /* _VIVI_BOOT_KERNEL_H_ */ 上面就是vivi支持的media_type,现在此开发板是MT_SMC_S3C2410,也就是nand flash memory的选择部分。 获取nand flash的kernel分区信息,为下载做好准备kernel_part = get_mtd_partition(kernel); if (kernel_part = NULL) printk(Cant find default kernel partitionn); return; from = ker

25、nel_part-offset; size = kernel_part-size; 这里获得了kernel所在nand flash的起始地址和大小。这里应该注意,虽然kernel_part-offset是偏移量,但是这个偏移是相对于0x00000000而言,所以这时的offset就是对应的起始地址。当然,对nand flash来说,这里的地址并非是内存映射,需要做一系列的变化,具体是在nand_read_ll函数中,前面的基本实验已经做过了。 启动内核boot_kernel(from, size, media_type); 利用前面得到的media_type,from,size就可以来启动内核

26、了,当然还有多步工作要去做。具体包括如下内容:(1)获取内存基地址boot_mem_base = get_param_value(boot_mem_base, &ret); 在vivi中,sdram是从0x30000000开始的,所以这里的boot_mem_base就是0x30000000.(2)把kernel映象从nand flash复制到sdram的固定位置 to = boot_mem_base + LINUX_KERNEL_OFFSET; printk(Copy linux kernel from 0x%08lx to 0x%08lx, size = 0x%08lx . , from,

27、to, size); ret = copy_kernel_img(to, (char *)from, size, media_type); 这里LINUX_KERNEL_OFFSET是0x8000,关于为什么是0x8000,这是历史原因造成的,是Linux内核的一个约定,具体可以查看Linux内核的源代码中的arch/arm/kernel/head_armv.S,如下:/* We place the page tables 16K below TEXTADDR. Therefore, we must make sure* that TEXTADDR is correctly set. Curr

28、ently, we expect the least significant* short to be 0x8000, but we could probably relax this restriction to* TEXTADDR PAGE_OFFSET + 0x4000* Note that swapper_pg_dir is the virtual address of the page tables, and* pgtbl gives us a position-independent reference to these tables. We can* do this because stext = TEXTADDR* swapper_pg_dir, pgtbl and krnladr are all closely related.*/ 可以看出,TEXTADDR就是stext的地址,本开发板上为0x30008000,在0x30008000往下,会放置16K的页表,预计是0x8000.不过此处可能会放松这个限制。另外,我们的一些参数也会放到内存起始区域。这在后面就可以看到。总之,这个地方的位置boot_mem_base也就是kernel的第一条指令所在地,最后的程序跳转要跳到这个位置。(

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1