You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

172 lines
5.3 KiB
Makefile

ARCH = x64
# You can alter the subsystem according to your EFI binary target:
# 10 = EFI application
# 11 = EFI boot service driver
# 12 = EFI runtime driver
SUBSYSTEM = 10
# Try to auto-detect the target ARCH
ifeq ($(shell uname -o),Msys)
IS_MINGW32 = $(findstring MINGW32,$(shell uname -s))
IS_MINGW64 = $(findstring MINGW64,$(shell uname -s))
ifeq ($(IS_MINGW32),MINGW32)
ARCH = ia32
endif
ifeq ($(IS_MINGW64),MINGW64)
ARCH = x64
endif
else
ifeq ($(shell uname -m),x86_64)
ARCH = x64
else ifeq ($(shell uname -m),arm)
ARCH = arm
CROSS_COMPILE =
else ifeq ($(shell uname -m),aarch64)
ARCH = aa64
CROSS_COMPILE =
else
ARCH = ia32
endif
endif
# Auto-detect the host arch for MinGW
ifeq ($(shell uname -m),x86_64)
MINGW_HOST = w64
else
MINGW_HOST = w32
endif
ifeq ($(ARCH),x64)
GNUEFI_ARCH = x86_64
GCC_ARCH = x86_64
QEMU_ARCH = x86_64
FW_BASE = OVMF
CROSS_COMPILE = $(GCC_ARCH)-$(MINGW_HOST)-mingw32-
EP_PREFIX =
CFLAGS = -m64 -mno-red-zone
LDFLAGS = -Wl,-dll -Wl,--subsystem,$(SUBSYSTEM)
else ifeq ($(ARCH),ia32)
GNUEFI_ARCH = ia32
GCC_ARCH = i686
QEMU_ARCH = i386
FW_BASE = OVMF
CROSS_COMPILE = $(GCC_ARCH)-$(MINGW_HOST)-mingw32-
EP_PREFIX = _
CFLAGS = -m32 -mno-red-zone
LDFLAGS = -Wl,-dll -Wl,--subsystem,$(SUBSYSTEM)
else ifeq ($(ARCH),arm)
GNUEFI_ARCH = arm
GCC_ARCH = arm
QEMU_ARCH = arm
FW_BASE = QEMU_EFI
CROSS_COMPILE = $(GCC_ARCH)-linux-gnueabihf-
EP_PREFIX =
CFLAGS = -marm -fpic -fshort-wchar
LDFLAGS = -Wl,--no-wchar-size-warning -Wl,--defsym=EFI_SUBSYSTEM=$(SUBSYSTEM)
CRT0_LIBS = -lgnuefi
QEMU_OPTS = -M virt -cpu cortex-a15
else ifeq ($(ARCH),aa64)
GNUEFI_ARCH = aarch64
GCC_ARCH = aarch64
QEMU_ARCH = aarch64
FW_BASE = QEMU_EFI
CROSS_COMPILE = $(GCC_ARCH)-linux-gnu-
EP_PREFIX =
CFLAGS = -fpic -fshort-wchar
LDFLAGS = -Wl,--no-wchar-size-warning -Wl,--defsym=EFI_SUBSYSTEM=$(SUBSYSTEM)
CRT0_LIBS = -lgnuefi
QEMU_OPTS = -M virt -cpu cortex-a57
endif
FW_ARCH = $(shell echo $(ARCH) | tr a-z A-Z)
FW_ZIP = $(FW_BASE)-$(FW_ARCH).zip
GNUEFI_DIR = $(CURDIR)/gnu-efi
GNUEFI_LIBS = lib
# If the compiler produces an elf binary, we need to fiddle with a PE crt0
ifneq ($(CRT0_LIBS),)
CRT0_DIR = $(GNUEFI_DIR)/$(GNUEFI_ARCH)/gnuefi
LDFLAGS += -L$(CRT0_DIR) -T $(GNUEFI_DIR)/gnuefi/elf_$(GNUEFI_ARCH)_efi.lds $(CRT0_DIR)/crt0-efi-$(GNUEFI_ARCH).o
GNUEFI_LIBS += gnuefi
endif
# SYSTEMROOT is only defined on Windows systems
ifneq ($(SYSTEMROOT),)
QEMU = "/c/Program Files/qemu/qemu-system-$(QEMU_ARCH)w.exe"
# MinGW on Windows doesn't use (tuple)-ar but (tuple)-gcc-ar
# so we remove the cross compiler tuple altogether
CROSS_COMPILE =
else
QEMU = qemu-system-$(QEMU_ARCH) -nographic
endif
CC := $(CROSS_COMPILE)gcc
OBJCOPY := $(CROSS_COMPILE)objcopy
CFLAGS += -fno-stack-protector -Wshadow -Wall -Wunused -Werror-implicit-function-declaration
CFLAGS += -I$(GNUEFI_DIR)/inc -I$(GNUEFI_DIR)/inc/$(GNUEFI_ARCH) -I$(GNUEFI_DIR)/inc/protocol
CFLAGS += -DCONFIG_$(GNUEFI_ARCH) -D__MAKEWITH_GNUEFI -DGNU_EFI_USE_MS_ABI
LDFLAGS += -L$(GNUEFI_DIR)/$(GNUEFI_ARCH)/lib -e $(EP_PREFIX)efi_main
LDFLAGS += -s -Wl,-Bsymbolic -nostdlib -shared
LIBS = -lefi $(CRT0_LIBS)
ifeq (, $(shell which $(CC)))
$(error The selected compiler ($(CC)) was not found)
endif
GCCVERSION := $(shell $(CC) -dumpversion | cut -f1 -d.)
GCCMINOR := $(shell $(CC) -dumpversion | cut -f2 -d.)
GCCMACHINE := $(shell $(CC) -dumpmachine)
GCCNEWENOUGH := $(shell ( [ $(GCCVERSION) -gt "4" ] \
|| ( [ $(GCCVERSION) -eq "4" ] \
&& [ $(GCCMINOR) -ge "7" ] ) ) \
&& echo 1)
ifneq ($(GCCNEWENOUGH),1)
$(error You need GCC 4.7 or later)
endif
ifneq ($(GCC_ARCH),$(findstring $(GCC_ARCH), $(GCCMACHINE)))
$(error The selected compiler ($(CC)) is not set for $(ARCH))
endif
.PHONY: all clean superclean
all: $(GNUEFI_DIR)/$(GNUEFI_ARCH)/lib/libefi.a main.efi
$(GNUEFI_DIR)/$(GNUEFI_ARCH)/lib/libefi.a:
$(MAKE) -C$(GNUEFI_DIR) CROSS_COMPILE=$(CROSS_COMPILE) ARCH=$(GNUEFI_ARCH) $(GNUEFI_LIBS)
%.efi: %.o
@echo [LD] $(notdir $@)
ifeq ($(CRT0_LIBS),)
@$(CC) $(LDFLAGS) $< -o $@ $(LIBS)
else
@$(CC) $(LDFLAGS) $< -o $*.elf $(LIBS)
@$(OBJCOPY) -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel* \
-j .rela* -j .reloc -j .eh_frame -O binary $*.elf $@
@rm -f $*.elf
endif
%.o: src/%.c
@echo [CC] $(notdir $@)
@$(CC) $(CFLAGS) -ffreestanding -c $<
qemu: CFLAGS += -D_DEBUG
qemu: all $(FW_BASE)_$(FW_ARCH).fd image/efi/boot/boot$(ARCH).efi
$(QEMU) $(QEMU_OPTS) -bios ./$(FW_BASE)_$(FW_ARCH).fd -net none -hda fat:rw:image
image/efi/boot/boot$(ARCH).efi: main.efi
mkdir -p image/efi/boot
cp -f $< $@
$(FW_BASE)_$(FW_ARCH).fd:
wget https://efi.akeo.ie/$(FW_BASE)/$(FW_ZIP)
unzip $(FW_ZIP) $(FW_BASE).fd
mv $(FW_BASE).fd $(FW_BASE)_$(FW_ARCH).fd
rm $(FW_ZIP)
clean:
rm -f main.efi *.o
rm -rf image
superclean: clean
$(MAKE) -C$(GNUEFI_DIR) ARCH=$(GNUEFI_ARCH) clean
rm -f *.fd