From ac82b7e5cc3e6d410aa9a0167f43b6b3b8c14452 Mon Sep 17 00:00:00 2001
From: mintsuki <mintsuki@protonmail.com>
Date: Wed, 15 Jun 2022 21:44:21 +0200
Subject: [PATCH] Make build more portable

---
 .gitignore         |  2 +-
 GNUmakefile        | 31 ++++++++++++++++++++-----------
 README.md          |  4 ++--
 kernel/GNUmakefile | 34 ++++++++++++++++++++++++----------
 kernel/linker.ld   |  4 ----
 5 files changed, 47 insertions(+), 28 deletions(-)

diff --git a/.gitignore b/.gitignore
index ebec950..fd3cdca 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,5 @@
 limine
-ovmf-x64
+ovmf-X64
 kernel/limine.h
 *.elf
 *.iso
diff --git a/GNUmakefile b/GNUmakefile
index ccec474..96e1602 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -1,3 +1,12 @@
+ARCH ?= x86_64
+
+# Check that the architecture is supported and set relevant variables.
+ifeq ($(ARCH),x86_64)
+    override EFI_ARCH := X64
+else
+    $(error Architecture $(ARCH) not supported)
+endif
+
 .PHONY: all
 all: barebones.iso
 
@@ -6,23 +15,23 @@ all-hdd: barebones.hdd
 
 .PHONY: run
 run: barebones.iso
-	qemu-system-x86_64 -M q35 -m 2G -cdrom barebones.iso -boot d
+	qemu-system-$(ARCH) -M q35 -m 2G -cdrom barebones.iso -boot d
 
 .PHONY: run-uefi
-run-uefi: ovmf-x64 barebones.iso
-	qemu-system-x86_64 -M q35 -m 2G -bios ovmf-x64/OVMF.fd -cdrom barebones.iso -boot d
+run-uefi: ovmf-$(EFI_ARCH) barebones.iso
+	qemu-system-$(ARCH) -M q35 -m 2G -bios ovmf-$(EFI_ARCH)/OVMF.fd -cdrom barebones.iso -boot d
 
 .PHONY: run-hdd
 run-hdd: barebones.hdd
-	qemu-system-x86_64 -M q35 -m 2G -hda barebones.hdd
+	qemu-system-$(ARCH) -M q35 -m 2G -hda barebones.hdd
 
 .PHONY: run-hdd-uefi
-run-hdd-uefi: ovmf-x64 barebones.hdd
-	qemu-system-x86_64 -M q35 -m 2G -bios ovmf-x64/OVMF.fd -hda barebones.hdd
+run-hdd-uefi: ovmf-$(EFI_ARCH) barebones.hdd
+	qemu-system-$(ARCH) -M q35 -m 2G -bios ovmf-$(EFI_ARCH)/OVMF.fd -hda barebones.hdd
 
-ovmf-x64:
-	mkdir -p ovmf-x64
-	cd ovmf-x64 && curl -o OVMF-X64.zip https://efi.akeo.ie/OVMF/OVMF-X64.zip && 7z x OVMF-X64.zip
+ovmf-$(EFI_ARCH):
+	mkdir -p ovmf-$(EFI_ARCH)
+	cd ovmf-$(EFI_ARCH) && curl -o OVMF-$(EFI_ARCH).zip https://efi.akeo.ie/OVMF/OVMF-$(EFI_ARCH).zip && 7z x OVMF-$(EFI_ARCH).zip
 
 limine:
 	git clone https://github.com/limine-bootloader/limine.git --branch=v3.0-branch-binary --depth=1
@@ -58,7 +67,7 @@ barebones.hdd: limine kernel
 	sudo mount `cat loopback_dev`p1 img_mount
 	sudo mkdir -p img_mount/EFI/BOOT
 	sudo cp -v kernel/kernel.elf limine.cfg limine/limine.sys img_mount/
-	sudo cp -v limine/BOOTX64.EFI img_mount/EFI/BOOT/
+	sudo cp -v limine/BOOT$(EFI_ARCH).EFI img_mount/EFI/BOOT/
 	sync
 	sudo umount img_mount
 	sudo losetup -d `cat loopback_dev`
@@ -71,5 +80,5 @@ clean:
 
 .PHONY: distclean
 distclean: clean
-	rm -rf limine ovmf-x64
+	rm -rf limine ovmf-$(EFI_ARCH)
 	$(MAKE) -C kernel distclean
diff --git a/README.md b/README.md
index 44ca95a..0d41e6b 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,8 @@
 # Limine Bare Bones
 
-This repository will show you how to set up a simple 64-bit x86_64 Long Mode higher half kernel using Limine.
+This repository will show you how to set up a simple 64-bit higher half kernel using Limine.
 
-This project can be built using the host compiler on most Linux distros on x86_64, but it's recommended you set up an x86_64-elf [cross compiler](https://wiki.osdev.org/GCC_Cross-Compiler).
+This project can be built using the host compiler on most Linux distros, but it's recommended you set up a [cross compiler](https://wiki.osdev.org/GCC_Cross-Compiler) for your target architecture.
 
 It is also recommended to cross reference the contents of this repository with [the Limine Bare Bones](https://wiki.osdev.org/Limine_Bare_Bones) OSDev wiki page.
 
diff --git a/kernel/GNUmakefile b/kernel/GNUmakefile
index 638f98a..0490512 100644
--- a/kernel/GNUmakefile
+++ b/kernel/GNUmakefile
@@ -1,13 +1,16 @@
+# Target processor architecture.
+ARCH ?= x86_64
+
 # This is the name that our final kernel executable will have.
 # Change as needed.
 override KERNEL := kernel.elf
 
 # Convenience macro to reliably declare overridable command variables.
 define DEFAULT_VAR =
-    ifeq ($(origin $1), default)
+    ifeq ($(origin $1),default)
         override $(1) := $(2)
     endif
-    ifeq ($(origin $1), undefined)
+    ifeq ($(origin $1),undefined)
         override $(1) := $(2)
     endif
 endef
@@ -32,14 +35,6 @@ override INTERNALCFLAGS := \
     -fno-stack-check       \
     -fno-pie               \
     -fno-pic               \
-    -mabi=sysv             \
-    -mno-80387             \
-    -mno-mmx               \
-    -mno-3dnow             \
-    -mno-sse               \
-    -mno-sse2              \
-    -mno-red-zone          \
-    -mcmodel=kernel        \
     -MMD
 
 # Internal linker flags that should not be changed by the user.
@@ -49,6 +44,25 @@ override INTERNALLDFLAGS :=     \
     -Wl,-z,max-page-size=0x1000 \
     -Wl,-T,linker.ld
 
+# Set archtecture specific variables (and check that the architecture is supported).
+ifeq ($(ARCH),x86_64)
+    override INTERNALCFLAGS += \
+        -m64                   \
+        -march=x86-64          \
+        -mabi=sysv             \
+        -mno-80387             \
+        -mno-mmx               \
+        -mno-sse               \
+        -mno-sse2              \
+        -mno-red-zone          \
+        -mcmodel=kernel
+    override INTERNALLDFLAGS +=    \
+        -Wl,-m,elf_x86_64          \
+        -Wl,--oformat=elf64-x86-64
+else
+    $(error Architecture $(ARCH) not supported)
+endif
+
 # Use find to glob all *.c files in the directory and extract the object names.
 override CFILES := $(shell find ./ -type f -name '*.c')
 override OBJ := $(CFILES:.c=.o)
diff --git a/kernel/linker.ld b/kernel/linker.ld
index 8056875..39848ea 100644
--- a/kernel/linker.ld
+++ b/kernel/linker.ld
@@ -1,7 +1,3 @@
-/* Tell the linker that we want an x86_64 ELF64 output file */
-OUTPUT_FORMAT(elf64-x86-64)
-OUTPUT_ARCH(i386:x86-64)
-
 /* We want the symbol _start to be our entry point */
 ENTRY(_start)