主Makefile分析
注:1)make -n可打印makefile执行的命令,而不执行。
2)可以在规则的命令中增加echo跟踪执行进度。
顶层目录的Makefile是openert的总Makefile,第一个编译目标world是make的默认编译目标。
world:
include $(TOPDIR)/include/host.mk
ifneq ($(OPENWRT_BUILD),1)
_SINGLE=export MAKEFLAGS=$(space);override OPENWRT_BUILD=1export OPENWRT_BUILD
GREP_OPTIONS=export GREP_OPTIONS
include $(TOPDIR)/include/debug.mk
include $(TOPDIR)/include/depends.mk
include $(TOPDIR)/include/toplevel.mkelseinclude 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.'; \
exit1; \
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)\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)\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里定义的两个函数来动态生成规则,这两个函数是subdir和stampfile。
subdir命令包
# Parameters:
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:
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依赖tools,target依赖toolchain,package依赖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
KERNELNAME:=zImage Image dtbs
KERNEL_PATCHVER:=3.14
include $(INCLUDE_DIR)/target.mk
$(eval $(call BuildTarget))
BuildTarget在include/target.mk中:
include $(INCLUDE_DIR)/kernel.mk
ifeq ($(TARGET_BUILD),1)
include $(INCLUDE_DIR)/kernel-build.mk
BuildTarget?=$(BuildKernel)
endif
BuildKernel在include/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
至此编译kernel时clean/prepare/compile/install目标规则出现,涉及的Makefile包括:include/kernel-build.mk,include/kernel-defaults.mk.
1)触发make
vmlinux命令生成vmlinux:install --> $(LINUX_DIR)/.image -->
$(KERNEL_BUILD_DIR)/symtab.h --> `$(MAKE) $(KERNEL_MAKEOPTS)
vmlinux`
2)对vmlinux做objcopy,
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编译
firmware由kernel和rootfs两个部分组成,要对两个部分先分别处理,然后再合并成一个.bin文件。
target/linux/ipq806x/image/Makefile中最后定义了生成image的规则:
$(eval $(call BuildImage))
本文件中也定义了生成Image镜像(包含ubifs镜像)的规则。
同时注意:编译kernel的compile或install时也会执行image下的compile和install。
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
至此编译firmware时clean/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处理
对文件系统处理(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
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
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.img(root.squashfs)。
4)ubifs处理
intall --> $(call
Image/mkfs/ubifs)
将文件系统格式化为ubifs格式:openwrt-ipq806x-ubifs-root.img(root.ubifs)。
镜像打包
intall --> $(call
Image/mkfs/ubifs)
将kernel处理后的FIT镜像openwrt-ipq806x-fit-uImage.itb和rootfs处理后的root.squashfs打包成ubi格式的ubi镜像openwrt-ipq806x-ubi-root.img。此镜像可直接在uboot下烧写和运行,也就是常说的factory.bin。
build_img.sh通过工具mkimage将ubi镜像增加firmware镜像头后生成sysupgrade.bin以支持sysupgrade升级使用
参考: