initfamfs: bring back to life. Was also easy!

This commit is contained in:
Ciro Santilli 六四事件 法轮功
2019-01-22 00:00:00 +00:00
parent cf662c4ab0
commit 3d02878c21
7 changed files with 49 additions and 37 deletions

View File

@@ -2617,6 +2617,8 @@ cat "$(./getvar run_dir)/run.sh"
Instead, we used the QEMU `-initrd` option to point to the `.cpio` filesystem that Buildroot generated for us.
Try removing that `-initrd` option to watch the kernel panic without rootfs at the end of boot.
When using `.cpio`, there can be no filesystem persistency across boots, since all file operations happen in memory in a tmpfs:
....
@@ -2674,25 +2676,25 @@ Related: https://stackoverflow.com/questions/6405083/initrd-and-booting-the-linu
TODO: broken when we started building the Linux manually with `./build-linux` instead of Buildroot. Was working before, see e.g. 56738a1c70e50bf7b6d5fbe02372c5d277a8286f.
initramfs is just like <<initrd>>, but you also glue the image directly to the kernel image itself.
So the only argument that QEMU needs is the `-kernel`, no `-drive` not even `-initrd`! Pretty cool.
initramfs is just like <<initrd>>, but you also glue the image directly to the kernel image itself using the kernel's build system.
Try it out with:
....
./build-buildroot --initramfs -l
./run --initramfs
....
The `-l` (ell) should only be used the first time you move to / from a different root filesystem method (ext2 or cpio) to initramfs to overcome: https://stackoverflow.com/questions/49260466/why-when-i-change-br2-linux-kernel-custom-config-file-and-run-make-linux-reconfi
....
./build-buildroot --initramfs
./build-linux --initramfs
./run --initramfs
....
It is interesting to see how this increases the size of the kernel image if you do a:
Notice how we had to rebuild the Linux kernel this time around as well after Buildroot, since in that build we will be gluing the CPIO to the kernel image.
Now, once again, if we look at the QEMU run command generated, we see all that QEMU needs is the `-kernel` option, no `-drive` not even `-initrd`! Pretty cool:
....
cat "$(./getvar run_dir)/run.sh"
....
It is also interesting to observe how this increases the size of the kernel image if you do a:
....
ls -lh "$(./getvar linux_image)"
@@ -2700,7 +2702,16 @@ ls -lh "$(./getvar linux_image)"
before and after using initramfs, since the `.cpio` is now glued to the kernel image.
In the background, it uses `BR2_TARGET_ROOTFS_INITRAMFS`, and this makes the kernel config option `CONFIG_INITRAMFS_SOURCE` point to the CPIO that will be embedded in the kernel image.
Don't forget that to stop using initramfs, you must rebuild the kernel without `--initramfs`:
....
./build-linux
./run
....
Also consider using <<linux-kernel-build-variants>> if you need to switch between initramfs and non initramfs often.
Setting up initramfs is very easy: our scripts just set `CONFIG_INITRAMFS_SOURCE` to point to the CPIO path.
http://nairobi-embedded.org/initramfs_tutorial.html shows a full manual setup.
@@ -5415,10 +5426,10 @@ Where the data comes from and how to modify it:
In this repo, leaking host information, and to make builds more reproducible, we are setting:
- user and date to dummy values
- hostname to the kernel git commit
- user and date to dummy values with `KBUILD_BUILD_USER` and `KBUILD_BUILD_TIMESTAMP`
- hostname to the kernel git commit with `KBUILD_BUILD_HOST` and `KBUILD_BUILD_VERSION`
So the file contains something like:
A sample result is:
....
Linux version 4.19.0-dirty (lkmc@84df9525b0c27f3ebc2ebb1864fa62a97fdedb7d) (gcc version 6.4.0 (Buildroot 2018.05-00002-gbc60382b8f)) #1 SMP Thu Jan 1 00:00:00 UTC 1970

View File

@@ -133,7 +133,7 @@ usually extra Buildroot targets.
config_fragments = [
os.path.join(self.env['root_dir'], 'buildroot_config', 'default')
] + self.env['config_fragment']
if self.env['initrd']:
if self.env['initrd'] or self.env['initramfs']:
configs.append('BR2_TARGET_ROOTFS_CPIO=y')
# TODO Can't get rid of these for now with nice fragments on Buildroot:
# http://stackoverflow.com/questions/44078245/is-it-possible-to-use-config-fragments-with-buildroots-config

View File

@@ -64,8 +64,6 @@ Run `make modules_install` after `make`.
def build(self):
build_dir = self.get_build_dir()
if self.env['initrd'] or self.env['initramfs']:
raise Exception('just trolling, --initrd and --initramfs are broken for now')
os.makedirs(build_dir, exist_ok=True)
tool = 'gcc'
gcc = self.get_toolchain_tool(tool)
@@ -105,10 +103,12 @@ Run `make modules_install` after `make`.
for i, config_fragment in enumerate(config_fragments):
config_fragments[i] = os.path.join(self.env['linux_config_dir'], config_fragment)
config_fragments.extend(self.env['config_fragment'])
if self.env['config'] != []:
cli_configs = self.env['config']
if self.env['initramfs']:
cli_configs.append('CONFIG_INITRAMFS_SOURCE="{}"'.format(self.env['buildroot_cpio']))
if cli_configs:
cli_config_fragment_path = os.path.join(build_dir, 'lkmc_cli_config_fragment')
cli_config_str = '\n'.join(self.env['config'])
self.sh.write_string_to_file(cli_config_fragment_path, cli_config_str)
self.sh.write_configs(cli_config_fragment_path, cli_configs, mode='w')
config_fragments.append(cli_config_fragment_path)
self.sh.cp(
base_config_file,
@@ -136,6 +136,7 @@ Run `make modules_install` after `make`.
common_make_args +
self.sh.add_newlines(self.env['extra_make_args'])
),
# https://github.com/cirosantilli/linux-kernel-module-cheat#proc-version
extra_env={
'KBUILD_BUILD_VERSION': '1',
'KBUILD_BUILD_TIMESTAMP': 'Thu Jan 1 00:00:00 UTC 1970',

View File

@@ -255,14 +255,16 @@ Use the given directory as the Linux source tree.
'''
)
self.add_argument(
'--initramfs', default=False,
'--initramfs',
default=False,
)
self.add_argument(
'--initrd',
default=False,
help='''\
Make Buildroot create a CPIO root filessytem, and make QEMU use it instead of
the default ext2.
For Buildroot: create a CPIO root filessytem.
For QEMU use that CPUI root filesystem initrd instead of the default ext2.
See: https://github.com/cirosantilli/linux-kernel-module-cheat#initrd
'''
)
@@ -477,6 +479,7 @@ Valid emulators: {}
env['buildroot_images_dir'] = join(env['buildroot_build_dir'], 'images')
env['buildroot_rootfs_raw_file'] = join(env['buildroot_images_dir'], 'rootfs.ext2')
env['buildroot_qcow2_file'] = env['buildroot_rootfs_raw_file'] + '.qcow2'
env['buildroot_cpio'] = join(self.env['buildroot_images_dir'], 'rootfs.cpio')
env['staging_dir'] = join(env['out_dir'], 'staging', env['arch'])
env['buildroot_staging_dir'] = join(env['buildroot_build_dir'], 'staging')
env['target_dir'] = join(env['buildroot_build_dir'], 'target')
@@ -601,6 +604,7 @@ Valid emulators: {}
else:
env['userland_quit_cmd'] = '/poweroff.out'
env['quit_init'] = 'init={}'.format(env['userland_quit_cmd'])
self.env['ramfs'] = self.env['initrd'] or self.env['initramfs']
# Kernel modules.
env['kernel_modules_build_dir'] = join(env['kernel_modules_build_base_dir'], env['arch'])

View File

@@ -10,7 +10,7 @@ cmd="./run --arch '$arch' --emulator 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=64kB --l1i_size=64kB --l2_size=256kB'
restore='--gem5-restore 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.

12
run
View File

@@ -117,7 +117,7 @@ gem.op5 --debug-flags=Exec fs.py --cpu-type=HPI --caches
'--kdb', default=False,
)
self.add_argument(
'-l', '--gem5-restore', type=int,
'--gem5-restore', type=int,
help='''\
Restore the nth most recently taken gem5 checkpoint according to directory
timestamps.
@@ -231,12 +231,8 @@ Run QEMU with VNC instead of the default SDL. Connect to it with:
vnc = ['-vnc', ':0', LF]
else:
vnc = []
if self.env['initrd'] or self.env['initramfs']:
ramfs = True
else:
ramfs = False
if self.env['eval'] is not None:
if ramfs:
if self.env['ramfs']:
initarg = 'rdinit'
else:
initarg = 'init'
@@ -504,9 +500,9 @@ Run QEMU with VNC instead of the default SDL. Connect to it with:
if not qemu_executable_prebuilt:
cmd.extend(qemu_user_and_system_options)
if self.env['initrd']:
extra_emulator_args.extend(['-initrd', os.path.join(self.env['buildroot_images_dir'], 'rootfs.cpio')])
extra_emulator_args.extend(['-initrd', self.env['buildroot_cpio'], LF])
rr = self.env['record'] or self.env['replay']
if ramfs:
if self.env['ramfs']:
# TODO why is this needed, and why any string works.
root = 'root=/dev/anything'
else:

View File

@@ -269,9 +269,9 @@ class ShellHelpers:
else:
os.unlink(path)
def write_configs(self, config_path, configs, config_fragments=None):
def write_configs(self, config_path, configs, config_fragments=None, mode='a'):
'''
Write extra KEY=val configs into the given config file.
Append extra KEY=val configs into the given config file.
'''
if config_fragments is None:
config_fragments = []
@@ -283,7 +283,7 @@ class ShellHelpers:
with open(config_fragment, 'r') as config_fragment_file:
for line in config_fragment_file:
config_file.write(line)
self.write_string_to_file(config_path, '\n'.join(configs), mode='a')
self.write_string_to_file(config_path, '\n'.join(configs), mode=mode)
def write_string_to_file(self, path, string, mode='w'):
if mode == 'a':
@@ -292,5 +292,5 @@ class ShellHelpers:
redirect = '>'
self.print_cmd("cat << 'EOF' {} {}\n{}\nEOF".format(redirect, path, string))
if not self.dry_run:
with open(path, 'a') as f:
with open(path, mode) as f:
f.write(string)