Linux内核生成uImage报错

作者

QQ群:852283276
微信:arm80x86
微信公众号:青儿创客基地
B站:主页 https://space.bilibili.com/208826118

参考

ARM架构生成uImage过程

生成uImage报错

编译uImage,

multiple (or no) load addresses: 
This is incompatible with uImages
Specify LOADADDR on the commandline to build an uImage
arch/arm/boot/Makefile:84: recipe for target 'arch/arm/boot/uImage' failed
make[1]: *** [arch/arm/boot/uImage] Error 1
arch/arm/Makefile:306: recipe for target 'uImage' failed
make: *** [uImage] Error 2

首先,在arch/arm/Makefile中,根据.config形成machine-y

machine-$(CONFIG_ARCH_ZYNQ)		+= zynq

生成MACINE,手里这几个平台都定义了CONFIG_ARCH_MULTIPLATFORM,导致MACINE为空,

# The first directory contains additional information for the boot setup code
ifneq ($(machine-y),)
MACHINE  := arch/arm/mach-$(word 1,$(machine-y))/
else
MACHINE  :=
endif
ifeq ($(CONFIG_ARCH_MULTIPLATFORM),y)
MACHINE  :=
endif

生成uImage的Makefile在arch/arm/boot/MakefileUIMAGE_LOADADDR最终是ZRELADDR,而ZRELADDR来自于$(srctree)/$(MACHINE)/Makefile.bootMACHINE为空,导致编译错误。

ifneq ($(MACHINE),)
include $(srctree)/$(MACHINE)/Makefile.boot
endif

# Note: the following conditions must always be true:
#   ZRELADDR == virt_to_phys(PAGE_OFFSET + TEXT_OFFSET)
#   PARAMS_PHYS must be within 4MB of ZRELADDR
#   INITRD_PHYS must be in RAM
ZRELADDR    := $(zreladdr-y)
PARAMS_PHYS := $(params_phys-y)
INITRD_PHYS := $(initrd_phys-y)

export ZRELADDR INITRD_PHYS PARAMS_PHYS
...
ifneq ($(LOADADDR),)
  UIMAGE_LOADADDR=$(LOADADDR)
else
  ifeq ($(CONFIG_ZBOOT_ROM),y)
    UIMAGE_LOADADDR=$(CONFIG_ZBOOT_ROM_TEXT)
  else
    UIMAGE_LOADADDR=$(ZRELADDR)
  endif
endif

check_for_multiple_loadaddr = \
if [ $(words $(UIMAGE_LOADADDR)) -ne 1 ]; then \
	echo 'multiple (or no) load addresses: $(UIMAGE_LOADADDR)'; \
	echo 'This is incompatible with uImages'; \
	echo 'Specify LOADADDR on the commandline to build an uImage'; \
	false; \
fi

# $(obj)/uImage:	$(obj)/zImage-dtb FORCE
$(obj)/uImage:	$(obj)/zImage FORCE
	@$(check_for_multiple_loadaddr)
	$(call if_changed,uimage)
	@$(kecho) '  Image $@ is ready'

生成uImage调用scripts/Makefile.lib中的cmd_uimage,

# U-Boot mkimage
# ---------------------------------------------------------------------------

MKIMAGE := $(srctree)/scripts/mkuboot.sh

# SRCARCH just happens to match slightly more than ARCH (on sparc), so reduces
# the number of overrides in arch makefiles
UIMAGE_ARCH ?= $(SRCARCH)
UIMAGE_COMPRESSION ?= $(if $(2),$(2),none)
UIMAGE_OPTS-y ?=
UIMAGE_TYPE ?= kernel
UIMAGE_LOADADDR ?= arch_must_set_this
UIMAGE_ENTRYADDR ?= $(UIMAGE_LOADADDR)
UIMAGE_NAME ?= 'Linux-$(KERNELRELEASE)'
UIMAGE_IN ?= $<
UIMAGE_OUT ?= $@

quiet_cmd_uimage = UIMAGE  $(UIMAGE_OUT)
      cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A $(UIMAGE_ARCH) -O linux \
			-C $(UIMAGE_COMPRESSION) $(UIMAGE_OPTS-y) \
			-T $(UIMAGE_TYPE) \
			-a $(UIMAGE_LOADADDR) -e $(UIMAGE_ENTRYADDR) \
			-n $(UIMAGE_NAME) -d $(UIMAGE_IN) $(UIMAGE_OUT)

mkuboot.sh脚本,

#!/bin/bash

#
# Build U-Boot image when `mkimage' tool is available.
#

MKIMAGE=$(type -path "${CROSS_COMPILE}mkimage")

if [ -z "${MKIMAGE}" ]; then
	MKIMAGE=$(type -path mkimage)
	if [ -z "${MKIMAGE}" ]; then
		# Doesn't exist
		echo '"mkimage" command not found - U-Boot images will not be built' >&2
		exit 1;
	fi
fi

# Call "mkimage" to create U-Boot image
${MKIMAGE} "$@"

可以采取的解决办法是,在make命令中指定LOADADDR的值。

你可能感兴趣的:(linux内核与驱动开发)