diff --git a/README.adoc b/README.adoc index 34bf0ae..cd9a8d0 100644 --- a/README.adoc +++ b/README.adoc @@ -19505,7 +19505,7 @@ Those for example are required to implement `malloc` in Newlib. We can play with === 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: diff --git a/build-baremetal b/build-baremetal index d3190b6..aaa8d14 100755 --- a/build-baremetal +++ b/build-baremetal @@ -92,7 +92,7 @@ Build the baremetal examples with crosstool-NG. ) cc_flags.extend([ '-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, ]) with thread_pool.ThreadPool( diff --git a/common.py b/common.py index 2c97f85..11c60d2 100644 --- a/common.py +++ b/common.py @@ -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 def python_struct_int_format(size): if size == 4: diff --git a/run b/run index 026cc50..cff39d6 100755 --- a/run +++ b/run @@ -471,6 +471,37 @@ Extra options to append at the end of the emulator command line. raise_image_not_found() else: 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['quiet']: 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: 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['kvm']: cmd.extend(['--cpu-type', 'X86KvmCPU', LF]) @@ -563,6 +599,7 @@ Extra options to append at the end of the emulator command line. '--command-line', '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 if self.env['dtb'] is not None: 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: cmd.extend(['--dtb-filename', dtb, LF]) - if self.env['baremetal'] is None: - cmd.extend(['--param', 'system.workload.panic_on_panic = True', LF]) else: cmd.extend([ '--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: cmd.extend(['-dtb', self.env['dtb'], LF]) 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([ '-device', 'loader,addr={},file={},force-raw=on'.format( hex(argc_addr),