Uboot2014.04移植到S3C2440(一)--编译过程

Uboot2014.04移植到S3C2440的编译过程

为了追赶时代的浪潮,我们还是研究一下最新的东西吧。教学视频和培训班中的uboot版本太低,而现在想要移植最新版本的uboot读了代码,就会发现新的源代码在结构上与以前的版本相比发生了很大变化。 其结构越来越接近linux kernel。
1 首先我们从makefile分析看一下uboot2014.04的编译过程。
   打开顶层目录的Makefile其内容如下:
##定义uboot版本号,很简单
VERSION = 2014
PATCHLEVEL = 04
SUBLEVEL =
EXTRAVERSION =
NAME =

MAKEFLAGS += -rR --no-print-directory

unexport LC_ALL
LC_COLLATE=C
LC_NUMERIC=C
export LC_COLLATE LC_NUMERIC
#命令行中输入一些命令执行相应动作,包括简化输出,指定code检查,指定外部模块,指定输出directory
ifeq ("$(origin V)", "command line")
  KBUILD_VERBOSE = $(V)
endif
ifndef KBUILD_VERBOSE
  KBUILD_VERBOSE = 0
endif

ifeq ("$(origin C)", "command line")
  KBUILD_CHECKSRC = $(C)
endif
ifndef KBUILD_CHECKSRC
  KBUILD_CHECKSRC = 0
endif

ifdef SUBDIRS
  KBUILD_EXTMOD ?= $(SUBDIRS)
endif


ifeq ("$(origin M)", "command line")
  KBUILD_EXTMOD := $(M)
endif


# kbuild supports saving output files in a separate directory.
# To locate output files in a separate directory two syntaxes are supported.
# In both cases the working directory must be the root of the kernel src.
# 1) O=
# Use "make O=dir/to/store/output/files/"
#
# 2) Set KBUILD_OUTPUT
# Set the environment variable KBUILD_OUTPUT to point to the directory
# where the output files shall be placed.
# export KBUILD_OUTPUT=dir/to/store/output/files/
# make
#
# The O= assignment takes precedence over the KBUILD_OUTPUT environment
# variable.




# KBUILD_SRC is set on invocation of make in OBJ directory
# KBUILD_SRC is not intended to be used by the regular user (for now)
ifeq ($(KBUILD_SRC),)


# OK, Make called in directory where kernel src resides
# Do we want to locate output files in a separate directory?
ifeq ("$(origin O)", "command line")
  KBUILD_OUTPUT := $(O)
endif


ifeq ("$(origin W)", "command line")
  export KBUILD_ENABLE_EXTRA_GCC_CHECKS := $(W)
endif


# That's our default target when none is given on the command line
PHONY := _all
_all:


# Cancel implicit rules on top Makefile
$(CURDIR)/Makefile Makefile: ;


ifneq ($(KBUILD_OUTPUT),)
# Invoke a second make in the output directory, passing relevant variables
# check that the output directory actually exists
saved-output := $(KBUILD_OUTPUT)
KBUILD_OUTPUT := $(shell mkdir -p $(KBUILD_OUTPUT) && cd $(KBUILD_OUTPUT) \
&& /bin/pwd)
$(if $(KBUILD_OUTPUT),, \
     $(error output directory "$(saved-output)" does not exist))


PHONY += $(MAKECMDGOALS) sub-make


$(filter-out _all sub-make $(CURDIR)/Makefile, $(MAKECMDGOALS)) _all: sub-make
@:


sub-make: FORCE
$(if $(KBUILD_VERBOSE:1=),@)$(MAKE) -C $(KBUILD_OUTPUT) \
KBUILD_SRC=$(CURDIR) \
KBUILD_EXTMOD="$(KBUILD_EXTMOD)" -f $(CURDIR)/Makefile \
$(filter-out _all sub-make,$(MAKECMDGOALS))


# Leave processing to above invocation of make
skip-makefile := 1
endif # ifneq ($(KBUILD_OUTPUT),)
endif # ifeq ($(KBUILD_SRC),)


# We process the rest of the Makefile if this is the final invocation of make
ifeq ($(skip-makefile),)


# If building an external module we do not care about the all: rule
# but instead _all depend on modules
PHONY += all
ifeq ($(KBUILD_EXTMOD),)
_all: all
else
_all: modules
endif
#在这之前都是和输入命令相关的东西,为了简便,编译时我们不指定任何东西,因此上面的也就可以忽略,涉及了一些make的一些函数,可以自己看看。

srctree := $(if $(KBUILD_SRC),$(KBUILD_SRC),$(CURDIR))
objtree := $(CURDIR)
src := $(srctree)
obj := $(objtree)


