iMXbspcustomizationAppNoteDraftV04.docx
- 文档编号:23558036
- 上传时间:2023-05-18
- 格式:DOCX
- 页数:86
- 大小:454.16KB
iMXbspcustomizationAppNoteDraftV04.docx
《iMXbspcustomizationAppNoteDraftV04.docx》由会员分享,可在线阅读,更多相关《iMXbspcustomizationAppNoteDraftV04.docx(86页珍藏版)》请在冰豆网上搜索。
iMXbspcustomizationAppNoteDraftV04
.
i.MxLinuxBSPCustomization
Abstract:
1)Thisdocumentisareadmeforbspcustomization
Keywords:
iMxLINUXBSP
Approved:
Author
COMMENTS
JohnLi(r64710@)
V0.1
Createthedocument
2009/07/03
JohnLi(r64710@)
V0.4
Changetoi.MX6X
2012/06/12
1Introduction
2GothoughtheBSP
2.1FSLi.MXBSPfolderstructure
Packages
|->arch
||->arm
|||->boot
|||->common
|||->kernel
||||->head.s
||||->head-common.s
||||->setup.c
|||->mach-mx6
||||->board-mx6dl_arm2.c
||||->board-mx6dl_sabreauto.c
||||->board-mx6dl_sabrelite.c
||||->board-mx6dl_sabresd.c
||||->cpu.c
||||->devices.c
|||->mm
||||->proc-v7.S
|->block
|->crypto
|->documention
|->drivers
||->block
||->char
||->mtd
||->serial
|||->mxc_uart.c
|->fs:
||->ext3
||->jffs2
||->ubifs:
||->yaffs2:
|->include
||->asm-generic
||->linux
||->mtd
|->init
||->main.c
|->ipc
|->kernel
||->printk.c
|->lib
|->mm
|->net
|->scriptes
|->security
|->sound
|->usr
|->virt
2.2linuxmakefile
TheusageofMakefile:
∙Whichfileswillbecompile.
∙Howtocompilethesefiles.
∙Howtolinktheobjfileanditsorder.
Topfoldermakefile
所有makefile文件的核心,从总体上控制着内核的编译,连接
.config
配置文件,在makemenuconfig时生成,所有的makefile文件,(包括顶层目录及各级子目录)都是根据.config来决定使用那些文件。
Arch/$(ARCH)/Makefile
对应体系结构的makefile,它用来决定那些体系结构相关的文件参与内核的生成,并提供一些规则赞成特定格式的内核映象
Scripts/Makefile.*
Makefile共用的通用规则,脚本等
KbuildMakefiles
各级子目录下的makefile,相对简单,被上层makefile调用来编译当前目录下的文件
Document/Documentation/kbuild/makefiles.txt对内核makefile的作用,用法
2.2.1Whichfilesbecompiled
∙Topmakefile决定内核根目录下那些子目录将被编进内核
∙Arch/$(ARCH)/Makefile决定arch/$(ARCH)目录下那些文件,目录将被编译进内核
∙各级子目录下的makefile决定此目录下那些文件将被编译进内核,那些将被编译成模块,进入那些子目录继续调用它们的makefile.
1.顶层makefile“\Makefile”
顶层makefile将13个子目录分为5类,
a)init-y:
=init/
b)drivers-y:
=drivers/sound/firmware/
c)net-y:
=net/
d)libs-y:
=lib/
e)core-y:
=usr/
core-y+=kernel/mm/fs/ipc/security/crypto/block/
include$(srctree)/arch/$(SRCARCH)/Makefile[arch目录被直接包含,扩展以上5类]
ARCH/CROSS_COMPILE变量设置
ARCH?
=$(SUBARCH)
CROSS_COMPILE?
=
2.arch/arm/Makefile
head-y:
=arch/arm/kernel/head$(MMUEXT).oarch/arm/kernel/init_task.o[除前面5类,还有一类head-y,直接以文件名出现,对于有MMU的CPU,使用文件head.s]
core-y+=arch/arm/kernel/arch/arm/mm/arch/arm/common/[进一步扩展了core-y的内容]
machine-$(CONFIG_ARCH_MX6):
=mx6[CONFIG_ARCH_MX6在配置内核中定义,可以是y,编译到内核,m,编译为模块,空,不编译]
machdirs:
=$(patsubst%,arch/arm/mach-%/,$(machine-y))
platdirs:
=$(patsubst%,arch/arm/plat-%/,$(plat-y))
core-y+=$(machdirs)$(platdirs)
libs-y:
=arch/arm/lib/$(libs-y)/[进一步扩展了lib-y的内容]
编译内核时,将依次进入init-y,core-y,libs-y,drivers-y,net-y,所列出的目录中执行他们的makefile,每个子目录都会生成一个built-in.o(libs-y所列目录会生成lib.a),最后,head-y所表示的文件将和这些built-in.o,lib.a一起连接为vmlinux.’
3.各子目录makefile
Makemenuconfig->.config,TOPmakefileincludeit
include/config/auto.conf[auto.conf只是将.config中的注释去掉,并根据topmakefile中定义的变量增加一些变量]
auto.conf中定义的变量值只有两类,y,m.各级子目录的makefile使用这些变量来决定那些文件编译到内核中,那些编译成模块,通过四种办法来确定。
a)Obj-y,编译进内核:
obj-y中定义的.o文件由当前目录下的.c,.s文件编译生成,它们连同下一层子目录中的built-in.o文件一起组合成(使用”$(LD)-r”命令)当然built-in.o文件。
此文件又被上一层makefile使用。
b)Obj-m,编译成可加载模块.
c)Lib-y,编译成库文件,要把lib.a编译时内核,在topmakefile中的libs-y变量列出的当前目录,并且内核代码一般放在lib/,arch/$(ARCH)/lib/下。
d)Obj-y,obj-m还可以用来指定要进入的下一层子目录。
2.2.2Howtocompilethesefiles
即编译选项,连接选项是什么,这些选项分三类,
∙全局的,适用于整个内核代码树。
定义在topmakefile,arch/$(ARCH)/makefile中定义,包括:
CFLAGS,AFLAGS,LDFLAGS,ARFLGAS
∙局部的,适用于某个makefile的所有文件。
EXTRA_CFLAGS,EXTRA_AFLAGS,EXTRA_LDFLAGS,EXTRA_ARFLGAS
∙个体的,只适用于某个文件。
包括CFLAG_XX,AFLAGS_XX
2.2.2Howtolinktheobjfileanditsorder
1.Topmakefile,arch/$(ARCH)/makefile定义了6类目录,head-y,init-y,drivers-y,net-y,libs-y,core-y.除了head-y,这样目录的后面直接加上built-in.o或lib.a,表示要连接进内核
∙init-y:
=$(patsubst%/,%/built-in.o,$(init-y))
∙core-y:
=$(patsubst%/,%/built-in.o,$(core-y))
∙drivers-y:
=$(patsubst%/,%/built-in.o,$(drivers-y))
∙net-y:
=$(patsubst%/,%/built-in.o,$(net-y))
libs-y1:
=$(patsubst%/,%/lib.a,$(libs-y))
libs-y2:
=$(patsubst%/,%/built-in.o,$(libs-y))
∙libs-y:
=$(libs-y1)$(libs-y2)
[patsubst将init-y转换为init/built-in.o]
2.
vmlinux-init:
=$(head-y)$(init-y)
vmlinux-main:
=$(core-y)$(libs-y)$(drivers-y)$(net-y)
vmlinux-all:
=$(vmlinux-init)$(vmlinux-main)
vmlinux-lds:
=arch/$(SRCARCH)/kernel/vmlinux.lds
∙vmlinux-all,表示所有构成vmlinux的目标文件,按顺序为head-y,init-y,core-y,libs-y,drivers-y,net-y即:
arch/arm/kernel/head.o,arch/arm/kernel/init_task.o,init/built-in.o,user/built-in.o等等
∙vmlinux-lds指定连接脚本为arch/$(ARCH)/kernel/vmlinux.lds,它是由arch/arm/kernel/vmlinux.lds.s文件生成的,规则在script/makefile.build中。
SECTIONS
{
.=0xC0000000+0x00008000;//代码段的起始地址,是一个虚拟地址
.text.head:
{
_stext=.;
_sinittext=.;
*(.text.head)
}
.init:
{/*Initcodeanddata*/内核初始化的代码与数据
……
}
.text:
{/*Realtextsegment*/真正的代码段
_text=.;/*Textandread-onlydata*/代码段和只读数据的开始地址
……
}
.=ALIGN((4096));.rodata:
AT(ADDR(.rodata)-0){…}.=ALIGN((4096));\\只读数据
_etext=.;/*Endoftextandrodatasection*/代码段和只读数据的结束地址
.=ALIGN(8192);
__data_loc=.;
.data:
AT(__data_loc){//数据段
__data_start=.;/*addressinmemory*//数据段开始地址
…
_edata=.;/数据段结束地址
}
_edata_loc=__data_loc+SIZEOF(.data);
.bss:
{//bss段,没有初始化或初值=0的全局,静态变量
_end=.;
}
/*Stabsdebuggingsections.*/调试信息段
.stab0:
{*(.stab)}
}
总结:
∙配置文件.config中定义了一系列的变量,makefile将结合它们来决定那些文件被编译进内核,那些被编译模块,涉及那些子目录。
∙顶层makefile和arch/$(ARCH)/Makefile决定根目录下那些子目录,arch/$(ARCH)下那些文件和目录将被编译进内核。
∙各级子目录下的Makefile决定所在目录下那些文件编译进内核,那些编译进模块,进入那些子目录继续调用它们的makefile.
∙Topmakefile和arch/$(ARCH)/Makefile设置了可以影响所有文件编译,连接选项。
∙各级子目录下的makefile中可以设置所有文件的编译,连接选项。
∙Topmakefile按照一定的顺序组织文件,根据连接脚本arch/$(ARCH)/kernel/vmlinux.lds生成内核映象文件vmlinux
2.2kernelKconfig
Makemenuconfig读取arch/$(ARCH)/Kconfig来生成配置界面,这个文件是所有Kconfig的入口,包括了其它目录下的Kconfig文件。
Kconfig用于配置内核,它是各种配置界面的源文件,最后生成配置文件.config,其语法参考\documentation\kbuild\kconfig-language.txt.
3Initialcallroutine
3.1initial
内核引导第一阶段:
汇编语言
使能MMU
__mmap_switched
复制数据段,清除BSS段,设置栈指针,保存CPUID到processor_id变量,保存机器类型ID到__machine_arch_type变量,调用start_kernel
使能MMU
__mmap_switched
复制数据段,清除BSS段,设置栈指针,保存CPUID到processor_id变量,保存机器类型ID到__machine_arch_type变量,调用start_kernel
内核启动的第二阶段:
C语言
3.2Firststeps(assemable)
Head.S[\arch\arm\kernel]
/*
*Kernelstartupentrypoint.内核入口
*Thisisnormallycalledfromthedecompressorcode.Therequirements
*are:
MMU=off,D-cache=off,I-cache=dontcare,r0=0,
*r1=machinenr,r2=atagspointer.进入内核要求,mmu关,dcache关,icache不关,r0=0,r1=cupid,r2=输入启动变量的指针
*Thiscodeismostlypositionindependent,soifyoulinkthekernelat
*0xc0008000,youcallthisat__pa(0xc0008000).
*Seelinux/arch/arm/tools/mach-typesforthecompletelistofmachine
*numbersforr1.
*We'retryingtokeepcraptoaminimum;DONOTaddanymachinespecific
*craphere-that'swhatthebootloader(orinextreme,welljustified
*circumstances,zImage)isfor.
*/
.section".text.head","ax"
ENTRY(stext)
msrcpsr_c,#PSR_F_BIT|PSR_I_BIT|SVC_MODE@ensuresvcmode
@andirqsdisabled进入svc模式,关中断
mrcp15,0,r9,c0,c0@getprocessorid从协处理器CP15的寄存器C0中获得CPUID,
[31:
24]
厂商编号:
0x41=A:
ARM公司
[23:
20]
产品子编号
[19:
16]
ARM体系版本号:
[15:
4]
产品主编号
[3:
0]
处理器版本号
bl__lookup_processor_type@r5=procinfor9=cpuid确定内核是否支持当前cpu,如果支持,r5返回一个用于描述处理器的结构体的地址,proc_info_list结构体原形定义在include/asm-arm/procinfo.h,表示它支持的cpu,arm这个结构体定义在arch/arm/mm/proc-v7.S
.section".proc.info.init",#alloc,#execinstr不同的proc_info_list结构支持不同的cpu,他们定义在.proc.info.init段中,连接时这些结构体组织在一起,在\arch\arm\kernel\vmlinux.lds中,
__proc_info_begin=.;//proc_info_list结构开始地址
*(.proc.info.init)
__proc_info_end=.;//proc_info_list结构结束地址
/*
*MatchanyARMv7processorcore.
*/
.type__v7_proc_info,#object
__v7_proc_info:
.long0x000f0000@RequiredIDvalue
.long0x000f0000@MaskforID
......
//cpuvalue,cpumask=0x000f0000,内核要包括arch/arm/mm/proc-v7.S文件,在\arch\arm\mm\Makefile中定义的:
obj-$(CONFIG_CPU_V7)+=proc-v7.o
CONFIG_CPU_V7定义在/include/linux/autoconf.h,它是从.config->来的。
函数__lookup_processor_type在\arch\arm\kernel\head-common.S中,根据前面读出的cpuid,存在寄存器r9中,然后从__proc_info_begin向后搜索,找到匹配的,
movsr10,r5@invalidprocessor(r5=0)?
beq__error_p@yes,error'p'
bl__lookup_machine_type@r5=machinfo
内核中对每个支持的开发板都会定义:
MACHINE_START,MACHINE_END,[\arch\arm\include\asm\mach\arch.h]来定义一个machine_desc结构,它定义了开发板相关属性和函数,包括,
MACHINE_START(MX6Q_SABRESD,"Freescalei.MX6Quad/DualLite/SoloSabre-SDBoard")机器ID,其中,MACH_TYPE_MX6Q_SABRESD定义在/include/asm-arm/Mach-types.h
/*Maintainer:
FreescaleSemiconductor,Inc.*/
.boot_params=PHYS_OFFSET+0x100,bootloader传入的参数地址
.fixup=fixup_mxc_board,
.map_io=mxc_map_io,io映射函数
.init_irq=mxc_init_irq,中断初始化函数
.init_machine=mx6_sabresd_board_init,
.timer=&mx6_sabresd_timer,
.reserve=mx6q_sabresd_reserve,
MACHINE_END
machine_desc结构,从\arch\arm\kernel\vmlinux.lds,连接在
__arch_info_begin=.;
*(.arch.info.init)
__arch_info_end=.;
bootloader会在r1中放入开发板的标记,函数__lookup_machine_type将其与machine_desc.nr比较,找到后从r5返回相应结构体machine_desc的指针
movsr8,r5@invalidmachine(r5=0)?
beq__error_a@yes,error'a'
bl__vet_atags
bl__create_page_tables//创建一级页表以建立虚拟地址到物理地址的映射关系,它用到了__lookup_processor_type函数返回的proc_info_list结构体
/*
*ThefollowingcallsCPUspecificcodeinapositionindependent
*manner.Seearch/arm/mm/proc-*.Sfordetails.r10=baseof
*xxx_proc_infostructureselectedby__lookup_machine_type
*above.Onreturn,theCPUwillbereadyfortheMMUtobe
*turnedon,andr0willholdtheCPUcontrolregistervalue.
*/
ldrr13,__switch_data@addresstojumptoafter
@mmuhasbeenenabled
adrlr,__enable_mmu@return(PIC)addres
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- iMXbspcustomizationAppNoteDraftV04