mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-22 17:55:57 +01:00
gem5: update to 7bfb7f3a43f382eb49853f47b140bfd6caad0fb8
The update is required to include 3c3ca64b5f0dd9eef7b1ce1c65cc6e8e9147dd38 otherwise baremetal does not on VExpress. baremetal: create a baremetal setup with crosstool-ng buildroot: improve directory location: move out/dl inside out/buildroot/download, and add a new out/buildroot/build level tagline: generalize, deliver more value than howto, since now howtos are starting to multiply rename all top scripts to separate words with hyphen more consistently, e.g. run-gdb instead of rungdb getvar: list all variables gem5: make m5out section to focus all releated information at Prevent m5term Text file busy when rebuilding gem5 while it is running.
This commit is contained in:
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -2,6 +2,9 @@
|
||||
path = submodules/buildroot
|
||||
url = https://github.com/cirosantilli/buildroot
|
||||
ignore = dirty
|
||||
[submodule "submodules/crosstool-ng"]
|
||||
path = submodules/crosstool-ng
|
||||
url = https://github.com/crosstool-ng/crosstool-ng
|
||||
[submodule "submodules/gem5"]
|
||||
path = submodules/gem5
|
||||
url = https://gem5.googlesource.com/public/gem5
|
||||
|
||||
833
README.adoc
833
README.adoc
File diff suppressed because it is too large
Load Diff
19
baremetal/arch/arm/gem5_assert.S
Normal file
19
baremetal/arch/arm/gem5_assert.S
Normal file
@@ -0,0 +1,19 @@
|
||||
/* assert 0x12345678 + 1 == 0x12345679 */
|
||||
.global main
|
||||
main:
|
||||
movw r0, #:lower16:myvar
|
||||
movt r0, #:upper16:myvar
|
||||
ldr r1, [r0]
|
||||
add r1, r1, #1
|
||||
str r1, [r0]
|
||||
movw r2, #0x5679
|
||||
movt r2, #0x1234
|
||||
cmp r1, r2
|
||||
beq ok
|
||||
# m5 fail 1
|
||||
mov r0, #0; mov r1, #0; mov r2, #1; mov r3, #0; .inst 0xEE000110 | (0x22 << 16);
|
||||
ok:
|
||||
# m5 exit
|
||||
mov r0, #0; mov r1, #0; .inst 0xEE000110 | (0x21 << 16);
|
||||
myvar:
|
||||
.word 0x12345678
|
||||
5
baremetal/arch/arm/no_bootloader/semihost_exit.S
Normal file
5
baremetal/arch/arm/no_bootloader/semihost_exit.S
Normal file
@@ -0,0 +1,5 @@
|
||||
.global mystart
|
||||
mystart:
|
||||
mov r0, #0x18
|
||||
ldr r1, =#0x20026
|
||||
svc 0x00123456
|
||||
5
baremetal/arch/arm/semihost_exit.S
Normal file
5
baremetal/arch/arm/semihost_exit.S
Normal file
@@ -0,0 +1,5 @@
|
||||
.global main
|
||||
main:
|
||||
mov r0, #0x18
|
||||
ldr r1, =#0x20026
|
||||
svc 0x00123456
|
||||
7
baremetal/exit.c
Normal file
7
baremetal/exit.c
Normal file
@@ -0,0 +1,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void main(void) {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
11
baremetal/lib/aarch64.S
Normal file
11
baremetal/lib/aarch64.S
Normal file
@@ -0,0 +1,11 @@
|
||||
.global mystart
|
||||
mystart:
|
||||
/* = NEON setup */
|
||||
mov x1, #(0x3 << 20)
|
||||
msr cpacr_el1, x1
|
||||
isb
|
||||
|
||||
ldr x0, =stack_top
|
||||
mov sp, x0
|
||||
bl main
|
||||
b .
|
||||
5
baremetal/lib/arm.S
Normal file
5
baremetal/lib/arm.S
Normal file
@@ -0,0 +1,5 @@
|
||||
.global mystart
|
||||
mystart:
|
||||
ldr sp, =stack_top
|
||||
bl main
|
||||
b .
|
||||
65
baremetal/lib/common.c
Normal file
65
baremetal/lib/common.c
Normal file
@@ -0,0 +1,65 @@
|
||||
#include <sys/stat.h>
|
||||
|
||||
enum {
|
||||
UART_FR_RXFE = 0x10,
|
||||
};
|
||||
|
||||
#define UART_DR(baseaddr) (*(unsigned int *)(baseaddr))
|
||||
#define UART_FR(baseaddr) (*(((unsigned int *)(baseaddr))+6))
|
||||
|
||||
int _close(int file) { return -1; }
|
||||
|
||||
int _fstat(int file, struct stat *st) {
|
||||
st->st_mode = S_IFCHR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _isatty(int file) { return 1; }
|
||||
int _lseek(int file, int ptr, int dir) { return 0; }
|
||||
int _open(const char *name, int flags, int mode) { return -1; }
|
||||
|
||||
int _read(int file, char *ptr, int len) {
|
||||
int todo;
|
||||
if (len == 0)
|
||||
return 0;
|
||||
while (UART_FR(UART0_ADDR) & UART_FR_RXFE);
|
||||
*ptr++ = UART_DR(UART0_ADDR);
|
||||
for (todo = 1; todo < len; todo++) {
|
||||
if (UART_FR(UART0_ADDR) & UART_FR_RXFE) {
|
||||
break;
|
||||
}
|
||||
*ptr++ = UART_DR(UART0_ADDR);
|
||||
}
|
||||
return todo;
|
||||
}
|
||||
|
||||
char *heap_end = 0;
|
||||
caddr_t _sbrk(int incr) {
|
||||
extern char heap_low;
|
||||
extern char heap_top;
|
||||
char *prev_heap_end;
|
||||
if (heap_end == 0) {
|
||||
heap_end = &heap_low;
|
||||
}
|
||||
prev_heap_end = heap_end;
|
||||
if (heap_end + incr > &heap_top) {
|
||||
/* Heap and stack collision */
|
||||
return (caddr_t)0;
|
||||
}
|
||||
heap_end += incr;
|
||||
return (caddr_t)prev_heap_end;
|
||||
}
|
||||
|
||||
int _write(int file, char *ptr, int len) {
|
||||
int todo;
|
||||
for (todo = 0; todo < len; todo++) {
|
||||
UART_DR(UART0_ADDR) = *ptr++;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
void _exit(int status) {
|
||||
#if defined(__arm__)
|
||||
__asm__ __volatile__ ("mov r0, #0x18; ldr r1, =#0x20026; svc 0x00123456");
|
||||
#endif
|
||||
}
|
||||
19
baremetal/link.ld
Normal file
19
baremetal/link.ld
Normal file
@@ -0,0 +1,19 @@
|
||||
ENTRY(mystart)
|
||||
SECTIONS
|
||||
{
|
||||
.text : {
|
||||
*/bootloader.o(.text)
|
||||
*(.text)
|
||||
*(.rodata)
|
||||
*(.data)
|
||||
*(COMMON)
|
||||
}
|
||||
/* gem5 uses the bss as a measure of the kernel size. */
|
||||
.bss : { *(.bss) }
|
||||
heap_low = .;
|
||||
. = . + 0x1000000;
|
||||
heap_top = .;
|
||||
. = . + 0x1000000;
|
||||
stack_top = .;
|
||||
}
|
||||
|
||||
22
baremetal/prompt.c
Normal file
22
baremetal/prompt.c
Normal file
@@ -0,0 +1,22 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void main(void) {
|
||||
char c;
|
||||
char *ptr = NULL;
|
||||
size_t alloc_size = 1;
|
||||
while (1) {
|
||||
printf("enter a character\n");
|
||||
c = getchar();
|
||||
printf("got: %c\n", c);
|
||||
ptr = realloc(ptr, alloc_size);
|
||||
if (ptr == NULL) {
|
||||
puts("out of memory");
|
||||
break;
|
||||
} else {
|
||||
printf("new alloc of %d bytes at address 0x%p\n", alloc_size, ptr);
|
||||
alloc_size <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ do_bench_buildroot_build() (
|
||||
baseline_suffix=
|
||||
fi
|
||||
common_build_dir="$("$getvar" --arch "$arch" --buildroot-build-id "$build_id" build_dir)"
|
||||
common_images_dir="$("$getvar" --arch "$arch" --buildroot-build-id "$build_id" images_dir)"
|
||||
common_images_dir="$("$getvar" --arch "$arch" --buildroot-build-id "$build_id" buildroot_images_dir)"
|
||||
"${root_dir}/build-buildroot" --arch "$arch" $baseline --buildroot-build-id "$build_id" --clean
|
||||
"${root_dir}/build-buildroot" --arch "$arch" $baseline --buildroot-build-id "$build_id" --no-all -- source
|
||||
"${root_dir}/build-buildroot" --arch "$arch" $baseline --buildroot-build-id "$build_id"
|
||||
|
||||
30
bench-boot
30
bench-boot
@@ -30,8 +30,13 @@ bench() (
|
||||
"${root_dir}/bench-cmd" "./run --arch ${1}${extra_args}" "$common_bench_boot"
|
||||
)
|
||||
|
||||
newline() (
|
||||
echo >> "$common_bench_boot"
|
||||
)
|
||||
|
||||
gem5_insts() (
|
||||
printf "instructions $(./gem5-stat --arch "$1" sim_insts)\n" >> "$common_bench_boot"
|
||||
newline
|
||||
)
|
||||
|
||||
qemu_insts() (
|
||||
@@ -39,10 +44,7 @@ qemu_insts() (
|
||||
./qemu-trace2txt --arch "$common_arch"
|
||||
common_qemu_trace_txt_file="$("$getvar" --arch "$common_arch" qemu_trace_txt_file)"
|
||||
printf "instructions $(wc -l "${common_qemu_trace_txt_file}" | cut -d' ' -f1)\n" >> "$common_bench_boot"
|
||||
)
|
||||
|
||||
newline() (
|
||||
echo >> "$common_bench_boot"
|
||||
newline
|
||||
)
|
||||
|
||||
rm -f "${common_bench_boot}"
|
||||
@@ -55,31 +57,26 @@ newline
|
||||
if [ "$test_size" -ge 2 ]; then
|
||||
bench "${arch} --eval '/poweroff.out' --trace exec_tb"
|
||||
qemu_insts "$arch"
|
||||
newline
|
||||
bench "$arch --eval 'm5 exit' --gem5"
|
||||
gem5_insts "$arch"
|
||||
newline
|
||||
fi
|
||||
#bench "$arch --eval 'm5 exit' --gem5 -- --cpu-type=DerivO3CPU ${caches}"
|
||||
#gem5_insts "$arch"
|
||||
#newline
|
||||
|
||||
arch=arm
|
||||
bench "$arch --eval '/poweroff.out'"
|
||||
newline
|
||||
if [ "$test_size" -ge 2 ]; then
|
||||
bench "$arch --eval '/poweroff.out' --trace exec_tb"
|
||||
qemu_insts "$arch"
|
||||
newline
|
||||
#bench "$arch --eval 'm5 exit' --gem5"
|
||||
#gem5_insts "$arch"
|
||||
#newline
|
||||
fi
|
||||
#if [ "$test_size" -ge 3 ]; then
|
||||
# bench "$arch --eval 'm5 exit' --gem5 -- --cpu-type=HPI ${caches}"
|
||||
# gem5_insts "$arch"
|
||||
# newline
|
||||
#fi
|
||||
if [ "$test_size" -ge 3 ]; then
|
||||
#bench "$arch --eval 'm5 exit' --gem5 -- --cpu-type=HPI ${caches}"
|
||||
#gem5_insts "$arch"
|
||||
bench "$arch --eval 'm5 exit' --gem5 --gem5-biglittle"
|
||||
gem5_insts "$arch"
|
||||
fi
|
||||
|
||||
arch=aarch64
|
||||
bench "$arch --eval '/poweroff.out'"
|
||||
@@ -87,13 +84,10 @@ newline
|
||||
if [ "$test_size" -ge 2 ]; then
|
||||
bench "$arch --eval '/poweroff.out' --trace exec_tb"
|
||||
qemu_insts "$arch"
|
||||
newline
|
||||
bench "$arch --eval 'm5 exit' --gem5"
|
||||
gem5_insts "$arch"
|
||||
newline
|
||||
fi
|
||||
if [ "$test_size" -ge 3 ]; then
|
||||
bench "$arch --eval 'm5 exit' --gem5 -- --cpu-type=HPI ${caches}"
|
||||
gem5_insts "$arch"
|
||||
newline
|
||||
fi
|
||||
|
||||
@@ -15,8 +15,14 @@ done
|
||||
shift "$(($OPTIND - 1))"
|
||||
for arch in $archs; do
|
||||
./build-qemu --arch "$arch"
|
||||
./build-buildroot --arch "$arch" --gem5 --kernel-modules -l "$@"
|
||||
if "$gem5"; then
|
||||
./build-gem5 --arch "$arch"
|
||||
fi
|
||||
./build-buildroot --arch "$arch" --gem5 --kernel-modules -l "$@"
|
||||
if [ ! "$arch" = x86_64 ]; then
|
||||
./build-crosstool-ng --arch "$arch"
|
||||
./build-baremetal --arch "$arch"
|
||||
./build-baremetal --arch "$arch" -g
|
||||
./build-baremetal --arch "$arch" -g --machine RealViewPBX
|
||||
fi
|
||||
done
|
||||
|
||||
151
build-baremetal
Executable file
151
build-baremetal
Executable file
@@ -0,0 +1,151 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import glob
|
||||
import multiprocessing
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import time
|
||||
|
||||
import common
|
||||
|
||||
def build_dir(subpath, gcc, cflags, entry_address, bootloader_obj, common_obj, bootloader=True):
|
||||
"""
|
||||
Build all .c and .S files in a given subpath of the baremetal source
|
||||
directory non recursively.
|
||||
|
||||
Place outputs on the same subpath or the output directory.
|
||||
"""
|
||||
in_dir = os.path.join(common.baremetal_src_dir, subpath)
|
||||
out_dir = os.path.join(common.baremetal_out_dir, subpath)
|
||||
os.makedirs(out_dir, exist_ok=True)
|
||||
if bootloader:
|
||||
bootloader_cmd = [bootloader_obj]
|
||||
else:
|
||||
bootloader_cmd = []
|
||||
for in_basename in os.listdir(in_dir):
|
||||
in_path = os.path.join(in_dir, in_basename)
|
||||
if os.path.isfile(in_path) and os.path.splitext(in_basename)[1] in (common.c_ext, common.asm_ext):
|
||||
in_name = os.path.splitext(in_basename)[0]
|
||||
main_obj = os.path.join(common.baremetal_out_dir, subpath, '{}{}'.format(in_name, common.obj_ext))
|
||||
assert common.run_cmd(
|
||||
[gcc] +
|
||||
cflags +
|
||||
[
|
||||
'-c',
|
||||
'-o', main_obj,
|
||||
os.path.join(common.baremetal_src_dir, in_path),
|
||||
]
|
||||
) == 0
|
||||
assert common.run_cmd(
|
||||
[gcc] +
|
||||
cflags +
|
||||
[
|
||||
'-Wl,--section-start=.text={:#x}'.format(entry_address),
|
||||
'-o', os.path.join(common.baremetal_out_dir, subpath, in_name + common.baremetal_out_ext),
|
||||
'-T', os.path.join(common.baremetal_src_dir, 'link.ld'),
|
||||
] +
|
||||
bootloader_cmd +
|
||||
[
|
||||
common_obj,
|
||||
main_obj,
|
||||
]
|
||||
) == 0
|
||||
|
||||
def get_argparse():
|
||||
parser = common.get_argparse(argparse_args={
|
||||
'description': 'Build the baremetal examples with crosstool-NG'
|
||||
})
|
||||
common.add_build_arguments(parser)
|
||||
return parser
|
||||
|
||||
def main(args, extra_args=None):
|
||||
if args.clean:
|
||||
common.rmrf(common.baremetal_out_dir)
|
||||
else:
|
||||
common.raise_no_x86(args.arch)
|
||||
bootloader_obj = os.path.join(common.baremetal_out_lib_dir, 'bootloader{}'.format(common.obj_ext))
|
||||
common_obj = os.path.join(common.baremetal_out_lib_dir, 'common{}'.format(common.obj_ext))
|
||||
cflags = [
|
||||
'-ggdb3',
|
||||
'-mcpu={}'.format(common.mcpu),
|
||||
'-nostartfiles',
|
||||
'-O0',
|
||||
]
|
||||
if args.prebuilt:
|
||||
gcc = 'arm-none-eabi-gcc'
|
||||
else:
|
||||
os.environ['PATH'] = common.crosstool_ng_bin_dir + os.environ['PATH']
|
||||
gcc = common.get_toolchain_tool('gcc')
|
||||
if args.gem5:
|
||||
if common.machine == 'VExpress_GEM5_V1':
|
||||
entry_address = 0x80000000
|
||||
uart_address = 0x1c090000
|
||||
elif common.machine == 'RealViewPBX':
|
||||
entry_address = 0x10000
|
||||
uart_address = 0x10009000
|
||||
else:
|
||||
raise Exception('unknown machine: ' + common.machine)
|
||||
else:
|
||||
entry_address = 0x40000000
|
||||
uart_address = 0x09000000
|
||||
os.makedirs(common.baremetal_out_dir, exist_ok=True)
|
||||
os.makedirs(common.baremetal_out_lib_dir, exist_ok=True)
|
||||
assert common.run_cmd(
|
||||
[gcc] +
|
||||
cflags +
|
||||
[
|
||||
'-c',
|
||||
'-o', bootloader_obj,
|
||||
os.path.join(common.baremetal_src_lib_dir, '{}{}'.format(args.arch, common.asm_ext)),
|
||||
]
|
||||
) == 0
|
||||
assert common.run_cmd(
|
||||
[gcc] +
|
||||
cflags +
|
||||
[
|
||||
'-c',
|
||||
'-D',
|
||||
'UART0_ADDR={:#x}'.format(uart_address),
|
||||
'-o', common_obj,
|
||||
os.path.join(common.baremetal_src_lib_dir, 'common' + common.c_ext),
|
||||
]
|
||||
) == 0
|
||||
build_dir(
|
||||
'',
|
||||
gcc=gcc,
|
||||
cflags=cflags,
|
||||
entry_address=entry_address,
|
||||
bootloader_obj=bootloader_obj,
|
||||
common_obj=common_obj,
|
||||
)
|
||||
build_dir(
|
||||
os.path.join('arch', args.arch),
|
||||
gcc=gcc,
|
||||
cflags=cflags,
|
||||
entry_address=entry_address,
|
||||
bootloader_obj=bootloader_obj,
|
||||
common_obj=common_obj,
|
||||
)
|
||||
build_dir(
|
||||
os.path.join('arch', args.arch, 'no_bootloader'),
|
||||
gcc=gcc,
|
||||
cflags=cflags,
|
||||
entry_address=entry_address,
|
||||
bootloader_obj=bootloader_obj,
|
||||
common_obj=common_obj,
|
||||
bootloader=False,
|
||||
)
|
||||
return 0
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = common.get_argparse(
|
||||
default_args={'baremetal': 'all'},
|
||||
)
|
||||
common.add_build_arguments(parser)
|
||||
args = common.setup(parser)
|
||||
start_time = time.time()
|
||||
exit_status = main(args)
|
||||
end_time = time.time()
|
||||
common.print_time(end_time - start_time)
|
||||
sys.exit(exit_status)
|
||||
@@ -168,9 +168,9 @@ def main(args, extra_args=None):
|
||||
buildroot_configs = args.buildroot_config
|
||||
buildroot_configs.extend([
|
||||
'BR2_JLEVEL={}'.format(nproc),
|
||||
'BR2_DL_DIR="{}"'.format(common.dl_dir),
|
||||
'BR2_DL_DIR="{}"'.format(common.buildroot_download_dir),
|
||||
])
|
||||
write_configs(buildroot_configs)
|
||||
common.write_configs(common.buildroot_config_file, buildroot_configs)
|
||||
if not args.baseline:
|
||||
buildroot_configs.extend([
|
||||
'BR2_GLOBAL_PATCH_DIR="{}"'.format(
|
||||
@@ -182,7 +182,7 @@ def main(args, extra_args=None):
|
||||
'BR2_ROOTFS_OVERLAY="{}"'.format(
|
||||
path_relative_to_buildroot(os.path.join(common.root_dir, 'rootfs_overlay'))),
|
||||
'BR2_ROOTFS_POST_BUILD_SCRIPT="{}"'.format(
|
||||
path_relative_to_buildroot(os.path.join(common.root_dir, 'rootfs_post_build_script'))),
|
||||
path_relative_to_buildroot(os.path.join(common.root_dir, 'rootfs-post-build-script'))),
|
||||
'BR2_ROOTFS_USERS_TABLES="{}"'.format(
|
||||
path_relative_to_buildroot(os.path.join(common.root_dir, 'user_table'))),
|
||||
])
|
||||
@@ -253,7 +253,7 @@ def main(args, extra_args=None):
|
||||
kernel_config_fragments[i] = path_relative_to_buildroot(frag)
|
||||
buildroot_kernel_config_fragment_str = 'BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES="{}"'.format(' '.join(kernel_config_fragments))
|
||||
buildroot_configs.append(buildroot_kernel_config_fragment_str)
|
||||
write_configs(buildroot_configs, buildroot_config_fragments)
|
||||
common.write_configs(common.buildroot_config_file, buildroot_configs, buildroot_config_fragments)
|
||||
subprocess.check_call(
|
||||
[
|
||||
'make',
|
||||
@@ -304,22 +304,6 @@ def main(args, extra_args=None):
|
||||
def path_relative_to_buildroot(abspath):
|
||||
return os.path.relpath(abspath, common.buildroot_src_dir)
|
||||
|
||||
def write_configs(buildroot_configs, buildroot_config_fragments=None):
|
||||
"""
|
||||
Write extra configs into the Buildroot config file.
|
||||
TODO Can't get rid of these for now with nice fragments:
|
||||
http://stackoverflow.com/questions/44078245/is-it-possible-to-use-config-fragments-with-buildroots-config
|
||||
"""
|
||||
if buildroot_config_fragments is None:
|
||||
buildroot_config_fragments = []
|
||||
with open(common.buildroot_config_file, 'a') as br2_config_file:
|
||||
for buildroot_config_fragment in buildroot_config_fragments:
|
||||
with open(buildroot_config_fragment, 'r') as br2_config_fragment:
|
||||
for line in br2_config_fragment:
|
||||
br2_config_file.write(line)
|
||||
for buildroot_config in buildroot_configs:
|
||||
br2_config_file.write(buildroot_config + '\n')
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = get_argparse()
|
||||
args = common.setup(parser)
|
||||
|
||||
83
build-crosstool-ng
Executable file
83
build-crosstool-ng
Executable file
@@ -0,0 +1,83 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import multiprocessing
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import time
|
||||
|
||||
import common
|
||||
|
||||
def get_argparse():
|
||||
parser = common.get_argparse(argparse_args={
|
||||
'description': 'Build crosstool-NG with Newlib for bare metal compilation'
|
||||
})
|
||||
common.add_build_arguments(parser)
|
||||
return parser
|
||||
|
||||
def main(args, extra_args=None):
|
||||
common.raise_no_x86(args.arch)
|
||||
nproc = multiprocessing.cpu_count()
|
||||
defconfig_dest = os.path.join(common.crosstool_ng_util_dir, 'defconfig')
|
||||
os.makedirs(common.crosstool_ng_util_dir, exist_ok=True)
|
||||
os.makedirs(common.crosstool_ng_download_dir, exist_ok=True)
|
||||
|
||||
# Bootstrap out-ot-tree WONTFIX. I've tried.
|
||||
# https://github.com/crosstool-ng/crosstool-ng/issues/1021
|
||||
os.chdir(common.crosstool_ng_src_dir)
|
||||
assert common.run_cmd(
|
||||
[os.path.join(common.crosstool_ng_src_dir, 'bootstrap')],
|
||||
) == 0
|
||||
os.chdir(common.crosstool_ng_util_dir)
|
||||
assert common.run_cmd(
|
||||
[
|
||||
os.path.join(common.crosstool_ng_src_dir, 'configure'),
|
||||
'--enable-local',
|
||||
],
|
||||
) == 0
|
||||
assert common.run_cmd(
|
||||
[
|
||||
'make',
|
||||
'-j', str(nproc)
|
||||
],
|
||||
) == 0
|
||||
|
||||
# Build the toolchain.
|
||||
shutil.copy2(
|
||||
os.path.join(common.root_dir, 'crosstool_ng_config', args.arch),
|
||||
defconfig_dest
|
||||
)
|
||||
common.write_configs(
|
||||
common.crosstool_ng_defconfig,
|
||||
[
|
||||
'CT_PREFIX_DIR="{}"'.format(common.crosstool_ng_install_dir),
|
||||
'CT_WORK_DIR="{}"'.format(common.crosstool_ng_build_dir),
|
||||
'CT_LOCAL_TARBALLS_DIR="{}"'.format(common.crosstool_ng_download_dir),
|
||||
]
|
||||
)
|
||||
assert common.run_cmd(
|
||||
[
|
||||
common.crosstool_ng_executable,
|
||||
'defconfig',
|
||||
],
|
||||
) == 0
|
||||
os.unlink(defconfig_dest)
|
||||
assert common.run_cmd(
|
||||
[
|
||||
common.crosstool_ng_executable,
|
||||
'build',
|
||||
'-j', str(nproc)
|
||||
],
|
||||
out_file=os.path.join(common.crosstool_ng_build_dir, 'lkmc.log'),
|
||||
delete_env=['LD_LIBRARY_PATH'],
|
||||
extra_env={'PATH': common.ccache_dir + ':' + os.environ['PATH']},
|
||||
) == 0
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = get_argparse()
|
||||
args = common.setup(parser)
|
||||
start_time = time.time()
|
||||
exit_status = main(args)
|
||||
end_time = time.time()
|
||||
common.print_time(end_time - start_time)
|
||||
sys.exit(exit_status)
|
||||
@@ -84,7 +84,13 @@ else:
|
||||
extra_env={'PATH': common.ccache_dir + ':' + os.environ['PATH']},
|
||||
) == 0
|
||||
term_src_dir = os.path.join(common.gem5_src_dir, 'util/term')
|
||||
m5term_build = os.path.join(term_src_dir, 'm5term')
|
||||
subprocess.check_call(['make', '-C', term_src_dir])
|
||||
shutil.copy2(os.path.join(term_src_dir, 'm5term'), common.gem5_m5term)
|
||||
if os.path.exists(common.gem5_m5term):
|
||||
# Otherwise shutil.copy2 would fail with "Text file busy" if you
|
||||
# tried to rebuild while running m5term:
|
||||
# https://stackoverflow.com/questions/16764946/what-generates-the-text-file-busy-message-in-unix/52427512#52427512
|
||||
os.unlink(common.gem5_m5term)
|
||||
shutil.copy2(m5term_build, common.gem5_m5term)
|
||||
end_time = time.time()
|
||||
common.print_time(end_time - start_time)
|
||||
|
||||
157
common.py
157
common.py
@@ -26,9 +26,11 @@ p9_dir = os.path.join(data_dir, '9p')
|
||||
gem5_non_default_src_root_dir = os.path.join(data_dir, 'gem5')
|
||||
out_dir = os.path.join(root_dir, 'out')
|
||||
bench_boot = os.path.join(out_dir, 'bench-boot.txt')
|
||||
dl_dir = os.path.join(out_dir, 'dl')
|
||||
packages_dir = os.path.join(root_dir, 'packages')
|
||||
kernel_modules_src_dir = os.path.join(this.packages_dir, 'kernel_modules')
|
||||
submodules_dir = os.path.join(root_dir, 'submodules')
|
||||
buildroot_src_dir = os.path.join(submodules_dir, 'buildroot')
|
||||
crosstool_ng_src_dir = os.path.join(submodules_dir, 'crosstool-ng')
|
||||
gem5_default_src_dir = os.path.join(submodules_dir, 'gem5')
|
||||
linux_src_dir = os.path.join(submodules_dir, 'linux')
|
||||
extract_vmlinux = os.path.join(linux_src_dir, 'scripts', 'extract-vmlinux')
|
||||
@@ -97,6 +99,14 @@ def get_argparse(default_args=None, argparse_args=None):
|
||||
'-a', '--arch', choices=arch_choices, default='x86_64',
|
||||
help='CPU architecture. Default: %(default)s'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--baremetal',
|
||||
help='Use Baremetal examples instead of Linux kernel ones'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--crosstool-ng-build-id', default=default_build_id,
|
||||
help='Crosstool-NG build ID. Allows you to keep multiple separate crosstool-NG builds. Default: %(default)s'
|
||||
)
|
||||
parser.add_argument(
|
||||
'-g', '--gem5', default=False, action='store_true',
|
||||
help='Use gem5 instead of QEMU'
|
||||
@@ -105,6 +115,14 @@ def get_argparse(default_args=None, argparse_args=None):
|
||||
'-L', '--linux-build-id', default=default_build_id,
|
||||
help='Linux build ID. Allows you to keep multiple separate Linux builds. Default: %(default)s'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--machine',
|
||||
help='''Machine type.
|
||||
QEMU default: virt
|
||||
gem5 default: VExpress_GEM5_V1
|
||||
See the documentation for other values known to work.
|
||||
'''
|
||||
)
|
||||
parser.add_argument(
|
||||
'-M', '--gem5-build-id', default=default_build_id,
|
||||
help='gem5 build ID. Allows you to keep multiple separate gem5 builds. Default: %(default)s'
|
||||
@@ -123,6 +141,14 @@ given, just use the submodule source.
|
||||
ID for run outputs such as gem5's m5out. Allows you to do multiple runs,
|
||||
and then inspect separate outputs later in different output directories.
|
||||
Default: %(default)s
|
||||
'''
|
||||
)
|
||||
parser.add_argument(
|
||||
'-P', '--prebuilt', default=False, action='store_true',
|
||||
help='''\
|
||||
Use prebuilt packaged host utilities as much as possible instead
|
||||
of the ones we built ourselves. Saves build time, but decreases
|
||||
the likelihood of compatibility.
|
||||
'''
|
||||
)
|
||||
parser.add_argument(
|
||||
@@ -190,7 +216,10 @@ def get_stats(stat_re=None, stats_file=None):
|
||||
|
||||
def get_toolchain_tool(tool):
|
||||
global this
|
||||
return glob.glob(os.path.join(this.host_bin_dir, '*-buildroot-*-{}'.format(tool)))[0]
|
||||
if this.baremetal is None:
|
||||
return glob.glob(os.path.join(this.host_bin_dir, '*-buildroot-*-{}'.format(tool)))[0]
|
||||
else:
|
||||
return os.path.join(this.crosstool_ng_bin_dir, '{}-{}'.format(this.crosstool_ng_prefix, tool))
|
||||
|
||||
def github_make_request(
|
||||
authenticate=False,
|
||||
@@ -228,6 +257,14 @@ def github_make_request(
|
||||
def log_error(msg):
|
||||
print('error: {}'.format(msg), file=sys.stderr)
|
||||
|
||||
def mkdir():
|
||||
global this
|
||||
os.makedirs(this.build_dir, exist_ok=True)
|
||||
os.makedirs(this.gem5_build_dir, exist_ok=True)
|
||||
os.makedirs(this.gem5_run_dir, exist_ok=True)
|
||||
os.makedirs(this.qemu_run_dir, exist_ok=True)
|
||||
os.makedirs(this.p9_dir, exist_ok=True)
|
||||
|
||||
def print_cmd(cmd, cmd_file=None, extra_env=None):
|
||||
'''
|
||||
Format a command given as a list of strings so that it can
|
||||
@@ -284,6 +321,10 @@ def raw_to_qcow2(prebuilt=False, reverse=False):
|
||||
outfile,
|
||||
]) == 0
|
||||
|
||||
def raise_no_x86(arch):
|
||||
if (arch == 'x86_64'):
|
||||
raise Exception('x86_64 not yet supported')
|
||||
|
||||
def resolve_args(defaults, args, extra_args):
|
||||
if extra_args is None:
|
||||
extra_args = {}
|
||||
@@ -362,6 +403,7 @@ def run_cmd(
|
||||
# https://stackoverflow.com/questions/15535240/python-popen-write-to-stdout-and-log-file-simultaneously/52090802#52090802
|
||||
with subprocess.Popen(cmd, stdout=stdout, stderr=stderr, env=env, **kwargs) as proc:
|
||||
if out_file is not None:
|
||||
os.makedirs(os.path.split(os.path.abspath(out_file))[0], exist_ok=True)
|
||||
with open(out_file, 'bw') as logfile:
|
||||
while True:
|
||||
byte = proc.stdout.read(1)
|
||||
@@ -385,15 +427,41 @@ def setup(parser):
|
||||
args = parser.parse_args()
|
||||
if args.arch in this.arch_map:
|
||||
args.arch = this.arch_map[args.arch]
|
||||
this.machine = args.machine
|
||||
if args.arch == 'arm':
|
||||
this.armv = 7
|
||||
this.gem5_arch = 'ARM'
|
||||
this.mcpu = 'cortex-a15'
|
||||
this.crosstool_ng_prefix = 'arm-unknown-eabi'
|
||||
if args.gem5:
|
||||
if this.machine is None:
|
||||
this.machine = 'VExpress_GEM5_V1'
|
||||
else:
|
||||
if this.machine is None:
|
||||
this.machine = 'virt'
|
||||
elif args.arch == 'aarch64':
|
||||
this.armv = 8
|
||||
this.gem5_arch = 'ARM'
|
||||
this.mcpu = 'cortex-a57'
|
||||
this.crosstool_ng_prefix = 'aarch64-unknown-elf'
|
||||
if args.gem5:
|
||||
if this.machine is None:
|
||||
this.machine = 'VExpress_GEM5_V1'
|
||||
else:
|
||||
if this.machine is None:
|
||||
this.machine = 'virt'
|
||||
elif args.arch == 'x86_64':
|
||||
this.crosstool_ng_prefix = 'TODO'
|
||||
this.gem5_arch = 'X86'
|
||||
this.buildroot_build_dir = os.path.join(this.out_dir, 'buildroot', args.arch, args.buildroot_build_id)
|
||||
if args.gem5:
|
||||
if this.machine is None:
|
||||
this.machine = 'TODO'
|
||||
else:
|
||||
if this.machine is None:
|
||||
this.machine = 'pc'
|
||||
this.buildroot_out_dir = os.path.join(this.out_dir, 'buildroot')
|
||||
this.buildroot_build_dir = os.path.join(this.buildroot_out_dir, 'build', args.buildroot_build_id, args.arch)
|
||||
this.buildroot_download_dir = os.path.join(this.buildroot_out_dir, 'download')
|
||||
this.buildroot_config_file = os.path.join(this.buildroot_build_dir, '.config')
|
||||
this.build_dir = os.path.join(this.buildroot_build_dir, 'build')
|
||||
this.linux_build_dir = os.path.join(this.build_dir, 'linux-custom')
|
||||
@@ -407,8 +475,8 @@ def setup(parser):
|
||||
this.qemu_guest_build_dir = os.path.join(this.build_dir, 'qemu-custom')
|
||||
this.host_dir = os.path.join(this.buildroot_build_dir, 'host')
|
||||
this.host_bin_dir = os.path.join(this.host_dir, 'usr', 'bin')
|
||||
this.images_dir = os.path.join(this.buildroot_build_dir, 'images')
|
||||
this.rootfs_raw_file = os.path.join(this.images_dir, 'rootfs.ext2')
|
||||
this.buildroot_images_dir = os.path.join(this.buildroot_build_dir, 'images')
|
||||
this.rootfs_raw_file = os.path.join(this.buildroot_images_dir, 'rootfs.ext2')
|
||||
this.qcow2_file = this.rootfs_raw_file + '.qcow2'
|
||||
this.staging_dir = os.path.join(this.buildroot_build_dir, 'staging')
|
||||
this.target_dir = os.path.join(this.buildroot_build_dir, 'target')
|
||||
@@ -425,11 +493,23 @@ def setup(parser):
|
||||
this.qemu_trace_txt_file = os.path.join(this.qemu_run_dir, 'trace.txt')
|
||||
this.qemu_termout_file = os.path.join(this.qemu_run_dir, 'termout.txt')
|
||||
this.qemu_rrfile = os.path.join(this.qemu_run_dir, 'rrfile')
|
||||
this.gem5_build_dir = os.path.join(this.out_dir, 'gem5', args.gem5_build_id)
|
||||
this.gem5_out_dir = os.path.join(this.out_dir, 'gem5')
|
||||
this.gem5_build_dir = os.path.join(this.gem5_out_dir, args.gem5_build_id)
|
||||
this.gem5_fake_iso = os.path.join(this.gem5_out_dir, 'fake.iso')
|
||||
this.gem5_m5term = os.path.join(this.gem5_build_dir, 'm5term')
|
||||
this.gem5_build_build_dir = os.path.join(this.gem5_build_dir, 'build')
|
||||
this.gem5_executable = os.path.join(this.gem5_build_build_dir, gem5_arch, 'gem5.{}'.format(args.gem5_build_type))
|
||||
this.gem5_system_dir = os.path.join(this.gem5_build_dir, 'system')
|
||||
this.crosstool_ng_out_dir = os.path.join(this.out_dir, 'crosstool-ng')
|
||||
this.crosstool_ng_buildid_dir = os.path.join(this.crosstool_ng_out_dir, 'build', args.crosstool_ng_build_id)
|
||||
this.crosstool_ng_install_dir = os.path.join(this.crosstool_ng_buildid_dir, 'install', args.arch)
|
||||
this.crosstool_ng_bin_dir = os.path.join(this.crosstool_ng_install_dir, 'bin')
|
||||
this.crosstool_ng_util_dir = os.path.join(this.crosstool_ng_buildid_dir, 'util')
|
||||
this.crosstool_ng_config = os.path.join(this.crosstool_ng_util_dir, '.config')
|
||||
this.crosstool_ng_defconfig = os.path.join(this.crosstool_ng_util_dir, 'defconfig')
|
||||
this.crosstool_ng_executable = os.path.join(this.crosstool_ng_util_dir, 'ct-ng')
|
||||
this.crosstool_ng_build_dir = os.path.join(this.crosstool_ng_buildid_dir, 'build')
|
||||
this.crosstool_ng_download_dir = os.path.join(this.crosstool_ng_out_dir, 'download')
|
||||
if args.gem5_worktree is not None:
|
||||
this.gem5_src_dir = os.path.join(this.gem5_non_default_src_root_dir, args.gem5_worktree)
|
||||
else:
|
||||
@@ -470,12 +550,63 @@ def setup(parser):
|
||||
this.qemu_hostfwd_ssh_port = this.qemu_base_port + 2
|
||||
this.qemu_gdb_port = this.qemu_base_port + 3
|
||||
this.gdb_port = this.qemu_gdb_port
|
||||
|
||||
# Baremetal.
|
||||
this.baremetal = args.baremetal
|
||||
this.baremetal_lib_basename = 'lib'
|
||||
this.baremetal_src_dir = os.path.join(this.root_dir, 'baremetal')
|
||||
this.baremetal_src_lib_dir = os.path.join(this.baremetal_src_dir, this.baremetal_lib_basename)
|
||||
this.c_ext = '.c'
|
||||
this.asm_ext = '.S'
|
||||
this.obj_ext = '.o'
|
||||
if args.gem5:
|
||||
this.simulator_name = 'gem5'
|
||||
else:
|
||||
this.simulator_name = 'qemu'
|
||||
this.baremetal_out_dir = os.path.join(out_dir, 'baremetal', args.arch, this.simulator_name, this.machine)
|
||||
this.baremetal_out_lib_dir = os.path.join(this.baremetal_out_dir, this.baremetal_lib_basename)
|
||||
this.baremetal_out_ext = '.elf'
|
||||
|
||||
# Image.
|
||||
if args.baremetal is None:
|
||||
if args.gem5:
|
||||
this.image = this.vmlinux
|
||||
this.disk_image = this.rootfs_raw_file
|
||||
else:
|
||||
this.image = this.linux_image
|
||||
this.disk_image = this.qcow2_file
|
||||
else:
|
||||
this.disk_image = this.gem5_fake_iso
|
||||
paths = [
|
||||
os.path.join(this.baremetal_out_dir, this.baremetal),
|
||||
os.path.join(
|
||||
this.baremetal_out_dir,
|
||||
os.path.relpath(this.baremetal, this.baremetal_src_dir),
|
||||
)
|
||||
]
|
||||
paths[:] = [os.path.splitext(path)[0] + this.baremetal_out_ext for path in paths]
|
||||
found = False
|
||||
for path in paths:
|
||||
if os.path.exists(path):
|
||||
found = True
|
||||
break
|
||||
if not found and this.baremetal != 'all':
|
||||
raise Exception('Baremetal ELF file not found. Tried:\n' + '\n'.join(paths))
|
||||
this.image = path
|
||||
return args
|
||||
|
||||
def mkdir():
|
||||
global this
|
||||
os.makedirs(this.build_dir, exist_ok=True)
|
||||
os.makedirs(this.gem5_build_dir, exist_ok=True)
|
||||
os.makedirs(this.gem5_run_dir, exist_ok=True)
|
||||
os.makedirs(this.qemu_run_dir, exist_ok=True)
|
||||
os.makedirs(this.p9_dir, exist_ok=True)
|
||||
def write_configs(config_path, configs, config_fragments=None):
|
||||
"""
|
||||
Write extra configs into the Buildroot config file.
|
||||
TODO Can't get rid of these for now with nice fragments:
|
||||
http://stackoverflow.com/questions/44078245/is-it-possible-to-use-config-fragments-with-buildroots-config
|
||||
"""
|
||||
if config_fragments is None:
|
||||
config_fragments = []
|
||||
with open(config_path, 'a') as config_file:
|
||||
for config_fragment in config_fragments:
|
||||
with open(config_fragment, 'r') as config_fragment:
|
||||
for line in config_fragment:
|
||||
config_file.write(line)
|
||||
for config in configs:
|
||||
config_file.write(config + '\n')
|
||||
|
||||
167
configure
vendored
167
configure
vendored
@@ -1,29 +1,51 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eu
|
||||
apt_get=true
|
||||
baremetal=false
|
||||
baremetal_given=false
|
||||
buildroot=true
|
||||
buildroot_given=false
|
||||
linux=true
|
||||
linux_given=false
|
||||
interactive_pkgs=libsdl2-dev
|
||||
gem5=false
|
||||
gem5_given=false
|
||||
qemu=true
|
||||
qemu_given=false
|
||||
submodules_dir=submodules
|
||||
submodules=buildroot
|
||||
submodules=
|
||||
y=
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--baremetal)
|
||||
baremetal=true
|
||||
baremetal_given=true
|
||||
shift
|
||||
;;
|
||||
--buildroot)
|
||||
buildroot_given=true
|
||||
shift
|
||||
;;
|
||||
--gem5)
|
||||
gem5_given=true
|
||||
shift
|
||||
;;
|
||||
--parsec-benchmark)
|
||||
submodules="${submodules} parsec-benchmark"
|
||||
shift
|
||||
;;
|
||||
--qemu)
|
||||
qemu_given=true
|
||||
shift
|
||||
;;
|
||||
--no-apt-get)
|
||||
apt_get=false
|
||||
shift
|
||||
;;
|
||||
--travis)
|
||||
interactive_pkgs=
|
||||
y=-y
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo 'unknown option' 1>&2
|
||||
@@ -37,84 +59,93 @@ fi
|
||||
if "$gem5_given"; then
|
||||
gem5=true
|
||||
fi
|
||||
|
||||
## apt-get
|
||||
|
||||
pkgs="\
|
||||
automake \
|
||||
bc \
|
||||
build-essential \
|
||||
coreutils \
|
||||
cpio \
|
||||
expect \
|
||||
git \
|
||||
moreutils \
|
||||
rsync \
|
||||
tmux \
|
||||
unzip \
|
||||
vinagre \
|
||||
wget \
|
||||
"
|
||||
if "$gem5"; then
|
||||
pkgs="$pkgs \
|
||||
ccache \
|
||||
gcc-aarch64-linux-gnu \
|
||||
gcc-arm-linux-gnueabi \
|
||||
libgoogle-perftools-dev \
|
||||
protobuf-compiler \
|
||||
python-dev \
|
||||
python-pip \
|
||||
scons \
|
||||
"
|
||||
if "$baremetal_given" && ! "$buildroot_given"; then
|
||||
buildroot=false
|
||||
fi
|
||||
command -v apt-get >/dev/null 2>&1 || {
|
||||
cat <<EOF
|
||||
|
||||
if "$apt_get"; then
|
||||
pkgs="\
|
||||
automake \
|
||||
bc \
|
||||
build-essential \
|
||||
coreutils \
|
||||
cpio \
|
||||
expect \
|
||||
git \
|
||||
moreutils \
|
||||
rsync \
|
||||
tmux \
|
||||
unzip \
|
||||
vinagre \
|
||||
wget \
|
||||
"
|
||||
if "$gem5"; then
|
||||
pkgs="$pkgs \
|
||||
ccache \
|
||||
gcc-aarch64-linux-gnu \
|
||||
gcc-arm-linux-gnueabi \
|
||||
libgoogle-perftools-dev \
|
||||
protobuf-compiler \
|
||||
python-dev \
|
||||
python-pip \
|
||||
scons \
|
||||
"
|
||||
fi
|
||||
command -v apt-get >/dev/null 2>&1 || {
|
||||
cat <<EOF
|
||||
apt-get not found. You're on your own for installing dependencies.
|
||||
|
||||
On Ubuntu they are:
|
||||
|
||||
$pkgs
|
||||
EOF
|
||||
exit 0
|
||||
}
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Without this started failing in kernel 4.15 with:
|
||||
# Makefile:932: *** "Cannot generate ORC metadata for CONFIG_UNWINDER_ORC=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel". Stop.
|
||||
pkgs="$pkgs libelf-dev"
|
||||
# Without this started failing in kernel 4.15 with:
|
||||
# Makefile:932: *** "Cannot generate ORC metadata for CONFIG_UNWINDER_ORC=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel". Stop.
|
||||
pkgs="$pkgs libelf-dev"
|
||||
|
||||
# https://stackoverflow.com/questions/20010199/determining-if-a-process-runs-inside-lxc-docker
|
||||
if [ -f /.dockerenv ]; then
|
||||
# https://askubuntu.com/questions/909277/avoiding-user-interaction-with-tzdata-when-installing-certbot-in-a-docker-contai
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
mysudo=
|
||||
# https://askubuntu.com/questions/496549/error-you-must-put-some-source-uris-in-your-sources-list
|
||||
sed -Ei 's/^# deb-src/deb-src/' /etc/apt/sources.list
|
||||
y=-y
|
||||
else
|
||||
mysudo=sudo
|
||||
fi
|
||||
$mysudo apt-get update $y
|
||||
# Building SDL for QEMU in Buildroot was rejected upstream because it adds many dependencies:
|
||||
# https://patchwork.ozlabs.org/patch/770684/
|
||||
# We are just using the host SDL for now, if it causes too much problems we might remove it.
|
||||
# libsdl2-dev needs to be installed separatedly from sudo apt-get build-dep qemu
|
||||
# because Ubuntu 16.04's QEMU uses SDL 1.
|
||||
$mysudo apt-get install $y \
|
||||
$pkgs \
|
||||
$interactive_pkgs \
|
||||
;
|
||||
if "$qemu"; then
|
||||
$mysudo apt-get build-dep $y qemu
|
||||
fi
|
||||
if "$gem5"; then
|
||||
# Generate graphs of config.ini under m5out.
|
||||
# Not with pip directly:
|
||||
# https://stackoverflow.com/questions/49836676/error-after-upgrading-pip-cannot-import-name-main/51846054#51846054
|
||||
python -m pip install --user pydot
|
||||
# https://stackoverflow.com/questions/20010199/determining-if-a-process-runs-inside-lxc-docker
|
||||
if [ -f /.dockerenv ]; then
|
||||
# https://askubuntu.com/questions/909277/avoiding-user-interaction-with-tzdata-when-installing-certbot-in-a-docker-contai
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
mysudo=
|
||||
# https://askubuntu.com/questions/496549/error-you-must-put-some-source-uris-in-your-sources-list
|
||||
sed -Ei 's/^# deb-src/deb-src/' /etc/apt/sources.list
|
||||
y=-y
|
||||
else
|
||||
mysudo=sudo
|
||||
fi
|
||||
$mysudo apt-get update $y
|
||||
# Building SDL for QEMU in Buildroot was rejected upstream because it adds many dependencies:
|
||||
# https://patchwork.ozlabs.org/patch/770684/
|
||||
# We are just using the host SDL for now, if it causes too much problems we might remove it.
|
||||
# libsdl2-dev needs to be installed separatedly from sudo apt-get build-dep qemu
|
||||
# because Ubuntu 16.04's QEMU uses SDL 1.
|
||||
$mysudo apt-get install $y \
|
||||
$pkgs \
|
||||
$interactive_pkgs \
|
||||
;
|
||||
if "$qemu"; then
|
||||
$mysudo apt-get build-dep $y qemu
|
||||
fi
|
||||
if "$gem5"; then
|
||||
# Generate graphs of config.ini under m5out.
|
||||
# Not with pip directly:
|
||||
# https://stackoverflow.com/questions/49836676/error-after-upgrading-pip-cannot-import-name-main/51846054#51846054
|
||||
python -m pip install --user pydot
|
||||
fi
|
||||
fi
|
||||
|
||||
## Submodules
|
||||
|
||||
if "$baremetal"; then
|
||||
submodules="${submodules} crosstool-ng"
|
||||
fi
|
||||
if "$buildroot"; then
|
||||
submodules="${submodules} buildroot"
|
||||
fi
|
||||
if "$qemu"; then
|
||||
submodules="${submodules} qemu"
|
||||
fi
|
||||
@@ -154,4 +185,6 @@ submodules="$(for submodule in ${submodules}; do printf "${submodules_dir}/${sub
|
||||
# `--jobs"`: https://stackoverflow.com/questions/26957237/how-to-make-git-clone-faster-with-multiple-threads/52327638#52327638
|
||||
#
|
||||
git submodule update --init --recursive -- ${submodules}
|
||||
git submodule update --depth 1 --init --recursive -- "${submodules_dir}/linux"
|
||||
if "$linux"; then
|
||||
git submodule update --depth 1 --init --recursive -- "${submodules_dir}/linux"
|
||||
fi
|
||||
|
||||
9
crosstool_ng_config/aarch64
Normal file
9
crosstool_ng_config/aarch64
Normal file
@@ -0,0 +1,9 @@
|
||||
CT_ARCH_64=y
|
||||
CT_ARCH_ARM=y
|
||||
CT_CC_LANG_CXX=y
|
||||
CT_DEBUG_GDB=y
|
||||
CT_GDB_CROSS_SIM=y
|
||||
CT_LIBC_NEWLIB_DISABLE_SUPPLIED_SYSCALLS=y
|
||||
CT_LIBC_NEWLIB_IO_C99FMT=y
|
||||
CT_LIBC_NEWLIB_IO_FLOAT=y
|
||||
CT_LIBC_NEWLIB_IO_LL=y
|
||||
12
crosstool_ng_config/arm
Normal file
12
crosstool_ng_config/arm
Normal file
@@ -0,0 +1,12 @@
|
||||
# ./ct-ng arm-unknown-eabi
|
||||
CT_ARCH_ARM=y
|
||||
CT_ARCH_FLOAT_SW=y
|
||||
CT_LIBC_NEWLIB_IO_C99FMT=y
|
||||
CT_LIBC_NEWLIB_IO_LL=y
|
||||
CT_LIBC_NEWLIB_IO_FLOAT=y
|
||||
CT_LIBC_NEWLIB_DISABLE_SUPPLIED_SYSCALLS=y
|
||||
CT_CC_LANG_CXX=y
|
||||
|
||||
# Modifications.
|
||||
CT_DEBUG_GDB=y
|
||||
CT_GDB_CROSS_SIM=y
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# https://github.com/cirosantilli/linux-kernel-module-cheat/tree/58de3f7243016c052ad080f82dd757d61878219b#gem5-run-benchmark
|
||||
# https://github.com/cirosantilli/linux-kernel-module-cheat#gem5-run-benchmark
|
||||
|
||||
set -eu
|
||||
root_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
|
||||
@@ -10,7 +10,7 @@ cmd="./run -a '$arch' --gem5 --eval-busybox '/gem5.sh'"
|
||||
|
||||
# These cache sizes roughly match the ARM Cortex A75
|
||||
# https://en.wikipedia.org/wiki/ARM_Cortex-A75
|
||||
restore='-l 1 -- --cpu-type=HPI --restore-with-cpu=HPI --caches --l2cache --l1d_size=128kB --l1i_size=1024kB --l2_size=256kB'
|
||||
restore='-l 1 -- --cpu-type=HPI --restore-with-cpu=HPI --caches --l2cache --l1d_size=64kB --l1i_size=64kB --l2_size=256kB'
|
||||
|
||||
# Generate a checkpoint after Linux boots, using the faster and less detailed CPU.
|
||||
# The boot takes a while, be patient young Padawan.
|
||||
|
||||
21
getvar
21
getvar
@@ -1,5 +1,9 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import types
|
||||
|
||||
import common
|
||||
|
||||
parser = common.get_argparse(argparse_args={
|
||||
'description': '''Print the value of a common.py variable.
|
||||
|
||||
@@ -14,8 +18,21 @@ For example, to get the Buildroot output directory for an ARM build, use:
|
||||
./%(prog)s -a arm buildroot_build_dir
|
||||
....
|
||||
|
||||
List all available variables:
|
||||
|
||||
....
|
||||
./%(prog)s
|
||||
....
|
||||
....
|
||||
'''
|
||||
})
|
||||
parser.add_argument('variable')
|
||||
parser.add_argument('variable', nargs='?')
|
||||
args = common.setup(parser)
|
||||
print(getattr(common, args.variable))
|
||||
if args.variable:
|
||||
print(getattr(common, args.variable))
|
||||
else:
|
||||
for attr in dir(common):
|
||||
if not attr.startswith('__'):
|
||||
val = getattr(common, attr)
|
||||
if not callable(val) and not type(val) is types.ModuleType:
|
||||
print('{} {}'.format(attr, val))
|
||||
|
||||
@@ -27,7 +27,7 @@ typedef struct {
|
||||
* @param[out] entry the parsed entry
|
||||
* @param[in] pagemap_fd file descriptor to an open /proc/pid/pagemap file
|
||||
* @param[in] vaddr virtual address to get entry for
|
||||
* @return 0 for success, 1 for failure
|
||||
* @return 0 for success, 1 for failure
|
||||
*/
|
||||
int pagemap_get_entry(PagemapEntry *entry, int pagemap_fd, uintptr_t vaddr)
|
||||
{
|
||||
@@ -60,8 +60,8 @@ int pagemap_get_entry(PagemapEntry *entry, int pagemap_fd, uintptr_t vaddr)
|
||||
*
|
||||
* @param[out] paddr physical address
|
||||
* @param[in] pid process to convert for
|
||||
* @param[in] vaddr virtual address to get entry for
|
||||
* @return 0 for success, 1 for failure
|
||||
* @param[in] vaddr virtual address to get entry for
|
||||
* @return 0 for success, 1 for failure
|
||||
*/
|
||||
int virt_to_phys_user(uintptr_t *paddr, pid_t pid, uintptr_t vaddr)
|
||||
{
|
||||
|
||||
12
patches/manual/gem5-aarch64-baremetal.patch
Normal file
12
patches/manual/gem5-aarch64-baremetal.patch
Normal file
@@ -0,0 +1,12 @@
|
||||
diff --git a/configs/example/fs.py b/configs/example/fs.py
|
||||
index 3997ed76c..c3259825d 100644
|
||||
--- a/configs/example/fs.py
|
||||
+++ b/configs/example/fs.py
|
||||
@@ -376,5 +376,7 @@ if buildEnv['TARGET_ISA'] == "arm" and options.generate_dtb:
|
||||
sys = getattr(root, sysname)
|
||||
sys.dtb_filename = create_dtb_for_system(sys, '%s.dtb' % sysname)
|
||||
|
||||
+test_sys.highest_el_is_64 = True
|
||||
+test_sys.auto_reset_addr_64 = True
|
||||
Simulation.setWorkCountOptions(test_sys, options)
|
||||
Simulation.run(options, root, test_sys, FutureClass)
|
||||
11
patches/manual/gem5-wait-gdb.patch
Normal file
11
patches/manual/gem5-wait-gdb.patch
Normal file
@@ -0,0 +1,11 @@
|
||||
diff --git a/configs/example/fs.py b/configs/example/fs.py
|
||||
index 3997ed76c..b4267ebc0 100644
|
||||
--- a/configs/example/fs.py
|
||||
+++ b/configs/example/fs.py
|
||||
@@ -376,5 +376,6 @@ if buildEnv['TARGET_ISA'] == "arm" and options.generate_dtb:
|
||||
sys = getattr(root, sysname)
|
||||
sys.dtb_filename = create_dtb_for_system(sys, '%s.dtb' % sysname)
|
||||
|
||||
+test_sys.cpu[0].wait_for_remote_gdb = True
|
||||
Simulation.setWorkCountOptions(test_sys, options)
|
||||
Simulation.run(options, root, test_sys, FutureClass)
|
||||
93
run
93
run
@@ -29,7 +29,6 @@ defaults = {
|
||||
'kgdb': False,
|
||||
'kvm': False,
|
||||
'memory': '256M',
|
||||
'prebuilt': False,
|
||||
'record': False,
|
||||
'replay': False,
|
||||
'terminal': False,
|
||||
@@ -98,17 +97,27 @@ def main(args, extra_args=None):
|
||||
|
||||
def raise_rootfs_not_found():
|
||||
raise Exception('Root filesystem not found. Did you build it?\n' \
|
||||
'Tried to use: ' + common.rootfs_raw_file)
|
||||
'Tried to use: ' + common.disk_image)
|
||||
def raise_image_not_found():
|
||||
raise Exception('Executable image not found. Did you build it?\n' \
|
||||
'Tried to use: ' + common.image)
|
||||
if common.image is None:
|
||||
raise Exception('Baremetal ELF file not found. Tried:\n' + '\n'.join(paths))
|
||||
if args.gem5:
|
||||
if not os.path.exists(common.rootfs_raw_file):
|
||||
if not os.path.exists(common.qcow2_file):
|
||||
raise_rootfs_not_found()
|
||||
common.raw_to_qcow2(prebuilt=args.prebuilt, reverse=True)
|
||||
if not os.path.exists(common.vmlinux):
|
||||
if args.baremetal is None:
|
||||
if not os.path.exists(common.rootfs_raw_file):
|
||||
if not os.path.exists(common.qcow2_file):
|
||||
raise_rootfs_not_found()
|
||||
common.raw_to_qcow2(prebuilt=args.prebuilt, reverse=True)
|
||||
else:
|
||||
if not os.path.exists(common.gem5_fake_iso):
|
||||
os.makedirs(os.path.dirname(common.gem5_fake_iso), exist_ok=True)
|
||||
with open(common.gem5_fake_iso, 'w') as f:
|
||||
f.write('a' * 512)
|
||||
if not os.path.exists(common.image):
|
||||
# This is to run gem5 from a prebuilt download.
|
||||
if not os.path.exists(common.linux_image):
|
||||
raise Exception('Linux kernel image not found. Did you compile it?\n' \
|
||||
'Tried: ' + common.vmlinux)
|
||||
if (not args.baremetal is None) or (not os.path.exists(common.linux_image)):
|
||||
raise_image_not_found()
|
||||
assert common.run_cmd([os.path.join(common.extract_vmlinux, common.linux_image)]) == 0
|
||||
os.makedirs(os.path.dirname(common.gem5_readfile), exist_ok=True)
|
||||
with open(common.gem5_readfile, 'w') as readfile:
|
||||
@@ -139,9 +148,9 @@ def main(args, extra_args=None):
|
||||
os.path.join(common.gem5_src_dir, 'configs', 'example', 'arm', 'fs_bigLITTLE.py'),
|
||||
'--big-cpus', '2',
|
||||
'--cpu-type', 'atomic',
|
||||
'--disk', common.rootfs_raw_file,
|
||||
'--disk', common.disk_image,
|
||||
'--dtb', os.path.join(common.gem5_system_dir, 'arm', 'dt', 'armv8_gem5_v1_big_little_2_2.dtb'),
|
||||
'--kernel', common.vmlinux,
|
||||
'--kernel', common.image,
|
||||
'--little-cpus', '2'
|
||||
]
|
||||
else:
|
||||
@@ -152,8 +161,8 @@ def main(args, extra_args=None):
|
||||
extra_emulator_args.extend(['-r', str(sorted(cpt_dirs).index(cpt_dir) + 1)])
|
||||
cmd += [
|
||||
common.gem5_fs_file,
|
||||
'--disk-image', common.rootfs_raw_file,
|
||||
'--kernel', common.vmlinux,
|
||||
'--disk-image', common.disk_image,
|
||||
'--kernel', common.image,
|
||||
'--mem-size', memory,
|
||||
'--num-cpus', str(args.cpus),
|
||||
'--script', common.gem5_readfile,
|
||||
@@ -168,9 +177,13 @@ def main(args, extra_args=None):
|
||||
cmd += [
|
||||
'--command-line', 'earlyprintk=pl011,0x1c090000 console=ttyAMA0 lpj=19988480 rw loglevel=8 mem={} root=/dev/sda {}'.format(memory, kernel_cli),
|
||||
'--dtb-file', os.path.join(common.gem5_system_dir, 'arm', 'dt', 'armv{}_gem5_v1_{}cpu.dtb'.format(common.armv, args.cpus)),
|
||||
'--machine-type', 'VExpress_GEM5_V1',
|
||||
'--machine-type', common.machine,
|
||||
]
|
||||
if not args.baremetal is None:
|
||||
cmd.append('--bare-metal')
|
||||
else:
|
||||
if not os.path.exists(common.image):
|
||||
raise_image_not_found()
|
||||
extra_emulator_args.extend(extra_qemu_args)
|
||||
os.makedirs(common.run_dir, exist_ok=True)
|
||||
if args.prebuilt:
|
||||
@@ -183,10 +196,6 @@ def main(args, extra_args=None):
|
||||
if not qemu_found:
|
||||
raise Exception('QEMU executable not found, did you forget to build or install it?\n' \
|
||||
'Tried to use: ' + qemu_executable)
|
||||
if not os.path.exists(common.qcow2_file):
|
||||
if not os.path.exists(common.rootfs_raw_file):
|
||||
raise_rootfs_not_found()
|
||||
common.raw_to_qcow2(prebuilt=args.prebuilt)
|
||||
if args.debug_vm:
|
||||
serial_monitor = []
|
||||
else:
|
||||
@@ -201,7 +210,7 @@ def main(args, extra_args=None):
|
||||
qemu_executable,
|
||||
'-device', 'rtl8139,netdev=net0',
|
||||
'-gdb', 'tcp::{}'.format(common.gdb_port),
|
||||
'-kernel', common.linux_image,
|
||||
'-kernel', common.image,
|
||||
'-m', args.memory,
|
||||
'-monitor', 'telnet::{},server,nowait'.format(common.qemu_monitor_port),
|
||||
'-netdev', 'user,hostfwd=tcp::{}-:{},hostfwd=tcp::{}-:22,id=net0'.format(common.qemu_hostfwd_generic_port, common.qemu_hostfwd_generic_port, common.qemu_hostfwd_ssh_port),
|
||||
@@ -215,7 +224,7 @@ def main(args, extra_args=None):
|
||||
vnc
|
||||
)
|
||||
if args.initrd:
|
||||
extra_emulator_args.extend(['-initrd', os.path.join(common.images_dir, 'rootfs.cpio')])
|
||||
extra_emulator_args.extend(['-initrd', os.path.join(common.buildroot_images_dir, 'rootfs.cpio')])
|
||||
rr = args.record or args.replay
|
||||
if ramfs:
|
||||
# TODO why is this needed, and why any string works.
|
||||
@@ -231,15 +240,20 @@ def main(args, extra_args=None):
|
||||
root = 'root=/dev/vda'
|
||||
rrid = ''
|
||||
snapshot = ',snapshot'
|
||||
extra_emulator_args.extend([
|
||||
'-drive',
|
||||
'file={},format=qcow2,if={}{}{}'.format(common.qcow2_file, driveif, snapshot, rrid)
|
||||
])
|
||||
if rr:
|
||||
if args.baremetal is None:
|
||||
if not os.path.exists(common.qcow2_file):
|
||||
if not os.path.exists(common.rootfs_raw_file):
|
||||
raise_rootfs_not_found()
|
||||
common.raw_to_qcow2(prebuilt=args.prebuilt)
|
||||
extra_emulator_args.extend([
|
||||
'-drive', 'driver=blkreplay,if=none,image=img-direct,id=img-blkreplay',
|
||||
'-device', 'ide-hd,drive=img-blkreplay'
|
||||
])
|
||||
'-drive',
|
||||
'file={},format=qcow2,if={}{}{}'.format(common.disk_image, driveif, snapshot, rrid)
|
||||
])
|
||||
if rr:
|
||||
extra_emulator_args.extend([
|
||||
'-drive', 'driver=blkreplay,if=none,image=img-direct,id=img-blkreplay',
|
||||
'-device', 'ide-hd,drive=img-blkreplay'
|
||||
])
|
||||
if rr:
|
||||
extra_emulator_args.extend([
|
||||
'-object', 'filter-replay,id=replay,netdev=net0',
|
||||
@@ -251,29 +265,32 @@ def main(args, extra_args=None):
|
||||
if args.arch == 'x86_64':
|
||||
if args.kgdb:
|
||||
kernel_cli += ' kgdboc=ttyS0,115200'
|
||||
append = ['-append', '{} nopat {}'.format(root, kernel_cli)]
|
||||
cmd.extend([
|
||||
'-M', 'pc',
|
||||
'-append', '{} nopat {}'.format(root, kernel_cli),
|
||||
'-M', common.machine,
|
||||
'-device', 'edu',
|
||||
])
|
||||
elif args.arch == 'arm' or args.arch == 'aarch64':
|
||||
extra_qemu_args.append('-semihosting')
|
||||
if args.kgdb:
|
||||
kernel_cli += ' kgdboc=ttyAMA0,115200'
|
||||
if args.arch == 'arm':
|
||||
cpu = 'cortex-a15'
|
||||
else:
|
||||
cpu = 'cortex-a57'
|
||||
# highmem=off needed since v3.0.0 due to:
|
||||
# http://lists.nongnu.org/archive/html/qemu-discuss/2018-08/msg00034.html
|
||||
append = ['-append', '{} {}'.format(root, kernel_cli)]
|
||||
cmd = (
|
||||
cmd +
|
||||
[
|
||||
'-M', 'virt,highmem=off',
|
||||
'-append', '{} {}'.format(root, kernel_cli),
|
||||
# highmem=off needed since v3.0.0 due to:
|
||||
# http://lists.nongnu.org/archive/html/qemu-discuss/2018-08/msg00034.html
|
||||
'-M', '{},highmem=off'.format(common.machine),
|
||||
'-cpu', cpu,
|
||||
] +
|
||||
virtio_gpu_pci
|
||||
)
|
||||
if args.baremetal is None:
|
||||
cmd.extend(append)
|
||||
if args.tmux:
|
||||
if args.gem5:
|
||||
subprocess.Popen([os.path.join(common.root_dir, 'tmu'),
|
||||
@@ -286,7 +303,7 @@ def main(args, extra_args=None):
|
||||
# but it cannot be used as a library properly it seems, and it is
|
||||
# slower than tmux.
|
||||
subprocess.Popen([os.path.join(common.root_dir, 'tmu'),
|
||||
"sleep 2;./rungdb -a '{}' -L '{}' -n '{}' {}" \
|
||||
"sleep 2;./run-gdb -a '{}' -L '{}' -n '{}' {}" \
|
||||
.format(args.arch, args.linux_build_id, args.run_id, args.tmux_args)
|
||||
])
|
||||
cmd.extend(extra_emulator_args)
|
||||
@@ -414,10 +431,6 @@ some arch to fail to boot.
|
||||
Default: %(default)s
|
||||
'''
|
||||
)
|
||||
parser.add_argument(
|
||||
'-P', '--prebuilt', default=defaults['prebuilt'], action='store_true',
|
||||
help='Run the downloaded prebuilt images with pre-packaged host tools.'
|
||||
)
|
||||
group = parser.add_mutually_exclusive_group()
|
||||
group.add_argument(
|
||||
'-R', '--replay', default=defaults['replay'], action='store_true',
|
||||
|
||||
@@ -11,6 +11,7 @@ import common
|
||||
defaults = {
|
||||
'after': '',
|
||||
'before': '',
|
||||
'sim': False,
|
||||
'no_continue': False,
|
||||
'kgdb': False,
|
||||
'no_lxsymbols': False,
|
||||
@@ -33,7 +34,7 @@ def main(args, extra_args=None):
|
||||
args = common.resolve_args(defaults, args, extra_args)
|
||||
after = shlex.split(args.after)
|
||||
before = shlex.split(args.before)
|
||||
if args.no_lxsymbols:
|
||||
if args.no_lxsymbols or args.baremetal is not None:
|
||||
lx_symbols = []
|
||||
else:
|
||||
lx_symbols = ['-ex', 'lx-symbols ../kernel_modules-1.0/']
|
||||
@@ -41,19 +42,25 @@ def main(args, extra_args=None):
|
||||
break_at = ['-ex', 'break {}'.format(args.break_at)]
|
||||
else:
|
||||
break_at = []
|
||||
if args.baremetal is None:
|
||||
image = common.vmlinux
|
||||
else:
|
||||
image = common.image
|
||||
cmd = (
|
||||
[
|
||||
os.path.join(common.host_bin_dir,
|
||||
'{}-linux-gdb'.format(args.arch))
|
||||
] +
|
||||
[common.get_toolchain_tool('gdb')] +
|
||||
before +
|
||||
[
|
||||
'-q',
|
||||
'-ex', 'add-auto-load-safe-path {}'.format(common.linux_variant_dir),
|
||||
'-ex', 'file {}'.format(common.vmlinux),
|
||||
'-ex', 'target remote localhost:{}'.format(common.gdb_port),
|
||||
]
|
||||
['-q']
|
||||
)
|
||||
if args.baremetal is None:
|
||||
cmd.extend(['-ex', 'add-auto-load-safe-path {}'.format(common.linux_variant_dir)])
|
||||
if args.sim:
|
||||
target = 'sim'
|
||||
else:
|
||||
target = 'remote localhost:{}'.format(common.gdb_port)
|
||||
cmd.extend([
|
||||
'-ex', 'file {}'.format(image),
|
||||
'-ex', 'target {}'.format(target),
|
||||
])
|
||||
if not args.kgdb:
|
||||
cmd.extend(break_at)
|
||||
if not args.no_continue:
|
||||
@@ -78,7 +85,7 @@ def main(args, extra_args=None):
|
||||
# which gets put on the kernel build root when python debugging scripts are enabled.
|
||||
cmd.extend(['-ex', 'continue'] + lx_symbols)
|
||||
cmd.extend(after)
|
||||
return common.run_cmd(cmd, cmd_file=os.path.join(common.run_dir, 'rungdb.sh'), cwd=common.linux_variant_dir)
|
||||
return common.run_cmd(cmd, cmd_file=os.path.join(common.run_dir, 'run-gdb.sh'), cwd=common.linux_variant_dir)
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = common.get_argparse(argparse_args={'description': 'Connect with GDB to an emulator to debug Linux itself'})
|
||||
@@ -97,6 +104,12 @@ if __name__ == '__main__':
|
||||
parser.add_argument(
|
||||
'-k', '--kgdb', default=defaults['kgdb'], action='store_true'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--sim', default=defaults['sim'], action='store_true',
|
||||
help='''Use the built-in GDB CPU simulator
|
||||
See: https://github.com/cirosantilli/linux-kernel-module-cheat#gdb-builtin-cpu-simulator
|
||||
'''
|
||||
)
|
||||
parser.add_argument(
|
||||
'-X', '--no-lxsymbols', default=defaults['no_lxsymbols'], action='store_true'
|
||||
)
|
||||
@@ -5,7 +5,7 @@ import os
|
||||
import sys
|
||||
|
||||
import common
|
||||
rungdb = imp.load_source('rungdb', os.path.join(common.root_dir, 'rungdb'))
|
||||
rungdb = imp.load_source('rungdb', os.path.join(common.root_dir, 'run-gdb'))
|
||||
|
||||
parser = common.get_argparse(argparse_args={
|
||||
'description': '''GDB step debug guest userland processes without gdbserver.
|
||||
@@ -42,6 +42,4 @@ else:
|
||||
sys.exit(common.run_cmd(
|
||||
[common.get_toolchain_tool(args.tool)] + args.extra_args,
|
||||
cmd_file=os.path.join(common.run_dir, 'run-toolchain.sh'),
|
||||
cwd=common.linux_variant_dir,
|
||||
show_cmd=False,
|
||||
))
|
||||
|
||||
1
submodules/crosstool-ng
Submodule
1
submodules/crosstool-ng
Submodule
Submodule submodules/crosstool-ng added at d5900debd3
Submodule submodules/gem5 updated: 200281b08c...7bfb7f3a43
Reference in New Issue
Block a user