编译内核

 

一、编译

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/ 目录看一下:

 cd ./arch/arm/configs/    ->>里面有很多配置文件 “ XXX_defconfig”  (XXX 代表很多类似的文件名       ->>我们找到和我们的2440开发板相似的配置文件 s3c2410_defconfig  

->返回 /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使用的.

| ONFIG_ROOT_NFS=y                  |

| CONFIG_TMPFS=y                    |

| CONFIG_LEDS_TRIGGER_HEARTBEAT=m   |

| CONFIG_GENERIC_GPIO=y             |

| CONFIG_S3C2410_PM=y               |

②从内核源码的角度

->“条件指示符”所指示的"代码"到底需不需要被编进内核.

->在include/linux目录下自动生成了autoconf.h这个头文件(当然,没有配置的内核代码是找不到 autoconf.h这个头文件的)       

在autoconf.h中可以看到类似于:                   这样的配置选项,这是提供给Linux源码使用.  

|  #define CONFIG_CPU_S3C2410_DMA 1        |

|  #define CONFIG_CRYPTO_ECB_MODULE 1      |

|  #define CONFIG_SMDK2440_CPU2440 1       |

 |  #define CONFIG_KGDB_PORT_NUM 0          |

 |  #define CONFIG_SERIAL_8250_SHARE_IRQ 1  |

(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

       arch/arm/configs/s3c2410_defconfig:929:# CONFIG_FB_S3C2410_DEBUG is not set

       config_ok:948:# CONFIG_FB_S3C2410_DEBUG is not set                         

       drivers/video/s3c2410fb.c:109:#ifdef CONFIG_FB_S3C2410_DEBUG               

       通过上面搜索的信息,我相信大家可以明白 .config(config_ok)的配置对 “源码”级别的影响了.

       

->注意:当然这个和“宏”还是有区别的,宏只能在 XX.h中定义, Linux中 include/linux/autoconfig.h 是自动生成的,

include/linux/autoconfig.h 中的内容就来源于 .config 换句话说,include/linux/autoconfig.h 中的内容是根据.config 中的内容而生成的.

       

(3)总结

  生成.config

-------------------------------------------------------------------------

  编译内核:make uImage

-------------------------------------------------------------------------

自动生成->

① auto.conf ②autoconf.h(宏)   

-------------------------------------------------------------------------

①提供给顶层Makefile使用 ②提供给内核C源码使用

    

备注:我们可以根据这些Linux给我们提供的这些"配置选项"来"裁剪"我们的内核,满足我们需要的小巧的Linux系统。

举个例子:

1.我们需要在开机启动我们的应用程序(比如QT)我们需要使用到 LCD,触摸屏。所以我们就需要根据配置选项来

将LCD,触摸屏的驱动程序"静态"编进内核。那我们得来修改"相关的Makefile"文件,最后再是"编译内核"

2.当然,我们要使用触摸屏,首先我们得需要把"触摸屏驱动"静态编进内核.针对我自己的开发板TQ2440

我们需要改一下Linux内核的Makefile。以支持我们TQ2440的触摸屏。

具体修改一下文件:   obj-$(CONFIG_TOUCHSCREEN_S3C2410)       += s3c2410_ts.o

修改/work/system/linux-2.6.22.6/drivers/input/touchscreen/Makefile 中的

obj-$(CONFIG_TOUCHSCREEN_S3C2410)       += s3c2410_ts.o

改为我们自己的触摸屏驱动:

obj-$(CONFIG_TOUCHSCREEN_S3C2410)       += s3c_ts.o        //s3c_ts 该驱动为TQ2440触摸屏的驱动程序。

有时候可能看不到这个"选项",因为我们还没有"配置内核",也就是没有make menuconfig(没有选中对触摸屏的支持)

当生成.config之后,可以查看里面的选项。对于s3c2410 而言,是在执行 make s3c2410_defconfig 后 

obj-$(CONFIG_TOUCHSCREEN_S3C2410)选项才生成的,不信可以看.config文件

.config文件当中必须得有这么一句: CONFIG_TOUCHSCREEN_S3C2410=y  

当然我们得把s3c_ts.c文件放到  /work/system/linux-2.6.22.6/drivers/input/touchscreen/  目录下。

然后将内核重新编译。再烧写。   

               

如果你的LCD也是特殊的(也就是内核不支持的),你自己的LCD驱动代码也得静态编译进内核。

做如下修改:

修改/work/system/linux-2.6.22.6/drivers/video/目录下的 Makefile 

将 obj-$(CONFIG_FB_S3C2410)          += s3c2410fb.o  改为:  obj-$(CONFIG_FB_S3C2410)          += lcd.o //lcd.o为TQ2440的LCD驱动程序

猜你喜欢

转载自blog.csdn.net/yilongdashi/article/details/83958646