mirror of
https://github.com/taigrr/gopher-os
synced 2025-01-18 04:43:13 -08:00
The makefile provides the following targets: - kernel - iso - run - gdb It sniffs the OS type and when running on non-linux hosts it uses vagrant ssh and runs make with the above targets inside the vagrant box. The kernel build process consists of the following steps: 1) Compile arch-specific (only x86 for now) assembly files. 2) Run go build -n to obtain the build commands for our kernel. The makefile sets the build target to 386/linux so that our current rt0 implementation does not need to switch to long-mode. 3) The build commands are then patched to: - use build/ as the output directory - force the go linker to use external link mode and to place its output files (--tmpdir) to the build folder. By forcing external link mode, the go linker will emit a single go.o file which can be used by ld. 4) We run our own link step and use ld to link the rt0 .o files with the go.o file and provide a custom linker script to ensure that our multiboot record is located at the top of the kernel image so that grub can find it. The ISO build process sets up a minimal folder structure for building a bootable ISO (basically the kernel image plus a grub configuration) and runs grub-mkrescue to produce the ISO file. Both the run and the gdb targets assume that qemu is installed. The gdb target starts qemu, attaches the debugger and sets a breakpoint to the rt0 entrypoint.
100 lines
2.9 KiB
Makefile
100 lines
2.9 KiB
Makefile
OS = $(shell uname -s)
|
|
ARCH := x86
|
|
BUILD_DIR := build
|
|
BUILD_ABS_DIR := $(CURDIR)/$(BUILD_DIR)
|
|
|
|
kernel_target :=$(BUILD_DIR)/kernel-$(ARCH).bin
|
|
iso_target := $(BUILD_DIR)/kernel-$(ARCH).iso
|
|
|
|
ifeq ($(OS), Linux)
|
|
export SHELL := /bin/bash
|
|
|
|
LD := ld
|
|
AS := nasm
|
|
|
|
GOOS := linux
|
|
GOARCH := 386
|
|
|
|
LD_FLAGS := -n -melf_i386 -T arch/$(ARCH)/script/linker.ld -static --no-ld-generated-unwind-info
|
|
AS_FLAGS := -g -f elf32 -F dwarf -I arch/$(ARCH)/asm/
|
|
|
|
asm_src_files := $(wildcard arch/$(ARCH)/asm/*.s)
|
|
asm_obj_files := $(patsubst arch/$(ARCH)/asm/%.s, $(BUILD_DIR)/arch/$(ARCH)/asm/%.o, $(asm_src_files))
|
|
|
|
.PHONY: kernel iso clean
|
|
|
|
kernel: $(kernel_target)
|
|
|
|
$(kernel_target): $(asm_obj_files) go.o
|
|
@echo "[$(LD)] linking kernel-$(ARCH).bin"
|
|
@$(LD) $(LD_FLAGS) -o $(kernel_target) $(asm_obj_files) $(BUILD_DIR)/go.o
|
|
|
|
go.o:
|
|
@mkdir -p $(BUILD_DIR)
|
|
|
|
@echo "[go] compiling go sources into a standalone .o file"
|
|
@GOARCH=386 GOOS=linux go build -n 2>&1 | sed \
|
|
-e "1s|^|set -e\n|" \
|
|
-e "1s|^|export GOOS=linux\n|" \
|
|
-e "1s|^|export GOARCH=386\n|" \
|
|
-e "1s|^|WORK='$(BUILD_ABS_DIR)'\n|" \
|
|
-e "1s|^|alias pack='go tool pack'\n|" \
|
|
-e "/^mv/d" \
|
|
-e "s|-extld|-tmpdir='$(BUILD_ABS_DIR)' -linkmode=external -extldflags='-nostdlib' -extld|g" \
|
|
| sh 2>&1 | sed -e "s/^/ | /g"
|
|
|
|
@# build/go.o is a elf32 object file but all go symbols are unexported. Our
|
|
@# asm entrypoint code needs to know the address to 'main.main' so we use
|
|
@# objcopy to make that symbol exportable
|
|
@echo "[objcopy] export 'main.main' symbol in go.o"
|
|
@objcopy --globalize-symbol='main.main' $(BUILD_DIR)/go.o $(BUILD_DIR)/go.o
|
|
|
|
$(BUILD_DIR)/arch/$(ARCH)/asm/%.o: arch/$(ARCH)/asm/%.s
|
|
@mkdir -p $(shell dirname $@)
|
|
@echo "[$(AS)] $<"
|
|
@$(AS) $(AS_FLAGS) $< -o $@
|
|
|
|
iso: $(iso_target)
|
|
|
|
$(iso_target): $(kernel_target)
|
|
@echo "[grub] building ISO kernel-$(ARCH).iso"
|
|
|
|
@mkdir -p $(BUILD_DIR)/isofiles/boot/grub
|
|
@cp $(kernel_target) $(BUILD_DIR)/isofiles/boot/kernel.bin
|
|
@cp arch/$(ARCH)/script/grub.cfg $(BUILD_DIR)/isofiles/boot/grub
|
|
@grub-mkrescue -o $(iso_target) $(BUILD_DIR)/isofiles 2>&1 | sed -e "s/^/ | /g"
|
|
@rm -r $(BUILD_DIR)/isofiles
|
|
|
|
else
|
|
VAGRANT_SRC_FOLDER = /home/vagrant/workspace/src/github.com/achilleasa/gopher-os
|
|
|
|
.PHONY: kernel iso vagrant-up vagrant-down vagrant-ssh run gdb clean
|
|
|
|
kernel:
|
|
vagrant ssh -c 'cd $(VAGRANT_SRC_FOLDER); make kernel'
|
|
|
|
iso:
|
|
vagrant ssh -c 'cd $(VAGRANT_SRC_FOLDER); make iso'
|
|
|
|
run: iso
|
|
qemu-system-i386 -cdrom $(iso_target)
|
|
|
|
gdb: iso
|
|
qemu-system-i386 -s -S -cdrom $(iso_target) &
|
|
sleep 1
|
|
gdb \
|
|
-ex "add-auto-load-safe-path $(pwd)" \
|
|
-ex "file $(kernel_target)" \
|
|
-ex "set disassembly-flavor intel" \
|
|
-ex 'set arch i386:intel' \
|
|
-ex 'target remote localhost:1234' \
|
|
-ex 'layout asm' \
|
|
-ex 'b _rt0_entry' \
|
|
-ex 'continue' \
|
|
-ex 'disass'
|
|
@killall qemu-system-i386 || true
|
|
endif
|
|
|
|
clean:
|
|
@test -d $(BUILD_DIR) && rm -rf $(BUILD_DIR) || true
|