1. 程式人生 > >編譯核心

編譯核心

 

一、編譯

 

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驅動程式