要分析内核源代码首先得知道怎样编译生成最终的二进制代码
根据操作过程得到相应的第一个执行的文件
目的:
1.第一个执行的文件是什么?
2.连接脚本怎么排布
make uImage
---->arch/arm/Makefile--->uImage:vmlinux:vmlinux才是真正的内核 --------->底层的Makefile被顶层的Makefile所包含
vmlinux 在顶层的Makefile中
要看vmlinux具体的原料----->1.分析Makefile 2.从编译过程中查看
Makefile分析
1.决定编译那些文件
编译从顶层的Makefile开始,然后递归进入各级子目录调用他们的Makefile Makefile决定了要编译包含那些文件夹,那些文件将被编译
2.根据.config文件决定编译那些文件,那些文件被编译进内核,那些被编译进模块
obj-y+=xxxx.o 编译进内核
obj-m+=xxxx.o 编译进模块
obj- +=xxxx.o 不处理
3.最后将包含的文件夹下生成的built-in.o、lib.a连接成内核映象文件vmlinux
arch/arm/Makefile
head-y := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o
libs-y := arch/arm/lib/ $(libs-y)
顶层Makefile
init-y := init/
drivers-y := drivers/ sound/ firmware/
net-y := net/
libs-y := lib/
core-y := usr/
# Build vmlinux
# ---------------------------------------------------------------------------
# vmlinux is built from the objects selected by $(vmlinux-init) and
# $(vmlinux-main). Most are built-in.o files from top-level directories
# in the kernel tree, others are specified in arch/$(ARCH)/Makefile.
# Ordering when linking is important, and $(vmlinux-init) must be first.
#
# vmlinux
# ^
# |
# +-< $(vmlinux-init)
# | +--< init/version.o + more
# |
# +--< $(vmlinux-main)
# | +--< driver/built-in.o mm/built-in.o + more
# |
# +-< kallsyms.o (see description in CONFIG_KALLSYMS section)
#
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
文件的顺序是根据相应变量的前后位置
如:head-y:=a.o
head-y+=b.o
则先执行a.o文件
arch/arm/kernel/vmlinux.lds文件内容
SECTIONS
{
. = 0xC0000000 + 0x00008000; //代码段的起始地址
.text.head : {
_stext = .;
_sinittext = .;
*(.text.head)
}
之后的init段,text段,data段都类似
段怎么分布由lds决定
所有的顺序由Makefile中.o文件出现的顺序决定
编译过程总结:
1.配置文件.config中定义了一系列的的变量,Makefile将结合他们来决定那些文件被编译进内核、那些文件被编译进模块、涉及那些子目录
2.顶层的Makefile和arch/$(ARCH)/Makefile决定根目录下那些子目录、arch/$(ARCH)目录下那些文件和目录将被编译进内核
3.最后各级子目录下的Makefile决定所在目录下那些文件将被编译进内核,那些文件将被编成模块(即驱动程序),进入那些子目录继续调用他们的Makefile
4.顶层Makefile和arch/$(ARCH)/Makefile设置了可以影响所有文件的编译、连接选项CFLAGS、AFLAGS、LDFLAGS、ARFLAGS
5.各级子目录下的Makefile中可以设置能够影响当前目录下所有文件的编译、连接选项:EXTRA_CFLAGS\EXTRA_AFLAGS\EXTRA_LDFLAGS\EXTRA_ARFLAGS还可以设置可以影响某个文件的编译选项:CFLAGS_$@,AFLAGS_$@
6.顶层的Makefile按照一定的顺序组织文件,根据连接脚本arch/$(ARCH)/kernel/vmlinux.lds生成顶层的映象文件vmlinux
根据操作过程得到相应的第一个执行的文件
目的:
1.第一个执行的文件是什么?
2.连接脚本怎么排布
make uImage
---->arch/arm/Makefile--->uImage:vmlinux:vmlinux才是真正的内核 --------->底层的Makefile被顶层的Makefile所包含
vmlinux 在顶层的Makefile中
要看vmlinux具体的原料----->1.分析Makefile 2.从编译过程中查看
Makefile分析
1.决定编译那些文件
编译从顶层的Makefile开始,然后递归进入各级子目录调用他们的Makefile Makefile决定了要编译包含那些文件夹,那些文件将被编译
2.根据.config文件决定编译那些文件,那些文件被编译进内核,那些被编译进模块
obj-y+=xxxx.o 编译进内核
obj-m+=xxxx.o 编译进模块
obj- +=xxxx.o 不处理
3.最后将包含的文件夹下生成的built-in.o、lib.a连接成内核映象文件vmlinux
arch/arm/Makefile
head-y := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o
libs-y := arch/arm/lib/ $(libs-y)
顶层Makefile
init-y := init/
drivers-y := drivers/ sound/ firmware/
net-y := net/
libs-y := lib/
core-y := usr/
# Build vmlinux
# ---------------------------------------------------------------------------
# vmlinux is built from the objects selected by $(vmlinux-init) and
# $(vmlinux-main). Most are built-in.o files from top-level directories
# in the kernel tree, others are specified in arch/$(ARCH)/Makefile.
# Ordering when linking is important, and $(vmlinux-init) must be first.
#
# vmlinux
# ^
# |
# +-< $(vmlinux-init)
# | +--< init/version.o + more
# |
# +--< $(vmlinux-main)
# | +--< driver/built-in.o mm/built-in.o + more
# |
# +-< kallsyms.o (see description in CONFIG_KALLSYMS section)
#
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
文件的顺序是根据相应变量的前后位置
如:head-y:=a.o
head-y+=b.o
则先执行a.o文件
arch/arm/kernel/vmlinux.lds文件内容
SECTIONS
{
. = 0xC0000000 + 0x00008000; //代码段的起始地址
.text.head : {
_stext = .;
_sinittext = .;
*(.text.head)
}
之后的init段,text段,data段都类似
段怎么分布由lds决定
所有的顺序由Makefile中.o文件出现的顺序决定
编译过程总结:
1.配置文件.config中定义了一系列的的变量,Makefile将结合他们来决定那些文件被编译进内核、那些文件被编译进模块、涉及那些子目录
2.顶层的Makefile和arch/$(ARCH)/Makefile决定根目录下那些子目录、arch/$(ARCH)目录下那些文件和目录将被编译进内核
3.最后各级子目录下的Makefile决定所在目录下那些文件将被编译进内核,那些文件将被编成模块(即驱动程序),进入那些子目录继续调用他们的Makefile
4.顶层Makefile和arch/$(ARCH)/Makefile设置了可以影响所有文件的编译、连接选项CFLAGS、AFLAGS、LDFLAGS、ARFLAGS
5.各级子目录下的Makefile中可以设置能够影响当前目录下所有文件的编译、连接选项:EXTRA_CFLAGS\EXTRA_AFLAGS\EXTRA_LDFLAGS\EXTRA_ARFLAGS还可以设置可以影响某个文件的编译选项:CFLAGS_$@,AFLAGS_$@
6.顶层的Makefile按照一定的顺序组织文件,根据连接脚本arch/$(ARCH)/kernel/vmlinux.lds生成顶层的映象文件vmlinux