You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
#!/bin/shset -e
# Nice output in kbuild format# Will be supressed by "make -s"info()
{
if [ "${quiet}"!="silent_" ];thenprintf" %-7s %s\n"${1}${2}fi
}
# Thin archive build here makes a final archive with# symbol table and indexes from vmlinux objects, which can be# used as input to linker.## Traditional incremental style of link does not require this step## built-in.o output file#archive_builtin()
{
if [ -n"${CONFIG_THIN_ARCHIVES}" ];then
info AR built-in.o
rm -f built-in.o;${AR} rcsT${KBUILD_ARFLAGS} built-in.o \
${KBUILD_VMLINUX_INIT} \
${KBUILD_VMLINUX_MAIN}if [ -n"${CONFIG_LTO_CLANG}" ];then
mv -f built-in.o built-in.o.tmp
${LLVM_AR} rcsT${KBUILD_ARFLAGS} built-in.o $(${AR} t built-in.o.tmp)
rm -f built-in.o.tmp
fifi
}
# If CONFIG_LTO_CLANG is selected, collect generated symbol versions into# .tmp_symversionsmodversions()
{
if [ -z"${CONFIG_LTO_CLANG}" ];thenreturnfiif [ -z"${CONFIG_MODVERSIONS}" ];thenreturnfi
rm -f .tmp_symversions
forain built-in.o ${KBUILD_VMLINUX_LIBS};doforoin$(${AR} t $a);doif [ -f${o}.symversions ];then
cat ${o}.symversions >> .tmp_symversions
fidonedoneecho"-T .tmp_symversions"
}
# Link of vmlinux.o used for section mismatch analysis# ${1} output filemodpost_link()
{
local objects
if [ -n"${CONFIG_THIN_ARCHIVES}" ];then
objects="--whole-archive built-in.o"else
objects="${KBUILD_VMLINUX_INIT}\ --start-group \${KBUILD_VMLINUX_MAIN}\ --end-group"fiif [ -n"${CONFIG_LTO_CLANG}" ];then# This might take a while, so indicate that we're doing# an LTO link
info LTO vmlinux.o
else
info LD vmlinux.o
fi${LD}${LDFLAGS} -r -o ${1}$(modversions)${objects}--------------------------------------链接head.o和built-in.o生成vmlinux.o。
}
# If CONFIG_LTO_CLANG is selected, we postpone running recordmcount until# we have compiled LLVM IR to an object file.recordmcount()
{
if [ -z"${CONFIG_LTO_CLANG}" ];thenreturnfiif [ -n"${CONFIG_FTRACE_MCOUNT_RECORD}" ];then
scripts/recordmcount ${RECORDMCOUNT_FLAGS}$*fi
}
# Link of vmlinux# ${1} - optional extra .o files# ${2} - output filevmlinux_link()
{
local lds="${objtree}/${KBUILD_LDS}"local objects
if [ "${SRCARCH}"!="um" ];thenlocal ld=${LD}local ldflags="${LDFLAGS}${LDFLAGS_vmlinux}"if [ -n"${LDFINAL_vmlinux}" ];then
ld=${LDFINAL_vmlinux}
ldflags="${LDFLAGS_FINAL_vmlinux}${LDFLAGS_vmlinux}"fiif [[ -n"${CONFIG_THIN_ARCHIVES}"&&-z"${CONFIG_LTO_CLANG}" ]];then
objects="--whole-archive built-in.o ${1}"else
objects="${KBUILD_VMLINUX_INIT}\ --start-group \${KBUILD_VMLINUX_MAIN}\ --end-group \${1}"fi${ld}${ldflags} -o ${2} -T ${lds}${objects}else
...
fi
}
# Create ${2} .o file with all symbols from the ${1} object filekallsyms()
{
info KSYM ${2}local kallsymopt;if [ -n"${CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX}" ];then
kallsymopt="${kallsymopt} --symbol-prefix=_"fiif [ -n"${CONFIG_KALLSYMS_ALL}" ];then
kallsymopt="${kallsymopt} --all-symbols"fiif [ -n"${CONFIG_KALLSYMS_ABSOLUTE_PERCPU}" ];then
kallsymopt="${kallsymopt} --absolute-percpu"fiif [ -n"${CONFIG_KALLSYMS_BASE_RELATIVE}" ];then
kallsymopt="${kallsymopt} --base-relative"filocal aflags="${KBUILD_AFLAGS}${KBUILD_AFLAGS_KERNEL}\${NOSTDINC_FLAGS}${LINUXINCLUDE}${KBUILD_CPPFLAGS}"local afile="`basename ${2} .o`.S"${NM} -n ${1}| scripts/kallsyms ${kallsymopt}>${afile}${CC}${aflags} -c -o ${2}${afile}
}
# Create map file with all symbols from ${1}# See mksymap for additional detailsmksysmap()
{
${CONFIG_SHELL}"${srctree}/scripts/mksysmap"${1}${2}
}
sortextable()
{
${objtree}/scripts/sortextable ${1}
}
# Delete output files in case of errorcleanup()
{
rm -f .old_version
rm -f .tmp_System.map
rm -f .tmp_kallsyms*
rm -f .tmp_version
rm -f .tmp_symversions
rm -f .tmp_vmlinux*
rm -f built-in.o
rm -f System.map
rm -f vmlinux
rm -f vmlinux.o
}
on_exit()
{
if [ $?-ne 0 ];then
cleanup
fi
}
trap on_exit EXIT
on_signals()
{
exit 1
}
trap on_signals HUP INT QUIT TERM
### Use "make V=1" to debug this scriptcase"${KBUILD_VERBOSE}"in*1*)
set -x
;;
esacif [ "$1"="clean" ];then
cleanup
exit 0
fi# We need access to CONFIG_ symbolscase"${KCONFIG_CONFIG}"in*/*)
."${KCONFIG_CONFIG}"
;;
*)
# Force using a file from the current directory."./${KCONFIG_CONFIG}"esac# Update version
info GEN .version
if [ !-r .version ];then
rm -f .version;echo 1 >.version;else
mv .version .old_version;
expr 0$(cat .old_version) + 1 >.version;fi;
archive_builtin
#link vmlinux.o
modpost_link vmlinux.o-----------------------------------------------生成vmlinux.o文件。
# modpost vmlinux.o to check for section mismatches${MAKE} -f "${srctree}/scripts/Makefile.modpost" vmlinux.o
# final build of init/${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init GCC_PLUGINS_CFLAGS="${GCC_PLUGINS_CFLAGS}"if [ -n"${CONFIG_LTO_CLANG}" ];then# Re-use vmlinux.o, so we can avoid the slow LTO link step in# vmlinux_link
KBUILD_VMLINUX_INIT=
KBUILD_VMLINUX_MAIN=vmlinux.o
# Call recordmcount if needed
recordmcount vmlinux.o
fi
kallsymso=""
kallsyms_vmlinux=""if [ -n"${CONFIG_KALLSYMS}" ];then# kallsyms support# Generate section listing all symbols and add it into vmlinux# It's a three step process:# 1) Link .tmp_vmlinux1 so it has all symbols and sections,# but __kallsyms is empty.# Running kallsyms on that gives us .tmp_kallsyms1.o with# the right size# 2) Link .tmp_vmlinux2 so it now has a __kallsyms section of# the right size, but due to the added section, some# addresses have shifted.# From here, we generate a correct .tmp_kallsyms2.o# 2a) We may use an extra pass as this has been necessary to# woraround some alignment related bugs.# KALLSYMS_EXTRA_PASS=1 is used to trigger this.# 3) The correct ${kallsymso} is linked into the final vmlinux.## a) Verify that the System.map from vmlinux matches the map from# ${kallsymso}.
kallsymso=.tmp_kallsyms2.o
kallsyms_vmlinux=.tmp_vmlinux2
# step 1
vmlinux_link "" .tmp_vmlinux1---------------------------------------------生成.tmp_vmlinux1文件。
kallsyms .tmp_vmlinux1 .tmp_kallsyms1.o-----------------------------------生成.tmp_kallsyms1.o文件。
# step 2
vmlinux_link .tmp_kallsyms1.o .tmp_vmlinux2-------------------------------生成.tmp_vmlinux2文件。
kallsyms .tmp_vmlinux2 .tmp_kallsyms2.o-----------------------------------生成.tmp_kallsyms2.o文件。
# step 2aif [ -n"${KALLSYMS_EXTRA_PASS}" ];then
kallsymso=.tmp_kallsyms3.o
kallsyms_vmlinux=.tmp_vmlinux3
vmlinux_link .tmp_kallsyms2.o .tmp_vmlinux3
kallsyms .tmp_vmlinux3 .tmp_kallsyms3.o
fifi
info LD vmlinux
vmlinux_link "${kallsymso}" vmlinux-------------------------------------------生成vmlinux文件。
if [ -n"${CONFIG_BUILDTIME_EXTABLE_SORT}" ];then
info SORTEX vmlinux
sortextable vmlinux
fi
info SYSMAP System.map
mksysmap vmlinux System.map---------------------------------------------------从vmlinux生成System.map文件。
# step a (see comment above)if [ -n"${CONFIG_KALLSYMS}" ];then
mksysmap ${kallsyms_vmlinux} .tmp_System.map
if! cmp -s System.map .tmp_System.map;thenecho>&2 Inconsistent kallsyms data
echo>&2 Try "make KALLSYMS_EXTRA_PASS=1" as a workaround
exit 1
fifi# We made a new kernel - delete old version file
rm -f .old_version
[Linux] 简析Linux镜像生成过程
Linux镜像原始输出为vmlinux,后续可能已Image、Image.gz、uImage形式输出。具体过程如下:
1. 生成vmlinux和System.map
根目录Makefile生成.vmlinux.cmd:
cmd_vmlinux := /bin/bash scripts/link-vmlinux.sh aarch64-linux-gnu-ld -EL --no-undefined -X -pie -shared -Bsymbolic --no-apply-dynamic-relocs --fix-cortex-a53-843419 --build-id ; true
link-vmlinux.sh链接head.o和built-in.o,并最终输出vmlinux和System.map文件。
arch/arm64/boot/.Image.cmd:
cmd_arch/arm64/boot/Image := aarch64-linux-gnu-objcopy -O binary -R .note -R .note.gnu.build-id -R .comment -S vmlinux arch/arm64/boot/Image
移除vmlinux中.note、.note.build-id、.comment段,并且移除所有符号和重定位信息,输出binary格式到Image中。
arch/arm64/boot/.Image.gz.cmd:
cmd_arch/arm64/boot/Image.gz := (cat arch/arm64/boot/Image | gzip -n -f -9 > arch/arm64/boot/Image.gz) || (rm -f arch/arm64/boot/Image.gz ; false)
Image.gz文件就是将Image文件通过gzip进行打包。
3. 生成uImage文件
uImage是对而进行文件加上Uboot头信息,Uboot读取后进行解析,校验并加载到特定位置运行。
在scripts/Makefile.lib中定义了生成uImage命令:
关于uImage的生成可以参考:[LS104x] 使用FIT的kernel格式和initramfs
Reference
The text was updated successfully, but these errors were encountered: