Skip to content

Commit e2f36b5

Browse files
committed
prebuilt: attempt gem5 a bit further, but stop at the vmlinux step
1 parent 762bb78 commit e2f36b5

File tree

4 files changed

+80
-23
lines changed

4 files changed

+80
-23
lines changed

README.adoc

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ The design goals are to provide setups that are:
4141
* highly automated: "just works"
4242
* thoroughly documented: you know what "just works" means
4343
* can be fully built from source: to give visibility and allow modifications
44-
* can also use prebuilt binaries as much as possible: in case you are lazy or unable to build from source
44+
* can also use <<prebuilt, prebuilt binaries>> as much as possible: in case you are lazy or unable to build from source
4545

4646
== Getting started
4747

@@ -522,17 +522,24 @@ Our prebuilts currently include:
522522
* Linux kernel
523523
* root filesystem
524524

525-
Advantages: saves time and disk space.
525+
Advantage: saves time and disk space on the initial install.
526526

527-
Limitations:
527+
The limitations are severe however:
528528

529529
* can't <<gdb,GDB step debug the kernel>>, since the source and cross toolchain with GDB are not available. Buildroot cannot easily use a host toolchain: <<prebuilt-toolchain>>.
530530
+
531531
Maybe we could work around this by just downloading the kernel source somehow, and using a host prebuilt GDB, but we felt that it would be too messy and unreliable.
532532
* can't create new modules or modify the existing ones, since no cross toolchain
533-
* can't use things that rely on our QEMU fork, e.g. in-fork <<device-models>> or <<tracing>>
534533
* you won't get the latest version of this repository. Our <<travis>> attempt to automate builds failed, and storing a release for every commit would likely make GitHub mad at us.
535-
* <<gem5>> is not currently supported, although it should not be too hard to do. One annoyance is that there is no Debian package for it, so you have to compile your own, so you might as well just build the image itself.
534+
* <<gem5>> is not currently supported, although it should not be too hard to do.
535+
+
536+
Annoyances:
537+
+
538+
** there is no Debian package for it, so you have to compile your own, so you might as well just build the image itself
539+
** it does not handle <<gem5-qcow2,qcow2>>, and we haven't gotten <<squashfs>> to work yet, therefore we would have to either distribute large ext2 images, or constantly fight with <<br2_target_rootfs_ext2_size>>
540+
** QEMU uses bzImage and gdm5 the raw `vmlinux`, and we don't want to distribute the same thing twice... https://github.com/torvalds/linux/blob/master/scripts/extract-vmlinux We could use `extract-vmlinux`, but that would imply cloning the Linux kernel, which is at least half of the kernel build time :-)
541+
542+
This setup might be good enough for those developing simulators, as that requires less image modification. But once again, if you are serious about this, why not just let your computer build the <<qemu-buildroot-setup,full featured setup>> while you take a coffee or a nap? :-)
536543

537544
==== Prebuilt setup getting started
538545

@@ -562,18 +569,32 @@ git submodule update --init "$(./getvar qemu_src_dir)"
562569

563570
and you are done.
564571

565-
Alternatively, you can also try to use the host QEMU:
572+
Alternatively, you can also try to use the host QEMU directly with:
566573

567574
....
568-
sudo apt-get install qemu-system-x86
575+
sudo apt-get install qemu-system-x86 qemu-utils
569576
./run --prebuilt
570577
....
571578

572579
but QEMU builds are pretty quick, and this further increases the probability of incompatibilities, are you really that lazy?
573580

581+
////
582+
For gem5, do:
583+
584+
....
585+
sudo apt-get install qemu-utils
586+
./build-gem5
587+
./run --gem5 --prebuilt
588+
....
589+
590+
`qemu-utils` is required because we currently distribute `.qcow2` files which <<gem5-qcow2,gem5 can't handle>>, so we need `qemu-img` to extract them first.
591+
////
592+
574593
[[host]]
575594
=== Host kernel module setup
576595

596+
**THIS IS DANGEROUS, YOU HAVE BEEN WARNED**
597+
577598
This method runs the kernel modules directly on your host computer without a VM, and saves you the compilation time and disk usage of the virtual machine method.
578599

579600
It has however severe limitations, and you will soon see that the compilation time and disk usage are well worth it:
@@ -6488,8 +6509,12 @@ index 17498c42b..76b8b351d 100644
64886509

64896510
The directory of interest is `src/dev/storage`.
64906511

6512+
=== gem5 qcow2
6513+
64916514
qcow2 does not appear supported, there are not hits in the source tree, and there is a mention on Nate's 2009 wishlist: http://gem5.org/Nate%27s_Wish_List
64926515

6516+
This would be good to allow storing smaller sparse ext2 images locally on disk.
6517+
64936518
=== Snapshot
64946519

64956520
QEMU allows us to take snapshots at any time through the monitor.

common.py

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -219,16 +219,32 @@ def print_time(ellapsed_seconds):
219219
minutes, seconds = divmod(rem, 60)
220220
print("time {:02}:{:02}:{:02}".format(int(hours), int(minutes), int(seconds)))
221221

222-
def raw_to_qcow2():
222+
def raw_to_qcow2(prebuilt=False, reverse=False):
223223
global this
224+
if prebuilt:
225+
qemu_img_executable = this.qemu_img_basename
226+
else:
227+
qemu_img_executable = this.qemu_img_executable
228+
infmt = 'raw'
229+
outfmt = 'qcow2'
230+
infile = this.rootfs_raw_file
231+
outfile = this.qcow2_file
232+
if reverse:
233+
tmp = infmt
234+
infmt = outfmt
235+
outfmt = tmp
236+
tmp = infile
237+
infile = outfile
238+
outfile = tmp
224239
assert this.run_cmd([
225-
this.qemu_img_executable,
240+
qemu_img_executable,
241+
# Prevent qemu-img from generating trace files like QEMU. Disgusting.
226242
'-T', 'pr_manager_run,file=/dev/null',
227243
'convert',
228-
'-f', 'raw',
229-
'-O', 'qcow2',
230-
this.rootfs_raw_file,
231-
this.qcow2_file,
244+
'-f', infmt,
245+
'-O', outfmt,
246+
infile,
247+
outfile,
232248
]) == 0
233249

234250
def resolve_args(defaults, args, extra_args):
@@ -337,13 +353,15 @@ def setup(parser, **extra_args):
337353
this.linux_variant_dir = '{}.{}'.format(this.linux_build_dir, args.linux_build_id)
338354
this.vmlinux = os.path.join(this.linux_variant_dir, "vmlinux")
339355
this.qemu_build_dir = os.path.join(this.out_dir, 'qemu', args.qemu_build_id)
340-
this.qemu_executable = os.path.join(this.qemu_build_dir, '{}-softmmu'.format(args.arch), 'qemu-system-{}'.format(args.arch))
341-
this.qemu_img_executable = os.path.join(this.qemu_build_dir, 'qemu-img')
356+
this.qemu_executable_basename = 'qemu-system-{}'.format(args.arch)
357+
this.qemu_executable = os.path.join(this.qemu_build_dir, '{}-softmmu'.format(args.arch), this.qemu_executable_basename)
358+
this.qemu_img_basename = 'qemu-img'
359+
this.qemu_img_executable = os.path.join(this.qemu_build_dir, this.qemu_img_basename)
342360
this.qemu_guest_build_dir = os.path.join(this.build_dir, 'qemu-custom')
343361
this.host_dir = os.path.join(this.buildroot_build_dir, 'host')
344362
this.host_bin_dir = os.path.join(this.host_dir, 'usr', 'bin')
345363
this.images_dir = os.path.join(this.buildroot_build_dir, 'images')
346-
this.rootfs_raw_file = os.path.join(this.images_dir, 'rootfs.squashfs')
364+
this.rootfs_raw_file = os.path.join(this.images_dir, 'rootfs.ext2')
347365
this.qcow2_file = this.rootfs_raw_file + '.qcow2'
348366
this.staging_dir = os.path.join(this.buildroot_build_dir, 'staging')
349367
this.target_dir = os.path.join(this.buildroot_build_dir, 'target')

