kernel的Makefile分析
2013-03-18 11:09
253 查看
以make uImage的过程进行分析
make uImage V=1 //会把命令详细地给你列出
分析makefie的目的:
1.第一个文件 head.S
2.链接脚本,文件是如何排列的。
vmlinux.lds是编译后生成的
在Kernel下面有几个Makefile:
1.子目录下面的Makefile
2.对应架构体系的Makefile,一般在目录arch/$(ARCH)/下面
3.顶层的Makefile
下面就研究这些Makefile
1.子目录下的Makefile
在子目录下的Makefile基本上的格式如下:
obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o
CONFIG_TOUCHSCREEN_S3C2410可以为y或m,
y:表示将s3c2410_ts.c编译进内核
m:表示将s3c2410_ts.c编译成一个模块
如果要将a.c b.c编译进内核,只要在Makefile中加入obj-y + = a.o b.o即可
那么如何将a.c b.c两个文件编译成一个模块呢???(将两个文件编译成一个模块)
在Makefile中加入:
obj-m + = ab.o //编译成ab模块
ab-objs : = a.o b.o
2.架构相关的Makefile
当在命令行中执行make uImage编译uImage的时候发现顶层的Makefile没有uImage的目标,可以想象一下,顶层Makefile一定将架构相关的Makefile包含了进去。
include $(srctree)/arch/$(ARCH)/Makefile //这就将架构相关的Makefile包含了进去
下面看下如何生成uImage的:
zImage Image xipImage bootpImage uImage: vmlinux
$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
uImage的依赖是vmlinux,也就是所谓的真正的内核。
下面先看看vmlinux是如何生成的:
通过sourceinsight发现vmlinux是在顶层Makefile中生成的,
vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE
ifdef CONFIG_HEADERS_CHECK
$(Q)$(MAKE) -f $(srctree)/Makefile headers_check
endif
$(call if_changed_rule,vmlinux__)
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $@
$(Q)rm -f .old_version
生成vmlinux的命令比较庞大,可以通过在命令行执行:
make uImage V=1进行查看
从上面的命令可知vmlinux的依赖为:
$(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE
$(vmlinux-lds)
vmlinux-lds := arch/$(ARCH)/kernel/vmlinux.lds
即:
vmlinux-lds := arch/arm/kernel/vmlinux.lds
$(vmlinux-init)
vmlinux-init := $(head-y) $(init-y)
查找$(head-y)发现它在架构相关的Makefile中定义
head-y := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o
= arch/arm/kernel/head.o arch/arm/kernel/init_task.o
/*注意MMUEXT是在arch/arm/Makefile中定义,对于没有MMU的处理器,MMUEXT = -nommu,使用head-nommu.S,对于有MMU的处理器,MMUEXT为空,使用head.S*/
init-y := init/
init-y := $(patsubst %/, %/built-in.o, $(init-y))
*******************************************************************************
插讲一个Makefile的函数patsubst:
patsubst ( patten substitude, 匹配替换的缩写)函数。它需要3个参数——第一个是
一个需要匹配的式样,第二个表示用什么来替换它,第三个是一个需要被处理的由空格分隔
的字列。例如,处理那个经过上面定义后的变量,
OBJS = $(patsubst %.c,%.o,$(SOURCES))
这行将处理所有在 SOURCES 字列中的字(一列文件名),如果它的 结尾是 '.c' ,就
用 '.o' 把 '.c' 取代。注意这里的 % 符号将匹 配一个或多个字符,而它每次所匹配的字
串叫做一个‘柄’(stem) 。 在第二个参数里, % 被解读成用第一参数所匹配的那个柄。
********************************************************************************
即:
vmlinux-init := arch/arm/kernel/head.o arch/arm/kernel/init_task.o init/built-in.o
$(vmlinux-main)
vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y)
core-y := usr/
core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
core-y := $(patsubst %/, %/built-in.o, $(core-y))
= usr/built-in.o kernel/built-in.o mm/built-in.o fs/built-in.o ipc/built-in.o security/built-in.o crypto/built-in.o block/built-in.o
libs-y := lib/
libs-y1 := $(patsubst %/, %/lib.a, $(libs-y))
libs-y2 := $(patsubst %/, %/built-in.o, $(libs-y))
libs-y := $(libs-y1) $(libs-y2)
= lib/lib.a lib/built-in.o
drivers-y := drivers/ sound/
drivers-y := $(patsubst %/, %/built-in.o, $(drivers-y))
= drivers/built-in.o sound/built-in.o
net-y := net/
net-y := $(patsubst %/, %/built-in.o, $(net-y))
= net/built-in.o
即:
vmlinux-main := usr/built-in.o kernel/built-in.o mm/built-in.o fs/built-in.o ipc/built-in.o security/built-in.o crypto/built-in.o block/built-in.o lib/lib.a lib/built-in.o drivers/built-in.o sound/built-in.o net/built-in.o
vmlinux的依赖已经分析完毕,下面看看vmlinux是如何生成的,可以通过执行:
make uImage V=1查看
V=1 表示可以将命令更加详细地列出来
编译命令如下:
arm-linux-ld -EL -p --no-undefined -X -o vmlinux -T arch/arm/kernel/vmlinux.lds arch/arm/kernel/head.o arch/arm/kernel/init_task.o
init/built-in.o --start-group usr/built-in.o arch/arm/kernel/built-in.o arch/arm/mm/built-in.o arch/arm/common/built-in.o
arch/arm/mach-s3c2410/built-in.o arch/arm/mach-s3c2400/built-in.o arch/arm/mach-s3c2412/built-in.o
arch/arm/mach-s3c2440/built-in.o arch/arm/mach-s3c2442/built-in.o arch/arm/mach-s3c2443/built-in.o arch/arm/nwfpe/built-in.o
arch/arm/plat-s3c24xx/built-in.o kernel/built-in.o mm/built-in.o fs/built-in.o ipc/built-in.o security/built-in.o crypto/built-in.o
block/built-in.o arch/arm/lib/lib.a lib/lib.a arch/arm/lib/built-in.o lib/built-in.o drivers/built-in.o sound/built-in.o net/built-in.o
--end-group .tmp_kallsyms2.o
解析:
-T arch/arm/kernel/vmlinux.lds :指定了链接脚本,这个文件是编译后生成的。
arch/arm/kernel/head.o 内核运行的第一个文件为head.S
3.顶层目录的Makefile
包含了
include $(srctree)/arch/$(ARCH)/Makefile //架构相关的Makefile
-include include/linux/autoconf.h //用于c源码的config
-include include/config/auto.conf //用于底层Makefile的config
make uImage V=1 //会把命令详细地给你列出
分析makefie的目的:
1.第一个文件 head.S
2.链接脚本,文件是如何排列的。
vmlinux.lds是编译后生成的
在Kernel下面有几个Makefile:
1.子目录下面的Makefile
2.对应架构体系的Makefile,一般在目录arch/$(ARCH)/下面
3.顶层的Makefile
下面就研究这些Makefile
1.子目录下的Makefile
在子目录下的Makefile基本上的格式如下:
obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o
CONFIG_TOUCHSCREEN_S3C2410可以为y或m,
y:表示将s3c2410_ts.c编译进内核
m:表示将s3c2410_ts.c编译成一个模块
如果要将a.c b.c编译进内核,只要在Makefile中加入obj-y + = a.o b.o即可
那么如何将a.c b.c两个文件编译成一个模块呢???(将两个文件编译成一个模块)
在Makefile中加入:
obj-m + = ab.o //编译成ab模块
ab-objs : = a.o b.o
2.架构相关的Makefile
当在命令行中执行make uImage编译uImage的时候发现顶层的Makefile没有uImage的目标,可以想象一下,顶层Makefile一定将架构相关的Makefile包含了进去。
include $(srctree)/arch/$(ARCH)/Makefile //这就将架构相关的Makefile包含了进去
下面看下如何生成uImage的:
zImage Image xipImage bootpImage uImage: vmlinux
$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
uImage的依赖是vmlinux,也就是所谓的真正的内核。
下面先看看vmlinux是如何生成的:
通过sourceinsight发现vmlinux是在顶层Makefile中生成的,
vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE
ifdef CONFIG_HEADERS_CHECK
$(Q)$(MAKE) -f $(srctree)/Makefile headers_check
endif
$(call if_changed_rule,vmlinux__)
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $@
$(Q)rm -f .old_version
生成vmlinux的命令比较庞大,可以通过在命令行执行:
make uImage V=1进行查看
从上面的命令可知vmlinux的依赖为:
$(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE
$(vmlinux-lds)
vmlinux-lds := arch/$(ARCH)/kernel/vmlinux.lds
即:
vmlinux-lds := arch/arm/kernel/vmlinux.lds
$(vmlinux-init)
vmlinux-init := $(head-y) $(init-y)
查找$(head-y)发现它在架构相关的Makefile中定义
head-y := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o
= arch/arm/kernel/head.o arch/arm/kernel/init_task.o
/*注意MMUEXT是在arch/arm/Makefile中定义,对于没有MMU的处理器,MMUEXT = -nommu,使用head-nommu.S,对于有MMU的处理器,MMUEXT为空,使用head.S*/
init-y := init/
init-y := $(patsubst %/, %/built-in.o, $(init-y))
*******************************************************************************
插讲一个Makefile的函数patsubst:
patsubst ( patten substitude, 匹配替换的缩写)函数。它需要3个参数——第一个是
一个需要匹配的式样,第二个表示用什么来替换它,第三个是一个需要被处理的由空格分隔
的字列。例如,处理那个经过上面定义后的变量,
OBJS = $(patsubst %.c,%.o,$(SOURCES))
这行将处理所有在 SOURCES 字列中的字(一列文件名),如果它的 结尾是 '.c' ,就
用 '.o' 把 '.c' 取代。注意这里的 % 符号将匹 配一个或多个字符,而它每次所匹配的字
串叫做一个‘柄’(stem) 。 在第二个参数里, % 被解读成用第一参数所匹配的那个柄。
********************************************************************************
即:
vmlinux-init := arch/arm/kernel/head.o arch/arm/kernel/init_task.o init/built-in.o
$(vmlinux-main)
vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y)
core-y := usr/
core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
core-y := $(patsubst %/, %/built-in.o, $(core-y))
= usr/built-in.o kernel/built-in.o mm/built-in.o fs/built-in.o ipc/built-in.o security/built-in.o crypto/built-in.o block/built-in.o
libs-y := lib/
libs-y1 := $(patsubst %/, %/lib.a, $(libs-y))
libs-y2 := $(patsubst %/, %/built-in.o, $(libs-y))
libs-y := $(libs-y1) $(libs-y2)
= lib/lib.a lib/built-in.o
drivers-y := drivers/ sound/
drivers-y := $(patsubst %/, %/built-in.o, $(drivers-y))
= drivers/built-in.o sound/built-in.o
net-y := net/
net-y := $(patsubst %/, %/built-in.o, $(net-y))
= net/built-in.o
即:
vmlinux-main := usr/built-in.o kernel/built-in.o mm/built-in.o fs/built-in.o ipc/built-in.o security/built-in.o crypto/built-in.o block/built-in.o lib/lib.a lib/built-in.o drivers/built-in.o sound/built-in.o net/built-in.o
vmlinux的依赖已经分析完毕,下面看看vmlinux是如何生成的,可以通过执行:
make uImage V=1查看
V=1 表示可以将命令更加详细地列出来
编译命令如下:
arm-linux-ld -EL -p --no-undefined -X -o vmlinux -T arch/arm/kernel/vmlinux.lds arch/arm/kernel/head.o arch/arm/kernel/init_task.o
init/built-in.o --start-group usr/built-in.o arch/arm/kernel/built-in.o arch/arm/mm/built-in.o arch/arm/common/built-in.o
arch/arm/mach-s3c2410/built-in.o arch/arm/mach-s3c2400/built-in.o arch/arm/mach-s3c2412/built-in.o
arch/arm/mach-s3c2440/built-in.o arch/arm/mach-s3c2442/built-in.o arch/arm/mach-s3c2443/built-in.o arch/arm/nwfpe/built-in.o
arch/arm/plat-s3c24xx/built-in.o kernel/built-in.o mm/built-in.o fs/built-in.o ipc/built-in.o security/built-in.o crypto/built-in.o
block/built-in.o arch/arm/lib/lib.a lib/lib.a arch/arm/lib/built-in.o lib/built-in.o drivers/built-in.o sound/built-in.o net/built-in.o
--end-group .tmp_kallsyms2.o
解析:
-T arch/arm/kernel/vmlinux.lds :指定了链接脚本,这个文件是编译后生成的。
arch/arm/kernel/head.o 内核运行的第一个文件为head.S
3.顶层目录的Makefile
包含了
include $(srctree)/arch/$(ARCH)/Makefile //架构相关的Makefile
-include include/linux/autoconf.h //用于c源码的config
-include include/config/auto.conf //用于底层Makefile的config
相关文章推荐
- 嵌入式 Linux开发Kernel移植(三)——Kernel工程Makefile分析
- 嵌入式 Linux开发Kernel移植(三)——Kernel工程Makefile分析
- 编译kernel: 根据内核makefile,分析内核的生成过程
- kernel makefile分析之include路径分析
- Kernel顶层Makefile文件分析
- Kernel 顶层Makefile文件引用Scripts/Kbuild.include分析
- linux kernel makefile整体分析
- grub kernel.img makefile源码分析
- Linux Kernel Makefile Test
- Kernel 中断分析六——softirq
- Linux Makefile分析-vmlinux生成
- Kernel logo到Bootanimaiton显示之源码分析
- linxu kernel version 1.0 TCP/IP 协议栈源代码分析1, UDP协议发送数据.
- Linux kernel config and makefile system
- Android Makefile and build system 分析(转)
- Uboot 2014.07 makefile分析
- linux源码Makefile的详细分析
- uboot makefile 分析 转
- Uboot Makefile 分析
- redis源码分析(1)--makefile和目录结构分析