From 8e4de054d70f8719c3fe0a503cedc8c3e861672e Mon Sep 17 00:00:00 2001 From: mintsuki Date: Sat, 3 Apr 2021 00:48:38 +0200 Subject: [PATCH] build: Generally rework build system to easily allow 3rd party toolchains to be used. Drop reliance on libgcc for BIOS builds by shipping our own routines instead --- .github/workflows/main.yml | 7 +-- Makefile | 17 ++---- decompressor/Makefile | 18 ++++-- ...ke_toolchain_uefi.sh => make_toolchain.sh} | 6 +- scripts/make_toolchain_bios.sh | 48 ---------------- stage23/Makefile | 30 +++++++--- stage23/lib/libc.s2.c | 1 - stage23/lib/libgcc.s2.asm | 55 +++++++++++++++++++ tinf/tinflate.c | 6 -- 9 files changed, 101 insertions(+), 87 deletions(-) rename scripts/{make_toolchain_uefi.sh => make_toolchain.sh} (72%) delete mode 100755 scripts/make_toolchain_bios.sh create mode 100644 stage23/lib/libgcc.s2.asm diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 8b2805a8..1efd9e2f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -25,11 +25,8 @@ jobs: - name: Install dependencies run: sudo apt-get update && sudo apt-get install git build-essential nasm gcc-mingw-w64 gcc-multilib wget mtools -y - - name: Build the toolchain (BIOS) - run: make toolchain-bios - - - name: Build the toolchain (UEFI) - run: make toolchain-uefi + - name: Build the toolchain + run: make toolchain - name: Build the bootloader run: make diff --git a/Makefile b/Makefile index 164841a3..bfe4be8f 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,8 @@ CC = cc PREFIX = /usr/local DESTDIR = +TOOLCHAIN = x86_64-elf + PATH := $(shell pwd)/toolchain/bin:$(PATH) .PHONY: all bin/limine-install clean install distclean limine-bios limine-uefi limine-bios-clean limine-uefi-clean stage23-bios stage23-bios-clean stage23-uefi stage23-uefi-clean decompressor decompressor-clean toolchain test.hdd echfs-test ext2-test fat16-test fat32-test iso9660-test iso9660-uefi-test pxe-test uefi-test hybrid-iso9660-test @@ -84,19 +86,12 @@ test-clean: rm -rf test_image test.hdd test.iso toolchain: - $(MAKE) toolchain-bios - $(MAKE) toolchain-uefi - -toolchain-bios: - scripts/make_toolchain_bios.sh "`realpath ./toolchain`" -j`nproc` - -toolchain-uefi: - scripts/make_toolchain_uefi.sh "`realpath ./toolchain`" -j`nproc` + scripts/make_toolchain.sh "`realpath ./toolchain`" -j`nproc` gnu-efi: - git clone https://git.code.sf.net/p/gnu-efi/code --branch=3.0.12 --depth=1 $@ - $(MAKE) -C gnu-efi/gnuefi CC=x86_64-elf-gcc AR=x86_64-elf-ar - $(MAKE) -C gnu-efi/lib CC=x86_64-elf-gcc ARCH=x86_64 x86_64/efi_stub.o + git clone https://git.code.sf.net/p/gnu-efi/code --branch=3.0.13 --depth=1 $@ + $(MAKE) -C gnu-efi/gnuefi CC="$(TOOLCHAIN)-gcc -m64" AR=$(TOOLCHAIN)-ar + $(MAKE) -C gnu-efi/lib CC="$(TOOLCHAIN)-gcc -m64" ARCH=x86_64 x86_64/efi_stub.o ovmf: mkdir -p ovmf diff --git a/decompressor/Makefile b/decompressor/Makefile index 4a2dcf78..f6356abf 100644 --- a/decompressor/Makefile +++ b/decompressor/Makefile @@ -1,19 +1,23 @@ -CC = i386-elf-gcc -LD = i386-elf-gcc -OBJCOPY = i386-elf-objcopy BUILDDIR = ifeq ($(BUILDDIR), ) $(error BUILDDIR not specified) endif +TOOLCHAIN = x86_64-elf + +CC = $(TOOLCHAIN)-gcc +OBJCOPY = $(TOOLCHAIN)-objcopy + CFLAGS = -flto -Os -pipe -Wall -Wextra -Werror INTERNAL_CFLAGS = \ + -m32 \ -std=gnu11 \ -ffreestanding \ -fno-stack-protector \ -fno-pic \ + -fno-pie \ -fomit-frame-pointer \ -Wno-address-of-packed-member \ -masm=intel \ @@ -24,10 +28,12 @@ INTERNAL_CFLAGS = \ LDFLAGS = -flto -Os INTERNAL_LDFLAGS = \ - -lgcc \ - -static-libgcc \ + -m32 \ + -Wl,-melf_i386 \ -nostdlib \ -no-pie \ + -fno-pic \ + -fno-pie \ -z max-page-size=0x1000 \ -static \ -Tlinker.ld @@ -47,7 +53,7 @@ builddir: for i in $(OBJ); do mkdir -p `dirname $$i`; done $(BUILDDIR)/decompressor.bin: $(OBJ) - $(LD) $(OBJ) $(LDFLAGS) $(INTERNAL_LDFLAGS) -o $(BUILDDIR)/decompressor.elf + $(CC) $(OBJ) $(LDFLAGS) $(INTERNAL_LDFLAGS) -o $(BUILDDIR)/decompressor.elf $(OBJCOPY) -O binary $(BUILDDIR)/decompressor.elf $@ -include $(HEADER_DEPS) diff --git a/scripts/make_toolchain_uefi.sh b/scripts/make_toolchain.sh similarity index 72% rename from scripts/make_toolchain_uefi.sh rename to scripts/make_toolchain.sh index b18ba981..ae4d6c58 100755 --- a/scripts/make_toolchain_uefi.sh +++ b/scripts/make_toolchain.sh @@ -7,6 +7,8 @@ TARGET=x86_64-elf BINUTILSVERSION=2.36.1 GCCVERSION=10.2.0 +CFLAGS="-O2 -pipe" + mkdir -p "$1" && cd "$1" PREFIX="$(pwd)" @@ -30,7 +32,7 @@ tar -xf ../gcc-$GCCVERSION.tar.gz mkdir build-binutils cd build-binutils -../binutils-$BINUTILSVERSION/configure --target=$TARGET --prefix="$PREFIX" --with-sysroot --disable-nls --disable-werror --enable-targets=x86_64-elf,x86_64-pe --enable-64-bit-bfd +../binutils-$BINUTILSVERSION/configure CFLAGS="$CFLAGS" CXXFLAGS="$CFLAGS" --target=$TARGET --prefix="$PREFIX" --with-sysroot --disable-nls --disable-werror --enable-targets=x86_64-elf,x86_64-pe make make install cd .. @@ -40,7 +42,7 @@ contrib/download_prerequisites cd .. mkdir build-gcc cd build-gcc -../gcc-$GCCVERSION/configure --target=$TARGET --prefix="$PREFIX" --disable-nls --enable-languages=c --without-headers +../gcc-$GCCVERSION/configure CFLAGS="$CFLAGS" CXXFLAGS="$CFLAGS" --target=$TARGET --prefix="$PREFIX" --disable-nls --enable-languages=c --without-headers make all-gcc make all-target-libgcc make install-gcc diff --git a/scripts/make_toolchain_bios.sh b/scripts/make_toolchain_bios.sh deleted file mode 100755 index c3c728e7..00000000 --- a/scripts/make_toolchain_bios.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/sh - -set -e -set -x - -TARGET=i386-elf -BINUTILSVERSION=2.36.1 -GCCVERSION=10.2.0 - -mkdir -p "$1" && cd "$1" -PREFIX="$(pwd)" - -export MAKEFLAGS="$2" - -export PATH="$PREFIX/bin:$PATH" - -if [ ! -f binutils-$BINUTILSVERSION.tar.gz ]; then - wget https://ftp.gnu.org/gnu/binutils/binutils-$BINUTILSVERSION.tar.gz -fi -if [ ! -f gcc-$GCCVERSION.tar.gz ]; then - wget https://ftp.gnu.org/gnu/gcc/gcc-$GCCVERSION/gcc-$GCCVERSION.tar.gz -fi - -rm -rf build -mkdir build -cd build - -tar -xf ../binutils-$BINUTILSVERSION.tar.gz -tar -xf ../gcc-$GCCVERSION.tar.gz - -mkdir build-binutils -cd build-binutils -../binutils-$BINUTILSVERSION/configure --target=$TARGET --prefix="$PREFIX" --with-sysroot --disable-nls --disable-werror --enable-64-bit-bfd -make -make install -cd .. - -cd gcc-$GCCVERSION -contrib/download_prerequisites -cd .. -mkdir build-gcc -cd build-gcc -../gcc-$GCCVERSION/configure --target=$TARGET --prefix="$PREFIX" --disable-nls --enable-languages=c --without-headers -make all-gcc -make all-target-libgcc -make install-gcc -make install-target-libgcc -cd .. diff --git a/stage23/Makefile b/stage23/Makefile index 40482a4d..b038263a 100644 --- a/stage23/Makefile +++ b/stage23/Makefile @@ -6,13 +6,15 @@ ifeq ($(BUILDDIR), ) endif ifeq ($(TARGET), bios) - TOOLCHAIN=i386-elf + OBJCOPY_ARCH = elf32-i386 else ifeq ($(TARGET), uefi) - TOOLCHAIN=x86_64-elf + OBJCOPY_ARCH = elf64-x86-64 else $(error Invalid target) endif +TOOLCHAIN = x86_64-elf + CC = $(TOOLCHAIN)-gcc OBJCOPY = $(TOOLCHAIN)-objcopy OBJDUMP = $(TOOLCHAIN)-objdump @@ -49,15 +51,25 @@ INTERNAL_CFLAGS := \ ifeq ($(TARGET), bios) INTERNAL_CFLAGS += \ + -m32 \ + -march=i386 \ -fno-pie endif ifeq ($(TARGET), uefi) INTERNAL_CFLAGS += \ + -m64 \ + -march=x86-64 \ -I../gnu-efi/inc \ -I../gnu-efi/inc/x86_64 \ -fpie \ -mno-red-zone + + INTERNAL_CFLAGS32 := \ + $(INTERNAL_CFLAGS) \ + -m32 \ + -march=i386 \ + -fpie endif LDFLAGS = -O3 -g @@ -70,15 +82,17 @@ INTERNAL_LDFLAGS := \ ifeq ($(TARGET), bios) INTERNAL_LDFLAGS += \ + -m32 \ + -Wl,-melf_i386 \ -static \ -no-pie \ - -fno-pie \ - -lgcc \ - -static-libgcc + -fno-pie endif ifeq ($(TARGET), uefi) INTERNAL_LDFLAGS += \ + -m64 \ + -Wl,-melf_x86_64 \ -shared \ -Wl,-Bsymbolic \ -Wl,--noinhibit-exec \ @@ -117,11 +131,11 @@ $(BUILDDIR)/sys/smp_trampoline.bin: sys/smp_trampoline.real $(BUILDDIR)/sys/smp_trampoline.o: $(BUILDDIR)/sys/smp_trampoline.bin cd "`dirname $<`" && \ - $(OBJCOPY) -B i8086 -I binary -O default "`basename $<`" $@ + $(OBJCOPY) -B i8086 -I binary -O $(OBJCOPY_ARCH) "`basename $<`" $@ $(BUILDDIR)/font.o: font.bin cd "`dirname $<`" && \ - $(OBJCOPY) -B i8086 -I binary -O default "`basename $<`" $@ + $(OBJCOPY) -B i8086 -I binary -O $(OBJCOPY_ARCH) "`basename $<`" $@ ifeq ($(TARGET), bios) @@ -191,7 +205,7 @@ endif ifeq ($(TARGET), uefi) $(BUILDDIR)/%.32.o: %.32.c - $(CC) -m32 $(CFLAGS) $(INTERNAL_CFLAGS) -c $< -o $@.32 + $(CC) $(CFLAGS) $(INTERNAL_CFLAGS32) -c $< -o $@.32 $(OBJCOPY) -I elf32-i386 -O elf64-x86-64 $@.32 $@ rm $@.32 endif diff --git a/stage23/lib/libc.s2.c b/stage23/lib/libc.s2.c index 3b378523..f8289973 100644 --- a/stage23/lib/libc.s2.c +++ b/stage23/lib/libc.s2.c @@ -1,7 +1,6 @@ #include #include #include -#include #include #include diff --git a/stage23/lib/libgcc.s2.asm b/stage23/lib/libgcc.s2.asm new file mode 100644 index 00000000..edaca298 --- /dev/null +++ b/stage23/lib/libgcc.s2.asm @@ -0,0 +1,55 @@ +section .text + +global __udivdi3 +__udivdi3: + mov eax, dword [esp+4] + mov edx, dword [esp+8] + div dword [esp+12] + xor edx, edx + ret + +global __divdi3 +__divdi3: + mov eax, dword [esp+4] + mov edx, dword [esp+8] + idiv dword [esp+12] + xor edx, edx + ret + +global __umoddi3 +__umoddi3: + mov eax, dword [esp+4] + mov edx, dword [esp+8] + div dword [esp+12] + mov eax, edx + xor edx, edx + ret + +global __moddi3 +__moddi3: + mov eax, dword [esp+4] + mov edx, dword [esp+8] + idiv dword [esp+12] + mov eax, edx + xor edx, edx + ret + +global __udivmoddi4 +__udivmoddi4: + mov eax, dword [esp+4] + mov edx, dword [esp+8] + div dword [esp+12] + mov ecx, dword [esp+20] + mov dword [ecx], edx + xor edx, edx + ret + +global __udivmoddi4 +__divmoddi4: + mov eax, dword [esp+4] + mov edx, dword [esp+8] + idiv dword [esp+12] + mov ecx, dword [esp+20] + mov dword [ecx], edx + xor edx, edx + ret diff --git a/tinf/tinflate.c b/tinf/tinflate.c index 79d43e83..eb3c4907 100644 --- a/tinf/tinflate.c +++ b/tinf/tinflate.c @@ -25,12 +25,6 @@ #include "tinf.h" -#include - -#if defined(UINT_MAX) && (UINT_MAX) < 0xFFFFFFFFUL -# error "tinf requires unsigned int to be at least 32-bit" -#endif - /* -- Internal data structures -- */ struct tinf_tree {