mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-23 02:05:57 +01:00
build: make baremetal parts more flexible and powerful
Document test-gdb on readme
This commit is contained in:
43
README.adoc
43
README.adoc
@@ -736,9 +736,7 @@ QEMU:
|
|||||||
|
|
||||||
....
|
....
|
||||||
./download-dependencies --baremetal --qemu && \
|
./download-dependencies --baremetal --qemu && \
|
||||||
./build-qemu --arch arm && \
|
./build --arch arm qemu-baremetal
|
||||||
./build-crosstool-ng --arch arm && \
|
|
||||||
./build-baremetal --arch arm && \
|
|
||||||
./run --arch arm --baremetal interactive/prompt
|
./run --arch arm --baremetal interactive/prompt
|
||||||
....
|
....
|
||||||
|
|
||||||
@@ -761,7 +759,19 @@ got: c
|
|||||||
new alloc of 4 bytes at address 0x0x4000a2c8
|
new alloc of 4 bytes at address 0x0x4000a2c8
|
||||||
....
|
....
|
||||||
|
|
||||||
`./build-baremetal` is the command that actually builds the baremetal system for us. It uses crosstool-NG, so that command must be preceded by `./build-crosstool-ng`.
|
To modify that program, edit:
|
||||||
|
|
||||||
|
....
|
||||||
|
vim baremetal/interactive/prompt.c
|
||||||
|
....
|
||||||
|
|
||||||
|
and run:
|
||||||
|
|
||||||
|
....
|
||||||
|
./build-baremetal --arch arm
|
||||||
|
....
|
||||||
|
|
||||||
|
`./build qemu-baremetal` had called link:build-baremetal[] for us previously, in addition to its requirements. `./build-baremetal` uses crosstool-NG, and so it must be preceded by link:build-crosstool-ng[], which `./build qemu-baremetal` also calls.
|
||||||
|
|
||||||
Every `.c` file inside link:baremetal/[] and `.S` file inside `baremetal/arch/<arch>/` generates a separate baremetal image. You can run a different image with commands such as:
|
Every `.c` file inside link:baremetal/[] and `.S` file inside `baremetal/arch/<arch>/` generates a separate baremetal image. You can run a different image with commands such as:
|
||||||
|
|
||||||
@@ -791,10 +801,8 @@ Absolute paths however are used as is and must point to the actual executable:
|
|||||||
To use gem5 instead of QEMU do:
|
To use gem5 instead of QEMU do:
|
||||||
|
|
||||||
....
|
....
|
||||||
./download-dependencies --baremetal --gem5
|
./download-dependencies --baremetal --gem5 && \
|
||||||
./build-gem5 --arch arm
|
./build gem5-baremetal
|
||||||
./build-crosstool-ng --arch arm
|
|
||||||
./build-baremetal --arch arm --gem5
|
|
||||||
./run --arch arm --baremetal interactive/prompt --gem5
|
./run --arch arm --baremetal interactive/prompt --gem5
|
||||||
....
|
....
|
||||||
|
|
||||||
@@ -11410,7 +11418,8 @@ It takes too much time to be feasible for every patch, but it should be done for
|
|||||||
==== Automated tests
|
==== Automated tests
|
||||||
|
|
||||||
....
|
....
|
||||||
./build-bench-boot --size 3 && ./test --size 3
|
./build-test --size 3 && \
|
||||||
|
./test --size 3
|
||||||
echo $?
|
echo $?
|
||||||
....
|
....
|
||||||
|
|
||||||
@@ -11418,7 +11427,7 @@ should output 0.
|
|||||||
|
|
||||||
Sources:
|
Sources:
|
||||||
|
|
||||||
* link:build[]
|
* link:build-test[]
|
||||||
* link:test[]
|
* link:test[]
|
||||||
|
|
||||||
Test just the kernel modules:
|
Test just the kernel modules:
|
||||||
@@ -11440,6 +11449,20 @@ Source: link:rootfs_overlay/test_all.sh[].
|
|||||||
|
|
||||||
===== Test GDB
|
===== Test GDB
|
||||||
|
|
||||||
|
We have some link:https://github.com/pexpect/pexpect[pexpect] automated tests for the baremetal programs!
|
||||||
|
|
||||||
|
....
|
||||||
|
./build-test-gdb && \
|
||||||
|
./test-gdb
|
||||||
|
....
|
||||||
|
|
||||||
|
Sources:
|
||||||
|
|
||||||
|
* link:build-test-gdb[]
|
||||||
|
* link:test-gdb[]
|
||||||
|
|
||||||
|
For the Linux kenel, do the following manual tests for now.
|
||||||
|
|
||||||
Shell 1:
|
Shell 1:
|
||||||
|
|
||||||
....
|
....
|
||||||
|
|||||||
71
build
71
build
@@ -16,22 +16,25 @@ class Component:
|
|||||||
and buildroot optionally depends on qemu to build the qcow2 version
|
and buildroot optionally depends on qemu to build the qcow2 version
|
||||||
of the image.
|
of the image.
|
||||||
'''
|
'''
|
||||||
def __init__(self, build_callback=None, dependencies=None):
|
def __init__(
|
||||||
|
self,
|
||||||
|
build_callback=None,
|
||||||
|
dependencies=None,
|
||||||
|
supported_archs=None,
|
||||||
|
):
|
||||||
self.build_callback = build_callback
|
self.build_callback = build_callback
|
||||||
|
self.supported_archs = supported_archs
|
||||||
if dependencies is None:
|
if dependencies is None:
|
||||||
self.dependencies = []
|
self.dependencies = []
|
||||||
else:
|
else:
|
||||||
self.dependencies = dependencies
|
self.dependencies = dependencies
|
||||||
def build(self, arch):
|
def build(self, arch):
|
||||||
if self.build_callback is not None:
|
if (
|
||||||
|
(self.build_callback is not None) and
|
||||||
|
(self.supported_archs is None or arch in self.supported_archs)
|
||||||
|
):
|
||||||
self.build_callback(arch)
|
self.build_callback(arch)
|
||||||
|
|
||||||
def build_baremetal(arch):
|
|
||||||
run_cmd(['build-crosstool-ng'], arch)
|
|
||||||
run_cmd(['build-baremetal'], arch)
|
|
||||||
run_cmd(['build-baremetal', '--gem5'], arch)
|
|
||||||
run_cmd(['build-baremetal', '--gem5', '--machine', 'RealViewPBX'], arch)
|
|
||||||
|
|
||||||
def run_cmd(cmd, arch):
|
def run_cmd(cmd, arch):
|
||||||
global args
|
global args
|
||||||
cmd_abs = cmd.copy()
|
cmd_abs = cmd.copy()
|
||||||
@@ -43,8 +46,17 @@ def run_cmd(cmd, arch):
|
|||||||
|
|
||||||
name_to_component_map = {
|
name_to_component_map = {
|
||||||
# Leaves without dependencies.
|
# Leaves without dependencies.
|
||||||
'baremetal': Component(
|
'baremetal-qemu': Component(
|
||||||
lambda arch: build_baremetal(arch),
|
lambda arch: run_cmd(['build-baremetal'], arch),
|
||||||
|
supported_archs=common.crosstool_ng_supported_archs,
|
||||||
|
),
|
||||||
|
'baremetal-gem5': Component(
|
||||||
|
lambda arch: run_cmd(['build-baremetal', '--gem5'], arch),
|
||||||
|
supported_archs=common.crosstool_ng_supported_archs,
|
||||||
|
),
|
||||||
|
'baremetal-gem5-pbx': Component(
|
||||||
|
lambda arch: run_cmd(['build-baremetal', '--gem5', '--machine', 'RealViewPBX'], arch),
|
||||||
|
supported_archs=common.crosstool_ng_supported_archs,
|
||||||
),
|
),
|
||||||
'buildroot': Component(
|
'buildroot': Component(
|
||||||
lambda arch: run_cmd(['build-buildroot'], arch),
|
lambda arch: run_cmd(['build-buildroot'], arch),
|
||||||
@@ -55,6 +67,10 @@ name_to_component_map = {
|
|||||||
'copy-overlay': Component(
|
'copy-overlay': Component(
|
||||||
lambda arch: run_cmd(['copy-overlay'], arch),
|
lambda arch: run_cmd(['copy-overlay'], arch),
|
||||||
),
|
),
|
||||||
|
'crosstool-ng': Component(
|
||||||
|
lambda arch: run_cmd(['build-crosstool-ng'], arch),
|
||||||
|
supported_archs=common.crosstool_ng_supported_archs,
|
||||||
|
),
|
||||||
'gem5': Component(
|
'gem5': Component(
|
||||||
lambda arch: run_cmd(['build-gem5'], arch),
|
lambda arch: run_cmd(['build-gem5'], arch),
|
||||||
),
|
),
|
||||||
@@ -84,12 +100,27 @@ name_to_component_map = {
|
|||||||
),
|
),
|
||||||
|
|
||||||
# Dependency only nodes.
|
# Dependency only nodes.
|
||||||
|
'all': Component(dependencies=[
|
||||||
|
'all-linux',
|
||||||
|
'all-baremetal',
|
||||||
|
]),
|
||||||
|
'all-baremetal': Component(dependencies=[
|
||||||
|
'qemu-baremetal',
|
||||||
|
'gem5-baremetal',
|
||||||
|
'baremetal-gem5-pbx',
|
||||||
|
],
|
||||||
|
supported_archs=common.crosstool_ng_supported_archs,
|
||||||
|
),
|
||||||
'all-linux': Component(dependencies=[
|
'all-linux': Component(dependencies=[
|
||||||
'qemu-gem5-buildroot',
|
'qemu-gem5-buildroot',
|
||||||
'gem5-debug',
|
'gem5-debug',
|
||||||
'gem5-fast',
|
'gem5-fast',
|
||||||
'qemu-user',
|
'qemu-user',
|
||||||
]),
|
]),
|
||||||
|
'baremetal': Component(dependencies=[
|
||||||
|
'baremetal-gem5',
|
||||||
|
'baremetal-qemu',
|
||||||
|
]),
|
||||||
'gem5-buildroot': Component(dependencies=[
|
'gem5-buildroot': Component(dependencies=[
|
||||||
'buildroot-gcc',
|
'buildroot-gcc',
|
||||||
'linux',
|
'linux',
|
||||||
@@ -97,12 +128,22 @@ name_to_component_map = {
|
|||||||
'overlay',
|
'overlay',
|
||||||
'gem5',
|
'gem5',
|
||||||
]),
|
]),
|
||||||
|
'gem5-baremetal': Component(dependencies=[
|
||||||
|
'gem5',
|
||||||
|
'crosstool-ng',
|
||||||
|
'baremetal-gem5',
|
||||||
|
]),
|
||||||
'overlay': Component(dependencies=[
|
'overlay': Component(dependencies=[
|
||||||
'copy-overlay',
|
'copy-overlay',
|
||||||
'modules',
|
'modules',
|
||||||
'userland',
|
'userland',
|
||||||
'buildroot',
|
'buildroot',
|
||||||
]),
|
]),
|
||||||
|
'qemu-baremetal': Component(dependencies=[
|
||||||
|
'qemu',
|
||||||
|
'crosstool-ng',
|
||||||
|
'baremetal-qemu',
|
||||||
|
]),
|
||||||
'qemu-buildroot': Component(dependencies=[
|
'qemu-buildroot': Component(dependencies=[
|
||||||
'qemu',
|
'qemu',
|
||||||
'buildroot-gcc',
|
'buildroot-gcc',
|
||||||
@@ -116,10 +157,6 @@ name_to_component_map = {
|
|||||||
'release': Component(dependencies=[
|
'release': Component(dependencies=[
|
||||||
'qemu-buildroot',
|
'qemu-buildroot',
|
||||||
]),
|
]),
|
||||||
'all': Component(dependencies=[
|
|
||||||
'all-linux',
|
|
||||||
'baremetal',
|
|
||||||
])
|
|
||||||
}
|
}
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description= '''\
|
description= '''\
|
||||||
@@ -168,11 +205,11 @@ parser.add_argument('--all', default=False, action='store_true', help='''\
|
|||||||
Build absolutely everything for all archs.
|
Build absolutely everything for all archs.
|
||||||
''')
|
''')
|
||||||
group = parser.add_mutually_exclusive_group(required=False)
|
group = parser.add_mutually_exclusive_group(required=False)
|
||||||
group.add_argument('--all-archs', default=False, action='store_true', help='''\
|
group.add_argument('-A', '--all-archs', default=False, action='store_true', help='''\
|
||||||
Build the selected components for all archs.
|
Build the selected components for all archs.
|
||||||
''')
|
''')
|
||||||
group.add_argument('--arch', choices=common.arch_choices, default=[], action='append', help='''\
|
group.add_argument('-a', '--arch', choices=common.arch_choices, default=[], action='append', help='''\
|
||||||
Build the selected components for this arch. Select multiple arches by
|
Build the selected components for this arch. Select multiple archs by
|
||||||
passing this option multiple times. Default: [{}]
|
passing this option multiple times. Default: [{}]
|
||||||
'''.format(common.default_arch))
|
'''.format(common.default_arch))
|
||||||
parser.add_argument('--extra-args', default='', help='''\
|
parser.add_argument('--extra-args', default='', help='''\
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import common
|
|||||||
|
|
||||||
class BaremetalComponent(common.Component):
|
class BaremetalComponent(common.Component):
|
||||||
def do_build(self, args):
|
def do_build(self, args):
|
||||||
common.raise_no_x86(args.arch)
|
common.assert_crosstool_ng_supports_arch(args.arch)
|
||||||
build_dir = self.get_build_dir(args)
|
build_dir = self.get_build_dir(args)
|
||||||
bootloader_obj = os.path.join(common.baremetal_build_lib_dir, 'bootloader{}'.format(common.obj_ext))
|
bootloader_obj = os.path.join(common.baremetal_build_lib_dir, 'bootloader{}'.format(common.obj_ext))
|
||||||
common_obj = os.path.join(common.baremetal_build_lib_dir, 'common{}'.format(common.obj_ext))
|
common_obj = os.path.join(common.baremetal_build_lib_dir, 'common{}'.format(common.obj_ext))
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import common
|
|||||||
|
|
||||||
class CrosstoolNgComponent(common.Component):
|
class CrosstoolNgComponent(common.Component):
|
||||||
def do_build(self, args):
|
def do_build(self, args):
|
||||||
common.raise_no_x86(args.arch)
|
common.assert_crosstool_ng_supports_arch(args.arch)
|
||||||
build_dir = self.get_build_dir(args)
|
build_dir = self.get_build_dir(args)
|
||||||
defconfig_dest = os.path.join(common.crosstool_ng_util_dir, 'defconfig')
|
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_util_dir, exist_ok=True)
|
||||||
|
|||||||
13
build-test
Executable file
13
build-test
Executable file
@@ -0,0 +1,13 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -eu
|
||||||
|
test_size=1
|
||||||
|
while [ $# -gt 0 ]; do
|
||||||
|
case "$1" in
|
||||||
|
--size)
|
||||||
|
test_size="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
./build-bench-boot --size "$test_size"
|
||||||
|
./build-test-gdb
|
||||||
2
build-test-gdb
Executable file
2
build-test-gdb
Executable file
@@ -0,0 +1,2 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
./build --all-archs all-baremetal
|
||||||
@@ -41,6 +41,7 @@ include_src_dir = os.path.join(this_module.root_dir, this_module.include_subdir)
|
|||||||
submodules_dir = os.path.join(root_dir, 'submodules')
|
submodules_dir = os.path.join(root_dir, 'submodules')
|
||||||
buildroot_src_dir = os.path.join(submodules_dir, 'buildroot')
|
buildroot_src_dir = os.path.join(submodules_dir, 'buildroot')
|
||||||
crosstool_ng_src_dir = os.path.join(submodules_dir, 'crosstool-ng')
|
crosstool_ng_src_dir = os.path.join(submodules_dir, 'crosstool-ng')
|
||||||
|
crosstool_ng_supported_archs = set(['arm', 'aarch64'])
|
||||||
linux_src_dir = os.path.join(submodules_dir, 'linux')
|
linux_src_dir = os.path.join(submodules_dir, 'linux')
|
||||||
linux_config_dir = os.path.join(this_module.root_dir, 'linux_config')
|
linux_config_dir = os.path.join(this_module.root_dir, 'linux_config')
|
||||||
rootfs_overlay_dir = os.path.join(this_module.root_dir, 'rootfs_overlay')
|
rootfs_overlay_dir = os.path.join(this_module.root_dir, 'rootfs_overlay')
|
||||||
@@ -169,6 +170,10 @@ def add_newlines(cmd):
|
|||||||
out.extend([arg, this_module.Newline])
|
out.extend([arg, this_module.Newline])
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
def assert_crosstool_ng_supports_arch(arch):
|
||||||
|
if arch not in this_module.crosstool_ng_supported_archs:
|
||||||
|
raise Exception('arch not yet supported: ' + arch)
|
||||||
|
|
||||||
def base64_encode(string):
|
def base64_encode(string):
|
||||||
return base64.b64encode(string.encode()).decode()
|
return base64.b64encode(string.encode()).decode()
|
||||||
|
|
||||||
@@ -555,10 +560,6 @@ def raw_to_qcow2(prebuilt=False, reverse=False):
|
|||||||
outfile, this_module.Newline,
|
outfile, this_module.Newline,
|
||||||
])
|
])
|
||||||
|
|
||||||
def raise_no_x86(arch):
|
|
||||||
if (arch == 'x86_64'):
|
|
||||||
raise Exception('x86_64 not yet supported')
|
|
||||||
|
|
||||||
def resolve_args(defaults, args, extra_args):
|
def resolve_args(defaults, args, extra_args):
|
||||||
if extra_args is None:
|
if extra_args is None:
|
||||||
extra_args = {}
|
extra_args = {}
|
||||||
|
|||||||
@@ -99,11 +99,18 @@ g++-arm-linux-gnueabihf \
|
|||||||
git \
|
git \
|
||||||
libguestfs-tools \
|
libguestfs-tools \
|
||||||
moreutils \
|
moreutils \
|
||||||
|
python3-pip \
|
||||||
rsync \
|
rsync \
|
||||||
tmux \
|
tmux \
|
||||||
unzip \
|
unzip \
|
||||||
vinagre \
|
vinagre \
|
||||||
wget \
|
wget \
|
||||||
|
"
|
||||||
|
# gem5 users Python 2.
|
||||||
|
pip2_pkgs="\
|
||||||
|
"
|
||||||
|
pip3_pkgs="\
|
||||||
|
pexpect==4.6.0 \
|
||||||
"
|
"
|
||||||
if "$gem5"; then
|
if "$gem5"; then
|
||||||
pkgs="${pkgs}\
|
pkgs="${pkgs}\
|
||||||
@@ -114,6 +121,9 @@ protobuf-compiler \
|
|||||||
python-dev \
|
python-dev \
|
||||||
python-pip \
|
python-pip \
|
||||||
scons \
|
scons \
|
||||||
|
"
|
||||||
|
pip2_pkgs="${pip2_pkgs}\
|
||||||
|
pydot \
|
||||||
"
|
"
|
||||||
fi
|
fi
|
||||||
if "$baremetal"; then
|
if "$baremetal"; then
|
||||||
@@ -171,12 +181,13 @@ EOF
|
|||||||
if "$qemu"; then
|
if "$qemu"; then
|
||||||
$mysudo apt-get build-dep $y qemu
|
$mysudo apt-get build-dep $y qemu
|
||||||
fi
|
fi
|
||||||
if "$gem5"; then
|
|
||||||
# Generate graphs of config.ini under m5out.
|
# Generate graphs of config.ini under m5out.
|
||||||
# Not with pip directly:
|
# Not with pip directly:
|
||||||
# https://stackoverflow.com/questions/49836676/error-after-upgrading-pip-cannot-import-name-main/51846054#51846054
|
# https://stackoverflow.com/questions/49836676/error-after-upgrading-pip-cannot-import-name-main/51846054#51846054
|
||||||
python -m pip install --user pydot
|
if "$gem5"; then
|
||||||
|
python -m pip install --user $pip2_pkgs
|
||||||
fi
|
fi
|
||||||
|
python3 -m pip install --user $pip3_pkgs
|
||||||
fi
|
fi
|
||||||
|
|
||||||
## Submodules
|
## Submodules
|
||||||
|
|||||||
Reference in New Issue
Block a user