move all our stuff into /lkmc in guest

Motivation: userland is getting several new subdirectories, it would be
too insane to just dump all of that in the guest root filesystem.

To alleviate the cd pain, .profile puts user inside /lkmc by default.
This commit is contained in:
Ciro Santilli 六四事件 法轮功
2019-05-05 00:00:00 +00:00
parent 42f8de774a
commit 146e568db8
63 changed files with 369 additions and 338 deletions

4
.gitignore vendored
View File

@@ -2,8 +2,8 @@
*.tmp
tmp.*
*~
?*.gitignore
gitignore*
*.gitignore
gitignore.*
# Specific files.
/data

File diff suppressed because it is too large Load Diff

View File

@@ -209,7 +209,7 @@ Run `make modules_install` after `make`.
(
common_make_args +
[
'INSTALL_MOD_PATH={}'.format(self.env['out_rootfs_overlay_dir']), LF,
'INSTALL_MOD_PATH={}'.format(self.env['out_rootfs_overlay_lkmc_dir']), LF,
'modules_install', LF,
]
),

View File

@@ -108,7 +108,7 @@ Place the modules on a separate magic directory from non --host builds.
if not self.env['host']:
self.sh.copy_dir_if_update_non_recursive(
srcdir=self.env['kernel_modules_build_subdir'],
destdir=self.env['out_rootfs_overlay_dir'],
destdir=self.env['out_rootfs_overlay_lkmc_dir'],
filter_ext=self.env['kernel_module_ext'],
)

View File

@@ -335,7 +335,7 @@ Default: build all examples that have their package dependencies met, e.g.:
return 1
self.sh.copy_dir_if_update(
srcdir=build_dir,
destdir=self.env['out_rootfs_overlay_dir'],
destdir=self.env['out_rootfs_overlay_lkmc_dir'],
filter_ext=self.env['userland_build_ext'],
)
return 0

View File

@@ -724,8 +724,12 @@ Valid emulators: {}
env['kernel_modules_build_subdir'] = join(env['kernel_modules_build_dir'], env['kernel_modules_subdir'])
env['kernel_modules_build_host_dir'] = join(env['kernel_modules_build_base_dir'], 'host')
env['kernel_modules_build_host_subdir'] = join(env['kernel_modules_build_host_dir'], env['kernel_modules_subdir'])
# Overlay.
env['out_rootfs_overlay_dir'] = join(env['out_dir'], 'rootfs_overlay', env['arch'])
env['out_rootfs_overlay_bin_dir'] = join(env['out_rootfs_overlay_dir'], 'bin')
env['out_rootfs_overlay_lkmc_dir'] = join(env['out_rootfs_overlay_dir'], 'lkmc')
env['out_rootfs_overlay_bin_dir'] = join(env['out_rootfs_overlay_lkmc_dir'], 'bin')
env['guest_lkmc_home'] = os.sep + 'lkmc'
# Baremetal.
env['baremetal_source_dir'] = join(env['root_dir'], 'baremetal')

View File

