├── .dockerignore ├── .gitignore ├── .gitmodules ├── Dockerfile ├── toolchain-build-install.sh ├── qemu-build-install.sh └── README.md /.dockerignore: -------------------------------------------------------------------------------- 1 | /qemu 2 | /workdir 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /*.tar.gz 2 | /workdir 3 | /rootfs -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "qemu"] 2 | path = qemu 3 | url = https://github.com/valkmit/qemu-execve-patch.git 4 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # we are the base image ;) 2 | FROM scratch 3 | ADD ./rootfs / 4 | CMD ["/x86_64/bin/qemu-aarch64", "-execve", "/bin/bash"] -------------------------------------------------------------------------------- /toolchain-build-install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | apt-get -y update 4 | apt-get -y install build-essential libncurses-dev \ 5 | file wget cpio unzip rsync bc python3 6 | 7 | cd /root/buildroot-src 8 | make 9 | 10 | cd /x86_64 11 | tar czf /root/buildroot-src/host.tar.gz ./host -------------------------------------------------------------------------------- /qemu-build-install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | apt-get -y update 4 | apt-get -y install build-essential \ 5 | python3 ninja-build pkg-config libglib2.0-dev git 6 | 7 | mkdir -p /root/build 8 | cd /root/build 9 | 10 | /root/qemu-src/configure \ 11 | --prefix="/root/qemu-install/" \ 12 | --target-list="aarch64-linux-user" \ 13 | --without-default-features \ 14 | --without-default-devices \ 15 | --static 16 | 17 | make install -j$(nproc) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Prebuilt images available on Docker Hub 2 | 3 | https://hub.docker.com/r/valkmit/aws-graviton2-on-intel 4 | 5 | ## What is this? 6 | 7 | An Arm filesystem based off an AWS Graviton 2 system. All binaries are emulated 8 | under Qemu, **EXCEPT** for a custom toolchain built with Buildroot. The 9 | toolchain is run natively, allowing for up to _20x_ faster compile times than 10 | when emulated. 11 | 12 | ``` 13 | # file $(which bash) 14 | /usr/bin/bash: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 3.7.0, BuildID[sha1]=03b374959d488851f8b6ef51a6a16e55eaedea98, stripped 15 | 16 | # file $(realpath $(which aarch64-linux-gcc)) 17 | /x86_64/host/bin/toolchain-wrapper: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 3.2.0, BuildID[sha1]=9c88d4609953b73d518a95e44ebc93d642a8174e, stripped 18 | ``` 19 | 20 | ## Usage 21 | 22 | If you wish to build the Docker image from source, you must run `./build.sh`. 23 | At a minimum, you must provide the rootfs as a .tar.gz with -r. The script 24 | will download buildroot if it is not provided with -b. For a prebuilt image, 25 | please visit the corresponding Docker hub page (link provided above). 26 | 27 | The only requirement to build is Docker - both Qemu and the toolchain are 28 | built in Docker containers based on Debian 10. 29 | 30 | All of the native cross compile tools are available prefixed with 31 | `aarch64-linux`. For example, `aarch64-linux-gcc`, or `aarch64-linux-g++`. 32 | To observe how the toolchain is configured, you may view 33 | buildroot-graviton2-config. 34 | 35 | Spin up an image quickly to play around with the compilers: 36 | 37 | ``` 38 | docker run -it --rm valkmit/aws-graviton2-on-intel 39 | ``` 40 | 41 | ## Justification 42 | 43 | When compiling for a target architecture different from the host architecture, 44 | developers have roughly two options 45 | 46 | 1. Set up a cross toolchain, which has fast performance, but makes it very 47 | difficult to automatically satisfy complex dependencies. For a sufficiently 48 | large project, this could mean compiling dozens of projects by hand using the 49 | newly built cross toolchain 50 | 51 | 2. Emulate the target system, which makes dependency satisfaction easier, 52 | since a native package manager can be used, but slows down compile times - 53 | the compiler has to be emulated, too! 54 | 55 | This project is designed to give developers the best of both worlds - the 56 | ease of using the target system's package manager (in this case, Yum configured 57 | with all of Amazon's aarch64 repos) - and the speed of native compilers. 58 | 59 | Long story short, a native cross-compiler is transplanted onto the Gravon2 60 | Arm filesystem. This project could probably be extended for other systems, too. 61 | 62 | ## Isn't a Docker container configured with binfmt-misc superior? 63 | 64 | Normally, yes. However, binfmt-misc currently doesn't have namespace support 65 | (though this is in the pipeline!) This means that if you choose to go the 66 | binfmt-misc route, you must run a privileged container. **This project does 67 | not require a privileged Docker container**. 68 | 69 | The lack of requirement of privileged container means that you may use this 70 | on public build systems that do not have Arm support, and expect much better 71 | performance. 72 | 73 | ## Credits 74 | 75 | Lots of back and forth with gh:JosiahWhite 76 | --------------------------------------------------------------------------------