Changeset View
Changeset View
Standalone View
Standalone View
sys/tools/kernel_boothdr.lua
- This file was added.
Property | Old Value | New Value |
---|---|---|
File Mode | null | 100755 |
-- | |||||
Lint: Invalid Executable: Executable files should either be binary or contain a shebang. | |||||
-- 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) | |||||
Not Done Inline ActionsThis may complicate things, but for booti on riscv you almost certainly want the _alt_start entry, which appears first in the .text section. See the comments in locore.S for a slight elaboration. mhorne: This may complicate things, but for booti on riscv you almost certainly want the `_alt_start`… | |||||
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) |
Executable files should either be binary or contain a shebang.