文章的原地址为:http://blog.sina.com.cn/s/blog_87c063060101klau.html 在此表示感谢
这里要注意的是文中提到自动生成的 /include/linux/autoconf.h 在我使用九鼎x210开发板所使用的linux内核时是在/include/generated/autoconf.h中的 ,这里要注意目录结构有些不一样
一、编译
1.解压缩
①tar xvf linux-2.6.22.6.tar.bz2
②进入linux-2.6.22.6目录
cd linux-2.6.22.6/
2.打补丁
patch -p1<../linux-2.6.22.6_jz2440.patch
3.配置内核(具体来说就是:支持哪个架构的单板)
->生成.config
①make menuconfig
->选择你所需的东西,编进内核(①做为模块编进内核 ②静态编进内核built-in.o)
->这种方法很复杂.因为配置选项太多.
②使用默认的配置,在上面修改
->在内核目录(linux-2.6.22.6/)下查找
find -name "*defconfig*" -->会搜索出很多文件
->进入 ./arch/arm/configs/ 目录看一下:
->返回 /work/system/linux-2.6.22.6$ 目录
执行:make s3c2410_defconfig ->>生成了 .config文件 (也就是Linux内核的配置文件)
->>我们的 make menuconfig 命令也是去 读 .config文件,然后出现菜单.
->.config里面的内容就是我们所需的配置内容,不同的开发板需要去做相应的修改
③使用厂家提供的配置文件(如:config_ok)
->厂商给我们提供了配置文件config_ok
那我们讲config_ok的内容拷贝到.config就可以了
cp config_ok .config
->执行make menuconfig
出现配置菜单,配置它
4.编译
①编译uImage
->make uImage
二、配置
(1) 为什么我们在编译内核之前需要配置呢? 原因很简单:需要哪些东西(也就是支持哪些东西)就配置它,让内核支持它.
从内核源码的角度来看的话,内核源码中出现了很多"判断语句"(官方的说法是:条件指示符),这样就会出现“动态编译”
的情况,内核怎么知道需要把哪些"条件指示符"所包含的内容 编译进内核呢? 就必须依靠配置文件(.config)了
总结:配置主要从两个方面出发
①从Makefile的角度
-> 静态编进内核(直接编进内核)
-> 动态编进内核(做为模块编进内核)
-> 在/include/config目录下自动生成auto.conf 给顶层Makefile使用
->>在顶层Makefile中搜索auto.conf : 可以看到 include/config/auto.conf (当然,没有配置的内核代码是找不到 include/目录下的config目录的)
在auto.conf中可以看到类似于: 这样的配置选项,这是提供给顶层Makefile使用的.
②从内核源码的角度
->“条件指示符”所指示的"代码"到底需不需要被编进内核.
->在include/linux目录下自动生成了autoconf.h这个头文件 (当然,没有配置的内核代码是找不到 autoconf.h这个头文件的)
在autoconf.h中可以看到类似于: 这样的配置选项,这是提供给Linux源码使用.
(2) 为了更好的说明这种情况我们来看个例子: 让内核支持 网卡(DM9000)
①在/work/system/linux-2.6.22.6 目录下搜索 CONFIG_DM9000
-> grep "CONFIG_DM9000" * -nR (搜索出一堆东西,我们来看我们所需的信息)
->> config_ok:599:CONFIG_DM9000=y
->> drivers/net/Makefile:197:obj-$(CONFIG_DM9000) += dm9000.o
->> arch/arm/plat-s3c24xx/common-smdk.c:46:#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
<注意:CONFIG_DM9000在原始的Linux内核源码可能找不到,要在打好补丁或者配置后的源码中才能找到,根据具体的厂商而定>
②我们看到config_ok 中有这么一句: CONFIG_DM9000 = y (y 的含义是静态编进内核 M 是以模块编进内核)
然后drivers/net/目录下的 Makefile 文件会把 dm9000.o 静态编进内核: obj-y += dm9000.o
这是站在Makefile的角度来说的.
<当然它还会自动生成一个配置文件auto.conf(在/include/config目录下) 给顶层Makefile使用>
③上面的例子不足以说明.config对源码层次的影响,我们再来看一个源码级别的例子.
-> 在s3c2410fb.c(driver/video)文件中找到了这么一段代码.
#ifdef CONFIG_FB_S3C2410_DEBUG
static int debug = 1;
#else
static int debug = 0;
#endif
->我们看到 CONFIG_FB_S3C2410_DEBUG 这么个宏定义.我们在内核源码里面是搜索不到的.其实它被定义在.config当中
(当然,定义在.config当中是不能被内核代码使用的,需要被定义为宏才能被内核代码使用, 这样就必须自动生成 XXX.h文件)
->我们在内核源码目录下搜索CONFIG_FB_S3C2410_DEBUG : grep "CONFIG_FB_S3C2410_DEBUG" * -nR
(3)总结
-------------------------------------------------------------------------
自动生成-> ① auto.conf ②autoconf.h(宏)
-------------------------------------------------------------------------
(4)autoconf.h的身影
cmd_drivers/leds/led-core.o := arm-linux-gcc -Wp,-MD,drivers/leds/.led-core.o.d
-nostdinc -isystem /work/tools/gcc-3.4.5-glibc-2.3.6/lib/gcc/arm-linux/3.4.5/include
-D__KERNEL__ -Iinclude -include include/linux/autoconf.h
-mlittle-endian
-Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Os -marm -fno-omit-frame-pointer
-mapcs -mno-sched-prolog -mapcs-32 -mno-thumb-interwork
-D__LINUX_ARM_ARCH__=4 -march=armv4t -mtune=arm9tdmi -malignment-traps -msoft-float
-Uarm -fno-omit-frame-pointer -fno-optimize-sibling-calls -g -Wdeclaration-after-statement
-D"KBUILD_STR(s)=\#s" -D"KBUILD_BASENAME=KBUILD_STR(led_core)" -D"KBUILD_MODNAME=KBUILD_STR(led_core)"
-c -o drivers/leds/led-core.o drivers/leds/led-core.c
这是一个自动生成的临时文件(里面记录了led-core.c 的依赖规则)
或许你会问:为什么autoconf.h 会出现在这个GCC命令行里面,出现在这个依赖文件里面?
答案其实很简单,前面说过, .C文件中 常常含有 类似与 CONFIG_FB_S3C2410_DEBUG 这样的宏,在内核被编译之前,CONFIG_FB_S3C2410_DEBUG这样的宏是没有定义的.它被定义在autoconf.h 文件中, 而autoconf.h 文件需要先配置好内核才能自动生成(具体配置看是什么芯片/平台,前面已经讲过了).
正因为.C文件有许多‘宏’在 autoconf.h 中,所以依赖肯定会包含这个‘自动生成的头文件’.