• openwrt固件编译过程


    Makefile分析

    注:1make -n可打印makefile执行的命令,而不执行。

    2)可以在规则的命令中增加echo跟踪执行进度。


    顶层目录的Makefileopenert的总Makefile,第一个编译目标worldmake的默认编译目标。

    world:
    
    
    include $(TOPDIR)/include/host.mk
    
    
    ifneq ($(OPENWRT_BUILD),1)
    
    _SINGLE=export MAKEFLAGS=$(space);
    
    
    override OPENWRT_BUILD=1
    
    export OPENWRT_BUILD
    
    GREP_OPTIONS=
    
    export GREP_OPTIONS
    
    include $(TOPDIR)/include/debug.mk
    
    include $(TOPDIR)/include/depends.mk
    
    include $(TOPDIR)/include/toplevel.mk
    
    else
    
    include rules.mk
    
    include $(INCLUDE_DIR)/depends.mk
    
    include $(INCLUDE_DIR)/subdir.mk
    
    include target/Makefile
    
    include package/Makefile
    
    include tools/Makefile
    
    include toolchain/Makefile
    
    printdb:
    
    @true
    
    
    prepare: $(target/stamp-compile)
    
    
    clean: FORCE
    
    rm -rf $(BUILD_DIR) $(STAGING_DIR) $(BIN_DIR) $(BUILD_LOG_DIR)
    
    
    dirclean: clean
    
    rm -rf $(STAGING_DIR_HOST) $(TOOLCHAIN_DIR) $(BUILD_DIR_HOST) $(BUILD_DIR_TOOLCHAIN)
    
    rm -rf $(TMP_DIR)
    
    
    ifndef DUMP_TARGET_DB
    
    $(BUILD_DIR)/.prepared: Makefile
    
    @mkdir -p $$(dirname $@)
    
    @touch $@
    
    
    tmp/.prereq_packages: .config
    
    unset ERROR; 
    
    for package in $(sort $(prereq-y) $(prereq-m)); do 
    
    $(_SINGLE)$(NO_TRACE_MAKE) -s -r -C package/$$package prereq || ERROR=1; 
    
    done; 
    
    if [ -n "$$ERROR" ]; then 
    
    echo "Package prerequisite check failed."; 
    
    false; 
    
    fi
    
    touch $@
    
    endif
    
    
    # check prerequisites before starting to build
    
    prereq: $(target/stamp-prereq) tmp/.prereq_packages
    
    @if [ ! -f "$(INCLUDE_DIR)/site/$(ARCH)" ]; then 
    
    echo 'ERROR: Missing site config for architecture "$(ARCH)" !'; 
    
    echo ' The missing file will cause configure scripts to fail during compilation.'; 
    
    echo ' Please provide a "$(INCLUDE_DIR)/site/$(ARCH)" file and restart the build.'; 
    
    exit 1; 
    
    fi
    
    
    prepare: .config $(tools/stamp-install) $(toolchain/stamp-install)
    
    world: prepare $(target/stamp-compile) $(package/stamp-compile) $(package/stamp-install) $(target/stamp-install) FORCE
    
    $(_SINGLE)$(SUBMAKE) -r package/index
    
    
    .PHONY: clean dirclean prereq prepare world package/symlinks package/symlinks-install package/symlinks-clean
    
    
    endif

    编译逻辑可简化为:

    world:
    
    ifndef ($(OPENWRT_BUILD),1)
    
    # 第一逻辑
    
    else
    
    # 第二逻辑
    
    endif

    第一逻辑

    make V=s时,$OPENWRT_BUILD没有定义赋值,所以总是执行“第一逻辑”,“第一逻辑”结束时再次执行make world,此时$OPENWRT_BUILD=1,所以执行“第二逻辑”。

    toplevel.mk%::解释world目标的规则。

    prereq:: prepare-tmpinfo .config

    @+$(NO_TRACE_MAKE) -r -s $@


    WARN_PARALLEL_ERROR = $(if $(BUILD_LOG),,$(and $(filter -j,$(MAKEFLAGS)),$(findstring s,$(OPENWRT_VERBOSE))))


    ifeq ($(SDK),1)


    %::

    @+$(PREP_MK) $(NO_TRACE_MAKE) -r -s prereq

    @./scripts/config/conf --defconfig=.config Config.in

    @+$(ULIMIT_FIX) $(SUBMAKE) -r $@


    else


    %::

    @+$(PREP_MK) $(NO_TRACE_MAKE) -r -s prereq

    @(

    cp .config tmp/.config;

    ./scripts/config/conf --defconfig=tmp/.config -w tmp/.config Config.in > /dev/null 2>&1;

    if ./scripts/kconfig.pl '>' .config tmp/.config | grep -q CONFIG; then

    printf "$(_R)WARNING: your configuration is out of sync. Please run make menuconfig, oldconfig or defconfig!$(_N) " >&2;

    fi

    )

    @+$(ULIMIT_FIX) $(SUBMAKE) -r $@ $(if $(WARN_PARALLEL_ERROR), || {

    printf "$(_R)Build failed - please re-run with -j1 to see the real error message$(_N) " >&2;

    false;

    } )


    endif

    执行make V=s时,上面规则简化为:

    prereq:: prepare-tmpinfo .config

    @make V=ss -r -s prereq


    %::

    @make V=s -r -s prereq

    @make -w -r world

    第二逻辑

    首先就引入了target, package, tools, toolchain这四个关键目录里的Makefile文件。

    include target/Makefile

    include package/Makefile

    include tools/Makefile

    include toolchain/Makefile

    这些子目录里的Makefile使用include/subdir.mk里定义的两个函数来动态生成规则,这两个函数是subdirstampfile

    subdir命令包

    # Parameters: <subdir>

    define subdir

    $(call warn,$(1),d,D $(1))

    $(foreach bd,$($(1)/builddirs),

    $(call warn,$(1),d,BD $(1)/$(bd))

    $(foreach target,$(SUBTARGETS),

    $(foreach btype,$(buildtypes-$(bd)),

    $(call warn_eval,$(1)/$(bd),t,T,$(1)/$(bd)/$(btype)/$(target): $(if $(QUILT),,$($(1)/$(bd)/$(btype)/$(target)) $(call $(1)//$(btype)/$(target),$(1)/$(bd)/$(btype))))

    $(if $(call debug,$(1)/$(bd),v),,@)+$$(SUBMAKE) -r -C $(1)/$(bd) $(btype)-$(target) $(if $(findstring $(bd),$($(1)/builddirs-ignore-$(btype)-$(target))), || $(call ERROR,$(1), ERROR: $(1)/$(bd) [$(btype)] failed to build.))

    $(if $(call diralias,$(bd)),$(call warn_eval,$(1)/$(bd),l,T,$(1)/$(call diralias,$(bd))/$(btype)/$(target): $(1)/$(bd)/$(btype)/$(target)))

    )

    $(call warn_eval,$(1)/$(bd),t,T,$(1)/$(bd)/$(target): $(if $(QUILT),,$($(1)/$(bd)/$(target)) $(call $(1)//$(target),$(1)/$(bd))))

    $(if $(BUILD_LOG),@mkdir -p $(BUILD_LOG_DIR)/$(1)/$(bd))

    $(foreach variant,$(if $(BUILD_VARIANT),$(BUILD_VARIANT),$(if $(strip $($(1)/$(bd)/variants)),$($(1)/$(bd)/variants),$(if $($(1)/$(bd)/default-variant),$($(1)/$(bd)/default-variant),__default))),

    $(if $(call debug,$(1)/$(bd),v),,@)+$(if $(BUILD_LOG),set -o pipefail;) $$(SUBMAKE) -r -C $(1)/$(bd) $(target) BUILD_VARIANT="$(filter-out __default,$(variant))" $(if $(BUILD_LOG),SILENT= 2>&1 | tee $(BUILD_LOG_DIR)/$(1)/$(bd)/$(target).txt) $(if $(findstring $(bd),$($(1)/builddirs-ignore-$(target))), || $(call ERROR,$(1), ERROR: $(1)/$(bd) failed to build$(if $(filter-out __default,$(variant)), (build variant: $(variant))).))

    )

    $(if $(PREREQ_ONLY)$(DUMP_TARGET_DB),,

    # aliases

    $(if $(call diralias,$(bd)),$(call warn_eval,$(1)/$(bd),l,T,$(1)/$(call diralias,$(bd))/$(target): $(1)/$(bd)/$(target)))

    )

    )

    )

    $(foreach target,$(SUBTARGETS),$(call subtarget,$(1),$(target)))

    endef

    subdir会遍历参数子目录,执行make -C操作。

    stampfile命令包

    # Parameters: <subdir> <name> <target> <depends> <config options> <stampfile location>

    define stampfile

    $(1)/stamp-$(3):=$(if $(6),$(6),$(STAGING_DIR))/stamp/.$(2)_$(3)$(5)

    $$($(1)/stamp-$(3)): $(TMP_DIR)/.build $(4)

    @+$(SCRIPT_DIR)/timestamp.pl -n $$($(1)/stamp-$(3)) $(1) $(4) ||

    $(MAKE) $(if $(QUIET),--no-print-directory) $$($(1)/flags-$(3)) $(1)/$(3)

    @mkdir -p $$$$(dirname $$($(1)/stamp-$(3)))

    @touch $$($(1)/stamp-$(3))


    $$(if $(call debug,$(1),v),,.SILENT: $$($(1)/stamp-$(3)))


    .PRECIOUS: $$($(1)/stamp-$(3)) # work around a make bug


    $(1)//clean:=$(1)/stamp-$(3)/clean

    $(1)/stamp-$(3)/clean: FORCE

    @rm -f $$($(1)/stamp-$(3))


    endef

    target/Makefile中调用:

    curdir:=target


    $(curdir)/builddirs:=linux sdk imagebuilder toolchain

    $(curdir)/builddirs-default:=linux

    $(curdir)/builddirs-install:=linux $(if $(CONFIG_SDK),sdk) $(if $(CONFIG_IB),imagebuilder) $(if $(CONFIG_MAKE_TOOLCHAIN),toolchain)


    $(curdir)/imagebuilder/install:=$(curdir)/linux/install


    $(eval $(call stampfile,$(curdir),target,prereq,.config))

    $(eval $(call stampfile,$(curdir),target,compile,$(TMP_DIR)/.build))

    $(eval $(call stampfile,$(curdir),target,install,$(TMP_DIR)/.build))


    $($(curdir)/stamp-install): $($(curdir)/stamp-compile)


    $(eval $(call subdir,$(curdir)))

    $(eval $(call stampfile,$(curdir),target,prereq,.config))

    会生成规则:

    target/stamp-prereq:=$(STAGING_DIR)/stamp/.target_prereq


    $$(target/stamp-prereq): $(TMP_DIR)/.build .config

    @+$(SCRIPT_DIR)/timestamp.pl -n $$(target/stamp-prereq) target .config ||

    make $$(target/flags-prereq) target/prereq

    @mkdir -p $$$$(dirname $$(target/stamp-prereq))

    @touch $$(target/stamp-prereq)


    $$(if $(call debug,target,v),,.SILENT: $$(target/stamp-prereq))


    .PRECIOUS: $$(target/stamp-prereq) # work around a make bug


    target//clean:=target/stamp-prereq/clean

    target/stamp-prereq/clean: FORCE

    @rm -f $$(target/stamp-prereq)

    所以可以简单的看作: $(eval $(call stampfile,$(curdir),target,prereq,.config)) 生成了目标 $(target/stamp-prereq)

    • 对于target分别生成了:$(target/stamp-prereq)$(target/stamp-compile)$(target/stamp-install)

    • toolchain : $(toolchain/stamp-install)

    • package : $(package/stamp-prereq),$(package/stamp-cleanup), $(package/stamp-compile),$(package/stamp-install)

    • tools : $(tools/stamp-install)

    倚赖关系如下:

    $(toolchain/stamp-install): $(tools/stamp-install)

    $(target/stamp-compile): $(toolchain/stamp-install) $(tools/stamp-install) $(BUILD_DIR)/.prepared

    $(package/stamp-compile): $(target/stamp-compile) $(package/stamp-cleanup)

    $(package/stamp-install): $(package/stamp-compile)

    $(target/stamp-install): $(package/stamp-compile) $(package/stamp-install)

    基本上就是toolchain依赖toolstarget依赖toolchainpackage依赖target,最后target/stamp-install倚赖于package

    kernel编译

    kernel编译可运行命令:make target/linux/{prepare,compile,install} V=s

    target/linux/Makefile

    include $(TOPDIR)/rules.mk

    include $(INCLUDE_DIR)/target.mk


    export TARGET_BUILD=1


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

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

    target/linux/ipq806x/Makefile

    include $(TOPDIR)/rules.mk


    ARCH:=arm

    BOARD:=ipq806x

    BOARDNAME:=Qualcomm Atheros IPQ806X

    FEATURES:=ubifs squashfs

    CPU_TYPE:=cortex-a7

    MAINTAINER:=John Crispin <blogic@openwrt.org>


    KERNELNAME:=zImage Image dtbs


    KERNEL_PATCHVER:=3.14

    include $(INCLUDE_DIR)/target.mk

    $(eval $(call BuildTarget))

    BuildTargetinclude/target.mk中:

    include $(INCLUDE_DIR)/kernel.mk

    ifeq ($(TARGET_BUILD),1)

    include $(INCLUDE_DIR)/kernel-build.mk

    BuildTarget?=$(BuildKernel)

    endif

    BuildKernelinclude/kernel-build.mk中:

    define BuildKernel

    $(if $(QUILT),$(Build/Quilt))

    $(if $(LINUX_SITE),$(call Download,kernel))

    define BuildKernel

    endef

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

    prepare: $(STAMP_CONFIGURED)

    compile: $(LINUX_DIR)/.modules

    $(MAKE) -C image compile TARGET_BUILD=


    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)


    install: $(LINUX_DIR)/.image

    +$(MAKE) -C image compile install TARGET_BUILD=


    clean: FORCE

    rm -rf $(KERNEL_BUILD_DIR)


    image-prereq:

    @+$(NO_TRACE_MAKE) -s -C image prereq TARGET_BUILD=


    prereq: image-prereq

    endef

    至此编译kernelclean/prepare/compile/install目标规则出现,涉及的Makefile包括:include/kernel-build.mkinclude/kernel-defaults.mk.

    1)触发make vmlinux命令生成vmlinuxinstall --> $(LINUX_DIR)/.image --> $(KERNEL_BUILD_DIR)/symtab.h --> `$(MAKE) $(KERNEL_MAKEOPTS) vmlinux`

    2)对vmlinuxobjcopy, strip操作: $(LINUX_DIR)/.image --> $(Kernel/CompileImage) --> $(call Kernel/CompileImage/Default) --> $(call Kernel/CopyImage)

    define Kernel/CopyImage

    $(KERNEL_CROSS)objcopy -O binary $(OBJCOPY_STRIP) -S $(LINUX_DIR)/vmlinux $(LINUX_KERNEL)$(1)

    $(KERNEL_CROSS)objcopy $(OBJCOPY_STRIP) -S $(LINUX_DIR)/vmlinux $(KERNEL_BUILD_DIR)/vmlinux$(1).elf

    $(CP) $(LINUX_DIR)/vmlinux $(KERNEL_BUILD_DIR)/vmlinux$(1).debug

    $(foreach k,

    $(if $(KERNEL_IMAGES),$(KERNEL_IMAGES),$(filter-out dtbs,$(KERNELNAME))),

    $(CP) $(LINUX_DIR)/arch/$(LINUX_KARCH)/boot/$(IMAGES_DIR)/$(k) $(KERNEL_BUILD_DIR)/$(k)$(1);

    )

    endef

    3)内核config处理

    prepare --> $(STAMP_CONFIGURED) --> $(Kernel/Configure) --> $(call Kernel/Configure/Default)

    define Kernel/Configure

    $(call Kernel/Configure/Default)

    endef


    define Kernel/Configure/Default

    $(LINUX_CONF_CMD) > $(LINUX_DIR)/.config.target

    # copy CONFIG_KERNEL_* settings over to .config.target

    awk '/^(#[[:space:]]+)?CONFIG_KERNEL/{sub("CONFIG_KERNEL_","CONFIG_");print}' $(TOPDIR)/.config >> $(LINUX_DIR)/.config.target

    echo "# CONFIG_KALLSYMS_EXTRA_PASS is not set" >> $(LINUX_DIR)/.config.target

    echo "# CONFIG_KALLSYMS_ALL is not set" >> $(LINUX_DIR)/.config.target

    echo "# CONFIG_KALLSYMS_UNCOMPRESSED is not set" >> $(LINUX_DIR)/.config.target

    $(SCRIPT_DIR)/metadata.pl kconfig $(TMP_DIR)/.packageinfo $(TOPDIR)/.config $(KERNEL_PATCHVER) > $(LINUX_DIR)/.config.override

    $(SCRIPT_DIR)/kconfig.pl 'm+' '+' $(LINUX_DIR)/.config.target /dev/null $(LINUX_DIR)/.config.override > $(LINUX_DIR)/.config

    $(call Kernel/SetNoInitramfs)

    rm -rf $(KERNEL_BUILD_DIR)/modules

    $(_SINGLE) [ -d $(LINUX_DIR)/user_headers ] || $(MAKE) $(KERNEL_MAKEOPTS) INSTALL_HDR_PATH=$(LINUX_DIR)/user_headers headers_install

    $(SH_FUNC) grep '=[ym]' $(LINUX_DIR)/.config | LC_ALL=C sort | md5s > $(LINUX_DIR)/.vermagic

    endef


    firmware编译

    firmwarekernelrootfs两个部分组成,要对两个部分先分别处理,然后再合并成一个.bin文件。

    target/linux/ipq806x/image/Makefile中最后定义了生成image的规则:

    $(eval $(call BuildImage))

    本文件中也定义了生成Image镜像(包含ubifs镜像)的规则。

    同时注意:编译kernelcompileinstall时也会执行image下的compileinstall

    include/image.mk定义BuildImage命令包:

    define BuildImage


    download:

    prepare:

    compile:

    clean:

    image_prepare:

    ifeq ($(IB),)

    .PHONY: download prepare compile clean image_prepare mkfs_prepare kernel_prepare install

    compile:

    $(call Build/Compile)


    clean:

    $(call Build/Clean)


    image_prepare: compile

    mkdir -p $(KDIR)/tmp

    $(call Image/Prepare)

    else

    image_prepare:

    mkdir -p $(KDIR)/tmp

    endif


    mkfs_prepare: image_prepare

    $(call Image/mkfs/prepare)


    kernel_prepare: mkfs_prepare

    $(call Image/BuildKernel)

    $(if $(CONFIG_TARGET_ROOTFS_INITRAMFS),$(if $(IB),,$(call Image/BuildKernel/Initramfs)))

    $(call Image/InstallKernel)


    $(foreach device,$(TARGET_DEVICES),$(call Device,$(device)))

    $(foreach fs,$(TARGET_FILESYSTEMS) $(fs-subtypes-y),$(call BuildImage/mkfs,$(fs)))


    $$(sort $$(_KERNEL_IMAGES)):

    @touch $$@


    install: kernel_prepare

    $(foreach fs,$(TARGET_FILESYSTEMS),

    $(call Image/Build,$(fs))

    )

    $(call Image/mkfs/ubifs)

    $(call Image/Checksum,md5sum --binary,md5sums)

    $(call Image/Checksum,openssl dgst -sha256,sha256sums)


    endef

    至此编译firmwareclean/prepare/compile/install目标规则出现,但只有install起作用。测试中发现直接运行make target/linux/ipq806x/image/install V=s出错,需要运行make target/linux/install V=s

    kernel处理

    install-->kernel_prepare -->mkfs_prepare -->image_prepare --> $(call Image/Prepare)

    kernel_prepare: mkfs_prepare

    $(call Image/BuildKernel)

    $(if $(CONFIG_TARGET_ROOTFS_INITRAMFS),$(if $(IB),,$(call Image/BuildKernel/Initramfs)))

    $(call Image/InstallKernel)


    $(foreach device,$(TARGET_DEVICES),$(call Device,$(device)))

    $(foreach fs,$(TARGET_FILESYSTEMS) $(fs-subtypes-y),$(call BuildImage/mkfs,$(fs)))


    $$(sort $$(_KERNEL_IMAGES)):

    @touch $$@


    mkfs_prepare: image_prepare

    $(call Image/mkfs/prepare)


    image_prepare: compile

    mkdir -p $(KDIR)/tmp

    $(call Image/Prepare)


    define Image/Prepare

    $(CP) $(LINUX_DIR)/vmlinux $(KDIR)/$(IMG_PREFIX)-vmlinux.elf

    endef

    主要处理命令包为:Image/BuildKernel,将设备树和镜像打包成FIT镜像树文件:openwrt-ipq806x-fit-uImage.itb

    define Image/BuildKernel

    $(call Image/BuildKernel/template,FIT)


    $(call Image/BuildKernel/GenericFIT,qcom-ipq40xx,$(IPQ40XX_KERNEL_LOADADDR))

    $(call Image/BuildKernel/MultiDTBFIT,qcom-ipq40xx-ap.dkxx,

    $(call FindDeviceTrees, qcom-ipq40??-ap) $(call FindDeviceTrees, qcom-ipq40??-db),

    $(IPQ40XX_KERNEL_LOADADDR))


    endef


    rootfs处理

    1. 对文件系统处理(include/image.mk

    install-->kernel_prepare -->mkfs_prepare -->$(call Image/mkfs/prepare)

    define Image/mkfs/prepare/default

    # Use symbolic permissions to avoid clobbering SUID/SGID/sticky bits

    - $(FIND) $(TARGET_DIR) -type f -not -perm /0100 -not -name 'ssh_host*' -not -name 'shadow' -print0 | $(XARGS) -0 chmod u+rw,g+r,o+r

    - $(FIND) $(TARGET_DIR) -type f -perm /0100 -print0 | $(XARGS) -0 chmod u+rwx,g+rx,o+rx

    - $(FIND) $(TARGET_DIR) -type d -print0 | $(XARGS) -0 chmod u+rwx,g+rx,o+rx

    $(INSTALL_DIR) $(TARGET_DIR)/tmp $(TARGET_DIR)/overlay

    chmod 1777 $(TARGET_DIR)/tmp

    chmod 700 $(TARGET_DIR)/usr/bin/scvt

    test -e $(TARGET_DIR)/etc/cert && chmod 0700 $(TARGET_DIR)/etc/cert || echo ok

    test -e $(TARGET_DIR)/etc/init.d/cert && chmod 0700 $(TARGET_DIR)/etc/init.d/cert || echo ok

    test -e $(TARGET_DIR)/.ocloud/ && chmod 0700 $(TARGET_DIR)/.ocloud/ || echo ok

    test -e $(TARGET_DIR)/.ocloud/ && chmod 0600 $(TARGET_DIR)/.ocloud/* || echo ok

    test -e $(TARGET_DIR)/etc/root.secret && chmod 0600 $(TARGET_DIR)/etc/root.secret || echo ok

    test -e $(TARGET_DIR)/etc/rsync.pass && chmod 0600 $(TARGET_DIR)/etc/rsync.pass || echo ok

    endef


    define Image/mkfs/prepare/pub_cfgs

    [ -d $(TARGET_DIR)/etc/cfm/config/config-pub ] || mkdir -p $(TARGET_DIR)/etc/cfm/config/config-pub

    cp $(TARGET_DIR)/etc/config/* $(TARGET_DIR)/etc/cfm/config/config-pub

    - mv $(TARGET_DIR)/etc/cfm/config/config-pub/network $(TARGET_DIR)/etc/cfm/config/config-priv/

    (cd $(TARGET_DIR)/etc/cfm/config/config-pub; md5sum * > pub-cfg-md5)

    endef


    define Image/mkfs/prepare

    $(call Image/mkfs/prepare/default)

    $(call Image/mkfs/prepare/pub_cfgs)

    endef


    1. squashfs处理

    install-->kernel_prepare -->$(call BuildImage/mkfs,$(fs))

    define BuildImage/mkfs

    install: mkfs-$(1)

    .PHONY: mkfs-$(1)

    mkfs-$(1): mkfs_prepare

    $(Image/mkfs/$(1))

    $(call Build/mkfs/default,$(1))

    $(call Build/mkfs/$(1),$(1))

    $(KDIR)/root.$(1): mkfs-$(1)


    endef


    define Image/mkfs/squashfs

    $(STAGING_DIR_HOST)/bin/mksquashfs4 $(TARGET_DIR) $(KDIR)/root.squashfs -nopad -noappend -root-owned -comp $(SQUASHFSCOMP) $(SQUASHFSOPT) -processors $(if $(CONFIG_PKG_BUILD_JOBS),$(CONFIG_PKG_BUILD_JOBS),1)

    endef


    1. squashfs打补丁

    install--> $(call Image/Build,$(fs))

    define Image/Build/squashfs

    $(call prepare_generic_squashfs,$(KDIR)/root.squashfs)

    endef

    define Image/Build

    $(call Image/Build/$(1),$(1))

    dd if=$(KDIR)/root$(2).$(1) of=$(BIN_DIR)/$(IMG_PREFIX)$(2)-$(1)-root$(3).img bs=2k conv=sync

    endef


    # pad to 4k, 8k, 16k, 64k, 128k, 256k and add jffs2 end-of-filesystem mark

    define prepare_generic_squashfs

    $(STAGING_DIR_HOST)/bin/padjffs2 $(1) 4 8 16 64 128 256

    endef

    至此生成squashfs文件系统镜像openwrt-ipq806x-squashfs-root.imgroot.squashfs)。

    4)ubifs处理

    intall --> $(call Image/mkfs/ubifs)

    将文件系统格式化为ubifs格式:openwrt-ipq806x-ubifs-root.imgroot.ubifs

    镜像打包

    intall --> $(call Image/mkfs/ubifs)

    kernel处理后的FIT镜像openwrt-ipq806x-fit-uImage.itbrootfs处理后的root.squashfs打包成ubi格式的ubi镜像openwrt-ipq806x-ubi-root.img。此镜像可直接在uboot下烧写和运行,也就是常说的factory.bin

    build_img.sh通过工具mkimageubi镜像增加firmware镜像头后生成sysupgrade.bin以支持sysupgrade升级使用

    参考:

    1. openwrt: Makefile 框架分析

    2. An introduction to Buildroot-ng

  • 相关阅读:
    计算机考研复试真题 数字求和
    计算机考研复试真题 简单计算器
    计算机考研复试真题 N阶楼梯上楼问题
    P1082 [NOIP2012 提高组] 同余方程
    进制转换
    浮点数加法
    N的阶乘
    1055 The World's Richest (25 分)
    1028 List Sorting (25 分)
    1062 Talent and Virtue (25 分)
  • 原文地址:https://www.cnblogs.com/embedded-linux/p/6654094.html
Copyright © 2020-2023  润新知