VPATH := $(srctree)$(if $(KBUILD_EXTMOD),:$(KBUILD_EXTMOD))


export srctree objtree VPATH

# 指定源码路径,依赖文件的查找路径等
MKCONFIG := $(srctree)/mkconfig
export MKCONFIG


# Make sure CDPATH settings don't interfere
unexport CDPATH


#########################################################################


HOSTARCH := $(shell uname -m | \
sed -e s/i.86/x86/ \
   -e s/sun4u/sparc64/ \
   -e s/arm.*/arm/ \
   -e s/sa110/arm/ \
   -e s/ppc64/powerpc/ \
   -e s/ppc/powerpc/ \
   -e s/macppc/powerpc/\
   -e s/sh.*/sh/)


HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \
   sed -e 's/\(cygwin\).*/cygwin/')


export HOSTARCH HOSTOS


# Deal with colliding definitions from tcsh etc.
VENDOR=

***指定结构相关的参数*******************************
还有经销商
#########################################################################


# set default to nothing for native builds
ifeq 
CROSS_COMPILE ?=
endif

#如果$(HOSTARCH),$(ARCH)一致那么 $(HOSTARCH),$(ARCH) 为空
# SHELL used by kbuild
CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
 else if [ -x /bin/bash ]; then echo /bin/bash; \
 else echo sh; fi ; fi)

#检测shell的解析器
HOSTCC       = gcc
HOSTCFLAGS   = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer

#主机的编译器,及其编译选项
ifeq ($(HOSTOS),cygwin)
HOSTCFLAGS += -ansi
endif


# Mac OS X / Darwin's C preprocessor is Apple specific.  It
# generates numerous errors and warnings.  We want to bypass it
# and use GNU C's cpp. To do this we pass the -traditional-cpp
# option to the compiler.  Note that the -traditional-cpp flag
# DOES NOT have the same semantics as GNU C's flag, all it does
# is invoke the GNU preprocessor in stock ANSI/ISO C fashion.
#
# Apple's linker is similar, thanks to the new 2 stage linking
# multiple symbol definitions are treated as errors, hence the
# -multiply_defined suppress option to turn off this error.
#
ifeq ($(HOSTOS),darwin)
# get major and minor product version (e.g. '10' and '6' for Snow Leopard)
DARWIN_MAJOR_VERSION = $(shell sw_vers -productVersion | cut -f 1 -d '.')
DARWIN_MINOR_VERSION = $(shell sw_vers -productVersion | cut -f 2 -d '.')


os_x_before = $(shell if [ $(DARWIN_MAJOR_VERSION) -le $(1) -a \
$(DARWIN_MINOR_VERSION) -le $(2) ] ; then echo "$(3)"; else echo "$(4)"; fi ;)


# Snow Leopards build environment has no longer restrictions as described above
HOSTCC       = $(call os_x_before, 10, 5, "cc", "gcc")
HOSTCFLAGS  += $(call os_x_before, 10, 4, "-traditional-cpp")
HOSTLDFLAGS += $(call os_x_before, 10, 5, "-multiply_defined suppress")
endif


# Decide whether to build built-in, modular, or both.
# Normally, just do built-in.


KBUILD_MODULES :=
KBUILD_BUILTIN := 1


# If we have only "make modules", don't compile built-in objects.
# When we're building modules with modversions, we need to consider
# the built-in objects during the descend as well, in order to
# make sure the checksums are up to date before we record them.


ifeq ($(MAKECMDGOALS),modules)
  KBUILD_BUILTIN := $(if $(CONFIG_MODVERSIONS),1)
endif


# If we have "make <whatever> modules", compile modules
# in addition to whatever we do anyway.
# Just "make" or "make all" shall build modules as well


# U-Boot does not need modules
#ifneq ($(filter all _all modules,$(MAKECMDGOALS)),)
#  KBUILD_MODULES := 1
#endif


#ifeq ($(MAKECMDGOALS),)
#  KBUILD_MODULES := 1
#endif


export KBUILD_MODULES KBUILD_BUILTIN
export KBUILD_CHECKSRC KBUILD_SRC KBUILD_EXTMOD