@@ -15,12 +15,9 @@ https://github.com/cirosantilli/linux-kernel-module-cheat#rootfs_overlay
''')
def build(self):
# TODO: print rsync equivalent, move into shell_helpers.
distutils.dir_util.copy_tree(
self.env['rootfs_overlay_dir'],
self.env['out_rootfs_overlay_dir'],
preserve_symlinks=True,
update=1,
self.sh.copy_dir_if_update(
srcdir=self.env['rootfs_overlay_dir'],
destdir=self.env['out_rootfs_overlay_dir'],
)
if __name__ == '__main__':

4
rootfs_overlay/.profile Normal file
View File

@@ -0,0 +1,4 @@
# https://github.com/cirosantilli/linux-kernel-module-cheat#busybox-shell-initrc-files
echo "hello .profile"
export PS1='\w\n\u@\h# '
cd /lkmc

View File

@@ -1,2 +0,0 @@
#!/bin/sh
zcat /proc/config.gz | grep -Ei "${1:-}"

View File

@@ -1,5 +1,7 @@
#!/bin/sh
# https://github.com/cirosantilli/linux-kernel-module-cheat#init-busybox
echo "hello S98"
cd "$lkmc_home"
if [ -n "$lkmc_eval" ]; then
eval "$lkmc_eval"
elif [ -n "$lkmc_eval_base64" ]; then

View File

@@ -1,18 +0,0 @@
#!/bin/sh
echo "$lkmc_eval"
eval "$lkmc_eval"
# Ideally, this script would do just:
#
## Get rid of the '-'.
#shift
#echo "$@"
#
# However, the kernel CLI parsing is crap, and the 4.14 docs lie.
#
# In particular, not all that is passed after "-" goes to an argument to init,
# e.g. stuff with dots like "- ./poweroff.out" still gets treated specially and
# does not go to init.
#
# This also likely means that the above solution is also unreliable in some cases,
# and that in the end you just have to add a script to the root filesystem.

View File

@@ -1,2 +0,0 @@
#!/bin/sh
eval "$(printf "$lkmc_eval" | base64 -d)"

3
rootfs_overlay/lkmc/conf.sh Executable file
View File

@@ -0,0 +1,3 @@
#!/bin/sh
# https://github.com/cirosantilli/linux-kernel-module-cheat#find-the-kernel-config
zcat /proc/config.gz | grep -Ei "${1:-}"

View File

@@ -1,4 +1,5 @@
#!/bin/sh
# Count to infinity with 1 second sleep between each increment.
# Generate infinitely many system calls :-)
i=0
while true; do

View File

@@ -0,0 +1,4 @@
#!/bin/sh
# https://github.com/cirosantilli/linux-kernel-module-cheat#replace-init
cd "$lkmc_home"
eval "$(printf "$lkmc_eval" | base64 -d)"

View File

@@ -0,0 +1,3 @@
#!/bin/sh
# https://github.com/cirosantilli/linux-kernel-module-cheat#tty
exec /bin/login root

View File

@@ -20,7 +20,7 @@ for test in \
; do
if ! "${test_dir}/${test}"; then
echo "Test failed: ${test}"
test_fail.sh
./test_fail.sh
exit 1
fi
done

View File

@@ -1,2 +0,0 @@
#!/bin/sh
exec /bin/login root

View File

@@ -1,4 +0,0 @@
# https://unix.stackexchange.com/questions/176027/ash-profile-configuration-file
echo "hello $(pwd)/.profile"
# Does not inherit init environment variables.
#env

84
run
View File

@@ -58,15 +58,8 @@ which is what you usually want.
help='''\
Replace the normal init with a minimal init that just evals the given string.
See: https://github.com/cirosantilli/linux-kernel-module-cheat#replace-init
'''
)
self.add_argument(
'--kernel-cli',
help='''\
Pass an extra Linux kernel command line options, and place them before
the dash separator `-`. Only options that come before the `-`, i.e.
"standard" options, should be passed with this option.
Example: `./run --arch arm --kernel-cli 'init=/poweroff.out'`
chdir into lkmc_home before running the command:
https://github.com/cirosantilli/linux-kernel-module-cheat#lkmc_home
'''
)
self.add_argument(
@@ -75,16 +68,8 @@ Example: `./run --arch arm --kernel-cli 'init=/poweroff.out'`
Pass a base64 encoded command line parameter that gets evalled at the end of
the normal init.
See: https://github.com/cirosantilli/linux-kernel-module-cheat#init-busybox
'''
)
self.add_argument(
'--kernel-cli-after-dash',
help='''\
Pass an extra Linux kernel command line options, add a dash `-`
separator, and place the options after the dash. Intended for custom
options understood by our `init` scripts, most of which are prefixed
by `lkmc_`.
Example: `./run --kernel-cli-after-dash 'lkmc_eval="wget google.com" lkmc_lala=y'`
chdir into lkmc_home before running the command:
https://github.com/cirosantilli/linux-kernel-module-cheat#lkmc_home
'''
)
self.add_argument(
@@ -108,16 +93,6 @@ gem.op5 --debug-flags=Exec fs.py --cpu-type=HPI --caches
'--gem5-readfile', default='',
help='Set the contents of m5 readfile to this string.'
)
self.add_argument(
'-K', '--kvm', default=False,
help='Use KVM. Only works if guest arch == host arch'
)
self.add_argument(
'--kgdb', default=False,
)
self.add_argument(
'--kdb', default=False,
)
self.add_argument(
'--gem5-restore', type=int,
help='''\
@@ -125,6 +100,35 @@ Restore the nth most recently taken gem5 checkpoint according to directory
timestamps.
'''
)
self.add_argument(
'--kdb', default=False,
)
self.add_argument(
'--kernel-cli',
help='''\
Pass an extra Linux kernel command line options, and place them before
the dash separator `-`. Only options that come before the `-`, i.e.
"standard" options, should be passed with this option.
Example: `./run --arch arm --kernel-cli 'init=/poweroff.out'`
'''
)
self.add_argument(
'--kernel-cli-after-dash',
help='''\
Pass an extra Linux kernel command line options, add a dash `-`
separator, and place the options after the dash. Intended for custom
options understood by our `init` scripts, most of which are prefixed
by `lkmc_`.
Example: `./run --kernel-cli-after-dash 'lkmc_eval="wget google.com" lkmc_lala=y'`
'''
)
self.add_argument(
'--kgdb', default=False,
)
self.add_argument(
'-K', '--kvm', default=False,
help='Use KVM. Only works if guest arch == host arch'
)
self.add_argument(
'-m', '--memory', default='256M',
help='''\
@@ -149,6 +153,15 @@ Setup a kernel init parameter that makes the emulator quit immediately after boo
'-r', '--record', default=False,
help='Record a QEMU run record for later replay with `-R`'
)
self.add_argument(
'--terminal', default=False,
help='''\
Output to the terminal, don't pipe to tee as the default.
Does not save the output to a file, but allows you to use debuggers.
Set automatically by --debug-vm, but you still need this option to debug
gem5 Python scripts with pdb.
'''
)
self.add_argument(
'-T', '--trace',
help='''\
@@ -171,15 +184,6 @@ Output trace to stdout instead of a file. Only works for gem5 currently.
default=False,
help='''\
Trace instructions run to stdout. Shortcut for --trace --trace-stdout.
'''
)
self.add_argument(
'--terminal', default=False,
help='''\
Output to the terminal, don't pipe to tee as the default.
Does not save the output to a file, but allows you to use debuggers.
Set automatically by --debug-vm, but you still need this option to debug
gem5 Python scripts with pdb.
'''
)
self.add_argument(
@@ -232,7 +236,7 @@ Run QEMU with VNC instead of the default SDL. Connect to it with:
kernel_cli += ' {}'.format(self.env['kernel_cli'])
if self.env['quit_after_boot']:
kernel_cli += ' {}'.format(self.env['quit_init'])
kernel_cli_after_dash = ''
kernel_cli_after_dash = ' lkmc_home={}'.format(self.env['guest_lkmc_home'])
extra_emulator_args = []
extra_qemu_args = []
if self.env['tmux_args'] is not None:
@@ -252,7 +256,7 @@ Run QEMU with VNC instead of the default SDL. Connect to it with:
else:
vnc = []
if self.env['eval'] is not None:
kernel_cli += ' {}=/eval_base64.sh'.format(self.env['initarg'])
kernel_cli += ' {}=/lkmc/eval_base64.sh'.format(self.env['initarg'])
kernel_cli_after_dash += ' lkmc_eval="{}"'.format(self.sh.base64_encode(self.env['eval']))
if not self.env['graphic']:
extra_qemu_args.extend(['-nographic', LF])

View File

@@ -124,12 +124,12 @@ class ShellHelpers:
os.makedirs(destdir, exist_ok=True)
for basename in sorted(os.listdir(srcdir)):
src = os.path.join(srcdir, basename)
if os.path.isfile(src):
if os.path.isfile(src) or os.path.islink(src):
noext, ext = os.path.splitext(basename)
dest = os.path.join(destdir, basename)
if (
(filter_ext is not None and ext == filter_ext) and
(os.path.exists(dest) and os.path.getmtime(src) > os.path.getmtime(dest))
(filter_ext is None or ext == filter_ext) and
(not os.path.exists(dest) or os.path.getmtime(src) > os.path.getmtime(dest))
):
self.cp(src, dest)
@@ -151,7 +151,13 @@ class ShellHelpers:
def cp(self, src, dest, **kwargs):
self.print_cmd(['cp', src, dest])
if not self.dry_run:
shutil.copy2(src, dest)
if os.path.islink(src):
if os.path.lexists(dest):
os.unlink(dest)
linkto = os.readlink(src)
os.symlink(linkto, dest)
else:
shutil.copy2(src, dest)
def print_cmd(self, cmd, cwd=None, cmd_file=None, extra_env=None, extra_paths=None):
'''

17
userland/c/false.c Normal file
View File

@@ -0,0 +1,17 @@
/* Exit with status 1.
*
* Can be uesd to test that emulators forward the exit status properly.
* https://github.com/cirosantilli/linux-kernel-module-cheat#gem5-syscall-emulation-exit-status
*/
#include <stdlib.h>
int main(int argc, char **argv) {
int ret;
if (argc == 1) {
ret = 1;
} else {
ret = strtoull(argv[1], NULL, 0);
}
return ret;
}

View File

@@ -1,3 +1,5 @@
/* Count to infinity with 1 second sleep between each increment. */
#define _XOPEN_SOURCE 700
#include <limits.h>
#include <stdio.h>

View File

@@ -1,13 +0,0 @@
/* Test that emulators forward the exit status properly. */
#include <stdlib.h>
int main(int argc, char **argv) {
int ret;
if (argc == 1) {
ret = 1;
} else {
ret = strtoull(argv[1], NULL, 0);
}
return ret;
}