gem5 baremetal cli!!!

Fix https://github.com/cirosantilli/linux-kernel-module-cheat/issues/67
This commit is contained in:
Ciro Santilli 六四事件 法轮功
2020-04-02 02:00:01 +00:00
parent 637ef640bf
commit b7887ac06b
4 changed files with 49 additions and 34 deletions

View File

@@ -19505,7 +19505,7 @@ Those for example are required to implement `malloc` in Newlib. We can play with
=== Baremetal command line arguments === Baremetal command line arguments
QEMU currently supports baremetal CLI arguments! TODO do it for gem5 as well. QEMU and gem5 currently supports baremetal CLI arguments!
You can see them in action e.g. with: You can see them in action e.g. with:

View File

@@ -92,7 +92,7 @@ Build the baremetal examples with crosstool-NG.
) )
cc_flags.extend([ cc_flags.extend([
'-Wl,--section-start=.text={:#x}'.format(self.env['entry_address']), LF, '-Wl,--section-start=.text={:#x}'.format(self.env['entry_address']), LF,
'-Wl,--section-start=.lkmc_memory={:#x}'.format(self.env['entry_address'] + 0x1000000), LF, # '-Wl,--section-start=.lkmc_memory={:#x}'.format(self.env['entry_address'] + 0x1000000), LF,
'-T', self.env['baremetal_link_script'], LF, '-T', self.env['baremetal_link_script'], LF,
]) ])
with thread_pool.ThreadPool( with thread_pool.ThreadPool(

View File

@@ -1247,6 +1247,16 @@ lunch aosp_{}-eng
) )
) )
@staticmethod
def python_escape_double_quotes(s):
s2 = []
for c in s:
if c == '"':
s2.append('\\"')
else:
s2.append(c)
return ''.join(s2)
@staticmethod @staticmethod
def python_struct_int_format(size): def python_struct_int_format(size):
if size == 4: if size == 4:

69
run
View File

