如何启动内核vivi与Linux kernel的参数传递情景分析Word格式.docx
- 文档编号:19097957
- 上传时间:2023-01-03
- 格式:DOCX
- 页数:20
- 大小:36.71KB
如何启动内核vivi与Linux kernel的参数传递情景分析Word格式.docx
《如何启动内核vivi与Linux kernel的参数传递情景分析Word格式.docx》由会员分享,可在线阅读,更多相关《如何启动内核vivi与Linux kernel的参数传递情景分析Word格式.docx(20页珍藏版)》请在冰豆网上搜索。
Date:
18May2002
Thefollowingdocumentationisrelevantto2.4.18-rmk6andbeyond.
InordertobootARMLinux,yourequireabootloader,whichisasmall
programthatrunsbeforethemainkernel.Thebootloaderisexpected
toinitialisevariousdevices,andeventuallycalltheLinuxkernel,
passinginformationtothekernel.
Essentially,thebootloadershouldprovide(asaminimum)the
following:
1.SetupandinitialisetheRAM.
2.Initialiseoneserialport.
3.Detectthemachinetype.
4.Setupthekerneltaggedlist.
5.Callthekernelimage.
1.SetupandinitialiseRAM
---------------------------
Existingbootloaders:
MANDATORY
Newbootloaders:
ThebootloaderisexpectedtofindandinitialiseallRAMthatthe
kernelwilluseforvolatiledatastorageinthesystem.Itperforms
thisinamachinedependentmanner.(Itmayuseinternalalgorithms
toautomaticallylocateandsizeallRAM,oritmayuseknowledgeof
theRAMinthemachine,oranyothermethodthebootloaderdesigner
seesfit.)
2.Initialiseoneserialport
-----------------------------
OPTIONAL,RECOMMENDED
Thebootloadershouldinitialiseandenableoneserialportonthe
target.Thisallowsthekernelserialdrivertoautomaticallydetect
whichserialportitshoulduseforthekernelconsole(generally
usedfordebuggingpurposes,orcommunicationwiththetarget.)
Asanalternative,thebootloadercanpasstherelevant'
console='
optiontothekernelviathetaggedlistsspecifingtheport,and
serialformatoptionsasdescribedin
linux/Documentation/kernel-parameters.txt.
3.Detectthemachinetype
--------------------------
OPTIONAL
Thebootloadershoulddetectthemachinetypeitsrunningonbysome
method.Whetherthisisahardcodedvalueorsomealgorithmthat
looksattheconnectedhardwareisbeyondthescopeofthisdocument.
ThebootloadermustultimatelybeabletoprovideaMACH_TYPE_xxx
valuetothekernel.(seelinux/arch/arm/tools/mach-types).
4.Setupthekerneltaggedlist
-------------------------------
OPTIONAL,HIGHLYRECOMMENDED
Thebootloadermustcreateandinitialisethekerneltaggedlist.
AvalidtaggedliststartswithATAG_COREandendswithATAG_NONE.
TheATAG_COREtagmayormaynotbeempty.AnemptyATAG_COREtag
hasthesizefieldsetto'
2'
(0x00000002).TheATAG_NONEmustset
thesizefieldtozero.
Anynumberoftagscanbeplacedinthelist.Itisundefined
whetherarepeatedtagappendstotheinformationcarriedbythe
previoustag,orwhetheritreplacestheinformationinits
entirety;
sometagsbehaveastheformer,othersthelatter.
Thebootloadermustpassataminimumthesizeandlocationof
thesystemmemory,androotfilesystemlocation.Therefore,the
minimumtaggedlistshouldlook:
+-----------+
base->
|ATAG_CORE||
+-----------+|
|ATAG_MEM||increasingaddress
|ATAG_NONE||
+-----------+v
ThetaggedlistshouldbestoredinsystemRAM.
Thetaggedlistmustbeplacedinaregionofmemorywhereneither
thekerneldecompressornorinitrd'
bootp'
programwilloverwrite
it.Therecommendedplacementisinthefirst16KiBofRAM.
5.Callingthekernelimage
TherearetwooptionsforcallingthekernelzImage.IfthezImage
isstoredinflash,andislinkedcorrectlytoberunfromflash,
thenitislegalforthebootloadertocallthezImageinflash
directly.
ThezImagemayalsobeplacedinsystemRAM(atanylocation)and
calledthere.Notethatthekerneluses16KofRAMbelowtheimage
tostorepagetables.Therecommendedplacementis32KiBintoRAM.
Ineithercase,thefollowingconditionsmustbemet:
-CPUregistersettings
r0=0,
r1=machinetypenumberdiscoveredin(3)above.
r2=physicaladdressoftaggedlistinsystemRAM.
-CPUmode
Allformsofinterruptsmustbedisabled(IRQsandFIQs)
TheCPUmustbeinSVCmode.(AspecialexceptionexistsforAngel)
-Caches,MMUs
TheMMUmustbeoff.
Instructioncachemaybeonoroff.
Datacachemustbeoff.
-Thebootloaderisexpectedtocallthekernelimagebyjumping
directlytothefirstinstructionofthekernelimage.
可以看出bootloader最少具备5项功能,上面比较清晰。
可以看出,现在2.4的内核都是希望采用taggedlist的方式来进行传递的,这里没有提到比较老的方式。
这里要特别注意的是,r2=physicaladdressoftaggedlistinsystemRAM.,这里的“必须”是针对于taggedlist而言的,如果采用param_struct,则并没有这个限制。
这在后面将会详细分析,而这正是可能导致疑惑的地方。
2、参数传递数据结构的定义位置【include/asm/setup.h】,在这里就可以看到两种参数传递方式了。
可以说,现在bootloader和Linuxkernel约定的参数传递机制就是这两种,必须严格按照这两种机制进行传输,否则的话,kernel可能因为无法识别bootloader传递过来的参数而导致无法启动。
关于这两种方式,在这里还有说明:
/*
*linux/include/asm/setup.h
*
*Copyright(C)1997-1999RussellKing
*Thisprogramisfreesoftware;
youcanredistributeitand/ormodify
*itunderthetermsoftheGNUGeneralPublicLicenseversion2as
*publishedbytheFreeSoftwareFoundation.
*Structurepassedtokerneltotellitaboutthe
*hardwareit'
srunningon.Seelinux/Documentation/arm/Setup
*formoreinfo.
*NOTE:
*Thisfilecontainstwowaystopassinformationfromtheboot
*loadertothekernel.Theoldstructparam_structisdeprecated,
*butitwillbekeptinthekernelfor5yearsfromnow
*(2001).Thiswillallowbootloaderstoconverttothenewstruct
*tagway.
*/
这说明,现在参数传递必须要采用tag方式,因为现在新的kernel已经不支持param_struct方式了。
不幸的是,vivi还是采用的param_struct方式。
这里暂时以param_struct为主分析,考虑以后更新为tag方式。
在这里你也可以参考【Documentation/arm/setup】,里面有关于选项具体含义的详细说明。
(在这里多说几句。
Linux的Documentation是一个很好的学习库,几乎所有的问题在这里都能有初步的解答。
如果要想继续深入,那么就要读源代码了。
学习上,先看README,然后翻阅Documentation,无疑是一条捷径。
而且,是否有完备的文档,也是判断这个软件是否优秀的重要标准。
)
二、vivi设置Linux参数分析
上面对bootloader与Linuxkernel之间参数传递的两种方式已经有了一个总体的理解。
下面就来先看vivi部分如何设置Linux参数。
【init/main.c】boot_or_vivi()-->
run_autoboot()-->
exec_string("
boot"
到此,也就是要执行boot命令。
与命令相关部分都在【lib/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这个顶层抽象,实现了与底层驱动的联系。
[armlinux@lqminclude]$catboot_kernel.h
#ifndef_VIVI_BOOT_KERNEL_H_
#define_VIVI_BOOT_KERNEL_H_
/*
*MediaType:
Atypeofstoragedevicethatcontainsthelinuxkernel
*+----------------+-----------------------------------------+
*|Value(Integer)|Type|
*|0|UNKNOWN|
*|1|RAM|
*|2|NORFlashMemory|
*|3|SMC(NANDFlashMemory)ontheS3C2410|
enum{
MT_UNKNOWN=0,
MT_RAM,
MT_NOR_FLASH,
MT_SMC_S3C2410
};
#endif/*_VIVI_BOOT_KERNEL_H_*/
上面就是vivi支持的media_type,现在此开发板是MT_SMC_S3C2410,也就是nandflashmemory的选择部分。
获取nandflash的kernel分区信息,为下载做好准备
kernel_part=get_mtd_partition("
kernel"
);
if(kernel_part==NULL){
printk("
Can'
tfinddefault'
kernel'
partition\n"
return;
}
from=kernel_part->
offset;
size=kernel_part->
size;
这里获得了kernel所在nandflash的起始地址和大小。
这里应该注意,虽然kernel_part->
offset是偏移量,但是这个偏移是相对于0x00000000而言,所以这时的offset就是对应的起始地址。
当然,对nandflash来说,这里的地址并非是内存映射,需要做一系列的变化,具体是在nand_read_ll函数中,前面的基本实验已经做过了。
启动内核
boot_kernel(from,size,media_type);
利用前面得到的media_type,from,size就可以来启动内核了,当然还有多步工作要去做。
具体包括如下内容:
(1)获取内存基地址
boot_mem_base=get_param_value("
boot_mem_base"
在vivi中,sdram是从0x30000000开始的,所以这里的boot_mem_base就是0x30000000.
(2)把kernel映象从nandflash复制到sdram的固定位置
to=boot_mem_base+LINUX_KERNEL_OFFSET;
printk("
Copylinuxkernelfrom0x%08lxto0x%08lx,size=0x%08lx..."
from,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,如下:
*Weplacethepagetables16KbelowTEXTADDR.Therefore,wemustmakesure
*thatTEXTADDRiscorrectlyset.Currently,weexpecttheleastsignificant
*"
short"
tobe0x8000,butwecouldprobablyrelaxthisrestrictionto
*TEXTADDR>
PAGE_OFFSET+0x4000
*Notethatswapper_pg_diristhevirtualaddressofthepagetables,and
*pgtblgivesusaposition-independentreferencetothesetables.Wecan
*dothisbecausestext==TEXTADDR
*swapper_pg_dir,pgtblandkrnladrareallcloselyrelated.
可以看出,TEXTADDR就是stext的地址,本开发板上为0x30008000,在0x30008000往下,会放置16K的页表,预计是0x8000.不过此处可能会放松这个限制。
另外,我们的一些参数也会放到内存起始区域。
这在后面就可以看到。
总之,这个地方的位置boot_mem_base也就是kernel的第一条指令所在地,最后的程序跳转要跳到这个位置。
(
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 如何启动内核vivi与Linux kernel的参数传递情景分析 如何 启动 内核 vivi Linux kernel 参数 传递 情景 分析