release

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ import common
77
zip_img = imp.load_source('zip_img', os.path.join(common.root_dir, 'zip-img'))
88

99
subprocess.check_call([os.path.join(common.root_dir, 'test')])
10+
# A clean release requires a full rebuild unless we hack it :-(
11+
# We can't just use our curent build as it contains packages we've
12+
# installed in random experiments. And with EXT2: we can't easily
13+
# know what the smallest root filesystem size is and use it either...
14+
# https://stackoverflow.com/questions/47320800/how-to-clean-only-target-in-buildroot
1015
subprocess.check_call([os.path.join(common.root_dir, 'build-all')])
1116
zip_img.main()
1217
tag = 'sha-{}'.format(common.sha)

run

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import os
44
import re
55
import shlex
6+
import shutil
67
import subprocess
78
import sys
89
import time
@@ -95,7 +96,14 @@ def main(args, extra_args=None):
9596
do_trace = True
9697
trace_type = args.trace
9798

99+
def raise_rootfs_not_found():
100+
raise Exception('Root filesystem not found. Did you build it?\n' \
101+
'Tried to use: ' + common.rootfs_raw_file)
98102
if args.gem5:
103+
if not os.path.exists(common.rootfs_raw_file):
104+
if not os.path.exists(common.qcow2_file):
105+
raise_rootfs_not_found()
106+
common.raw_to_qcow2(prebuilt=args.prebuilt, reverse=True)
99107
os.makedirs(os.path.dirname(common.gem5_readfile), exist_ok=True)
100108
with open(common.gem5_readfile, 'w') as readfile:
101109
readfile.write(args.gem5_readfile)
@@ -161,17 +169,18 @@ def main(args, extra_args=None):
161169
os.makedirs(common.run_dir, exist_ok=True)
162170
if args.prebuilt:
163171
common.mkdir()
164-
qemu_executable = "qemu-system-{}".format(args.arch)
172+
qemu_executable = common.qemu_executable_basename
173+
qemu_found = shutil.which(qemu_executable) is not None
165174
else:
166175
qemu_executable = common.qemu_executable
167-
if not os.path.exists(qemu_executable):
168-
raise Exception('QEMU executable does not exist, did you forget to build or install it?\n' \
176+
qemu_found = os.path.exists(qemu_executable)
177+
if not qemu_found:
178+
raise Exception('Could not find the QEMU executable, did you forget to build or install it?\n' \
169179
'Tried to use: ' + qemu_executable)
170180
if not os.path.exists(common.qcow2_file):
171181
if not os.path.exists(common.rootfs_raw_file):
172-
raise Exception('Root filesystem not found. Did you build it?\n' \
173-
'Tried to use: ' + common.rootfs_raw_file)
174-
common.raw_to_qcow2()
182+
raise_rootfs_not_found()
183+
common.raw_to_qcow2(prebuilt=args.prebuilt)
175184
if args.debug_vm:
176185
serial_monitor = []
177186
else:
@@ -401,7 +410,7 @@ Default: %(default)s
401410
)
402411
parser.add_argument(
403412
'-P', '--prebuilt', default=defaults['prebuilt'], action='store_true',
404-
help='Run the downloaded prebuilt images.'
413+
help='Run the downloaded prebuilt images with pre-packaged host tools.'
405414
)
406415
group = parser.add_mutually_exclusive_group()
407416
group.add_argument(

0 commit comments

Comments
 (0)