天天看點

(二)openwrt make kernel_menuconfig流程分析

(二)openwrt make kernel_menuconfig流程分析

在上一篇文章“(一)openwrt make menuconfig流程分析”中,我們分析了make menuconfig的流程,在配置菜單中,我們并沒有看到kernel相關的配置,這是因為在openwrt中,我們想要配置核心的話,需要使用make kernel_menuconfig指令。我們将通過分析這個指令執行的流程,看看它具體做了哪些工作。下面是我總結的分析過程,希望與大家分享,共同學習,共同成長,其中可能會有一些了解不正确的地方,還望各位不吝指教,謝謝,^_^。

當我們在頂層目錄輸入make kernel_menuconfig時,由于指定的目标為kernel_menuconfig,是以make會去尋找檔案中kernel_menuconfig所在的地方,然後去執行其相應規則。同menuconfig目标一樣,我們可以看到,kernel_menuconfig目标也在$(TOPDIR)/include/toplevel.mk中,下面是它的依賴和規則。其中$(TOPDIR)就是頂層目錄,定義在主Makefile中TOPDIR:=${CURDIR}。

    kernel_menuconfig: prepare_kernel_conf  

        $(_SINGLE)$(NO_TRACE_MAKE) -C target/linux menuconfig  

1 kernel_menuconfig的依賴目标prepare_kernel_conf

第1行,依賴目标prepare_kernel_conf的定義在$(TOPDIR)/include/toplevel.mk中:

    prepare_kernel_conf: .config FORCE

    ifeq ($(wildcard staging_dir/host/bin/quilt),)

      prepare_kernel_conf:

        @+$(SUBMAKE) -r tools/quilt/install

    else

      prepare_kernel_conf: ;

    endif

下面對各依賴目标和規則進行分析。

1.1 prepare_kernel_conf的依賴目标.config

.config定義在$(TOPDIR)/include/toplevel.mk中:

    ifeq ($(FORCE),)

      .config scripts/config/conf scripts/config/mconf: tmp/.prereq-build

    endif

    .config: ./scripts/config/conf $(if $(CONFIG_HAVE_DOT_CONFIG),,prepare-tmpinfo)

        @+if [ \! -e .config ] || ! grep CONFIG_HAVE_DOT_CONFIG .config >/dev/null; then \

            [ -e $(HOME)/.openwrt/defconfig ] && cp $(HOME)/.openwrt/defconfig .config; \

            $(_SINGLE)$(NO_TRACE_MAKE) menuconfig $(PREP_MK); \

        fi

  1)第1~3行,預設FORCE是等于空的,是以這裡的if條件成立,即.config依賴于tmp/.prereq-build,我們看一下tmp/.prereq-build的定義:

    tmp/.prereq-build: include/prereq-build.mk

        mkdir -p tmp

        rm -f tmp/.host.mk

        @$(_SINGLE)$(NO_TRACE_MAKE) -j1 -r -s -f $(TOPDIR)/include/prereq-build.mk prereq 2>/dev/null || { \

            echo "Prerequisite check failed. Use FORCE=1 to override."; \

            false; \

        }

        touch $@

    下面分析tmp/.prereq-build的依賴目标和規則。

    1.1)第1~3行,tmp/.prereq-build依賴include/prereq-build.mk檔案,建立tmp目錄,删除tmp/.host.mk。

    1.2)第4~7行,執行prereq-build.mk檔案,用于檢查一些必備條件是否準備好,例如下面列出的檢查項,如果檢查失敗,則列印後面“Prerequisite check ...”資訊。

    Checking 'working-make'... ok.

    Checking 'case-sensitive-fs'... ok.

    Checking 'getopt'... ok.

    Checking 'fileutils'... ok.

    Checking 'working-gcc'... ok.

    ...

    1.3)第8行,檢查完後,建立tmp/.prereq-build檔案。

  2)第5~9行,繼續來看簡化一下如下:

    .config: ./scripts/config/conf prepare-tmpinfo

        @+if [ \! -e .config ] || ! grep CONFIG_HAVE_DOT_CONFIG .config >/dev/null; then \

            [ -e $(HOME)/.openwrt/defconfig ] && cp $(HOME)/.openwrt/defconfig .config; \

            make menuconfig; \

        fi

    第5行,./scripts/config/conf依賴目标的分析可參考“(一)openwrt make menuconfig流程分析”文章中scripts/config/mconf。CONFIG_HAVE_DOT_CONFIG變量的值為空,是以if條件不成立,得到prepare-tmpinfo依賴條件,該依賴條件的分析也在“(一)openwrt make menuconfig流程分析”文章中有講到。

    第6~9行,這裡的規則隻有一個if條件語句,其表示如果頂層目錄下不存在.config檔案,或存在.config,但是該檔案中沒找到CONFIG_HAVE_DOT_CONFIG,則if條件成立,那将會執行make menuconfig指令;否則該規則什麼也不做。

