LDFLAGS ?= -O2
LDFLAGS := $(LDFLAGS) -Wall -Wextra -Werror -std=c++20 \
- -ffreestanding -T linker.ld -z max-page-size=0x1000
+ -ffreestanding -T linker.ld -z max-page-size=0x1000 \
+ -mno-red-zone -mcmodel=large # Normally has no effect, but is used to change the multilib libgcc, to use mcmodel=large and be able to use global constructors and destructors.
LDLIBS := $(LDLIBS) -nostdlib -lgcc
CPPOBJS := $(patsubst $(SRC_DIR)%,$(OUT_DIR)%.o,$(shell find $(SRC_DIR) -name '*.cpp'))
-ASMOBJS := $(patsubst $(SRC_DIR)%,$(OUT_DIR)%.o,$(shell find $(SRC_DIR) -name '*.S'))
+ASMOBJS := $(patsubst $(SRC_DIR)%,$(OUT_DIR)%.o,$(shell find $(SRC_DIR) -name '*.S' -and -not -name 'crti.S' -and -not -name 'crtn.S'))
OBJECTS := $(CPPOBJS) $(ASMOBJS)
+CRTI_OBJ := $(OUT_DIR)crti.S.o
+CRTBEGIN_OBJ := $(shell $(CXX) $(LDFLAGS) -print-file-name=crtbegin.o)
+CRTEND_OBJ := $(shell $(CXX) $(LDFLAGS) -print-file-name=crtend.o)
+CRTN_OBJ := $(OUT_DIR)crtn.S.o
build: $(OUT_DIR)amycros.iso
qemu: build
-rm -rf $(OUT_DIR) $(DEPS_DIR) isodir
-$(OUT_DIR)kernel.elf64: $(OBJECTS) linker.ld
+$(OUT_DIR)kernel.elf64: $(OBJECTS) $(CRTI_OBJ) $(CRTBEGIN_OBJ) $(CRTEND_OBJ) $(CRTN_OBJ) linker.ld
mkdir -p $(OUT_DIR)
- $(CXX) $(LDFLAGS) -o "$@" $(OBJECTS) $(LDLIBS)
+ $(CXX) $(LDFLAGS) -o "$@" $(CRTI_OBJ) $(CRTBEGIN_OBJ) $(OBJECTS) $(CRTEND_OBJ) $(CRTN_OBJ) $(LDLIBS)
$(OUT_DIR)%.o: $(SRC_DIR)%
mkdir -p $(@D)
.text ALIGN(4K) : AT(ADDR(.text) - KERNEL_VMA) {
*(.text)
+ *(.text*)
+ *(.gnu.linkonce.t*)
+ . = ALIGN(8);
+ *(.init)
+ . = ALIGN(8);
+ *(.fini)
+ . = ALIGN(8);
+ *(.ctors)
+ . = ALIGN(8);
+ *(.dtors)
}
.rodata ALIGN(4K) : AT(ADDR(.rodata) - KERNEL_VMA) {
+ *(.rodata)
*(.rodata*)
- }
- .data ALIGN(4K) : AT(ADDR(.data) - KERNEL_VMA) {
- *(.data)
+ *(.gnu.linkonce.r*)
}
.eh_frame ALIGN(4K) : AT(ADDR(.eh_frame) - KERNEL_VMA) {
*(.eh_frame)
}
+ .data ALIGN(4K) : AT(ADDR(.data) - KERNEL_VMA) {
+ *(.data)
+ *(.data*)
+ *(.gnu.linkonce.d*)
+ }
.bss ALIGN(4K) : AT(ADDR(.bss) - KERNEL_VMA) {
*(.bss)
*(COMMON)
+ *(.bss*)
+ *(.gnu.linkonce.b*)
}
. = ALIGN(4K);
_kernel_phys_end = . - KERNEL_VMA;
mov $PML4T - KERNEL_VMA, %rax
mov %rax, %cr3
+ call _init
+
mov %r14, %rsi
mov %r15, %rdi
call kmain # With the two arguments popped earlier.
+
+ # Should never reach that point, but, oh well.
+ call _fini
+
+ cli
+1: hlt
+ jmp 1b