@@ -471,6 +471,37 @@ Extra options to append at the end of the emulator command line.
raise_image_not_found() raise_image_not_found()
else: else:
raise_image_not_found() raise_image_not_found()
if self.env['baremetal'] is not None:
# Setup CLI arguments into a single raw binary file to be loaded into memory.
# The memory setup of that file is:
# argc
# argv[0] pointer
# argv[1] pointer
# ...
# argv[N] pointer
# argv[0][0] data
# argv[0][1] data
# ...
# argv[1][0] data
# argv[1][1] data
# ...
if self.env['cli_args'] is not None:
cli_args_split = shlex.split(self.env['cli_args'])
else:
cli_args_split = []
argc_addr = self.env['entry_address'] + self.env['baremetal_max_text_size'] + self.env['baremetal_memory_size']
argv_addr = argc_addr + self.env['int_size']
argv_data_addr = argv_addr + len(cli_args_split) * self.env['address_size']
argv_addr_data = []
argv_addr_cur = argv_data_addr
for arg in cli_args_split:
argv_addr_data.append(struct.pack('<{}'.format(self.python_struct_int_format(self.env['address_size'])), argv_addr_cur))
argv_addr_cur += len(arg) + 1
baremetal_cli_path = os.path.join(self.env['run_dir'], 'baremetal_cli.raw')
with open(baremetal_cli_path, 'wb') as f:
f.write(struct.pack('<{}'.format(self.python_struct_int_format(self.env['int_size'])), len(cli_args_split)))
f.write(b''.join(argv_addr_data))
f.write(b'\0'.join(arg.encode() for arg in cli_args_split) + b'\0')
if self.env['emulator'] == 'gem5': if self.env['emulator'] == 'gem5':
if self.env['quiet']: if self.env['quiet']:
show_stdout = False show_stdout = False
@@ -541,6 +572,11 @@ Extra options to append at the end of the emulator command line.
]) ])
if self.env['disk_image'] is not None: if self.env['disk_image'] is not None:
cmd.extend(['--disk-image', self.env['disk_image'], LF]) cmd.extend(['--disk-image', self.env['disk_image'], LF])
if not self.env['baremetal'] is None:
cmd.extend([
'--param', 'system.workload.extras = "{}"'.format(self.python_escape_double_quotes(baremetal_cli_path)), LF,
'--param', 'system.workload.extras_addrs = {}'.format(hex(argc_addr)), LF,
])
if self.env['arch'] == 'x86_64': if self.env['arch'] == 'x86_64':
if self.env['kvm']: if self.env['kvm']:
cmd.extend(['--cpu-type', 'X86KvmCPU', LF]) cmd.extend(['--cpu-type', 'X86KvmCPU', LF])
@@ -563,6 +599,7 @@ Extra options to append at the end of the emulator command line.
'--command-line', '--command-line',
'earlyprintk=pl011,0x1c090000 lpj=19988480 rw loglevel=8 mem={} root=/dev/sda {}'.format(memory, kernel_cli), LF 'earlyprintk=pl011,0x1c090000 lpj=19988480 rw loglevel=8 mem={} root=/dev/sda {}'.format(memory, kernel_cli), LF
]) ])
cmd.extend(['--param', 'system.workload.panic_on_panic = True', LF])
dtb = None dtb = None
if self.env['dtb'] is not None: if self.env['dtb'] is not None:
dtb = self.env['dtb'] dtb = self.env['dtb']
@@ -579,8 +616,6 @@ Extra options to append at the end of the emulator command line.
) )
if dtb is not None: if dtb is not None:
cmd.extend(['--dtb-filename', dtb, LF]) cmd.extend(['--dtb-filename', dtb, LF])
if self.env['baremetal'] is None:
cmd.extend(['--param', 'system.workload.panic_on_panic = True', LF])
else: else:
cmd.extend([ cmd.extend([
'--bare-metal', LF, '--bare-metal', LF,
@@ -727,36 +762,6 @@ Extra options to append at the end of the emulator command line.
if self.env['dtb'] is not None: if self.env['dtb'] is not None:
cmd.extend(['-dtb', self.env['dtb'], LF]) cmd.extend(['-dtb', self.env['dtb'], LF])
if self.env['baremetal'] is not None: if self.env['baremetal'] is not None:
# Setup CLI arguments into a single raw binary file to be loaded into memory.
# The memory setup of that file is:
# argc
# argv[0] pointer
# argv[1] pointer
# ...
# argv[N] pointer
# argv[0][0] data
# argv[0][1] data
# ...
# argv[1][0] data
# argv[1][1] data
# ...
if self.env['cli_args'] is not None:
cli_args_split = shlex.split(self.env['cli_args'])
else:
cli_args_split = []
argc_addr = self.env['entry_address'] + self.env['baremetal_max_text_size'] + self.env['baremetal_memory_size']
argv_addr = argc_addr + self.env['int_size']
argv_data_addr = argv_addr + len(cli_args_split) * self.env['address_size']
argv_addr_data = []
argv_addr_cur = argv_data_addr
for arg in cli_args_split:
argv_addr_data.append(struct.pack('<{}'.format(self.python_struct_int_format(self.env['address_size'])), argv_addr_cur))
argv_addr_cur += len(arg) + 1
baremetal_cli_path = os.path.join(self.env['run_dir'], 'baremetal_cli.raw')
with open(baremetal_cli_path, 'wb') as f:
f.write(struct.pack('<{}'.format(self.python_struct_int_format(self.env['int_size'])), len(cli_args_split)))
f.write(b''.join(argv_addr_data))
f.write(b'\0'.join(arg.encode() for arg in cli_args_split) + b'\0')
cmd.extend([ cmd.extend([
'-device', 'loader,addr={},file={},force-raw=on'.format( '-device', 'loader,addr={},file={},force-raw=on'.format(
hex(argc_addr), hex(argc_addr),