1.2 prepare_kernel_conf的依賴目标FORCE

依賴目标FORCE在“(一)openwrt make menuconfig流程分析”文章中有分析,這裡不再分析了。

1.3 prepare_kernel_conf的規則

第3~8行,表示若staging_dir/host/bin/quilt工具不存在,即ifeq條件成立,則執行下面指令,生成該工具,否則執行else部分,即什麼都不做。quilt是一個幫助我們管理patch的工具。

@+$(SUBMAKE) -r tools/quilt/install

1.4 小結

kernel_menuconfig的依賴目标prepare_kernel_conf主要做的工作是:

(1)檢查一些必備條件是否準備好,比如gawk、zlib、getopt、openssl等,

(2)根據頂層目錄下是否存在.config檔案,以及該檔案中是否有CONFIG_HAVE_DOT_CONFIG,決定要不要執行make menuconfig指令。

2 kernel_menuconfig的規則

第2行,kernel_menuconfig的依賴目标分析完後,我們再看一下它的規則,将其簡化一下:

make -C target/linux menuconfig

可以看到,這行規則表示要去執行$(TOPDIR)/target/linux目錄下Makefile,目标是menuconfig。繼續看一下此Makefile中menuconfig目标的定義:

    prereq clean download prepare compile install menuconfig nconfig oldconfig update refresh: FORCE

        @+$(NO_TRACE_MAKE) -C $(BOARD) $@

将其簡化一下,如下,menuconfig的規則表示要進入$(TOPDIR)/target/linux/ramips目錄,去執行裡面的Makefile,目标為menuconfig。

    menuconfig: FORCE

        @+make -C ramips menuconfig

下面分析一下BOARD變量如何得到的,以及在$(TOPDIR)/target/linux/ramips/Makefile中執行的規則。

2.1 BOARD變量

上面規則中BOARD變量定義在$(TOPDIR)/include/rules.mk檔案中,如下所示,rules.mk是由上面的$(TOPDIR)/target/linux/Makefile讀入的。

    ifeq ($(DUMP),)

      -include $(TOPDIR)/.config

    endif

    qstrip=$(strip $(subst ",,$(1)))

    #"))

    BOARD:=$(call qstrip,$(CONFIG_TARGET_BOARD))

第1~3行,表示讀取頂層目錄中的.config檔案,它包含了CONFIG_TARGET_BOARD=“ramips”變量的值。

第4行,定義了一個qstrip變量,其含義為去掉$(1)參數中的 “雙引号,以及多餘的空格或tab。

第5行,是注釋,我的了解是,它對實際文法的正确性沒有影響,由于第4行出現了單個雙引号,增加這行,可以避免影響第4行之後指令的顯示。

第6行,從CONFIG_TARGET_BOARD變量擷取值,我這裡擷取的值為ramips。

2.2 ramips的目标和規則

接下來繼續來分析$(TOPDIR)/target/linux/ramips/Makefile,該檔案中核心代碼如下,其他部分代碼定義的是一些公共變量,我們在用到的時候再去分析:

$(eval $(call BuildTarget))

根據該代碼可知,這裡調用了BuildTarget變量,BuildTarget定義在$(TOPDIR)/include/target.mk中,如下:

    ifeq ($(TARGET_BUILD),1)

      include $(INCLUDE_DIR)/kernel-build.mk

      BuildTarget?=$(BuildKernel)

    endif

TARGET_BUILD變量的值在$(TOPDIR)/target/linux/Makefile中定義為1,是以if條件成立,是以BuildTarget的值為BuildKernel變量的值。

BuildKernel定義在$(TOPDIR)/include/kernel-build.mk中,這個變量中定義的目标和規則較多,我們直接看要執行的menuconfig目标的規則:

    define BuildKernel

        ...

        oldconfig menuconfig nconfig: $(STAMP_PREPARED) $(STAMP_CHECKED) FORCE

        rm -f $(STAMP_CONFIGURED)

        $(LINUX_RECONF_CMD) > $(LINUX_DIR)/.config

        $(_SINGLE)$(MAKE) -C $(LINUX_DIR) $(KERNEL_MAKEOPTS) $$@

        $(LINUX_RECONF_DIFF) $(LINUX_DIR)/.config > $(LINUX_RECONFIG_TARGET)

        ...

    endef

我們将其簡化一下如下。

    define BuildKernel

    ...

    menuconfig: $(TOPDIR)/build_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/linux-ramips_mt7628/linux-3.10.14/.prepared $(TOPDIR)/build_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/linux-ramips_mt7628/linux-3.10.14/.quilt_checked FORCE

        rm -f $(TOPDIR)/build_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/linux-ramips_mt7628/linux-3.10.14/.configured

        $(LINUX_RECONF_CMD) > $(LINUX_DIR)/.config

        make -C build_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/linux-ramips_mt7628/linux-3.10.14 menuconfig

        $(LINUX_RECONF_DIFF) $(TOPDIR)/.config > $(LINUX_RECONFIG_TARGET)

    ...

    endef

下面詳細分析這些目标和規則。

2.2.1 核心menuconfig的依賴目标

第3行,menuconfig依賴.prepared、.quilt_checked這兩個依賴目标,它們是核心頂層目錄下的兩個檔案。當這兩個目标檔案不存在時,他們對應的規則就會被執行,我們依次來分析這倆目标。

  1)依賴目标.prepared

    .prepared定義在$(TOPDIR)/include/kernel-build.mk中

    $(STAMP_PREPARED): $(if $(LINUX_SITE),$(DL_DIR)/$(LINUX_SOURCE))

        -rm -rf $(KERNEL_BUILD_DIR)

        -mkdir -p $(KERNEL_BUILD_DIR)

        $(Kernel/Prepare)

        touch $$@

    1.1).prepared的依賴目标

      第1行,LINUX_SITE定義在$(TOPDIR)/include/kernel.mk中,CONFIG_EXTERNAL_KERNEL_TREE、CONFIG_KERNEL_GIT_CLONE_URI在頂層.config中都為"",LINUX_VERSION值為3.10.14。

    TESTING:=$(if $(findstring -rc,$(LINUX_VERSION)),/testing,)

     ifeq ($(call qstrip,$(CONFIG_EXTERNAL_KERNEL_TREE))$(call qstrip,$(CONFIG_KERNEL_GIT_CLONE_URI)),)

        LINUX_SITE:[email protected]/linux/kernel/v3.x$(TESTING)

    endif

      是以ifeq條件成立,LINUX_SITE值為@KERNEL/linux/kernel/v3.x,則.prepared的依賴目标為$(DL_DIR)/$(LINUX_SOURCE)。

      DL_DIR定義在$(TOPDIR)/rules.mk中,CONFIG_DOWNLOAD_FOLDER在頂層.config中為"",是以$(DL_DIR)值為$(TOPDIR)/dl。

DL_DIR:=$(if $(call qstrip,$(CONFIG_DOWNLOAD_FOLDER)),$(call qstrip,$(CONFIG_DOWNLOAD_FOLDER)),$(TOPDIR)/dl)

      LINUX_SOURCE定義在$(TOPDIR)/include/kernel.mk中

LINUX_SOURCE:=linux-$(LINUX_VERSION).tar.xz

      由此可知,.prepared的依賴目标即為$(TOPDIR)/dl/linux-3.10.14.tar.xz

    1.2).prepared的規則

      第2、3行,KERNEL_BUILD_DIR定義在$(TOPDIR)/include/kernel.mk中,BOARD值為ramips,SUBTARGET值為mt7628。

KERNEL_BUILD_DIR ?= $(BUILD_DIR)/linux-$(BOARD)$(if $(SUBTARGET),_$(SUBTARGET))

      BUILD_DIR定義在$(TOPDIR)/rules.mk中,TARGET_DIR_NAME值為target-mipsel_24kec+dsp_uClibc-0.9.33.2。

    BUILD_DIR_BASE:=$(TOPDIR)/build_dir

    BUILD_DIR:=$(BUILD_DIR_BASE)/$(TARGET_DIR_NAME)

      最終可得到KERNEL_BUILD_DIR值為:

