mirror of
https://github.com/zephyrproject-rtos/zephyr
synced 2025-08-21 13:35:22 +00:00
See https://groups.google.com/forum/#!topic/ia32-abi/cn7TM6J_TIg for more details. • Support IA32 without FPU. • Minimum ISA: Pentium ISA without x87 FPU instructions. • Don't allow mixing i386 object files with Intel MCU object files. • Support floating point with software emulation: a. Long double is the same as double. b. Use __float80 for 80-bit double. • Minimize memory footprint: a. Code size b. Data size c. Stack size Here is the draft of Intel MCU psABI. The differences from IA32 psABI are 1. The minimum instruction set is Intel Pentium ISA minus instructions for x87 floating point unit. 2. There are no x87 floating point registers. 3. There are no vector registers. 4. Segment registers are optional. 5. Support for TLS relocations are optional. 6. Scalar types larger than 4 bytes are aligned to 4 bytes. 7. There are no vector types. 8. _Decimal32, _Decimal64, and _Decimal128 types are optional. 9. long double type is the same as double. 10. float, double and long double types are passed and returned in general purpose registers. 11. _Decimal32 and _Decimal64 types are passed in general purpose registers. 12. Aggregate types no larger than 8 bytes are passed and returned in general purpose registers. 13. Stack is 4-byte aligned. 14. The auxiliary vector support is optional. 15. Register %edx has undefined value at process entry. 16. New ELF machine code: EM_IAMCU. 17. New predefined C/C++ pre-processor symbols: __iamcu and __iamcu__ Change-Id: I6a0c45ad22d8f710b6f37a041aaa2fc1bf0b1c39 Signed-off-by: Anas Nashif <anas.nashif@intel.com>
289 lines
7.1 KiB
Bash
Executable File
289 lines
7.1 KiB
Bash
Executable File
#!/bin/sh
|
|
#
|
|
# link the kernel
|
|
#
|
|
# The kernel is linked from the objects selected by $(KBUILD_ZEPHYR_INIT) and
|
|
# $(KBUILD_ZEPHYR_MAIN). Most are built-in.o files from top-level directories
|
|
# in the kernel tree, others are specified in arch/$(ARCH)/Makefile.
|
|
# Ordering when linking is important, and $(KBUILD_ZEPHYR_INIT) must be first.
|
|
#
|
|
# microkernel/nanokernel
|
|
# ^
|
|
# |
|
|
# +-< $(KBUILD_ZEPHYR_INIT)
|
|
# | +--< init/version.o + more
|
|
# |
|
|
# +--< $(KBUILD_ZEPHYR_MAIN)
|
|
# | +--< drivers/built-in.o mm/built-in.o + more
|
|
# |
|
|
# +-< ${kallsymso} (see description in KALLSYMS section)
|
|
#
|
|
|
|
# Error out on error
|
|
set -e
|
|
|
|
# Nice output in kbuild format
|
|
# Will be supressed by "make -s"
|
|
info()
|
|
{
|
|
if [ "${quiet}" != "silent_" ]; then
|
|
printf " %-7s %s\n" ${1} ${2}
|
|
fi
|
|
}
|
|
|
|
# Creates linker parameters.
|
|
# {1} output file
|
|
# {2} symbol map file
|
|
linker_params()
|
|
{
|
|
LIBS=""
|
|
for tcl in ${ALL_LIBS}; do LIBS="${LIBS} -l${tcl}"; done
|
|
echo "${LDFLAGS_zephyr}" > ${1}
|
|
echo "-Map ./${2}" >> ${1}
|
|
echo "-L ${objtree}/include/generated" >> ${1}
|
|
echo "-u _OffsetAbsSyms -u _ConfigAbsSyms" >> ${1}
|
|
echo "-e __start" >> ${1}
|
|
echo "--start-group ${KBUILD_ZEPHYR_MAIN}" >> ${1}
|
|
echo "${objtree}/include/generated/offsets.o" >> ${1}
|
|
echo "--end-group" >> ${1}
|
|
echo "${LIB_INCLUDE_DIR} ${LIBS}" >> ${1}
|
|
}
|
|
|
|
#Creates linker command file
|
|
# {1} output file
|
|
# {2} optional additional link parameters
|
|
linker_command()
|
|
{
|
|
${CC} -x assembler-with-cpp -nostdinc -undef -E -P \
|
|
${LDFLAG_LINKERCMD} \
|
|
${LD_TOOLCHAIN} ${2} \
|
|
-I${srctree}/include -I${objtree}/include/generated \
|
|
${KBUILD_LDS} \
|
|
-o ${1}
|
|
}
|
|
|
|
# Link of ${KERNEL_NAME}.o used for section mismatch analysis
|
|
# ${1} output file
|
|
# ${2} linker parameters file
|
|
# ${3} linker command file
|
|
initial_link()
|
|
{
|
|
${LD} -T ${3} @${2} -o ${1}
|
|
}
|
|
|
|
#Generates IDT and merge them into final binary
|
|
# ${1} input file (${KERNEL_NAME}.elf)
|
|
# ${2} output file (staticIdt.o)
|
|
gen_idt()
|
|
{
|
|
test -z $OUTPUT_FORMAT && OUTPUT_FORMAT=elf32-i386
|
|
test -z $OUTPUT_ARCH && OUTPUT_ARCH=i386
|
|
${OBJCOPY} -I $OUTPUT_FORMAT -O binary -j intList ${1} isrList.bin
|
|
${GENIDT} -i isrList.bin -n ${CONFIG_IDT_NUM_VECTORS:-256} -o staticIdt.bin
|
|
${OBJCOPY} -I binary -B $OUTPUT_ARCH -O $OUTPUT_FORMAT --rename-section .data=staticIdt staticIdt.bin ${2}
|
|
rm -f staticIdt.bin
|
|
rm -f isrList.bin
|
|
}
|
|
|
|
# Linking the kernel
|
|
# ${1} - linker params file (${KERNEL_NAME}.lnk)
|
|
# ${2} - linker command file (final-linker.cmd)
|
|
# ${3} - input file (staticIdt.o)
|
|
# ${4} - output file
|
|
zephyr_link()
|
|
{
|
|
${LD} -T ${2} @${1} ${3} -o ${4}
|
|
${OBJCOPY} --set-section-flags intList=noload ${4} elf.tmp
|
|
${OBJCOPY} -R intList elf.tmp ${4}
|
|
rm elf.tmp
|
|
}
|
|
|
|
zephyr_bin_strip()
|
|
{
|
|
${OBJDUMP} -S ${1} >${2}
|
|
${OBJCOPY} -S -O binary -R .note -R .comment -R COMMON -R .eh_frame ${1} ${3}
|
|
${STRIP} -s -o ${4} ${1}
|
|
}
|
|
|
|
|
|
# Create ${2} .o file with all symbols from the ${1} object file
|
|
kallsyms()
|
|
{
|
|
info KSYM ${2}
|
|
local kallsymopt;
|
|
|
|
if [ -n "${CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX}" ]; then
|
|
kallsymopt="${kallsymopt} --symbol-prefix=_"
|
|
fi
|
|
|
|
if [ -n "${CONFIG_KALLSYMS_ALL}" ]; then
|
|
kallsymopt="${kallsymopt} --all-symbols"
|
|
fi
|
|
|
|
if [ -n "${CONFIG_ARM}" ] && [ -n "${CONFIG_PAGE_OFFSET}" ]; then
|
|
kallsymopt="${kallsymopt} --page-offset=$CONFIG_PAGE_OFFSET"
|
|
fi
|
|
|
|
if [ -n "${CONFIG_X86_64}" ]; then
|
|
kallsymopt="${kallsymopt} --absolute-percpu"
|
|
fi
|
|
|
|
local aflags="${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL} \
|
|
${NOSTDINC_FLAGS} ${ZEPHYRINCLUDE} ${KBUILD_CPPFLAGS}"
|
|
|
|
${NM} -n ${1} | \
|
|
scripts/kallsyms ${kallsymopt} | \
|
|
${CC} ${aflags} -c -o ${2} -x assembler-with-cpp -
|
|
}
|
|
|
|
# Create map file with all symbols from ${1}
|
|
# See mksymap for additional details
|
|
mksysmap()
|
|
{
|
|
${CONFIG_SHELL} "${srctree}/scripts/mksysmap" ${1} ${2}
|
|
}
|
|
|
|
sortextable()
|
|
{
|
|
${objtree}/scripts/sortextable ${1}
|
|
}
|
|
|
|
# Delete output files in case of error
|
|
trap cleanup SIGHUP SIGINT SIGQUIT SIGTERM ERR
|
|
cleanup()
|
|
{
|
|
rm -f .old_version
|
|
rm -f .tmp_System.map
|
|
rm -f .tmp_kallsyms*
|
|
rm -f .tmp_version
|
|
rm -f .tmp_${KERNEL_NAME}*
|
|
rm -f System.map
|
|
rm -f ${KERNEL_NAME}.lnk
|
|
rm -f ${KERNEL_NAME}.map
|
|
rm -f ${KERNEL_NAME}.elf
|
|
rm -f ${KERNEL_NAME}.lst
|
|
rm -f ${KERNEL_NAME}.bin
|
|
rm -f ${KERNEL_NAME}.strip
|
|
rm -f staticIdt.o
|
|
rm -f linker.cmd
|
|
rm -f final-linker.cmd
|
|
}
|
|
|
|
#
|
|
#
|
|
# Use "make V=1" to debug this script
|
|
case "${KBUILD_VERBOSE}" in
|
|
*1*)
|
|
set -x
|
|
;;
|
|
esac
|
|
|
|
if [ "$1" = "clean" ]; then
|
|
cleanup
|
|
exit 0
|
|
fi
|
|
|
|
# We need access to CONFIG_ symbols
|
|
case "${KCONFIG_CONFIG}" in
|
|
*/*)
|
|
. "${KCONFIG_CONFIG}"
|
|
;;
|
|
*)
|
|
# Force using a file from the current directory
|
|
. "./${KCONFIG_CONFIG}"
|
|
esac
|
|
|
|
#link ${KERNEL_NAME}.o
|
|
info LD ${KERNEL_NAME}.elf
|
|
linker_params ${KERNEL_NAME}.lnk ${KERNEL_NAME}.map
|
|
linker_command linker.cmd
|
|
initial_link ${KERNEL_NAME}.elf ${KERNEL_NAME}.lnk linker.cmd
|
|
|
|
# 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;
|
|
|
|
kallsymso=""
|
|
kallsyms_zephyr=""
|
|
if [ -n "${CONFIG_KALLSYMS}" ]; then
|
|
|
|
# kallsyms support
|
|
# Generate section listing all symbols and add it into the kernel
|
|
# It's a three step process:
|
|
# 1) Link .tmp_${KERNEL_NAME} 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_${KERNEL_NAME}2 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 kernel.
|
|
#
|
|
# a) Verify that the System.map matches the map from
|
|
# ${kallsymso}.
|
|
|
|
kallsymso=.tmp_kallsyms2.o
|
|
kallsyms_zephyr=.tmp_${KERNEL_NAME}2
|
|
|
|
# step 1
|
|
zephyr_link "" .tmp_${KERNEL_NAME}1
|
|
kallsyms .tmp_${KERNEL_NAME}1 .tmp_kallsyms1.o
|
|
|
|
# step 2
|
|
zephyr_link .tmp_kallsyms1.o .tmp_${KERNEL_NAME}2
|
|
kallsyms .tmp_${KERNEL_NAME}2 .tmp_kallsyms2.o
|
|
|
|
# step 2a
|
|
if [ -n "${KALLSYMS_EXTRA_PASS}" ]; then
|
|
kallsymso=.tmp_kallsyms3.o
|
|
kallsyms_zephyr=.tmp_${KERNEL_NAME}3
|
|
|
|
zephyr_link .tmp_kallsyms2.o .tmp_${KERNEL_NAME}3
|
|
|
|
kallsyms .tmp_${KERNEL_NAME}3 .tmp_kallsyms3.o
|
|
fi
|
|
fi
|
|
|
|
if [ "${SRCARCH}" = "x86" ]; then
|
|
info SIDT ${KERNEL_NAME}.elf
|
|
gen_idt ${KERNEL_NAME}.elf staticIdt.o
|
|
linker_command final-linker.cmd -DFINAL_LINK
|
|
zephyr_link ${KERNEL_NAME}.lnk final-linker.cmd staticIdt.o ${KERNEL_NAME}.elf
|
|
fi
|
|
|
|
info BIN ${KERNEL_NAME}.bin
|
|
zephyr_bin_strip ${KERNEL_NAME}.elf ${KERNEL_NAME}.lst ${KERNEL_NAME}.bin ${KERNEL_NAME}.strip
|
|
|
|
if [ -n "${CONFIG_BUILDTIME_EXTABLE_SORT}" ]; then
|
|
info SORTEX ${KERNEL_NAME}
|
|
sortextable ${KERNEL_NAME}
|
|
fi
|
|
|
|
info SYSMAP System.map
|
|
mksysmap ${KERNEL_NAME}.elf System.map
|
|
|
|
# step a (see comment above)
|
|
if [ -n "${CONFIG_KALLSYMS}" ]; then
|
|
mksysmap ${kallsyms_zephyr} .tmp_System.map
|
|
|
|
if ! cmp -s System.map .tmp_System.map; then
|
|
echo >&2 Inconsistent kallsyms data
|
|
echo >&2 Try "make KALLSYMS_EXTRA_PASS=1" as a workaround
|
|
cleanup
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# We made a new kernel - delete old version file
|
|
rm -f .old_version
|