#我们不进行相关设置,上述代码忽略
# Beautify output
# ---------------------------------------------------------------------------
#
# Normally, we echo the whole command before executing it. By making
# that echo $($(quiet)$(cmd)), we now have the possibility to set
# $(quiet) to choose other forms of output instead, e.g.
#
#         quiet_cmd_cc_o_c = Compiling $(RELDIR)/$@
#         cmd_cc_o_c       = $(CC) $(c_flags) -c -o $@ $<
#
# If $(quiet) is empty, the whole command will be printed.
# If it is set to "quiet_", only the short version will be printed. 
# If it is set to "silent_", nothing will be printed at all, since
# the variable $(silent_cmd_cc_o_c) doesn't exist.
#
# A simple variant is to prefix commands with $(Q) - that's useful
# for commands that shall be hidden in non-verbose mode.
#
# $(Q)ln $@ :<
#
# If KBUILD_VERBOSE equals 0 then the above command will be hidden.
# If KBUILD_VERBOSE equals 1 then the above command is displayed.


ifeq ($(KBUILD_VERBOSE),1)
  quiet =
  Q =
else
  quiet=quiet_
  Q = @
endif


# If the user is running make -s (silent mode), suppress echoing of
# commands


ifneq ($(filter s% -s%,$(MAKEFLAGS)),)
  quiet=silent_
endif


export quiet Q KBUILD_VERBOSE

#设置是否显示编译过程中的命令


# Look for make include files relative to root of kernel src
MAKEFLAGS += --include-dir=$(srctree)


# We need some generic definitions (do not try to remake the file).
$(srctree)/scripts/Kbuild.include: ;
include $(srctree)/scripts/Kbuild.include


# Make variables (CC, etc...)


AS = $(CROSS_COMPILE)as
# Always use GNU ld
ifneq ($(shell $(CROSS_COMPILE)ld.bfd -v 2> /dev/null),)
LD = $(CROSS_COMPILE)ld.bfd
else
LD = $(CROSS_COMPILE)ld
endif
CC = $(CROSS_COMPILE)gcc
CPP = $(CC) -E
AR = $(CROSS_COMPILE)ar
NM = $(CROSS_COMPILE)nm
LDR = $(CROSS_COMPILE)ldr
STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
AWK = awk
RANLIB = $(CROSS_COMPILE)RANLIB
DTC = dtc
CHECK = sparse


CHECKFLAGS     := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \
 -Wbitwise -Wno-return-void -D__CHECK_ENDIAN__ $(CF)


KBUILD_CPPFLAGS := -D__KERNEL__


KBUILD_CFLAGS   := -Wall -Wstrict-prototypes \
  -Wno-format-security \
  -fno-builtin -ffreestanding
KBUILD_AFLAGS   := -D__ASSEMBLY__


# Read UBOOTRELEASE from include/config/uboot.release (if it exists)
UBOOTRELEASE = $(shell cat include/config/uboot.release 2> /dev/null)
UBOOTVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(SUBLEVEL)))$(EXTRAVERSION)


export VERSION PATCHLEVEL SUBLEVEL UBOOTRELEASE UBOOTVERSION
export ARCH CPU BOARD VENDOR SOC CPUDIR BOARDDIR
export CONFIG_SHELL HOSTCC HOSTCFLAGS HOSTLDFLAGS CROSS_COMPILE AS LD CC
export CPP AR NM LDR STRIP OBJCOPY OBJDUMP
export MAKE AWK
export DTC CHECK CHECKFLAGS


export KBUILD_CPPFLAGS NOSTDINC_FLAGS UBOOTINCLUDE OBJCOPYFLAGS LDFLAGS
export KBUILD_CFLAGS KBUILD_AFLAGS


# When compiling out-of-tree modules, put MODVERDIR in the module
# tree rather than in the kernel tree. The kernel tree might
# even be read-only.
export MODVERDIR := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_versions


# Files to ignore in find ... statements


RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS \
  -o -name .pc -o -name .hg -o -name .git \) -prune -o
export RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn \
--exclude CVS --exclude .pc --exclude .hg --exclude .git

#编译相关的选项设置
# ===========================================================================
# Rules shared between *config targets and build targets


# Basic helpers built in scripts/
PHONY += scripts_basic
scripts_basic:
$(Q)$(MAKE) $(build)=scripts/basic
$(Q)rm -f .tmp_quiet_recordmcount


# To avoid any implicit rule to kick in, define an empty command.
scripts/basic/%: scripts_basic ;

#调用脚本文件,显示相关的帮助信息。
PHONY += outputmakefile
# outputmakefile generates a Makefile in the output directory, if using a
# separate output directory. This allows convenient use of make in the
# output directory.
outputmakefile:
ifneq ($(KBUILD_SRC),)
$(Q)ln -fsn $(srctree) source
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile \
   $(srctree) $(objtree) $(VERSION) $(PATCHLEVEL)
endif


# To make sure we do not include .config for any of the *config targets
# catch them early, and hand them over to scripts/kconfig/Makefile
# It is allowed to specify more targets when calling make, including
# mixing *config targets and build targets.
# For example 'make oldconfig all'.
# Detect when mixed targets is specified, and make a second invocation
# of make so .config is not included in this case either (for *config).


version_h := include/generated/version_autogenerated.h
timestamp_h := include/generated/timestamp_autogenerated.h


no-dot-config-targets := clean clobber mrproper distclean \
help %docs check% coccicheck \
ubootversion backup tools-only


config-targets := 0
mixed-targets  := 0
dot-config     := 1


ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),)
ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),)
dot-config := 0
endif
endif


ifeq ($(KBUILD_EXTMOD),)
        ifneq ($(filter config %config,$(MAKECMDGOALS)),)
                config-targets := 1
                ifneq ($(filter-out config %config,$(MAKECMDGOALS)),)
                        mixed-targets := 1
                endif
        endif
endif


ifeq ($(mixed-targets),1)
# ===========================================================================
# We're called with mixed targets (*config and build targets).
# Handle them one by one.


PHONY += $(MAKECMDGOALS) build-one-by-one


$(MAKECMDGOALS): build-one-by-one
@:


build-one-by-one:
$(Q)set -e; \
for i in $(MAKECMDGOALS); do \
$(MAKE) -f $(srctree)/Makefile $$i; \
done


else
ifeq ($(config-targets),1)
# ===========================================================================
# *config targets only - make sure prerequisites are updated, and descend
# in scripts/kconfig to make the *config target


# Read arch specific Makefile to set KBUILD_DEFCONFIG as needed.
# KBUILD_DEFCONFIG may point out an alternative default configuration
# used for 'make defconfig'


%_config:: outputmakefile
@$(MKCONFIG) -A $(@:_config=)
#调用mkconfig 进行配置, 配置时会调用boards.cfg文件,从该文件中读取相应的参数,产生配置文件,config.mk config.h, 其它的和以前的版本基本差不多了,只是新增加了一些代码,帮助信息等。

else
# ===========================================================================
# Build targets only - this includes vmlinux, arch specific targets, clean
# targets and others. In general all targets except *config targets.


# load ARCH, BOARD, and CPU configuration
-include include/config.mk


ifeq ($(dot-config),1)
# Read in config
-include include/autoconf.mk
-include include/autoconf.mk.dep


# load other configuration
include $(srctree)/config.mk


ifeq ($(wildcard include/config.mk),)
$(error "System not configured - see README")
endif


# If board code explicitly specified LDSCRIPT or CONFIG_SYS_LDSCRIPT, use
# that (or fail if absent).  Otherwise, search for a linker script in a
# standard location.


ifndef LDSCRIPT
#LDSCRIPT := $(srctree)/board/$(BOARDDIR)/u-boot.lds.debug
ifdef CONFIG_SYS_LDSCRIPT
# need to strip off double quotes
LDSCRIPT := $(srctree)/$(CONFIG_SYS_LDSCRIPT:"%"=%)
endif
endif

2 mkconfig 是一个shell脚本,完成配置读取boards.cfg

#!/bin/sh -e


# Script to create header files and links to configure
# U-Boot for a specific board.
#
# Parameters:  Target  Architecture  CPU  Board [VENDOR] [SOC]
#
# (C) 2002-2013 DENX Software Engineering, Wolfgang Denk <wd@denx.de>
#
# SPDX-License-Identifier: GPL-2.0+
#


APPEND=no # Default: Create new config file
BOARD_NAME="" # Name to print in make output
TARGETS=""


arch=""
cpu=""
board=""
vendor=""
soc=""
options=""


if [ \( $# -eq 2 \) -a \( "$1" = "-A" \) ] ; then
# Automatic mode
line=`awk '($0 !~ /^#/ && $7 ~ /^'"$2"'$/) { print $1, $2, $3, $4, $5, $6, $7, $8 }' $srctree/boards.cfg`
if [ -z "$line" ] ; then
echo "make: *** No rule to make target \`$2_config'.  Stop." >&2
exit 1
fi


set ${line}
# add default board name if needed
[ $# = 3 ] && set ${line} ${1}
fi


while [ $# -gt 0 ] ; do
case "$1" in
--) shift ; break ;;
-a) shift ; APPEND=yes ;;
-n) shift ; BOARD_NAME="${7%_config}" ; shift ;;
-t) shift ; TARGETS="`echo $1 | sed 's:_: :g'` ${TARGETS}" ; shift ;;
*)  break ;;
esac
done


