(二)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  

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:=@KERNEL/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)文中有个别地方,我目前理解的可能不太准确,希望有人能给予指出。或我知道了之后,再来更新,谢谢。




  • 6
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Luci是OpenWrt中的一种Web界面管理工具,它基于Lua语言和MVC框架。它提供了一种友好且易于使用的方式来管理路由器设备,包括网络设置、软件安装、用户管理等等。下面是Luci的流程分析。 1. 用户请求 当用户在浏览器中输入路由器IP地址并访问时,就会向路由器发送一个HTTP请求。这个请求包含了用户请求的页面信息和参数。 2. HTTP服务器 路由器中运行着一个HTTP服务器,它接收用户的HTTP请求并将请求转发给Luci。 3. URL分发 Luci中的URL分发器会解析HTTP请求中的URL,并将其映射到对应的控制器和方法上。URL分发器是Luci的核心组件之一,它负责将用户请求与Luci后端代码进行关联。 4. 控制器 控制器是Luci的另一个核心组件,它接收URL分发器分发的请求并处理用户请求,包括输入参数验证、数据查询、业务逻辑处理等等。控制器会将处理后的结果返回给视图。 5. 视图 视图是Luci的界面组件,它负责将控制器返回的数据渲染成HTML页面并返回给用户。视图采用MVC模式,将业务逻辑和界面逻辑分离,从而提高代码的可维护性和可扩展性。 6. 数据库 Luci中使用SQLite作为默认的数据库,用于存储和管理路由器设备的配置信息、用户信息等等。控制器会调用数据库API,从数据库中读取或写入数据,从而支持Luci的各种功能。 7. 系统调用 Luci还提供了一些系统调用接口,用于执行系统命令、读取系统信息等等。控制器可以通过系统调用来获取系统状态、执行网络管理等操作。 以上就是Luci的流程分析,Luci的设计理念是简单、易用、可扩展。通过良好的代码架构和设计模式,Luci提供了一种高效、安全、可靠的管理方式,使得路由器设备的管理变得更加简单和方便。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值