diff --git a/sys/conf/Makefile.arm64 b/sys/conf/Makefile.arm64 index e75062115121..e8a534dadf5c 100644 --- a/sys/conf/Makefile.arm64 +++ b/sys/conf/Makefile.arm64 @@ -1,102 +1,102 @@ # Makefile.arm64 -- with config changes. # Copyright 1990 W. Jolitz # from: @(#)Makefile.i386 7.1 5/10/91 # from FreeBSD: src/sys/conf/Makefile.i386,v 1.255 2002/02/20 23:35:49 # $FreeBSD$ # # Makefile for FreeBSD # # This makefile is constructed from a machine description: # config machineid # Most changes should be made in the machine description # /sys/arm64/conf/``machineid'' # after which you should do # config machineid # Generic makefile changes should be made in # /sys/conf/Makefile.arm64 # after which config should be rerun for all machines. # # Which version of config(8) is required. %VERSREQ= 600012 .if !defined(S) S= ../../.. .endif .include "$S/conf/kern.pre.mk" INCLUDES+= -I$S/contrib/libfdt -I$S/contrib/device-tree/include LINUX_DTS_VERSION!= awk '/freebsd,dts-version/ { sub(/;$$/,"", $$NF); print $$NF }' $S/dts/freebsd-compatible.dts CFLAGS += -DLINUX_DTS_VERSION=\"${LINUX_DTS_VERSION}\" PERTHREAD_SSP_ENABLED!= grep PERTHREAD_SSP opt_global.h || true ; echo .if !empty(PERTHREAD_SSP_ENABLED) . if ${COMPILER_TYPE} == "clang" && ${COMPILER_VERSION} >= 130000 ARM64_SSP_CFLAGS = -mstack-protector-guard=sysreg ARM64_SSP_CFLAGS += -mstack-protector-guard-reg=sp_el0 ARM64_SSP_CFLAGS += -mstack-protector-guard-offset=0 . else ARM64_SSP_CFLAGS += -DPERTHREAD_SSP_WARNING . warning "Compiler is too old to support PERTHREAD_SSP" . endif CFLAGS += ${ARM64_SSP_CFLAGS} ARCH_FLAGS += ${ARM64_SSP_CFLAGS} .endif # Use a custom SYSTEM_LD command to generate the elf kernel, so we can # set the text segment start address, and also strip the "arm mapping # symbols" which have names like $a.0 and $d.2; see the document # "ELF for the ARM architecture" for more info on the mapping symbols. SYSTEM_LD= \ ${SYSTEM_LD_BASECMD} \ --defsym='text_start=kernbase + SIZEOF_HEADERS' \ -o ${.TARGET} ${SYSTEM_OBJS} vers.o; \ $(OBJCOPY) \ --wildcard \ --strip-symbol='$$[adtx]*' \ ${.TARGET} # Generate the .bin (booti images) kernel as an extra build output. # The targets and rules to generate these appear near the end of the file. KERNEL_EXTRA+= ${KERNEL_KO}.bin KERNEL_EXTRA_INSTALL+= ${KERNEL_KO}.bin .if !empty(DDB_ENABLED) || !empty(DTR_ENABLED) || !empty(HWPMC_ENABLED) CFLAGS += -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer .endif %BEFORE_DEPEND %OBJS %FILES.c %FILES.s %FILES.m %CLEAN CLEAN+= ${KERNEL_KO}.bin %RULES .include "$S/conf/kern.post.mk" # Create a kernel.bin file... # Copy the kernel to u-boot's booti image format (the elf headers are # stripped and a custom binary head blob is prepended), saving the # output in a temp file. We also strip arm "marker" symbols which are # used only by elf toolchains. Read the symbols from kernel.full and pass # them to arm_kernel_boothdr.awk, which generates a binary header blob # that goes on the front of the stripped kernel. Cat the header blob # and the temp file together to make the kernel.bin file. ${KERNEL_KO}.bin: ${FULLKERNEL} @${OBJCOPY} --wildcard --strip-symbol='$$[adtx]*' \ --output-target=binary ${.ALLSRC} ${.TARGET}.temp - @{ readelf -s ${.ALLSRC} | \ + @{ ${NM} ${.ALLSRC} | \ ${AWK} -f $S/tools/arm_kernel_boothdr.awk -v hdrtype=v8booti && \ cat ${.TARGET}.temp; \ } > ${.TARGET} @rm ${.TARGET}.temp @echo "created ${.TARGET} from ${.ALLSRC}" diff --git a/sys/tools/arm_kernel_boothdr.awk b/sys/tools/arm_kernel_boothdr.awk index f22c6167c7b0..cda56e2225cd 100644 --- a/sys/tools/arm_kernel_boothdr.awk +++ b/sys/tools/arm_kernel_boothdr.awk @@ -1,190 +1,190 @@ #!/usr/bin/awk -f #- # SPDX-License-Identifier: BSD-2-Clause-FreeBSD # # Copyright 2019 Ian Lepore # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $FreeBSD$ BEGIN { # Init global vars. gBytesOut = 0; # How many output bytes we've written so far gKernbase = 0; # Address of first byte of loaded kernel image gStart = 0; # Address of _start symbol gStartOff = 0; # Offset of _start symbol from start of image gEnd = 0; # Address of _end symbol gEndOff = 0; # Offset of _end symbol from start of image # The type of header we're writing is set using -v hdrtype= on # the command line, ensure we got a valid value for it. if (hdrtype != "v7jump" && hdrtype != "v8jump" && hdrtype != "v8booti") { print "arm_kernel_boothdr.awk: " \ "missing or invalid '-v hdrtype=' argument" >"/dev/stderr" gHdrType = "error_reported" exit 1 } gHdrType = hdrtype } function addr_to_offset(addr) { # Turn an address into an offset from the start of the loaded image. return addr % gKernbase } function hexstr_to_num(str) { # Prepend a 0x onto the string, then coerce it to a number by doing # arithmetic with it, which makes awk run it through strtod(), # which handles hex numbers that have a 0x prefix. return 0 + ("0x" str) } function write_le32(num) { for (i = 0; i < 4; i++) { printf("%c", num % 256); num /= 256 } gBytesOut += 4 } function write_le64(num) { for (i = 0; i < 8; i++) { printf("%c", num % 256); num /= 256 } gBytesOut += 8 } function write_padding() { # Write enough padding bytes so that the header fills all the # remaining space before the _start symbol. while (gBytesOut++ < gStartOff) { printf("%c", 0); } } function write_v7jump() { # Write the machine code for "b _start"... # 0xea is armv7 "branch always" and the low 24 bits is the signed # offset from the current PC, in words. We know the gStart offset # is in the first 2mb, so it'll fit in 24 bits. write_le32(hexstr_to_num("ea000000") + (gStartOff / 4) - 2) } function write_v8jump() { # Write the machine code for "b _start"... # 0x14 is armv8 "branch always" and the low 26 bits is the signed # offset from the current PC, in words. We know the gStart offset # is in the first 2mb, so it'll fit in 26 bits. write_le32(hexstr_to_num("14000000") + (gStartOff / 4)) } function write_v8booti() { # We are writing this struct... # # struct Image_header { # uint32_t code0; /* Executable code */ # uint32_t code1; /* Executable code */ # uint64_t text_offset; /* Image load offset, LE */ # uint64_t image_size; /* Effective Image size, LE */ # uint64_t flags; /* Kernel flags, LE */ # uint64_t res1[3]; /* reserved */ # uint32_t magic; /* Magic number */ # uint32_t res2; # }; # # We write 'b _start' into code0. The image size is everything from # the start of the loaded image to the offset given by the _end symbol. write_v8jump() # code0 write_le32(0) # code1 write_le64(0) # text_offset write_le64(gEndOff) # image_size write_le64(hexstr_to_num("8")) # flags write_le64(0) # res1[0] write_le64(0) # res1[1] write_le64(0) # res1[2] write_le32(hexstr_to_num("644d5241")) # magic (LE "ARMd" (d is 0x64)) write_le32(0) # res2 } /kernbase/ { # If the symbol name is exactly "kernbase" save its address. - if ($8 == "kernbase") { - gKernbase = hexstr_to_num($2) + if ($3 == "kernbase") { + gKernbase = hexstr_to_num($1) } } /_start/ { # If the symbol name is exactly "_start" save its address. - if ($8 == "_start") { - gStart = hexstr_to_num($2) + if ($3 == "_start") { + gStart = hexstr_to_num($1) } } /_end/ { # If the symbol name is exactly "_end" remember its value. - if ($8 == "_end") { - gEnd = hexstr_to_num($2) + if ($3 == "_end") { + gEnd = hexstr_to_num($1) } } END { # Note that this function runs even if BEGIN calls exit(1)! if (gHdrType == "error_reported") { exit 1 } # Make sure we got all three required symbols. if (gKernbase == 0 || gStart == 0 || gEnd == 0) { print "arm_kernel_boothdr.awk: " \ "missing kernbase/_start/_end symbol(s)" >"/dev/stderr" exit 1 } gStartOff = addr_to_offset(gStart) gEndOff = addr_to_offset(gEnd) if (gHdrType == "v7jump") { write_v7jump() } else if (gHdrType == "v8jump") { write_v8jump() } else if (gHdrType == "v8booti") { write_v8booti() } write_padding() }