From 6936bd6ba996dee40f7cd826e5cf01ef39c2cabf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ciro=20Santilli=20=E5=85=AD=E5=9B=9B=E4=BA=8B=E4=BB=B6=20?= =?UTF-8?q?=E6=B3=95=E8=BD=AE=E5=8A=9F?= Date: Thu, 31 Oct 2019 00:00:00 +0000 Subject: [PATCH] how to update gcc Automatically add extra remotes from ./build. --- .gitmodules | 9 --- README.adoc | 152 +++++++++++++++++++++++++++++++++++++++++++-- build | 50 ++++++++++++++- build-userland | 16 ++++- common.py | 14 ++++- path_properties.py | 2 +- run | 4 +- 7 files changed, 227 insertions(+), 20 deletions(-) diff --git a/.gitmodules b/.gitmodules index d118666..834b2a4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -3,31 +3,25 @@ url = git://git.kernel.org/pub/scm/linux/kernel/git/mark/boot-wrapper-aarch64.git [submodule "submodules/binutils-gdb"] path = submodules/binutils-gdb - # url = git://sourceware.org/git/binutils-gdb.git url = https://github.com/cirosantilli/binutils-gdb [submodule "submodules/buildroot"] path = submodules/buildroot - # url = git://git.busybox.net/buildroot url = https://github.com/cirosantilli/buildroot ignore = dirty [submodule "submodules/crosstool-ng"] path = submodules/crosstool-ng - # url = https://github.com/crosstool-ng/crosstool-ng url = https://github.com/cirosantilli/crosstool-ng [submodule "submodules/dhrystone"] path = submodules/dhrystone url = https://github.com/cirosantilli/dhrystone [submodule "submodules/gcc"] path = submodules/gcc - # url = git://gcc.gnu.org/git/gcc.git url = https://github.com/cirosantilli/gcc [submodule "submodules/gem5"] path = submodules/gem5 - # url = https://gem5.googlesource.com/public/gem5 url = https://github.com/cirosantilli/gem5 [submodule "submodules/glibc"] path = submodules/glibc - # url = git://sourceware.org/git/glibc.git url = https://github.com/cirosantilli/glibc # The true upstream does not accept git submodule update --init --depth 1 # git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git @@ -35,16 +29,13 @@ # https://unix.stackexchange.com/questions/338578/linux-kernel-source-code-size-difference [submodule "submodules/linux"] path = submodules/linux - # usl = git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git url = https://github.com/cirosantilli/linux [submodule "submodules/parsec-benchmark"] path = submodules/parsec-benchmark url = https://github.com/cirosantilli/parsec-benchmark [submodule "submodules/qemu"] path = submodules/qemu - # url = https://github.com/qemu/qemu url = https://github.com/cirosantilli/qemu [submodule "submodules/xen"] path = submodules/xen - # url = git://xenbits.xen.org/xen.git url = https://github.com/cirosantilli/xen diff --git a/README.adoc b/README.adoc index b0aed22..88c32f2 100644 --- a/README.adoc +++ b/README.adoc @@ -11952,6 +11952,8 @@ What they mean: https://stackoverflow.com/questions/50583962/what-are-the-gem5-a https://gem5.googlesource.com/arm/linux/ contains an ARM Linux kernel forks with a few gem5 specific Linux kernel patches on top of mainline created by ARM Holdings on top of a few upstream kernel releases. +Our link:build[] script automatically adds that remote for us as `gem5-arm`. + The patches are optional: the vanilla kernel does boot. But they add some interesting gem5-specific optimizations, instrumentations and device support. The patches also <> that are known to work well with gem5. @@ -11961,7 +11963,7 @@ E.g. for arm v4.9 there is: https://gem5.googlesource.com/arm/linux/+/917e007a41 In order to use those patches and their associated configs, and, we recommend using <> as: .... -git -C "$(./getvar linux_source_dir)" fetch https://gem5.googlesource.com/arm/linux gem5/v4.15:gem5/v4.15 +git -C "$(./getvar linux_source_dir)" fetch gem5-arm:gem5/v4.15 git -C "$(./getvar linux_source_dir)" checkout gem5/v4.15 ./build-linux \ --arch aarch64 \ @@ -13508,9 +13510,131 @@ Here are some good working commands for several ISAs: These can come in handy if you want to debug something in Buildroot itself and possibly report an upstream bug. +=== Update the toolchain + +Users of this repo will often want to update the compilation toolchain to the latest version to get fresh new features like new ISA instructions. + +Because the toolchain is so complex and tightly knitted with the rest of the system, this is more of an art than a science. + +However, it is not something to be feared, and you will get there without help in most cases. + +In this section we cover the most common cases. + +==== Update GCC: GCC supported by Buildroot + +This is of course the simplest case. + +You can quickly determine all the GCC versions supported by Buildroot by looking at: + +.... +submodules/buildroot/package/gcc/Config.in.host +.... + +For example, in Buildroot 2018.08, which was used at LKMC 5d10529c10ad8a4777b0bac1543320df0c89a1ce, the default toolchain was 7.3.0, and the latest supported one was 8.2.0. + +To just upgrade the toolchain to 8.2.0, and rebuild some userland executables to later run them, we could do: + +.... +cd submodules/gcc +git fetch up +git checkout -b lkmc-gcc-8_2_0-release gcc-8_2_0-release +git am ../buildroot/package/gcc/8.2.0/* +cd ../.. +./build-buildroot \ + --arch aarch64 \ + --buildroot-build-id gcc-8-2 \ + --config 'BR2_GCC_VERSION_8_X=y' \ + --config 'BR2_GCC_VERSION="8.2.0"' \ + --no-all \ + -- \ + toolchain \ +; +./build-userland \ + --arch aarch64 \ + --buildroot-build-id gcc-8-2 \ + --out-rootfs-overlay-dir-prefix gcc-8-2 \ + --userland-build-id gcc-8-2 \ +; +./build-buildroot --arch aarch64 +.... + +where the `toolchain` Buildroot target builds only Buildroot: https://stackoverflow.com/questions/44521150/buildroot-install-and-build-the-toolchain-only + +Note that this setup did not overwrite any of our default Buildroot due to careful namespacing with our `gcc-8-2` prefix! + +Now you can either run the executables on <> with: + +.... +./run --arch aarch64 --userland userland/c/hello.c --userland-build-id gcc-8-2 +.... + +or in full system with: + +.... +./run --arch aarch64 --eval-after './gcc-8-2/c/hello.out' +.... + +where the `gcc-8-2` prefix was added by `--out-rootfs-overlay-dir-prefix`. + +<> support was only added to GCC 8 and can be enabled with the flag: `-march=armv8.2-a+sve`. + +We already even had a C SVE test in-tree, but it was disabled because the old toolchain does not support it. + +So once the new GCC 8 toolchain was built, we can first enable that test by editing the <> file to not skip C SVE tests anymore: + +.... + #os.path.splitext(self.path_components[-1])[1] == '.c' and self['arm_sve'] +.... + +and then rebuild run one of the experiments from <>: + +.... +./build-userland \ + --arch aarch64 \ + --buildroot-build-id gcc-8-2 \ + --force-rebuild \ + --march=armv8.2-a+sve \ + --out-rootfs-overlay-dir-prefix gcc-8-2 \ + --static \ + --userland-build-id gcc-8-2 \ +; +./run \ + --arch aarch64 \ + --userland userland/arch/aarch64/inline_asm/sve_addvl.c \ + --userland-build-id gcc-8-2 \ + --static \ + --gem5-worktree master \ + -- \ + --param 'system.cpu[:].isa[:].sve_vl_se = 4' \ +.... + +Bibliography: + +* https://github.com/cirosantilli/linux-kernel-module-cheat/issues/87 + +==== Update GCC: GCC not supported by Buildroot + +Now it gets fun, but well, guess what, we will try to do the same as xref:update-gcc-gcc-supported-by-buildroot[xrefstyle=full] but: + +* pick the Buildroot version that comes closest to the GCC you want +* if any `git am` patches don't apply, skip them + +Now, if things fail, you can try: + +* if the GCC version is supported by a newer Buildroot version: +** quick and dirty: see what they are doing differently there, and patch it in here +** golden star: upgrade our default Buildroot, <>, and send a pull request! +* otherwise: OK, go and patch Buildroot, time to become a Buildroot dev + +Known setups: + +* Buildroot 2018.08: +** GCC 8.3.0: OK +** GCC 9.2.0: KO https://github.com/cirosantilli/linux-kernel-module-cheat/issues/97 + == Userland content -This section contains userland content, such as <>, <> and <> examples. +This section documents our test and educational userland content, such as <>, <> and <> examples, present mostly under link:userland/[]. Getting started at: xref:userland-setup[xrefstyle=full] @@ -18911,7 +19035,7 @@ Also we don't have a choice in the case of C++ template, which must stay in head ==== buildroot_packages directory -Source: link:buildroot_packages/[] +Source: link:buildroot_packages/[]. Every directory inside it is a Buildroot package. @@ -19003,6 +19127,8 @@ These are typically patches that don't contain fundamental functionality, so we ==== rootfs_overlay +Source: link:rootfs_overlay[]. + We use this directory for: * customized configuration files @@ -19029,6 +19155,25 @@ ls /mnt/9p/rootfs_overlay This way you can just hack away the scripts and try them out immediately without any further operations. +===== out_rootfs_overlay_dir + +This path can be found with: + +.... +./getvar out_rootfs_overlay_dir +.... + +This output directory contains all the files that LKMC will put inside the final image, including for example: + +* <> that needs to be compiled +* <> content that gets put inside the image as is + +LKMC first collects all the files that it will dump into the guest there, and then in the very last step dumps everything into the final image. + +In Buildroot, this is done by pointing `BR2_ROOTFS_OVERLAY` to that directory. + +This does not include native image modification mechanisms such as <>, which we let Buildroot itself manage. + ==== lkmc.c The files: @@ -19404,7 +19549,6 @@ git remote set-url origin git@github.com:cirosantilli/linux.git git push git checkout master -git remote add up git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git git fetch up git rebase --onto "$next_mainline_revision" "$last_mainline_revision" diff --git a/build b/build index 7500c63..12a3ff2 100755 --- a/build +++ b/build @@ -7,6 +7,7 @@ import cli_function import collections import common import copy +import itertools import math import subprocess import shell_helpers @@ -55,7 +56,40 @@ class _Component: ): self.build_callback() +submodule_extra_remotes = { + 'binutils-gdb': { + 'up': 'git://sourceware.org/git/binutils-gdb.git', + }, + 'buildroot': { + 'up': 'https://gem5.googlesource.com/public/gem5', + }, + 'crosstool-ng': { + 'up': 'https://github.com/crosstool-ng/crosstool-ng', + }, + 'gcc': { + 'up': 'git://gcc.gnu.org/git/gcc.git', + }, + 'gem5': { + 'up': 'https://gem5.googlesource.com/public/gem5', + }, + 'glibc': { + 'up': 'git://sourceware.org/git/glibc.git', + }, + 'linux': { + # https://cirosantilli.com/linux-kernel-module-cheat#gem5-arm-linux-kernel-patches + 'gem5-arm': 'https://gem5.googlesource.com/arm/linux', + 'up': 'git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git', + }, + 'qemu': { + 'up': 'https://git.qemu.org/git/qemu.git', + }, + 'xen': { + 'up': 'git://xenbits.xen.org/xen.git', + }, +} + class Main(common.LkmcCliFunction): + def __init__(self): super().__init__( description='''\ @@ -170,7 +204,6 @@ so looping over all of them would waste time. }, 'submodules_shallow': {'gem5'}, } - self.name_to_component_map = { 'all': _Component(dependencies=[ 'qemu-gem5-buildroot', @@ -596,6 +629,21 @@ Which components to build. Default: qemu-buildroot self.log_warn('update to git 2.17 or newer and you will save clone time') self.log_warn('see: https://github.com/cirosantilli/linux-kernel-module-cheat/issues/44') self.sh.run_cmd(cmd + ['--', LF] + submodule_ids_to_cmd(submodules_shallow)) + for submodule_name in submodule_extra_remotes: + submodule = submodule_extra_remotes[submodule_name] + for remote_name in submodule: + self.sh.run_cmd( + [ + 'git', LF, + '-C', os.path.join(common.consts['submodules_dir'], submodule_name), LF, + 'remote', LF, + 'add', LF, + remote_name, LF, + submodule[remote_name], LF, + ], + # In case the remote already exists. + raise_on_failure=False + ) # Do the build. for component in selected_components: diff --git a/build-userland b/build-userland index 637963f..5f7b338 100755 --- a/build-userland +++ b/build-userland @@ -23,6 +23,17 @@ Build our compiled userland examples. self._add_argument('--ccflags') self._add_argument('--force-rebuild') self._add_argument('--optimization-level') + self.add_argument( + '--out-rootfs-overlay-dir-prefix', + default='', + help='''\ +Place the output files inside the image within this additional prefix. +This is mostly useful to place different versions of binaries with different +build parameters inside image to compare them. See: +* https://cirosantilli.com/linux-kernel-module-cheat#update-the-toolchain +* https://cirosantilli.com/linux-kernel-module-cheat#out_rootfs_overlay_dir +''' + ) self.add_argument( 'targets', default=[], @@ -88,7 +99,10 @@ Default: build all examples that have their package dependencies met, e.g.: if not self.env['in_tree']: self.sh.copy_dir_if_update( srcdir=build_dir, - destdir=self.env['out_rootfs_overlay_lkmc_dir'], + destdir=os.path.join( + self.env['out_rootfs_overlay_lkmc_dir'], + self.env['out_rootfs_overlay_dir_prefix'] + ), filter_ext=self.env['userland_executable_ext'], ) return exit_status diff --git a/common.py b/common.py index 7a8608d..ee9ffb6 100644 --- a/common.py +++ b/common.py @@ -252,6 +252,13 @@ Which toolchain binaries to use: - crosstool-ng: the ones we built with ./build-crosstool-ng. For baremetal, links to newlib. - host: the host distro pre-packaged userland ones. For userland, links to glibc. - host-baremetal: the host distro pre-packaged bare one. For baremetal, links to newlib. +''' + ) + self.add_argument( + '--march', + help='''\ +GCC -march option to use. Currently only used for the more LKMC-specific builds such as +./build-userland and ./build-baremetal. Maybe we will use it for more things some day. ''' ) self.add_argument( @@ -702,14 +709,16 @@ Incompatible archs are skipped. env['crosstool_ng_toolchain_prefix'] = 'arm-unknown-eabi' env['ubuntu_toolchain_prefix'] = 'arm-linux-gnueabihf' env['is_arm'] = True - env['march'] = 'armv8-a' + if not env['_args_given']['march']: + env['march'] = 'armv8-a' elif env['arch'] == 'aarch64': env['armv'] = 8 env['buildroot_toolchain_prefix'] = 'aarch64-buildroot-linux-gnu' env['crosstool_ng_toolchain_prefix'] = 'aarch64-unknown-elf' env['ubuntu_toolchain_prefix'] = 'aarch64-linux-gnu' env['is_arm'] = True - env['march'] = 'armv8-a+lse' + if not env['_args_given']['march']: + env['march'] = 'armv8-a+lse' elif env['arch'] == 'x86_64': env['crosstool_ng_toolchain_prefix'] = 'x86_64-unknown-elf' env['gem5_arch'] = 'X86' @@ -931,6 +940,7 @@ Incompatible archs are skipped. env['kernel_modules_build_host_subdir'] = join(env['kernel_modules_build_host_dir'], env['kernel_modules_subdir']) # Overlay. + # https://cirosantilli.com/linux-kernel-module-cheat#buildroot_packages-directory env['out_rootfs_overlay_dir'] = join(env['out_dir'], 'rootfs_overlay', env['arch']) env['out_rootfs_overlay_lkmc_dir'] = join(env['out_rootfs_overlay_dir'], env['repo_short_id']) env['out_rootfs_overlay_bin_dir'] = join(env['out_rootfs_overlay_dir'], 'bin') diff --git a/path_properties.py b/path_properties.py index 96bf157..4d35371 100644 --- a/path_properties.py +++ b/path_properties.py @@ -158,7 +158,7 @@ class PathProperties: self['no_executable'] ) and not ( # Our C compiler does not suppport SVE yet. - # https://github.com/cirosantilli/linux-kernel-module-cheat/issues/87 + # https://cirosantilli.com/linux-kernel-module-cheat#update-gcc-gcc-supported-by-buildroot os.path.splitext(self.path_components[-1])[1] == '.c' and self['arm_sve'] ) ) diff --git a/run b/run index caace9e..0e53990 100755 --- a/run +++ b/run @@ -75,8 +75,8 @@ https://cirosantilli.com/linux-kernel-module-cheat#lkmc_home '--eval-after', help='''\ Similar to --eval, but the string gets evaled at the last init script, -after the normal init finished. -See: https://cirosantilli.com/linux-kernel-module-cheat#init-busybox +after the normal init finished. After this string is evaled, you are left +inside a shell. See: https://cirosantilli.com/linux-kernel-module-cheat#init-busybox ''' ) self.add_argument(