$(TOPDIR)/build_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/linux-ramips_mt7628

      是以,這兩行規則是删除linux-ramips_mt7628目錄,再重新建立。

      第4行,Kernel/Prepare定義在$(TOPDIR)/include/kernel-build.mk中

    define Kernel/Prepare

        $(call Kernel/Prepare/Default)

    endef

      Kernel/Prepare/Default定義在$(TOPDIR)/include/kernel-defaults.mk中

    ifeq ($(strip $(CONFIG_EXTERNAL_KERNEL_TREE)),"")

      ifeq ($(strip $(CONFIG_KERNEL_GIT_CLONE_URI)),"")

        define Kernel/Prepare/Default

        $(CP) $(TOPDIR)/target/linux/src/linux-$(LINUX_VERSION) $(KERNEL_BUILD_DIR)

        ln -sf $(LINUX_DIR) `echo $(LINUX_DIR) | sed 's/linux-[0-9]*\.[0-9]*\.[0-9]*/linux-kernel/g'`

        endef

      else

        define Kernel/Prepare/Default

        ...

        endef

      endif

    else

      define Kernel/Prepare/Default

        ...

      endef

    endif

      兩個ifeq都成立,是以使用第一個Kernel/Prepare/Default變量,将其簡化一下,LINUX_VERSION值在後面的2.2.3的2)有分析。

    cp -fpR $(TOPDIR)/target/linux/src/linux-3.10.14 $(TOPDIR)/build_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/linux-ramips_mt7628

    ln -sf $(TOPDIR)/build_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/linux-ramips_mt7628/linux-3.10.14 $(TOPDIR)/build_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/linux-ramips_mt7628/linux-kernel

      是以可知道,第4行所做工作就是從target目錄拷貝核心源碼linux-3.10.14到build_dir目錄中,并為核心源碼建立軟連結linux-kernel。

      第5行,準備工作完成後,建立.prepared檔案。

  2)依賴目标.quilt_checked

    .quilt_checked的規則定義在$(TOPDIR)/include/quilt.mk中,它是由BuildKernel變量中$(if $(QUILT),$(Build/Quilt))這行指令展開的,QUILT值為1。

    $(1)值為$(TOPDIR)/build_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/linux-ramips_mt7628/linux-3.10.14,$(2)值為空,因為if中series檔案不存在,是以if條件不成立,.quilt_checked的規則隻是建立了一個.quilt_checked這個檔案。

    define Quilt/Template

      ...

      $($(2)STAMP_CHECKED): $($(2)STAMP_PREPARED)

        if [ -s "$(1)/patches/series" ]; then \

            (cd "$(1)"; \

                if $(QUILT_CMD) next >/dev/null 2>&1; then \

                    $(QUILT_CMD) push -a; \

                else \

                    $(QUILT_CMD) top >/dev/null 2>&1; \

                fi \

            ); \

        fi

        touch "$$@"

      ...

    endef

    Build/Quilt=$(call Quilt/Template,$(PKG_BUILD_DIR),,,$(if $(TARGET_BUILD),Kernel,Package))

2.2.2 删除核心的.configured檔案

第4行,删除核心頂層目錄中的.configured檔案。

2.2.3 核心.config的生成

第5行,這行規則不複雜,但是變量的定義比較繁瑣,我們依次分析LINUX_RECONF_CMD、LINUX_DIR變量的值,最後再看這行規則的作用。

  1)LINUX_RECONF_CMD變量

    LINUX_RECONF_CMD定義在$(TOPDIR)/include/target.mk中:

LINUX_RECONF_CMD = $(call __linux_confcmd,$(LINUX_RECONFIG_LIST),)

    1.1)__linux_confcmd變量

      __linux_confcmd定義在$(TOPDIR)/include/target.mk中:

__linux_confcmd = $(SCRIPT_DIR)/kconfig.pl $(2) $(patsubst %,+,$(wordlist 2,9999,$(1))) $(1)

    1.2)LINUX_RECONFIG_LIST變量

      LINUX_RECONFIG_LIST定義在$(TOPDIR)/include/target.mk中:

LINUX_RECONFIG_LIST = $(wildcard $(GENERIC_LINUX_CONFIG) $(LINUX_TARGET_CONFIG) $(if $(USE_SUBTARGET_CONFIG), $(LINUX_SUBTARGET_CONFIG)))

      通過這行指令,最終可得到LINUX_RECONFIG_LIST的值為:

LINUX_RECONFIG_LIST = $(TOPDIR)/target/linux/generic/config-3.10 $(TOPDIR)/target/linux/ramips/mt7628/config-3.10

      下面分析 LINUX_RECONFIG_LIST的這行指令。

      1.2.1)GENERIC_LINUX_CONFIG變量

        GENERIC_LINUX_CONFIG定義在$(TOPDIR)/include/target.mk中:

GENERIC_LINUX_CONFIG = $(call find_kernel_config,$(GENERIC_PLATFORM_DIR))

        其中,find_kernel_config、GENERIC_PLATFORM_DIR變量定義在$(TOPDIR)/include/target.mk中,KERNEL_PATCHVER變量定義在$(TOPDIR)/include/kernel-version.mk中,為3.10。

    __config_name_list = $(1)/config-$(KERNEL_PATCHVER) $(1)/config-default

    __config_list = $(firstword $(wildcard $(call __config_name_list,$(1))))

    find_kernel_config=$(if $(__config_list),$(__config_list),$(lastword $(__config_name_list)))

    GENERIC_PLATFORM_DIR := $(TOPDIR)/target/linux/generic

        是以,由上面指令,可以知道GENERIC_LINUX_CONFIG變量後面的指令表示,在$(TOPDIR)/target/linux/generic目錄中為GENERIC_LINUX_CONFIG變量尋找config-3.10或config-default配置檔案,如兩個都有,則優先指派config-3.10,如隻有config-default,則指派此檔案,如都沒有,則預設指派config-default。由于$(TOPDIR)/target/linux/generic目錄中有config-3.10檔案,是以在這裡指派的是$(TOPDIR)/target/linux/generic/config-3.10。

      1.2.2)LINUX_TARGET_CONFIG變量

        LINUX_TARGET_CONFIG定義在$(TOPDIR)/include/target.mk中,BOARD變量值為ramips,前面有分析。

    PLATFORM_DIR:=$(TOPDIR)/target/linux/$(BOARD)

    LINUX_TARGET_CONFIG = $(call find_kernel_config,$(PLATFORM_DIR))

        LINUX_TARGET_CONFIG變量後面的指令表示的含義與GENERIC_LINUX_CONFIG類似。由于$(TOPDIR)/target/linux/ramips/目錄中無config-3.10、config-default檔案,是以在這裡指派的是$(TOPDIR)/target/linux/ramips/config-default。

      1.2.3)USE_SUBTARGET_CONFIG和LINUX_SUBTARGET_CONFIG變量

        USE_SUBTARGET_CONFIG、LINUX_SUBTARGET_CONFIG定義在$(TOPDIR)/include/target.mk中,SUBTARGET變量值為mt7628。

    PLATFORM_SUBDIR:=$(PLATFORM_DIR)$(if $(SUBTARGET),/$(SUBTARGET))

    ifneq ($(PLATFORM_DIR),$(PLATFORM_SUBDIR))

        LINUX_SUBTARGET_CONFIG = $(call find_kernel_config,$(PLATFORM_SUBDIR))

    endif

    USE_SUBTARGET_CONFIG = $(if $(wildcard $(LINUX_TARGET_CONFIG)),,$(if $(LINUX_SUBTARGET_CONFIG),1))

        上面指令中,PLATFORM_DIR的值由1.2.2)可得到,PLATFORM_SUBDIR的值為$(TOPDIR)/target/linux/ramips/mt7628,是以這兩個變量不相等,ifneq條件成立,進而可知LINUX_SUBTARGET_CONFIG變量值為$(TOPDIR)/target/linux/ramips/mt7628/config-3.10。USE_SUBTARGET_CONFIG變量的為1。

  2)LINUX_DIR變量

    LINUX_DIR定義在$(TOPDIR)/include/kernel.mk中,BOARD值為ramips,SUBTARGET值為mt7628,LINUX_VERSION值為3.10.14。

    KERNEL_BUILD_DIR ?= $(BUILD_DIR)/linux-$(BOARD)$(if $(SUBTARGET),_$(SUBTARGET))

    LINUX_DIR ?= $(KERNEL_BUILD_DIR)/linux-$(LINUX_VERSION)

    BUILD_DIR定義在$(TOPDIR)/rules.mk中,TARGET_DIR_NAME值為target-mipsel_24kec+dsp_uClibc-0.9.33.2。

    BUILD_DIR_BASE:=$(TOPDIR)/build_dir

    BUILD_DIR:=$(BUILD_DIR_BASE)/$(TARGET_DIR_NAME)

    最終可得到LINUX_DIR值為:

$(TOPDIR)/build_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/linux-ramips_mt7628/linux-3.10.14

  3)合并config檔案為.config

    通過1)、2)的分析,我們知道了LINUX_RECONF_CMD、LINUX_DIR變量的值,此時,我們可将第5行規則簡化如下:

$(TOPDIR)/scripts/kconfig.pl + $(TOPDIR)/target/linux/generic/config-3.10 $(TOPDIR)/target/linux/ramips/mt7628/config-3.10 > $(TOPDIR)/build_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/linux-ramips_mt7628/linux-3.10.14/.config

    這行規則作用是通過kconfig.pl腳本将兩個config-3.10檔案合并為核心頂層目錄下的.config檔案。

2.2.4  生成核心圖形界面配置核心

第6行,make指令進入到核心頂層目錄下,并在該目錄下Makefile中尋找menuconfig目标,然後執行其對應規則,最主要的是會執行核心scripts目錄中mconf可執行檔案。mconf會解析核心頂層目錄下Kconfig、.config檔案,并繪制圖形界面供我們進行相關選項的配置。然後在我們儲存退出時,.config就會被及時的更新。

2.2.5  更新mt7628的config-3.10檔案

第7行,先分析一下LINUX_RECONF_DIFF,LINUX_RECONFIG_TARGET這兩個變量,再分析這行規則的作用。

  1)LINUX_RECONF_DIFF變量

    LINUX_RECONF_DIFF定義在$(TOPDIR)/include/target.mk中,__linux_confcmd在2.2.3的1.1)中可得到,LINUX_RECONFIG_LIST在2.2.3的1.2)中可得到。

LINUX_RECONF_DIFF = $(call __linux_confcmd,$(filter-out $(LINUX_RECONFIG_TARGET),$(LINUX_RECONFIG_LIST)),'>')

    1.1)LINUX_RECONFIG_TARGET變量

      LINUX_RECONFIG_TARGET定義在$(TOPDIR)/include/target.mk中。

LINUX_RECONFIG_TARGET = $(if $(USE_SUBTARGET_CONFIG),$(LINUX_SUBTARGET_CONFIG),$(LINUX_TARGET_CONFIG))

      USE_SUBTARGET_CONFIG,LINUX_SUBTARGET_CONFIG在2.2.3 的1.2.3)中得到,是以LINUX_RECONFIG_TARGET變量值為$(TOPDIR)/target/linux/ramips/mt7628/config-3.10。

  2)更新config檔案

    可将第7行指令簡化如下:

$(TOPDIR)/scripts/kconfig.pl ‘>’ $(TOPDIR)/target/linux/generic/config-3.10 $(TOPDIR)/build_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/linux-ramips_mt7628/linux-3.10.14/.config > $(TOPDIR)/target/linux/ramips/mt7628/config-3.10

    我們知道核心頂層目錄中的.config檔案是由兩個config-3.10檔案合并得到的,在我們配置了核心後,.config檔案将被更新。

    而這行規則作用是通過kconfig.pl腳本将更新過的.config檔案,去掉$(TOPDIR)/target/linux/generic/config-3.10中的配置,得到已更新的$(TOPDIR)/target/linux/ramips/mt7628/config-3.10檔案,然後重新寫回到$(TOPDIR)/target/linux/ramips/mt7628/config-3.10檔案。也就是說,當我們在核心中更改了配置更新了.config後,需要把mt7628的config-3.10檔案也對應的更新了。

2.3 小結

kernel_menuconfig的規則主要做的工作是:

(1)将核心源碼從$(TOPDIR)/target/linux/src/linux-3.10.14目錄拷貝到$(TOPDIR)/build_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/linux-ramips_mt7628目錄,等待make指令去build_dir目錄中編譯核心。核心源碼也可以是從網上進行下載下傳解壓得到,這個過程我還未去了解,之後再找時間去看一看。

(2)将$(TOPDIR)/target/linux/generic/config-3.10、$(TOPDIR)/target/linux/ramips/mt7628/config-3.10這兩個配置檔案合并到編譯目錄$(TOPDIR)/build_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/linux-ramips_mt7628/linux-3.10.14/.config中。

(3)啟動核心圖形配置界面,對核心進行配置,完成後更新核心頂層目錄的.config檔案,并由該檔案更新target目錄中mt7628的config-3.10檔案。

3 總結

(1)在分析核心的配置流程後,我們可以發現整個流程其實是比較簡單的,大緻的主要過程是複制核心到編譯目錄,合并生成一個.config檔案,然後進行核心配置并更新.config,最後更新mt7628的config-3.10。

(2)一些變量的定義比較繁瑣,在分析的時候比較花時間。

(3)文中有個别地方,我目前了解的可能不太準确,希望有人能給予指出。或我知道了之後,再來更新,謝謝。