1.首先是获得linux内核源码,好像是废话,下载地址如下:ftp://ftp.kernel.org/pub/linux/kernel/v2.6/下载:
linux-2.6.16.22.tar.bz2 patch-2.6.22.6.bz2
上面一步需要说明的是一般而言,linux内核的各个补丁文件是根据某个linux内核的版本号来作的patch。
将上面的两个压缩文件解压:
tar jxvf linux-2.6.22.tar.bz2
tar jxvf patch-2.6.22.6.bz2
cd linux-2.6.22
patch -p1 < ../patch-2.6.22.6
2.linux内核源码结构和Makefile分析
linux内核源码的结构比较清晰,我就不罗嗦了,如果对于linux源码的结构不是很了解的话,可以参考下面的文章
http://www.kerneltravel.net/kernel-book/%E7%AC%AC%E4%B8%80%E7%AB%A0%E8%B5%B0%E8%BF%9Blinux/1.6.2.htm
对于移植linux到s3c2410而言,主要的工作目录是/arch/arm/下。
在windows中大多是IDE来负责项目的管理,但是在linux中主要是通过Makefile来实现相应的功能。Makefiie主要有下面的
三个作用:
1.首先决定编译那些文件
2.怎样编译这些文件
3.如何链接这些编译完的文件,他们的顺序有是什么。
###################
1.首先决定编译那些文件
##################
linux中Makefie体系:
在linux内核文件夹中的Documentation/kbuild/makefiles.txt中对内核中的Makefile中提供了详细的信息:
The Makefiles have five parts:
Makefile the top Makefile. 顶层的Makefile
.config the kernel configuration file.配置文件,在顶层的Makefile中使用.config来决定使用那些文件
arch/$(ARCH)/Makefile the arch Makefile.和体系平台相关的Makefile
scripts/Makefile.* common rules etc. for all kbuild Makefiles.Makefile公用的通用规则,脚本等。
kbuild Makefiles there are about 500 of these.各个子目录下的Makefile,被该上层的Makefile调用
The top Makefile reads the .config file, which comes from the kernel
configuration process.
顶层的Makefile读取.config中的信息,这些.config信息来自于make menuconfig中
The top Makefile is responsible for building two major products: vmlinux
(the resident kernel image) and modules (any module files).
顶层的Makefile主要是用来编译mlinux和modules的。
It builds these goals by recursively descending into the subdirectories of
the kernel source tree.
The list of subdirectories which are visited depends upon the kernel
configuration. The top Makefile textually includes an arch Makefile
with the name arch/$(ARCH)/Makefile. The arch Makefile supplies
architecture-specific information to the top Makefile.
Each subdirectory has a kbuild Makefile which carries out the commands
passed down from above. The kbuild Makefile uses information from the
.config file to construct various file lists used by kbuild to build
any built-in or modular targets.
scripts/Makefile.* contains all the definitions/rules etc. that
are used to build the kernel based on the kbuild makefiles.
然后下面根据Makefile的三个作用来分析这五类Makefile作用。
1.决定编译那些文件:linux内核的编译过程是从顶层的Makefile来开始编译的,然后递归的调用相应的文件夹下的Makefile,
主要分为三个步骤:
最顶层的Makefile决定相应的那些子目录来编译进内核
arch/$(ARCH)/Makefile决定的是该目录下那些文件或者是文件夹被编译进内核
各级子目录下的Makefile决定所在目录下那些文件被编译进内核,那些文件被编译成模块,进入子目录继续掉调用Makefile
在顶层的Makefile中:
# Objects we will link into vmlinux / subdirs we need to visit
init-y := init/
drivers-y := drivers/ sound/
net-y := net/
libs-y := lib/
core-y := usr/
endif # KBUILD_EXTMOD
顶层的Makefile将linux源码中的子目录划分为上面的几类。
另外的在include $(srctree)/arch/$(ARCH)/Makefile就是将特定平台的Makefile包含进内核。
对于上面的ARCH的定义的话,可以通过make的参数来传递
make CROSS_COMPLIE=arm-linux-
或者是直接修改Makefile文件
ARCH ?= arm
CROSS_COMPILE ?= arm-linux-
arc/$(ARCH)/arm/下的Makefile:
#Default value
head-y := arch/arm/kernel/head.o arch/arm/kernel/init_task.o
...
# If we have a machine-specific directory, then include it in the build.
core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
core-y += $(MACHINE)
core-$(CONFIG_FPE_NWFPE) += arch/arm/nwfpe/
core-$(CONFIG_FPE_FASTFPE) += $(FASTFPE_OBJ)
core-$(CONFIG_VFP) += arch/arm/vfp/
...
libs-y := arch/arm/lib/ $(libs-y)
在编译内核时,make会依次进入上面的所列出的目录里,然后执行其中的Makefile,最后head-y所表示的文件将被连接
到vmlinux中。
arch/$(ARCH)/arm/kernel/Makefile中:
# Object file lists.
obj-y := compat.o entry-armv.o entry-common.o irq.o \
process.o ptrace.o semaphore.o setup.o signal.o sys_arm.o \
time.o traps.o
...
head-y := head.o
...
extra-y := $(head-y) init_task.o vmlinux.lds
配置内核时,生成配置文件,顶层的Makefile包含这个config,然后根据定义中的各个变量决定编译那些文件。看看下面的
文档(Documentation/kbuild/makefiles.txt)吧。
Goal definitions are the main part (heart) of the kbuild Makefile.
These lines define the files to be built, any special compilation
options, and any subdirectories to be entered recursively.
The most simple kbuild makefile contains one line:
Example:
obj-y += foo.o
This tell kbuild that there is one object in that directory named
foo.o. foo.o will be built from foo.c or foo.S.
If foo.o shall be built as a module, the variable obj-m is used.
Therefore the following pattern is often used:
Example:
obj-$(CONFIG_FOO) += foo.o
$(CONFIG_FOO) evaluates to either y (for built-in) or m (for module).
If CONFIG_FOO is neither y nor m, then the file will not be compiled
nor linked.
################
2.怎样编译这些文件
################
如何编译文件,是通过编译时flag来指定的。他们分为三种,首先是全局的flag,在顶层Makefile或者是在arch/$(ARCH)/arm
中定义,其次是局部的,仅适用于某个Makefile中的所有文件,使用EXTRA_CFLAGS来定义。最后一种的Makefile只是针
对的是某一个具体的文件,使用CFLAG_$@来标识。
############################################
3.如何链接这些编译完的文件,他们的顺序有是什么关系
############################################
在顶层的Makefile中:
# Objects we will link into vmlinux / subdirs we need to visit
init-y := init/
drivers-y := drivers/ sound/
net-y := net/
libs-y := lib/
core-y := usr/
endif # KBUILD_EXTMOD
....
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)
...
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/$(ARCH)/kernel/vmlinux.lds
在arch/arm/Makefile中;
# If we have a machine-specific directory, then include it in the build.
core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
core-y += $(MACHINE)
core-$(CONFIG_FPE_NWFPE) += arch/arm/nwfpe/
core-$(CONFIG_FPE_FASTFPE) += $(FASTFPE_OBJ)
core-$(CONFIG_VFP) += arch/arm/vfp/
未完,待续 。。。