[ $# -lt 7 ] && exit 1
[ $# -gt 8 ] && exit 1


# Strip all options and/or _config suffixes
CONFIG_NAME="${7%_config}"


[ "${BOARD_NAME}" ] || BOARD_NAME="${7%_config}"


arch="$2"
cpu=`echo $3 | awk 'BEGIN {FS = ":"} ; {print $1}'`
spl_cpu=`echo $3 | awk 'BEGIN {FS = ":"} ; {print $2}'`
if [ "$6" = "<none>" ] ; then
board=
elif [ "$6" = "-" ] ; then
board=${BOARD_NAME}
else
board="$6"
fi
[ "$5" != "-" ] && vendor="$5"
[ "$4" != "-" ] && soc="$4"
[ $# -gt 7 ] && [ "$8" != "-" ] && {
# check if we have a board config name in the options field
# the options field mave have a board config name and a list
# of options, both separated by a colon (':'); the options are
# separated by commas (',').
#
# Check for board name
tmp="${8%:*}"
if [ "$tmp" ] ; then
CONFIG_NAME="$tmp"
fi
# Check if we only have a colon...
if [ "${tmp}" != "$8" ] ; then
options=${8#*:}
TARGETS="`echo ${options} | sed 's:,: :g'` ${TARGETS}"
fi
}


if [ "${ARCH}" -a "${ARCH}" != "${arch}" ]; then
echo "Failed: \$ARCH=${ARCH}, should be '${arch}' for ${BOARD_NAME}" 1>&2
exit 1
fi


#
# Test above needed aarch64, now we need arm
#
if [ "${arch}" = "aarch64" ]; then
arch="arm"
fi


if [ "$options" ] ; then
echo "Configuring for ${BOARD_NAME} - Board: ${CONFIG_NAME}, Options: ${options}"
else
echo "Configuring for ${BOARD_NAME} board..."
fi


#
# Create link to architecture specific headers
#
if [ -n "$KBUILD_SRC" ] ; then
mkdir -p ${objtree}/include
LNPREFIX=${srctree}/arch/${arch}/include/asm/
cd ${objtree}/include
mkdir -p asm
else
cd arch/${arch}/include
fi


rm -f asm/arch


if [ -z "${soc}" ] ; then
ln -s ${LNPREFIX}arch-${cpu} asm/arch
else
ln -s ${LNPREFIX}arch-${soc} asm/arch
fi


if [ "${arch}" = "arm" ] ; then
rm -f asm/proc
ln -s ${LNPREFIX}proc-armv asm/proc
fi


if [ -z "$KBUILD_SRC" ] ; then
cd ${srctree}/include
fi


#
# Create include file for Make
#
( echo "ARCH   = ${arch}"
    if [ ! -z "$spl_cpu" ] ; then
echo 'ifeq ($(CONFIG_SPL_BUILD),y)'
echo "CPU    = ${spl_cpu}"
echo "else"
echo "CPU    = ${cpu}"
echo "endif"
    else
echo "CPU    = ${cpu}"
    fi
    echo "BOARD  = ${board}"


    [ "${vendor}" ] && echo "VENDOR = ${vendor}"
    [ "${soc}"    ] && echo "SOC    = ${soc}"
    exit 0 ) > config.mk


# Assign board directory to BOARDIR variable
if [ -z "${vendor}" ] ; then
    BOARDDIR=${board}
else
    BOARDDIR=${vendor}/${board}
fi


#
# Create board specific header file
#
if [ "$APPEND" = "yes" ] # Append to existing config file
then
echo >> config.h
else
> config.h # Create new config file
fi
echo "/* Automatically generated - do not edit */" >>config.h


for i in ${TARGETS} ; do
i="`echo ${i} | sed '/=/ {s/=/ /;q; } ; { s/$/ 1/; }'`"
echo "#define CONFIG_${i}" >>config.h ;
done


echo "#define CONFIG_SYS_ARCH  \"${arch}\""  >> config.h
echo "#define CONFIG_SYS_CPU   \"${cpu}\""   >> config.h
echo "#define CONFIG_SYS_BOARD \"${board}\"" >> config.h


[ "${vendor}" ] && echo "#define CONFIG_SYS_VENDOR \"${vendor}\"" >> config.h


[ "${soc}"    ] && echo "#define CONFIG_SYS_SOC    \"${soc}\""    >> config.h


[ "${board}"  ] && echo "#define CONFIG_BOARDDIR board/$BOARDDIR" >> config.h
cat << EOF >> config.h
#include <config_cmd_defaults.h>
#include <config_defaults.h>
#include <configs/${CONFIG_NAME}.h>
#include <asm/config.h>
#include <config_fallbacks.h>
#include <config_uncmd_spl.h>
EOF


exit 0


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值