diff --git a/README.adoc b/README.adoc index 006a8b7..2cc9df7 100644 --- a/README.adoc +++ b/README.adoc @@ -521,9 +521,9 @@ After this, to start using Docker again will you need another: Tested on: a760cb1196161e913a94684e03cfeaebf71f0cdd [[prebuilt]] -=== Prebuilt setup +=== Prebuilt Buildroot setup -==== About the prebuilt setup +==== About the prebuilt Buildroot setup This setup uses prebuilt binaries of the <> that we upload to GitHub from time to time. @@ -556,7 +556,7 @@ run-detectors: unable to find an interpreter for 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 <> while you take a coffee or a nap? :-) -==== Prebuilt setup getting started +==== Prebuilt Buildroot setup getting started Some times it works with the host QEMU: @@ -620,6 +620,41 @@ sudo apt-get install qemu-utils The Linux kernel is required for `extract-vmlinux` to convert the compressed kernel image which QEMU understands into the raw vmlinux that gem5 understands: https://superuser.com/questions/298826/how-do-i-uncompress-vmlinuz-to-vmlinux //// +=== Ubuntu guest setup + +==== About the Ubuntu guest setup + +This setup is similar to <>, but it instead downloads an Ubuntu image with Docker, and uses that as the root filesystem. + +Advantages over Buildroot: + +* saves build time +* you get to play with a huge selection of Debian packages out of the box +* more representative of most non-embedded production systems than BusyBox + +Disadvantages: + +* less visibility: https://askubuntu.com/questions/82302/how-to-compile-ubuntu-from-source-code The fact that that question has no answer makes me cringe +* less compatibility, e.g. no one knows what the officially supported cross compilers are: https://askubuntu.com/questions/1046294/what-are-the-officially-supported-cross-compilers-for-ubuntu-server-alternative + +Docker is used here just as an image download provider since it has a wide variety of images. Why we don't just download the regular Ubuntu disk image: + +* that image is not ready to boot, but rather goes into an interactive installer: https://askubuntu.com/questions/884534/how-to-run-ubuntu-16-04-desktop-on-qemu/1046792#1046792 +* the default Ubuntu image has a large collection of software, and is large. The docker version is much more minimal. + +One alternative would be to use link:https://wiki.ubuntu.com/Base[Ubuntu base] which can be downloaded from: http://cdimage.ubuntu.com/ubuntu-base That provides a `.tgz` and comes very close to what we obtain with Docker, but without the need for `sudo`. + +==== Ubuntu guest setup getting started + +TODO + +.... +sudo ./build-docker +./run --docker +.... + +`sudo` is required for Docker operations: https://askubuntu.com/questions/477551/how-can-i-use-docker-without-sudo + [[host]] === Host kernel module setup @@ -9894,7 +9929,7 @@ collect2: error: ld returned 1 exit status .... + with the prebuilt toolchain, and I'm lazy to debug. -* there seems to to be no analogous `aarch64` Ubuntu package to `gcc-arm-none-eabi` +* there seems to to be no analogous `aarch64` Ubuntu package to `gcc-arm-none-eabi`: https://askubuntu.com/questions/1049249/is-there-a-package-with-the-aarch64-version-of-gcc-arm-none-eabi-for-bare-metal === C++ baremetal diff --git a/build-docker b/build-docker new file mode 100755 index 0000000..9ad7444 --- /dev/null +++ b/build-docker @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 + +import os + +import common +import subprocess +import tarfile +import time + +parser = common.get_argparse(argparse_args={ + 'description': '''\ +Build a guest root filesystem based on prebuilt Docker Ubuntu root filesystems. + +See also:https://github.com/cirosantilli/linux-kernel-module-cheat#ubuntu-guest-setup +''' + }, + default_args={'docker': True}, +) +common.add_build_arguments(parser) +args = common.setup(parser) +container_name = 'lkmc-guest' +#common.rmrf(common.docker_build_dir) +if not args.clean: + start_time = time.time() + target_dir = os.path.join('/root', 'linux-kernel-module-cheat') + os.makedirs(common.docker_build_dir, exist_ok=True) + containers = subprocess.check_output([ + 'docker', + 'ps', + '-a', + '--format', '{{.Names}}', + ]).decode() + if container_name in containers.split(): + assert common.run_cmd([ + 'docker', + 'rm', + container_name, + ]) == 0 + assert common.run_cmd([ + 'docker', + 'create', + '--name', container_name, + '--net', + 'host', + '-i', + '--privileged', + '-t', + '-w', target_dir, + '-v', '{}:{}'.format(common.root_dir, target_dir), + 'ubuntu:18.04', + 'bash', + ]) == 0 + assert common.run_cmd([ + 'docker', + 'export', + '-o', + common.docker_tar_file, + container_name, + ]) == 0 + tar = tarfile.open(common.docker_tar_file) + tar.extractall(common.docker_tar_dir) + tar.close() + # sudo not required in theory + # https://askubuntu.com/questions/1046828/how-to-run-libguestfs-tools-tools-such-as-virt-make-fs-without-sudo + assert common.run_cmd([ + 'virt-make-fs', + '--format', 'raw', + '--size', '+1G', + '--type', 'ext2', + common.docker_tar_dir, + common.docker_rootfs_raw_file, + ]) == 0 + common.raw_to_qcow2(prebuilt=True) + end_time = time.time() + common.print_time(end_time - start_time) diff --git a/build-modules b/build-modules index 89b86a4..4b1be8a 100755 --- a/build-modules +++ b/build-modules @@ -11,14 +11,18 @@ import time import common parser = common.get_argparse(argparse_args={ - 'description': 'Build our Linux kernel module examples' + 'description': '''\ +Build our Linux kernel module without using Buildroot. + +See also:https://github.com/cirosantilli/linux-kernel-module-cheat#host +''' }) common.add_build_arguments(parser) parser.add_argument( '--host', action='store_true', default=False, - help='Build the modules for the host instead of guest', + help='Build the Linux kernel modules for the host instead of guest', ) parser.add_argument( 'kernel_modules', diff --git a/common.py b/common.py index 7f1238e..cbc62e9 100644 --- a/common.py +++ b/common.py @@ -118,6 +118,12 @@ def get_argparse(default_args=None, argparse_args=None): '--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( + '--docker', default=False, action='store_true', + help='''\ +Use the docker download Ubuntu root filesystem instead of the default Buildroot one. +''' + ) parser.add_argument( '-g', '--gem5', default=False, action='store_true', help='Use gem5 instead of QEMU' @@ -552,8 +558,8 @@ def setup(parser): this.host_bin_dir = os.path.join(this.host_dir, 'usr', 'bin') this.buildroot_pkg_config = os.path.join(this.host_bin_dir, 'pkg-config') 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.buildroot_rootfs_raw_file = os.path.join(this.buildroot_images_dir, 'rootfs.ext2') + this.buildroot_qcow2_file = this.buildroot_rootfs_raw_file + '.qcow2' this.staging_dir = os.path.join(this.out_dir, 'staging', args.arch) this.buildroot_staging_dir = os.path.join(this.buildroot_build_dir, 'staging') this.target_dir = os.path.join(this.buildroot_build_dir, 'target') @@ -663,6 +669,20 @@ def setup(parser): this.baremetal_out_lib_dir = os.path.join(this.baremetal_out_dir, this.baremetal_lib_basename) this.baremetal_out_ext = '.elf' + + # Docker + this.docker_build_dir = os.path.join(this.out_dir, 'docker', args.arch) + this.docker_tar_dir = os.path.join(this.docker_build_dir, 'export') + this.docker_tar_file = os.path.join(this.docker_build_dir, 'export.tar') + this.docker_rootfs_raw_file = os.path.join(this.docker_build_dir, 'export.ext2') + this.docker_qcow2_file = os.path.join(this.docker_rootfs_raw_file + '.qcow2') + if args.docker: + this.rootfs_raw_file = this.docker_rootfs_raw_file + this.qcow2_file = this.docker_qcow2_file + else: + this.rootfs_raw_file = this.buildroot_rootfs_raw_file + this.qcow2_file = this.buildroot_qcow2_file + # Image. if args.baremetal is None: if args.gem5: diff --git a/configure b/configure index 73c4de0..d59ab2b 100755 --- a/configure +++ b/configure @@ -85,6 +85,7 @@ expect \ gcc-aarch64-linux-gnu \ gcc-arm-linux-gnueabi \ git \ +libguestfs-tools \ moreutils \ rsync \ tmux \