Skip to content

Instantly share code, notes, and snippets.

@willnode
Last active March 4, 2024 12:22
Show Gist options
  • Save willnode/a31a1265d955dbb914001aba8a576ad2 to your computer and use it in GitHub Desktop.
Save willnode/a31a1265d955dbb914001aba8a576ad2 to your computer and use it in GitHub Desktop.
Build Redox for Aarch64 OS Guide

[WIP] Building Aarch64 Redox OS from Mac/Windows

I recommend to spawn a Virtualized Ubuntu. I'm coming from M1 Macbook but I hate building from Podman.

I run with UTM on QEMU virtualization, with 6 CPU, 6 GB RAM and 100 GB disk space. It works for me.

Cloning

cd ~/Document
git clone https://gitlab.redox-os.org/redox-os/redox
cd redox
git submodule --init --recursive

Installing

I assume you're running from fresh Ubuntu aarch64.

sudo apt-get install cbindgen just make build-essential nasm pkg-config fuse3 libfuse3-dev libmpc-dev \
    texinfo bison flex cmake ninja-build autoconf autopoint libtool po4a doxygen gperf

Or if you dare directly running it on Mac.

brew install coreutils binutils findutils gnu-sed osxfuse cbindgen just make nasm pkg-config libmpc \
    mpfr gmp texinfo bison flex cmake ninja autoconf automake libtool libicinv po4a doxygen gperf

Then:

export LIBRARY_PATH=/opt/homebrew/Cellar/gmp/6.3.0/lib:/opt/homebrew/Cellar/mpfr/4.2.1/lib:/opt/homebrew/opt/libiconv/lib
export C_INCLUDE_PATH=/opt/homebrew/Cellar/gmp/6.3.0/include:/opt/homebrew/Cellar/mpfr/4.2.1/include:/opt/homebrew/opt/libiconv/include
export CPLUS_INCLUDE_PATH=/opt/homebrew/Cellar/gmp/6.3.0/include:/opt/homebrew/Cellar/mpfr/4.2.1/include:/opt/homebrew/opt/libiconv/include
export PATH="/opt/homebrew/opt/coreutils/libexec/gnubin:/opt/homebrew/opt/findutils/libexec/gnubin:/opt/homebrew/opt/gnu-sed/libexec/gnubin:$PATH"

Patches

I recommend patch the rust (see bootloader section) before compiling anything.

When recompiling GCC or Rust, don't forget to delete relevant builds in /prefix.

bootloader update toolchain

Switch /rust beforehand to redox-2023-09-07 to include fix rust-lang/rust#98254

GCC compile configure

mk/prefix.mk:

	"$(ROOT)/$</configure" \
		--target="$(TARGET)" \
		--program-prefix="$(TARGET)-" \
		--prefix="" \
		--with-sysroot \
		--with-build-sysroot="$(ROOT)/$(PREFIX)/relibc-freestanding-install/$(TARGET)" \
		--with-native-system-header-dir="/include" \
+		--without-long-double-128 \
		--disable-multilib \
		--disable-nls \
		--disable-werror \
		--enable-languages=c,c++ \
		--enable-shared \
		--enable-threads=posix \

gettext with include libunistring && patch atomic

Need to patch all the long double to double. I have this change implemented for gettext and nano. Reference: https://stackoverflow.com/a/49123064/3908409

cd cookbook/recipes/tools/gettext/source
grep -Rl 'long double' * | xargs -tn1 sed -i -e 's/long double/double/g'
grep -Rl 'SIZEOF_LDBL <= sizeof (double)' * | xargs -tn1 sed -i -e 's/SIZEOF_LDBL <= sizeof (double)/SIZEOF_LDBL <= sizeof (long double)/g'

cookbook/recipes/tools/gettext/recipe.toml

script = """
COOKBOOK_CONFIGURE_FLAGS+=(
+   --disable-glib
    --disable-shared
+   --disable-java
+   --disable-csharp
    --enable-static
+   --with-included-libunistring
    ac_cv_have_decl_program_invocation_name=no
    gt_cv_locale_fr=false
    gt_cv_locale_fr_utf8=false
    gt_cv_locale_ja=false
    gt_cv_locale_tr_utf8=false
    gt_cv_locale_zh_CN=false
)
cookbook_configure
"""

PS: Not sure if anything else except --with-included-libunistring is necessary.

cookbook/recipes/tools/gettext/source/gettext-tools/gnulib-lib/asyncsafe-spin.c

#  if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7) \
       || __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 1)) \
-     && !defined __ibmxl__
+     && !defined __ibmxl__ && !defined __redox__
/* Use GCC built-ins (available in GCC >= 4.7 and clang >= 3.1) that operate on
   the first byte of the lock.
   Documentation:
   <https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/_005f_005fatomic-Builtins.html>
 */
#  elif (((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) \
          && !defined __sparc__) \
         || __clang_major__ >= 3) \
-       && !defined __ibmxl__
+       && !defined __ibmxl__ && !defined __redox__
/* Use GCC built-ins (available in GCC >= 4.1, except on SPARC, and
   clang >= 3.0).
   Documentation:
   <https://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html>  */
  • cookbook/recipes/tools/gettext/source/gettext-tools/gnulib-lib/math.in.h
  • cookbook/recipes/tools/gettext/source/libtextstyle/lib/math.in.h
#if @GNULIB_FREXP@
# if @REPLACE_FREXP@
-#  if !(defined __cplusplus&& defined GNULIB_NAMESPACE)
+#  if !(defined __cplusplus && defined __redox__ && defined GNULIB_NAMESPACE)
#   undef frexp
#   define frexp rpl_frexp
#  endif

bash have long double set no

cookbook/recipes/shells/bash/source/configure

  if test "$GCC" = yes; then
-      ac_cv_type_long_double=yes
+      ac_cv_type_long_double=no
     else

openssl add platform and disable asm and patch sigjmp

cookbook/recipes/libs/openssl1/recipe.toml

COOKBOOK_CONFIGURE_FLAGS=(
    no-shared
    no-dgram
+   no-asm
    "redox-${ARCH}"
    --prefix="/"
)

cookbook/recipes/libs/openssl1/source/Configurations/10-main.conf

    "redox-x86_64" => {
        inherit_from     => [ "BASE_common", asm("x86_64_asm") ],
        cc               => "gcc",
        cflags           => "-DL_ENDIAN -DOSSL_SSIZE_MAX=LONG_MAX -DNO_SYSLOG -O3 -static -Wall",
        bn_ops           => "SIXTY_FOUR_BIT_LONG",
        thread_scheme    => "(unknown)",
    },
+   "redox-aarch64" => {
+       inherit_from     => [ "linux-generic64", asm("aarch64_asm") ],
+       cc               => "gcc",
+       cflags           => "-DL_ENDIAN -DOSSL_SSIZE_MAX=LONG_MAX -DNO_SYSLOG -O3 -static -Wall",
+       bn_ops           => "SIXTY_FOUR_BIT_LONG",
+       thread_scheme    => "(unknown)",
+       perlasm_scheme   => "void",
+   },

cookbook/recipes/libs/openssl1/source/crypto/armcap.c

#else

+/* Some platforms don't have the sigjmp_buf type in <setjmp.h>.  */
+#if defined _MSC_VER || defined __MINGW32__ || defined(__redox__)
+/* Native Woe32 API.  */
+# define sigjmp_buf jmp_buf
+# define sigsetjmp(env,savesigs) setjmp (env)
+# define siglongjmp longjmp
+#endif

static sigset_t all_masked;

patch ring (installer + pkgutils + installer-gui)

Apply https://gitlab.redox-os.org/willnode/ring/-/commit/5d895ab1e

  • cookbook/recipes/core/installer/source/Cargo.toml
  • cookbook/recipes/core/pkgutils/source/Cargo.toml
  • cookbook/recipes/gui/installer-gui/source/Cargo.toml
[patch.crates-io]
-ring = { git = "https://gitlab.redox-os.org/redox-os/ring.git", branch = "redox-unix-0.13.5" }
+ring = { git = "https://gitlab.redox-os.org/willnode/ring.git", branch = "redox-unix-0.13.5" }

fix git build unknown endianness

cookbook/recipes/tools/git/source/compat/bswap.h

# if defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)
#  define GIT_BYTE_ORDER GIT_BIG_ENDIAN
# elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
#  define GIT_BYTE_ORDER GIT_LITTLE_ENDIAN
# elif defined(__THW_BIG_ENDIAN__) && !defined(__THW_LITTLE_ENDIAN__)
#  define GIT_BYTE_ORDER GIT_BIG_ENDIAN
# elif defined(__THW_LITTLE_ENDIAN__) && !defined(__THW_BIG_ENDIAN__)
#  define GIT_BYTE_ORDER GIT_LITTLE_ENDIAN
# else
-#  error "Cannot determine endianness"
+#  define GIT_BYTE_ORDER GIT_LITTLE_ENDIAN
# endif

fix std1 build hint

cookbook/recipes/backends/sdl1/recipe.toml

script = """
COOKBOOK_CONFIGURE_FLAGS+=(
+   --build=aarch64-unknown-linux-gnu
+   --host=aarch64-unknown-redox
    --disable-loadso
    --disable-pthread-sem
    --disable-pulseaudio
    --disable-video-x11
    --enable-clock_gettime
    --enable-redoxaudio
    --enable-video-orbital
)

unlock vesad in initfs (for unlocking display)

cookbook/recipes/core/drivers-initfs/recipe.toml

aarch64_redefine_bin()
{
-   BINS=(inputd lived)
    case "${BOARD}" in
        raspi3bp)
            BINS+=(bcm2835-sdhcid)
        ;;
        raspi3b)
            BINS+=(bcm2835-sdhcid)
        ;;
        *)
        #qemu-virt
        ;;
    esac
}

Add PCID driver (trying for virtio display)

cookbook/recipes/core/drivers/recipe.toml

# Add additional drivers to the list to build, that are not in drivers-initfs
# depending on the target architecture
case "${TARGET}" in
    i686-unknown-redox | x86_64-unknown-redox)
        BINS+=(ac97d bgad pcid pcspkrd sb16d vboxd)
        ;;
+   aarch64-unknown-redox)
+       BINS+=(pcid)
+       ;;
    *)
        ;;
esac

Add desktop profile to aarch64

config/aarch64/desktop.toml (new file)

# Default desktop configuration

include = ["../desktop.toml"]

# Override the default settings here

# General settings
[general]
# Filesystem size in MiB
# filesystem_size = 1024

# Package settings
[packages]
# example = {}

Switch QEMU EFI back to default

This make ramfb device available. But then you have apply my patch to get it working

mk/qemu.mk (please adjust qemu version)

else ifeq ($(ARCH),x86_64)
+	efi=yes
+	live=yes
	QEMU_ARCH=x86_64
	QEMU_MACHINE?=q35
-	QEMU_CPU?=core2duo
-	QEMU_EFI=/usr/share/OVMF/OVMF_CODE.fd
+	QEMU_CPU=qemu64
+	QEMU_EFI=/opt/homebrew/Cellar/qemu/8.2.1/share/qemu/edk2-x86_64-code.fd
	QEMUFLAGS+=-smp 4 -m 2048
else ifeq ($(ARCH),aarch64)
	efi=yes
	live=yes
	QEMU_ARCH=aarch64
	QEMU_MACHINE=virt
-	QEMU_CPU=max
-	ifeq ($(BOARD),raspi3bp)
-		QEMU_EFI=https://gitlab.redox-os.org/Ivan/redox_firmware/-/raw/main/platform/raspberry_pi/rpi3/u-boot-rpi-3-b-plus.bin
-	else
-		QEMU_EFI=https://gitlab.redox-os.org/Ivan/redox_firmware/-/raw/main/platform/qemu/qemu_arm64/u-boot-qemu-arm64.bin
-	endif
+	QEMU_CPU=cortex-a72
+	QEMU_EFI=/opt/homebrew/Cellar/qemu/8.2.1/share/qemu/edk2-aarch64-code.fd
	QEMUFLAGS+=-smp 1 -m 2048
	ifneq ($(vga),no)
...
ifeq ($(efi),yes)
	FIRMWARE=$(BUILD)/firmware.rom
-	QEMUFLAGS+=-bios $(BUILD)/firmware.rom
+	QEMUFLAGS+= -drive if=pflash,format=raw,unit=0,file=$(FIRMWARE),readonly=on   
else
...

$(BUILD)/firmware.rom:
- ifeq ($(ARCH),aarch64)
-	wget -O $@ $(QEMU_EFI)
- else
	cp $(QEMU_EFI) $@
- endif

Current state of the work

Should have the disk image now and it's bootable and able to display though can't interact because ACPI drivers is yet supported.

Currently likely stuck here forever because at this time Redox has no BIOS in aarch64 for easy framebuffer access, or an ACPI support for aarch64 to get access for virtio display.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment