linux的标准内核的编译-----分离编译过程中产生的文件

来源:互联网 发布:手机页游刷元宝软件 编辑:程序博客网 时间:2024/04/30 01:44

花时间写了一个Makefile文件,用来实现编译生成的文件的完全分离。如果有人要转载,烦请写上这篇文章的链接。毕竟花时间写代码不容易。

这个Makefile文件有以下功能:
1. 可以在不修改linux内核源码目录下的所有文件的情况下,对linux的内核进行交叉编译,并且生成的文件放在另一个目录,生成modules的tar包,也放在另一个目录。

2. 不用修改内核源码中的Makefile,也能实现交叉编译。我以前碰到过这样一个问题,修改了内核源码中的Makefile文件的ARCH和CROSS_COMPILE这两个变量后,在命令行下输入make menuconfig,结果告诉我no rules to make menuconfig,估计是改时不小心,改了Makefile其它的字符了,最后的解决办法是,拷了一个没有修改的Makefile,然后就好用了。

3. 使得linux的源代码和编译生成的文件做到完全独立。如果你想了解具体的实现原理,请看linux源代码下的README文件和$make help,里面会有详细的说明。

4. 自己可以发挥自己的想象力,无限丰富下去。

先贴上我的Makefile文件。注意,由于Makefile文件前面是用Tab键隔开的,拷贝过后会变成空格键,要改成Tab键。

# The example of linux kernel build
#
#     Author: yucheng.wang
#     Email: wfing123@gmail.com
#
# My own linux kernel environment. Divided the *.o file, .config file to
# different directory.

ARCH = arm
CROSS_COMPILE = arm-linux-
CPU = s3c2410
KERNEL_DIR = linux

MAKE = /usr/bin/make

CUR_DIR = $(shell pwd)
#This directory includes the images, temprary files .config and other files.
CONFIG_DIR = $(CPU)/linux-$(CPU)-config

#You can find the kernel image file and modules in this directory
EXPORT_DIR = $(CPU)/export

ACTION =

#For install modules
INSTALL_MOD_PATH = $(EXPORT_DIR)/$(CPU)-modules
MODULEARGS += INSTALL_MOD_PATH=$(CUR_DIR)/$(INSTALL_MOD_PATH)

MAKEARGS += O=$(CUR_DIR)/$(CONFIG_DIR)
MAKEARGS += ARCH=$(ARCH)
MAKEARGS += CROSS_COMPILE=$(CROSS_COMPILE)

MAKEFLAGS += --no-print-directory

all:
ifdef ACTION
    $(MAKE) -C $(KERNEL_DIR) $(MAKEARGS) $(MAKEFLAGS) $(ACTION)
else
    @$(MAKE) echo_show 0>/dev/null
endif

echo_show:
    @echo
    @echo ==============================================================
    @echo
    @echo     You can use make ACTION=action to operate the kernel.
    @echo         like make ACTION=menuconfig
    @echo
    @echo     The default operation is make ACTION=kernelversion
    @echo     The kernel version of this kernel is:
    @$(MAKE) -C $(KERNEL_DIR) $(MAKEARGS) $(MAKEFLAGS) kernelversion 0>/dev/null
    @echo
    @echo ==============================================================
    @echo

#If you want to use shell command ,the command must be used in one line,
#like if...fi
init:
    $(MAKE) -C $(KERNEL_DIR) distclean
    @if [ ! -d $(CPU) ]; then mkdir $(CPU); fi
    @if [ ! -d $(CONFIG_DIR) ]; then mkdir $(CONFIG_DIR); fi
    @if [ ! -d $(EXPORT_DIR) ]; then mkdir $(EXPORT_DIR); fi
    $(MAKE) -C $(KERNEL_DIR) $(MAKEARGS) $(MAKEFLAGS) $(CPU)_defconfig
    @echo
    @echo ==============================================================
    @echo
    @echo     Finished init the linux kernel environment.
    @echo
    @echo ==============================================================
    @echo

menuconfig:
    $(MAKE) -C $(KERNEL_DIR) $(MAKEARGS) $(MAKEFLAGS) menuconfig
bzImage:
    $(MAKE) -C $(KERNEL_DIR) $(MAKEARGS) $(MAKEFLAGS) bzImage
uImage:
    $(MAKE) -C $(KERNEL_DIR) $(MAKEARGS) $(MAKEFLAGS) uImage
modules:
    @if [ ! -d $(CUR_DIR)/$(INSTALL_MOD_PATH) ]; /
    then mkdir $(CUR_DIR)/$(INSTALL_MOD_PATH); fi
    $(MAKE) -C linux $(MAKEARGS) $(MAKEFLAGS) modules
    $(MAKE) -C linux $(MAKEARGS) $(MAKEFLAGS) INSTALL_MOD_PATH=$(CUR_DIR)/$(INSTALL_MOD_PATH) modules_install
    @cd $(CUR_DIR)/$(INSTALL_MOD_PATH); /
    tar -cf $(CUR_DIR)/$(EXPORT_DIR)/$(CPU)-modules.tar *; /
    cd $(CUR_DIR)
    @echo
    @echo ==============================================================
    @echo
    @echo Finised build modules.
    @echo The export file is  $(EXPORT_DIR)/$(CPU)-modules.tar
    @echo
    @echo ==============================================================
    @echo
distclean:
    $(MAKE) -C $(KERNEL_DIR) $(MAKEARGS) $(MAKEFLAGS) distclean

#End file.



下面写出Makefile的使用步骤:

1. 新建一个文件夹,然后把Makefile拷进来
现在我的电脑上新建的目录是这样子的一种情况:
[wyc@wyc-desktop:mainline-2.6.34.1]$ pwd
/home/wyc/desktop/arm/mainline-2.6.34.1


2. 把你的kernel解压到当前目录下的一个目录中,我把内核源码的目录改名为linux目录,然后对这个Makefile做一些修改。
ARCH = arm
CROSS_COMPILE = arm-linux-
CPU = s3c2410
KERNEL_DIR = linux


ARCH代表你当前的架构,CROSS_COMPILE代表你的编译器,这个跟你在内核源码下做交叉编译一模一样,KERNEL_DIR表示你的linux源码目录,一定要注意,和你的Makefile在一级中。
CPU代表你的CPU类型,如果你用的arm架构,如果你用内核中已经支持的CPU来编译的话,一定要先看一下/arch/arm/configs目录下是否有$(CPU)_defconfig这个文件。
还有一种情况是,你拿着一个linux内核不支持的CPU编的话,那样,你直接把Makefile文件第65行注释掉,然后直接运行make menuconfig
-        $(MAKE) -C $(KERNEL_DIR) $(MAKEARGS) $(MAKEFLAGS) $(CPU)_defconfig
+#    $(MAKE) -C $(KERNEL_DIR) $(MAKEARGS) $(MAKEFLAGS) $(CPU)_defconfig

3.开始编译,第一步会运行make init
[wyc@wyc-desktop:mainline-2.6.34.1]$ make init
/usr/bin/make -C linux distclean
/usr/bin/make -C linux O=/home/wyc/desktop/arm/mainline-2.6.34.1/s3c2410/linux-s3c2410-config ARCH=arm CROSS_COMPILE=arm-linux-  --no-print-directory s3c2410_defconfig
  GEN     /home/wyc/desktop/arm/mainline-2.6.34.1/s3c2410/linux-s3c2410-config/Makefile
#
# configuration written to .config
#

==============================================================

Finished init the linux kernel environment.

==============================================================
它会把linux的源代码下的东西先清除掉。然后替你新建了以CPU为名称的目录,以这个Makefile为例,他替你在文件同级新建了s3c2410目录,这个目录代表你的CPU,然后在这个目录下新奸了两个目录export  linux-s3c2410-config。其中,export目录中包含kernel的所有驱动及驱动的tar包,然后linux-s3c2410-config包括你的内核中生成的文件,例如*.o,*.ko,.config,System.map等文件。
最后执行了make s3c2410_defconfig,只不过他把产生的文件都放在linux-s3c2410-config目录中了,没有对源码文件做任何删减。

4.运行完make init之后,就是普通的编译过程了,
$make menuconfig
$make uImage
$make modules
......
运行这些命令后,就在s3c2410/linux-s3c2410目录下去找生成的image吧,如果你乐意的话,也可以在Makefile的uImage规则后加一个cp命令,把uImage拷到export目录下。
在make modules完成后,将会生成一个tar包,这个包就放在export目录下。

5.如果有特殊需求,例如make deb-pkg等命令,可以用make ACTION=deb-pkg来执行,实际上,在这个规则中,make menuconfigmake ACTION=menuconfig命令相同,我也是为了不一条一条写对应内核的编译规则而加的一个命令,当然,你也可以在Makefile中加入适合你的编译特点的一些规则。

6.习惯了用vim+ctags的人,可以采用这种方法。在Makefile的平级目录中打入ctags -R linux,等生成完之后,你可以用vi linux/drivers/...来编辑源代码,并且进行代码跟踪,这样完全可以做到在内核中不加入任何一个非C代码文件。

如果大家伙儿有其它建议,欢迎给我提提意见,毕竟,写了这么长时间,不容易。

原创粉丝点击