diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..94ad118 --- /dev/null +++ b/flake.nix @@ -0,0 +1,248 @@ +{ + description = "Bare-metal Rust on Zynq-7000"; + + inputs.nixpkgs.url = github:NixOS/nixpkgs/nixos-21.11; + inputs.mozilla-overlay = { url = github:mozilla/nixpkgs-mozilla; flake = false; }; + + outputs = { self, nixpkgs, mozilla-overlay }: + let + pkgs = import nixpkgs { system = "x86_64-linux"; overlays = [ (import mozilla-overlay) ]; }; + + # ==== rustPlatform + let + rustManifest = pkgs.fetchurl { + url = "https://static.rust-lang.org/dist/2021-01-29/channel-rust-nightly.toml"; + sha256 = "sha256-T0D0ypXA+nuH7o3AHCokzSBZAvQxvef4x9+XxO3aBao="; + }; + targets = []; + rustChannelOfTargets = _channel: _date: targets: + (pkgs.lib.rustLib.fromManifestFile rustManifest { + inherit (pkgs) stdenv lib fetchurl patchelf; + }).rust.override { + inherit targets; + extensions = ["rust-src"]; + }; + rust = rustChannelOfTargets "nightly" null targets; + in + rustPlatform = pkgs.recurseIntoAttrs (pkgs.makeRustPlatform { + rustc = rust; + cargo = rust; + }); + # ==== rustPlatform / gnutoolchain + gnutoolchain = { + let + gnu-platform = "arm-none-eabi"; + + binutils-pkg = { extraConfigureFlags ? [] }: pkgs.stdenv.mkDerivation rec { + basename = "binutils"; + version = "2.30"; + name = "${basename}-${gnu-platform}-${version}"; + src = pkgs.fetchurl { + url = "https://ftp.gnu.org/gnu/binutils/binutils-${version}.tar.bz2"; + sha256 = "028cklfqaab24glva1ks2aqa1zxa6w6xmc8q34zs1sb7h22dxspg"; + }; + configureFlags = [ + "--enable-deterministic-archives" + "--target=${gnu-platform}" + "--with-cpu=cortex-a9" + "--with-fpu=vfpv3" + "--with-float=hard" + "--with-mode=thumb" + ] ++ extraConfigureFlags; + outputs = [ "out" "info" "man" ]; + depsBuildBuild = [ pkgs.buildPackages.stdenv.cc ]; + buildInputs = [ pkgs.lib.zlib ]; + enableParallelBuilding = true; + meta = { + description = "Tools for manipulating binaries (linker, assembler, etc.)"; + longDescription = '' + The GNU Binutils are a collection of binary tools. The main + ones are `ld' (the GNU linker) and `as' (the GNU assembler). + They also include the BFD (Binary File Descriptor) library, + `gprof', `nm', `strip', etc. + ''; + homepage = http://www.gnu.org/software/binutils/; + license = pkgs.lib.licenses.gpl3Plus; + /* Give binutils a lower priority than gcc-wrapper to prevent a + collision due to the ld/as wrappers/symlinks in the latter. */ + priority = "10"; + }; + }; + + gcc-pkg = { platform-binutils, extraConfigureFlags ? [] }: pkgs.stdenv.mkDerivation rec { + basename = "gcc"; + version = "9.1.0"; + name = "${basename}-${gnu-platform}-${version}"; + src = pkgs.fetchurl { + url = "https://ftp.gnu.org/gnu/gcc/gcc-${version}/gcc-${version}.tar.xz"; + sha256 = "1817nc2bqdc251k0lpc51cimna7v68xjrnvqzvc50q3ax4s6i9kr"; + }; + preConfigure = + '' + mkdir build + cd build + ''; + configureScript = "../configure"; + configureFlags = + [ "--target=${gnu-platform}" + "--with-arch=armv7-a" + "--with-tune=cortex-a9" + "--with-fpu=vfpv3" + "--with-float=hard" + "--disable-libssp" + "--enable-languages=c" + "--with-as=${platform-binutils}/bin/${gnu-platform}-as" + "--with-ld=${platform-binutils}/bin/${gnu-platform}-ld" ] ++ extraConfigureFlags; + outputs = [ "out" "info" "man" ]; + hardeningDisable = [ "format" "pie" ]; + propagatedBuildInputs = with pkgs.libs [ gmp mpfr libmpc platform-binutils ]; + enableParallelBuilding = true; + dontFixup = true; + }; + + newlib-pkg = { platform-binutils, platform-gcc }: pkgs.stdenv.mkDerivation rec { + pname = "newlib"; + version = "3.1.0"; + src = pkgs.fetchurl { + url = "ftp://sourceware.org/pub/newlib/newlib-${version}.tar.gz"; + sha256 = "0ahh3n079zjp7d9wynggwrnrs27440aac04340chf1p9476a2kzv"; + }; + nativeBuildInputs = [ platform-binutils pkgs.platform-gcc ]; + configureFlags = [ + "--target=${gnu-platform}" + + "--with-cpu=cortex-a9" + "--with-fpu=vfpv3" + "--with-float=hard" + "--with-mode=thumb" + "--enable-interwork" + "--disable-multilib" + + "--disable-newlib-supplied-syscalls" + "--with-gnu-ld" + "--with-gnu-as" + "--disable-newlib-io-float" + "--disable-werror" + ]; + dontFixup = true; + }; + in rec { + binutils-bootstrap = pkgs.callPackage binutils-pkg { }; + gcc-bootstrap = pkgs.callPackage gcc-pkg { + platform-binutils = binutils-bootstrap; + extraConfigureFlags = [ "--disable-libgcc" ]; + }; + newlib = pkgs.callPackage newlib-pkg { + platform-binutils = binutils-bootstrap; + platform-gcc = gcc-bootstrap; + }; + binutils = pkgs.callPackage binutils-pkg { + extraConfigureFlags = [ "--with-lib-path=${newlib}/arm-none-eabi/lib" ]; + }; + gcc = pkgs.callPackage gcc-pkg { + platform-binutils = binutils; + extraConfigureFlags = [ "--enable-newlib" "--with-headers=${newlib}/arm-none-eabi/include" ]; + }; + } + } + # ==== gnutoolchain/cargo-xbuild + cargo-xbuild = rustPlatform.buildRustPackage rec { + pname = "cargo-xbuild"; + version = "0.6.5"; + + src = pkgs.fetchFromGitHub { + owner = "rust-osdev"; + repo = pname; + rev = "v${version}"; + sha256 = "18djvygq9v8rmfchvi2hfj0i6fhn36m716vqndqnj56fiqviwxvf"; + }; + cargoLock = { + lockFile = [ ./Cargo.lock ] + } + meta = with pkgs.lib; { + description = "Automatically cross-compiles the sysroot crates core, compiler_builtins, and alloc"; + homepage = "https://github.com/rust-osdev/cargo-xbuild"; + license = with licenses; [ mit asl20 ]; + maintainers = with maintainers; [ johntitor xrelkd ]; + }; + } + # ==== cargo-xbuild/mkbootimage + mkbootimage = pkgs.stdenv.mkDerivation { + pname = "mkbootimage"; + version = "2.2"; + + src = pkgs.fetchFromGitHub { + owner = "antmicro"; + repo = "zynq-mkbootimage"; + rev = "4ee42d782a9ba65725ed165a4916853224a8edf7"; + sha256 = "1k1mbsngqadqihzjgvwvsrkvryxy5ladpxd9yh9iqn2s7fxqwqa9"; + }; + + propagatedBuildInputs = [ pkgs.libelf pkgs.pcre ]; + patchPhase = + '' + substituteInPlace Makefile --replace "git rev-parse --short HEAD" "echo nix" + ''; + installPhase = + '' + mkdir -p $out/bin + cp mkbootimage $out/bin + ''; + } + # ==== mkbootimage/fsbl + fsbl = { board ? "zc706" }: pkgs.stdenv.mkDerivation { + name = "${board}-fsbl"; + src = pkgs.fetchFromGitHub { + owner = "Xilinx"; + repo = "embeddedsw"; + rev = "65c849ed46c88c67457e1fc742744f96db968ff1"; + sha256 = "1rvl06ha40dzd6s9aa4sylmksh4xb9dqaxq462lffv1fdk342pda"; + }; + patches = [ ./fsbl.patch ]; + nativeBuildInputs = [ + pkgs.gnumake + gnutoolchain.binutils + gnutoolchain.gcc + ]; + patchPhase = '' + patch -p1 -i ${./fsbl.patch} + patchShebangs lib/sw_apps/zynq_fsbl/misc/copy_bsp.sh + echo 'SEARCH_DIR("${gnutoolchain.newlib}/arm-none-eabi/lib");' >> lib/sw_apps/zynq_fsbl/src/lscript.ld + ''; + buildPhase = '' + cd lib/sw_apps/zynq_fsbl/src + make BOARD=${board} "CFLAGS=-DFSBL_DEBUG_INFO -g" + ''; + installPhase = '' + mkdir $out + cp fsbl.elf $out + ''; + doCheck = false; + dontFixup = true; + } + # ==== fsbl/ + in { + packages.x86_64-linux = { + + }; + + hydraJobs = { + + }; + + devShell.x86_64-linux = pkgs.mkShell { + name = "zynq-rs-dev-shell"; + buildInputs = with pkgs; [ + rustPlatform.rust.rustc + rustPlatform.rust.cargo + cacert + cargo-xbuild + + openocd gdb + openssh rsync + llvmPackages_9.clang-unwrapped + mkbootimage + }; + defaultPackage.x86_64-linux = zynq-rs; + }; +} \ No newline at end of file