WDS1期第10课 内核 3 内核之Makefile

整个内核Makefile的分析过程与uboot的Makefile分析类似,最终都是找到链接文件lds和第一个文件.s是哪个,.S中可以看到内核的启动流程。

选择子目录下的Makefile,drivers/char/Makefile,-y表示被编译进内核,-m表示编译成模块

obj-y	 += mem.o random.o tty_io.o n_tty.o tty_ioctl.o

组合成模块:

obj-m   += ab.o
ab-objs := a.o  b.o

a.c b.c生成a.0 b.o,最终ab.ko

顶层Makefile

根据命令和顶层Makefile顺藤摸瓜,编译内核时,make或make uImage命令,在顶层Makefile中没有uImage,uImage在arch/arm/Makefile中,所以子目录下的M会被包含到顶层的M,

根目录下:
ARCH		?= arm
CROSS_COMPILE	?= arm-linux-
...
include $(srctree)/arch/$(ARCH)/Makefile

子目录下:
zImage Image xipImage bootpImage uImage: vmlinux

由上可知,ARCH也在顶层M目录下,include $(srctree)/arch/$(ARCH)/Makefile --> include $(srctree)/arch/arm/Makefile,也就是顶层M下包含了子层那个M,所以可以找到uImage。
  之前由.config生成的auto.conf是Makefile的参数来源之一,所以它也被包含在顶层M中,

-include include/config/auto.conf

回到上上面,uImage依赖vmlinux(真内核),第一个目标是生成vmlinux。它依赖一堆东西,链接文件/初始化/主要文件等

all: vmlinux
...
# vmlinux image - including updated kernel symbols
vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE
...

vmlinux-init := $(head-y) $(init-y)

...
# Objects we will link into vmlinux / subdirs we need to visit
init-y		:= init/
...
init-y		:= $(patsubst %/, %/built-in.o, $(init-y))

...
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))
...
libs-y		:= lib/
libs-y1		:= $(patsubst %/, %/lib.a, $(libs-y))
libs-y2		:= $(patsubst %/, %/built-in.o, $(libs-y))
libs-y		:= $(libs-y1) $(libs-y2)
...
drivers-y	:= drivers/ sound/
drivers-y	:= $(patsubst %/, %/built-in.o, $(drivers-y))
...
net-y		:= net/
net-y		:= $(patsubst %/, %/built-in.o, $(net-y))

  init-y那两句是将所有init/目录下的文件编成init/built-in.o文件。
  在顶层找不到head-y,所以在arch/arm/Makefile中,可见head-y由两个文件组成,MMUEXT没有定义,就是head.o 和 init_task.o组成,

#Default value
head-y		:= arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o

vmlinux-main依赖核心/驱动/网络,vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y)
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/lib.a lib/built-in.o
drivers-y最终是 drivers/built-in.o sound/built-in.o
net-y最终是 net/built-in.o

以上大堆垃圾怎么组合编译生成vmlinux的,还需看vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE其他,但是很庞大,

# vmlinux image - including updated kernel symbols
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

可以看编译内核最后的一些提示信息来反向分析,先删除rm vmlinux,再make uImage V=1,V=1表示详细列出信息,最终输出vmlinux,与
vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE对应,
所以链接文件arch/arm/kernel/vmlinux.lds ,和第一个文件arch/arm/kernel/head.o很重要,

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

uImage依赖vmlinux,vmlinux依赖$(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o),其中vmlinux-main由$(core-y) $(libs-y) $(drivers-y) $(net-y)生成。

所以链接文件arch/arm/kernel/vmlinux.lds ,和第一个文件arch/arm/kernel/head.o很重要,
arch/arm/kernel/vmlinux.lds内容如下,首先给出内核应该存放的位置,但这里是虚拟地址。下面接着放所有文件的(.text.head)段,然后所有文件的(.init.text)段。文件的顺序由.o的出现的顺序决定,.o内部的各个段存放的顺序由lds链接脚本决定,

SECTIONS
{
 . = (0xc0000000) + 0x00008000;
 .text.head : {
  _stext = .;
  _sinittext = .;
  *(.text.head)
 }
 .init : { /* Init code and data		*/
   *(.init.text)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值