-
Notifications
You must be signed in to change notification settings - Fork 27
Expand file tree
/
Copy pathgenerate_loader_asm.py
More file actions
executable file
·114 lines (98 loc) · 3.29 KB
/
Copy pathgenerate_loader_asm.py
File metadata and controls
executable file
·114 lines (98 loc) · 3.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#! /usr/bin/env python3
# -*- mode: python; coding: utf-8; -*-
#
# Codezero -- a microkernel for embedded systems.
#
# Copyright © 2009 B Labs Ltd
#
import os, sys, shelve, subprocess
from os.path import join
PROJRELROOT = "../../"
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), PROJRELROOT)))
from scripts.config.projpaths import *
from scripts.config.configuration import *
from scripts.config.lib import *
from scripts.config.config_invoke import *
config = configuration_retrieve()
# Convert address from python literal to numeric value
def address_remove_literal(address):
value = hex(int(address, 16) - 0xF0000000)
if value[-1] in ["l", "L"]:
value = value[:-1]
return value
ksym_header = """
/*
* %s autogenerated from %s.
* by %s
*
* This file is included by the loader sources so that any
* kernel symbol address can be known in advance and stopped
* at by debuggers before virtual memory is enabled.
*/
"""
assembler_symbol_definition = """
.section .text
.align 4
.global %s
.type %s, function
.equ %s, %s
"""
def generate_ksym_to_loader(target_path, source_path):
symbols = ["break_virtual"]
with open(target_path, "w") as asm_file:
asm_file.write(ksym_header % (target_path, source_path, sys.argv[0]))
for symbol in symbols:
process = subprocess.Popen(
config.toolchain_kernel
+ "objdump -d "
+ source_path
+ ' | grep "<'
+ symbol
+ '>"',
shell=True,
stdout=subprocess.PIPE,
)
ret = process.wait()
if ret != 0:
raise RuntimeError(
f"objdump failed with exit code {ret} for symbol '{symbol}'"
)
output = process.stdout.read().decode("utf-8", errors="replace").strip()
parts = output.split(maxsplit=1)
if len(parts) != 2:
raise ValueError(
f"Unexpected objdump output for symbol '{symbol}': {output!r}"
)
address, name = parts
expected_name = "<" + symbol + ">:"
if name != expected_name:
raise ValueError(
f"Symbol mismatch: expected {expected_name!r}, got {name!r}"
)
asm_file.write(
assembler_symbol_definition
% (symbol, symbol, symbol, address_remove_literal(address))
)
decl_sect_asm = """
.align 4
.section %s
.incbin "%s"
"""
def generate_image_S(target_path, images):
kern_fname = "kernel.elf"
conts_fname = "containers.elf"
fbody = ""
with open(target_path, "w+") as images_S:
for img in images:
if os.path.basename(img.path) == kern_fname:
fbody += decl_sect_asm % (".kernel", img)
if os.path.basename(img.path) == conts_fname:
fbody += decl_sect_asm % (".containers", img)
images_S.write(fbody)
if __name__ == "__main__":
if len(sys.argv) == 1:
generate_ksym_to_loader(join(PROJROOT, "loader/ksyms.S"), KERNEL_ELF)
elif len(sys.argv) == 3:
generate_ksym_to_loader(sys.argv[1], sys.argv[1])
else:
print("Usage: %s <asm filename> <kernel image filename>" % sys.argv[0])