updated build process to work with newer versions of riscv-unknown-gcc
This commit is contained in:
parent
a3cc3cccbd
commit
43bb013fb5
2
Makefile
2
Makefile
@ -14,7 +14,7 @@ CFLAGS += -DTEXT_IO_ADDR=0xff0000 -DTEXT_IO_BUFLEN=64
|
||||
# If you want to build without any extension, you can uncomment the next line
|
||||
#CFLAGS += -D__risc_no_ext=1
|
||||
# also change this to represent your target RISC-V architecture and extensions
|
||||
ARCH = rv32im
|
||||
ARCH = rv32im_zicsr
|
||||
|
||||
# Configure if mtime is memory-mapped or inside a CSR:
|
||||
# replace 0xFF11FF22FF33 with the correct address
|
||||
|
12
kernel.c
12
kernel.c
@ -1,10 +1,10 @@
|
||||
#include "kernel.h"
|
||||
#include "ktypes.h"
|
||||
#include "ecall.h"
|
||||
#include "sched.h"
|
||||
#include "io.h"
|
||||
#include "malloc.h"
|
||||
#include "csr.h"
|
||||
#include "kinclude/ktypes.h"
|
||||
#include "kinclude/ecall.h"
|
||||
#include "kinclude/sched.h"
|
||||
#include "kinclude/io.h"
|
||||
#include "kinclude/malloc.h"
|
||||
#include "kinclude/csr.h"
|
||||
|
||||
void read_binary_table();
|
||||
void setup_mem_protection();
|
||||
|
129
package.py
129
package.py
@ -2,7 +2,8 @@
|
||||
from dataclasses import dataclass
|
||||
from elftools.elf.elffile import ELFFile
|
||||
from elftools.elf.sections import Section, SymbolTableSection
|
||||
from typing import List, Tuple, Dict, Generator, Union
|
||||
from typing import List, Tuple, Dict, Generator, Union, Set
|
||||
from collections import defaultdict
|
||||
|
||||
import os, sys
|
||||
import json
|
||||
@ -50,6 +51,101 @@ def overlaps(p1, l1, p2, l2) -> bool:
|
||||
"""
|
||||
return (p1 <= p2 and p1 + l1 > p2) or (p2 <= p1 and p2 + l2 > p1)
|
||||
|
||||
class MemoryImageDebugInfos:
|
||||
"""
|
||||
This defines the riscemu debug information format.
|
||||
|
||||
See the riscemu project for more detail.
|
||||
"""
|
||||
|
||||
VERSION = '1'
|
||||
"""
|
||||
Schema version
|
||||
"""
|
||||
|
||||
base: int = 0
|
||||
"""
|
||||
The base address where the image starts. Defaults to zero.
|
||||
"""
|
||||
|
||||
sections: Dict[str, Dict[str, Tuple[int, int]]]
|
||||
"""
|
||||
This dictionary maps a program and section to (start address, section length)
|
||||
"""
|
||||
|
||||
symbols: Dict[str, Dict[str, int]]
|
||||
"""
|
||||
This dictionary maps a program and a symbol to a value
|
||||
"""
|
||||
|
||||
globals: Dict[str, Set[str]]
|
||||
"""
|
||||
This dictionary contains the list of all global symbols of a given program
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
sections: Dict[str, Dict[str, Tuple[int, int]]],
|
||||
symbols: Dict[str, Dict[str, int]],
|
||||
globals: Dict[str, Set[str]],
|
||||
base: int = 0
|
||||
):
|
||||
self.sections = sections
|
||||
self.symbols = symbols
|
||||
self.globals = globals
|
||||
self.base = base
|
||||
|
||||
def serialize(self) -> str:
|
||||
def serialize(obj: any) -> str:
|
||||
if isinstance(obj, defaultdict):
|
||||
return dict(obj)
|
||||
if isinstance(obj, (set, tuple)):
|
||||
return list(obj)
|
||||
return "<<unserializable {}>>".format(getattr(obj, '__qualname__', '{unknown}'))
|
||||
|
||||
return json.dumps(
|
||||
dict(
|
||||
sections=self.sections,
|
||||
symbols=self.symbols,
|
||||
globals=self.globals,
|
||||
base=self.base,
|
||||
VERSION=self.VERSION
|
||||
),
|
||||
default=serialize,
|
||||
indent=2
|
||||
)
|
||||
|
||||
def add_section(self, program: str, name: str, start: int, length: str):
|
||||
self.sectionss[program][name] = (start, length)
|
||||
|
||||
def add_symbol(self, program: str, name: str, val: int):
|
||||
self.symbols[program][name] = val
|
||||
|
||||
@classmethod
|
||||
def load(cls, serialized_str: str) -> 'MemoryImageDebugInfos':
|
||||
json_obj: dict = json.loads(serialized_str)
|
||||
|
||||
if 'VERSION' not in json_obj:
|
||||
raise RuntimeError("Unknown MemoryImageDebugInfo version!")
|
||||
|
||||
version: str = json_obj.pop('VERSION')
|
||||
|
||||
# compare major version
|
||||
if version != cls.VERSION or version.split('.')[0] != cls.VERSION.split('.')[0]:
|
||||
raise RuntimeError(
|
||||
"Unknown MemoryImageDebugInfo version! This emulator expects version {}, debug info version {}".format(
|
||||
cls.VERSION, version
|
||||
)
|
||||
)
|
||||
|
||||
return MemoryImageDebugInfos(**json_obj)
|
||||
|
||||
@classmethod
|
||||
def builder(cls) -> 'MemoryImageDebugInfos':
|
||||
return MemoryImageDebugInfos(
|
||||
defaultdict(dict), defaultdict(dict), defaultdict(set)
|
||||
)
|
||||
|
||||
|
||||
class Section:
|
||||
name: str
|
||||
start: int
|
||||
@ -76,12 +172,16 @@ class Bin:
|
||||
name: str
|
||||
secs: List[Section]
|
||||
symtab: Dict[str, int]
|
||||
global_symbols: List[str]
|
||||
entry: int
|
||||
start: int
|
||||
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self.secs = list()
|
||||
self.symtab = dict()
|
||||
self.global_symbols = list()
|
||||
|
||||
with open(self.name, 'rb') as f:
|
||||
elf = ELFFile(f)
|
||||
if not elf.header.e_machine == 'EM_RISCV':
|
||||
@ -93,9 +193,14 @@ class Bin:
|
||||
if sec.name in INCLUDE_THESE_SECTIONS:
|
||||
self.secs.append(Section(sec) )
|
||||
if isinstance(sec, SymbolTableSection):
|
||||
self.symtab = {
|
||||
sym.name: sym.entry.st_value for sym in sec.iter_symbols() if sym.name
|
||||
}
|
||||
for sym in sec.iter_symbols():
|
||||
if not sym.name:
|
||||
continue
|
||||
|
||||
self.symtab[sym.name] = sym.entry.st_value
|
||||
|
||||
if sym.entry.st_info.bind == 'STB_GLOBAL':
|
||||
self.global_symbols.append(sym.name)
|
||||
|
||||
self.secs = sorted(self.secs, key=lambda sec: sec.start)
|
||||
self.start = self.secs[0].start
|
||||
@ -113,15 +218,12 @@ class MemImageCreator:
|
||||
"""
|
||||
data: bytes
|
||||
patches: List[Tuple[int, bytes]]
|
||||
dbg_nfo: Dict
|
||||
dbg_nfo: MemoryImageDebugInfos
|
||||
|
||||
def __init__(self):
|
||||
self.data = b''
|
||||
self.patches = list()
|
||||
self.dbg_nfo = {
|
||||
'sections': dict(),
|
||||
'symbols': dict()
|
||||
}
|
||||
self.dbg_nfo = MemoryImageDebugInfos.builder()
|
||||
|
||||
def seek(self, pos):
|
||||
if len(self.data) > pos:
|
||||
@ -140,7 +242,8 @@ class MemImageCreator:
|
||||
def put(self, stuff: bytes, parent: str, name: str) -> int:
|
||||
pos = len(self.data)
|
||||
self.data += stuff
|
||||
self.dbg_nfo['sections'][pos] = parent + ':' + name
|
||||
if parent:
|
||||
self.dbg_nfo.sections[parent][name] = (pos, len(stuff))
|
||||
return pos
|
||||
|
||||
def putBin(self, bin: Bin) -> int:
|
||||
@ -150,11 +253,12 @@ class MemImageCreator:
|
||||
self.seek(img_pos)
|
||||
print(f" - section {sec.name:<6} {img_pos:x}:{img_pos + sec.size:x}")
|
||||
self.put(sec.data, bin.name, sec.name)
|
||||
self.dbg_nfo['symbols'][bin.name] = {
|
||||
self.dbg_nfo.symbols[bin.name] = {
|
||||
name: bin_start + val - bin.start
|
||||
for name, val in sorted(bin.symtab.items(), key=lambda x:x[1])
|
||||
if val != 0
|
||||
}
|
||||
self.dbg_nfo.globals[bin.name] = set(bin.global_symbols)
|
||||
return bin_start
|
||||
|
||||
def patch(self, pos, bytes):
|
||||
@ -184,13 +288,12 @@ class MemImageCreator:
|
||||
print(f" - data {pos:x}:{len(self.data):x}")
|
||||
f.write(self.data[pos : len(self.data)])
|
||||
if len(self.data) % SECTOR_SIZE != 0:
|
||||
self.dbg_nfo['sections'][len(self.data)] = ':.empty'
|
||||
print(f" - zeros {len(self.data):x}:{(SECTOR_SIZE - (len(self.data) % SECTOR_SIZE))+len(self.data):x}")
|
||||
f.write(bytes(SECTOR_SIZE - (len(self.data) % SECTOR_SIZE)))
|
||||
# done!
|
||||
print(f"writing debug info to {fname}.dbg")
|
||||
with open(fname + '.dbg', 'w') as f:
|
||||
json.dump(self.dbg_nfo, f, indent = 2)
|
||||
f.write(self.dbg_nfo.serialize())
|
||||
|
||||
|
||||
def package(kernel: str, binaries: List[str], out: str):
|
||||
|
Loading…
Reference in New Issue
Block a user