Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F140165986
D31191.id92231.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
14 KB
Referenced Files
None
Subscribers
None
D31191.id92231.diff
View Options
Index: sys/conf/Makefile.arm64
===================================================================
--- sys/conf/Makefile.arm64
+++ sys/conf/Makefile.arm64
@@ -23,6 +23,7 @@
.if !defined(S)
S= ../../..
.endif
+.include "src.lua.mk"
.include "$S/conf/kern.pre.mk"
INCLUDES+= -I$S/contrib/libfdt -I$S/contrib/device-tree/include
@@ -74,14 +75,14 @@
# 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
+# them to kernel_boothdr.lua, 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} | \
- ${AWK} -f $S/tools/arm_kernel_boothdr.awk -v hdrtype=v8booti && \
+ @{
+ ${LUA} $S/tools/kernel_boothdr.lua ${.ALLSRC} v8booti && \
cat ${.TARGET}.temp; \
} > ${.TARGET}
@rm ${.TARGET}.temp
Index: sys/conf/Makefile.riscv
===================================================================
--- sys/conf/Makefile.riscv
+++ sys/conf/Makefile.riscv
@@ -24,6 +24,7 @@
.if !defined(S)
S= ../../..
.endif
+.include "src.lua.mk"
.include "$S/conf/kern.pre.mk"
INCLUDES+= -I$S/contrib/libfdt -I$S/contrib/device-tree/include
@@ -37,6 +38,24 @@
KERNEL_LMA?= 0x80200000
LDFLAGS+= --defsym='kernel_lma=${KERNEL_LMA}'
+# 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)
CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls
.endif
@@ -59,3 +78,21 @@
%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 kernel_boothdr.lua, 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
+ @{
+ ${LUA} $S/tools/kernel_boothdr.lua ${.ALLSRC} riscvbooti && \
+ cat ${.TARGET}.temp; \
+ } > ${.TARGET}
+ @rm ${.TARGET}.temp
+ @echo "created ${.TARGET} from ${.ALLSRC}"
Index: sys/conf/ldscript.riscv
===================================================================
--- sys/conf/ldscript.riscv
+++ sys/conf/ldscript.riscv
@@ -6,9 +6,9 @@
SECTIONS
{
/* Read-only sections, merged into text segment: */
- . = kernbase;
+ . = text_start;
/* The load address kernel_lma is set using --defsym= on the command line. */
- .text : AT(kernel_lma)
+ .text :
{
*(.text)
*(.stub)
Index: sys/tools/arm_kernel_boothdr.awk
===================================================================
--- sys/tools/arm_kernel_boothdr.awk
+++ /dev/null
@@ -1,190 +0,0 @@
-#!/usr/bin/awk -f
-#-
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
-#
-# Copyright 2019 Ian Lepore <ian@freebsd.org>
-#
-# 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(0) # 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)
- }
-}
-
-/_start/ {
- # If the symbol name is exactly "_start" save its address.
- if ($8 == "_start") {
- gStart = hexstr_to_num($2)
- }
-}
-
-/_end/ {
- # If the symbol name is exactly "_end" remember its value.
- if ($8 == "_end") {
- gEnd = hexstr_to_num($2)
- }
-}
-
-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()
-}
Index: sys/tools/kernel_boothdr.lua
===================================================================
--- /dev/null
+++ sys/tools/kernel_boothdr.lua
@@ -0,0 +1,157 @@
+--
+-- SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+--
+-- Copyright (c) 2021 Conclusive Engineering Sp. z o. o.
+--
+-- 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$
+--
+
+function printf(s, ...)
+ return io.stderr:write(s:format(...))
+end
+
+function write_packed(fmt, ...)
+ io.write(fmt:pack(...))
+ g_written = g_written + fmt:packsize(...)
+end
+
+function read_symbols(kernel)
+ local pipe = io.popen("nm " .. kernel)
+
+ for line in pipe:lines() do
+ address, t, name = line:match("(%x+)%s(%g)%s(%g+)")
+
+ if name == "_start" then
+ g_start = tonumber(address, 16)
+ elseif name == "_end" then
+ g_end = tonumber(address, 16)
+ elseif name == "kernbase" then
+ g_kernbase = tonumber(address, 16)
+ end
+ end
+
+ pipe:close()
+
+ if g_start == nil or g_end == nil or g_kernbase == nil then
+ printf("error: failed to read nm output\n");
+ os.exit(1)
+ end
+end
+
+function addr_to_offset(addr)
+ return math.abs(math.fmod(g_kernbase, addr))
+end
+
+function write_armv7_jump()
+ local insn = 0xea000000 | (g_start_off / 4) - 2
+ write_packed("<I4", insn)
+end
+
+function write_armv8_jump()
+ local insn = 0x14000000 | g_start_off / 4
+ write_packed("<I4", insn)
+end
+
+function write_riscv_jump()
+ local insn = 0x0000006f
+ local imm1912 = (g_start_off >> 12) & 0xff
+ local imm11 = (g_start_off) >> 11 & 0x1
+ local imm1001 = (g_start_off) >> 1 & 0x3ff
+ local imm20 = (g_start_off) >> 20 & 0x1
+
+ write_packed("<I4", insn |
+ (imm1912 << 12) |
+ (imm11 << 20) |
+ (imm1001 << 21) |
+ (imm20 << 31))
+end
+
+function write_armv8_booti()
+ write_armv8_jump() -- code0
+ write_packed("<I4", 0) -- code1
+ write_packed("<I8", 0) -- text_offset
+ write_packed("<I8", g_end_off) -- image_size
+ write_packed("<I8", 0) -- flags
+ write_packed("<I8", 0) -- res1[0]
+ write_packed("<I8", 0) -- res1[1]
+ write_packed("<I8", 0) -- res1[2]
+ write_packed("<c4", "ARM\x64") -- magic
+ write_packed("<I4", 0)
+end
+
+function write_riscv_booti()
+ write_riscv_jump() -- code0
+ write_packed("<I4", 0) -- code1
+ write_packed("<I8", 0) -- text_offset
+ write_packed("<I8", g_end_off) -- image_size
+ write_packed("<I8", 0) -- flags
+ write_packed("<I8", 0) -- res1[0]
+ write_packed("<I8", 0) -- res1[1]
+ write_packed("<I8", 0x5643534952) -- res1[2]
+ write_packed("<c4", "RSC\x05") -- magic
+ write_packed("<I4", 0)
+end
+
+function write_padding()
+ while g_written < g_start_off do
+ write_packed("x")
+ end
+end
+
+if #arg ~= 2 then
+ printf("usage: %s <input file> <v7jump|v8jump|v8booti|riscvbooti>\n", arg[0])
+ os.exit(1)
+end
+
+read_symbols(arg[1])
+g_written = 0
+g_start_off = addr_to_offset(g_start)
+g_end_off = addr_to_offset(g_end)
+
+if arg[2] == "v7jump" then
+ write_armv7_jump()
+ write_padding()
+ return
+end
+
+if arg[2] == "v8jump" then
+ write_armv8_jump()
+ write_padding()
+ return
+end
+
+if arg[2] == "v8booti" then
+ write_armv8_booti()
+ write_padding()
+ return
+end
+
+if arg[2] == "riscvbooti" then
+ write_riscv_booti()
+ write_padding()
+ return
+end
+
+printf("error: unknown action %s\n", arg[2])
+os.exit(1)
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Dec 22, 1:18 AM (5 h, 24 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27114687
Default Alt Text
D31191.id92231.diff (14 KB)
Attached To
Mode
D31191: build: Rewrite arm_kernel_boothdr in Lua and add RISC-V support.
Attached
Detach File
Event Timeline
Log In to Comment