MAKEFILE介绍

MAKEFILE工程最重要的一环,MAKEFILE可以链接操作系统的每个文件,然后构建出我们需要的操作系统文件.对MAKEFILE进行介绍可以帮助我们了解OS的构建模式.

首先我们定义了几个工具的名字,包括QEMU,编译器和交叉编译的前缀等等.

TOOLPREFIX=riscv64-linux-gnu-

QEMU = qemu-system-riscv64

CC = $(TOOLPREFIX)gcc
AS = $(TOOLPREFIX)gas
LD = $(TOOLPREFIX)ld
OBJCOPY = $(TOOLPREFIX)objcopy
OBJDUMP = $(TOOLPREFIX)objdump

下面的代码定义了编译器的选项.

CFLAGS = -Wall -Werror -O -fno-omit-frame-pointer -ggdb -DDEBUG -DWARNING -DERROR -D$(FS) -D$(MAC)
CFLAGS += -MD
CFLAGS += -mcmodel=medany
CFLAGS += -ffreestanding -fno-common -nostdlib -mno-relax
CFLAGS += -I. -I./src
CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector)

# Disable PIE when possible (for Ubuntu 16.10 toolchain)
ifneq ($(shell $(CC) -dumpspecs 2>/dev/null | grep -e '[^f]no-pie'),)
CFLAGS += -fno-pie -no-pie
endif
ifneq ($(shell $(CC) -dumpspecs 2>/dev/null | grep -e '[^f]nopie'),)
CFLAGS += -fno-pie -nopie
endif

首先我们定义qemu这个目标,当执行make qemu的时候,就会运行我们需要的代码.

QEMUOPTS = -machine $(M) -bios $(SBI) -kernel $K/kernel -smp $(CPUS) -nographic
qemu: $K/kernel
	$(QEMU) $(QEMUOPTS)

我们还知道,要生成qemu这个目标,我们需要kernel的二进制文件.生成kernel二进制文件的命令如下:

$K/kernel:$K/syscall.c $(OBJS) $(LINKER)
	@$(LD) $(LDFLAGS) -T $(LINKER) -o $K/kernel $(OBJS)
	@$(OBJDUMP) -S $K/kernel > $K/kernel.asm
	@$(OBJDUMP) -t $K/kernel | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > $K/kernel.sym

这个命令,负责根据LINKER(连接脚本)整合$(OBJS)的代码,然后利用OBJDUMP软件生成汇编文件.执行这个命令需要$(OBJS),syscall.cLINKER.

首先看$(OBJS):

OBJS += \
	$K/entry.o \
	$K/bio.o \
	$(DISK) \
	$K/ramdisk.o \
	$K/spi.o \
	$K/sd.o \
	$K/diskio.o \
	$K/disk.o \
	$K/string.o \
	$K/intr.o \
	$K/image.o \
	$K/proc.o \
	$K/fat32.o \
	$K/pipe.o \
	$K/file.o \
	$K/bin.o \
	$K/dev.o \
	$K/swtch.o \
	$K/trampoline.o \
	$K/sig_trampoline.o \
	$K/signal.o \
	$K/spinlock.o \
	$K/sleeplock.o \
	$K/printf.o \
	$K/pm.o \
	$K/kmalloc.o \
	$K/vm.o \
	$K/timer.o \
	$K/main.o \
	$K/kernelvec.o \
	$K/trap.o \
	$K/copy.o \
	$K/poll.o \
	$K/cpu.o \
	$K/vma.o \
	$K/mmap.o \
	$K/uarg.o \
	$K/exec.o \
	$K/uname.o\
	$K/sysfile.o \
	$K/systime.o \
	$K/sysproc.o \
	$K/syslog.o \
	$K/syspoll.o \
	$K/syssig.o \
	$K/syscall.o

全部是.o文件,所以说在执行MAKE操作的时候会自动生成.

LINKER是已经存在的文件.

syscall.c需要执行sys.sh生成

$K/syscall.c:
	./syscall/sys.sh

在shell文件中,我们通过执行脚本文件生成syscall.cusys.S文件,这个负责产生系统调用的中间转化代码.至此MAKEFILE的讲解结束.

Last updated