练习1:理解通过make生成执行文件的过程
操作系统镜像文件ucore.img是如何一步一步生成的?
V := @
#need llvm/cang-3.5+
#USELLVM := 1
# try to infer the correct GCCPREFX ifndef GCCPREFIX GCCPREFIX := $(shell if i386-elf-objdump -i 2>&1 | grep '^elf32-i386$$'
>/dev/null 2>&1; \ then echo 'i386-elf-'; \ elif objdump -i 2>&1 | grep 'elf32-i386' >/dev/null 2>&1; \ then echo ''; \ else
echo
"***" 1>&2; \ echo "*** Error: Couldn't find an i386-elf version of
GCC/binutils." 1>&2; \ echo "*** Is the directory with i386-elf-gcc
in your PATH?" 1>&2; \ echo "*** If your i386-elf toolchain is
installed with a command" 1>&2; \ echo "*** prefix other than
'i386-elf-', set your GCCPREFIX" 1>&2; \ echo "*** environment
variable to that prefix and run 'make' again." 1>&2; \ echo "*** To
turn off this error, run 'gmake GCCPREFIX= ...'." 1>&2; \ echo
"***" 1>&2; exit 1; fi) endif
# try to infer the correct QEMU ifndef QEMU QEMU := $(shell if which qemu-system-i386 > /dev/null; \ then echo 'qemu-system-i386';
exit;
\ elif which i386-elf-qemu > /dev/null; \ then echo
'i386-elf-qemu'; exit; \ elif which qemu > /dev/null; \ then echo
'qemu'; exit; \ else \ echo "***" 1>&2; \ echo "*** Error:
Couldn't find a working QEMU executable." 1>&2; \ echo "*** Is the
directory containing the qemu binary in your PATH" 1>&2; \ echo
"***" 1>&2; exit 1; fi) endif
# eliminate default suffix rules .SUFFIXES: .c .S .h
# delete target files if there is an error (or make is interrupted) .DELETE_ON_ERROR:
# define compiler and flags ifndef USELLVM HOSTCC := gcc HOSTCFLAGS := -g -Wall -O2 CC := $(GCCPREFIX)gcc CFLAGS :=
-march=i686 -fno-builtin -fno-PIC -Wall -ggdb -m32 -gstabs -nostdinc $(DEFS) CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c
/dev/null >/dev/null 2>&1 && echo -fno-stack-protector) else
HOSTCC := clang HOSTCFLAGS := -g -Wall -O2 CC := clang CFLAGS :=
-march=i686 -fno-builtin -fno-PIC -Wall -g -m32 -nostdinc $(DEFS) CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null
>/dev/null 2>&1 && echo -fno-stack-protector) endif
CTYPE := c S
LD := $(GCCPREFIX)ld LDFLAGS := -m $(shell $(LD) -V | grep
elf_i386 2>/dev/null | head -n 1) LDFLAGS += -nostdlib
OBJCOPY := $(GCCPREFIX)objcopy OBJDUMP := $(GCCPREFIX)objdump
COPY := cp MKDIR := mkdir -p MV := mv RM := rm -f AWK := awk
SED := sed SH := sh TR := tr TOUCH := touch -c
OBJDIR := obj BINDIR := bin
ALLOBJS := ALLDEPS := TARGETS :=
include tools/function.mk
listf_cc = $(call listf,$(1),$(CTYPE))
# for cc add_files_cc = $(call add_files,$(1),$(CC),$(CFLAGS) $(3),$(2),$(4)) create_target_cc = $(call
create_target,$(1),$(2),$(3),$(CC),$(CFLAGS))
# for hostcc add_files_host = $(call add_files,$(1),$(HOSTCC),$(HOSTCFLAGS),$(2),$(3)) create_target_host
= $(call create_target,$(1),$(2),$(3),$(HOSTCC),$(HOSTCFLAGS))
cgtype = $(patsubst %.$(2),%.$(3),$(1)) objfile = $(call toobj,$(1))
asmfile = $(call cgtype,$(call toobj,$(1)),o,asm) outfile = $(call
cgtype,$(call toobj,$(1)),o,out) symfile = $(call cgtype,$(call
toobj,$(1)),o,sym)
# for match pattern match = $(shell echo $(2) | $(AWK) '{for(i=1;i<=NF;i++){if(match("$(1)","^"$$(i)"$$")){exit 1;}}}';
echo $$?)
# >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
# include kernel/user
INCLUDE += libs/
CFLAGS += $(addprefix -I,$(INCLUDE))
LIBDIR += libs
$(call add_files_cc,$(call listf_cc,$(LIBDIR)),libs,)
# -------------------------------------------------------------------
# kernel
KINCLUDE += kern/debug/ \
kern/driver/ \
kern/trap/ \
kern/mm/
KSRCDIR += kern/init \
kern/libs \
kern/debug \
kern/driver \
kern/trap \
kern/mm
KCFLAGS += $(addprefix -I,$(KINCLUDE))
$(call add_files_cc,$(call listf_cc,$(KSRCDIR)),kernel,$(KCFLAGS))
KOBJS = $(call read_packet,kernel libs)
# create kernel target kernel = $(call totarget,kernel)
$(kernel): tools/kernel.ld
$(kernel): $(KOBJS) @echo + ld $@ $(V)$(LD) $(LDFLAGS) -T
tools/kernel.ld -o $@ $(KOBJS) @$(OBJDUMP) -S $@ > $(call
asmfile,kernel) @$(OBJDUMP) -t $@ | $(SED) '1,/SYMBOL TABLE/d; s/
.* / /; /^$$/d' > $(call symfile,kernel)
$(call create_target,kernel)
# -------------------------------------------------------------------
# create bootblock bootfiles = $(call listf_cc,boot) $(foreach f,$(bootfiles),$(call cc_compile,$(f),$(CC),$(CFLAGS) -Os
-nostdinc))
bootblock = $(call totarget,bootblock)
$(bootblock): $(call toobj,$(bootfiles)) | $(call totarget,sign)
@echo + ld $@ $(V)$(LD) $(LDFLAGS) -N -e start -Ttext 0x7C00 $^ -o
$(call toobj,bootblock) @$(OBJDUMP) -S $(call objfile,bootblock) >
$(call asmfile,bootblock) @$(OBJCOPY) -S -O binary $(call
objfile,bootblock) $(call outfile,bootblock) @$(call totarget,sign)
$(call outfile,bootblock) $(bootblock)
$(call create_target,bootblock)
# -------------------------------------------------------------------
# create 'sign' tools $(call add_files_host,tools/sign.c,sign,sign) $(call
create_target_host,sign,sign)
# -------------------------------------------------------------------
# create ucore.img UCOREIMG := $(call totarget,ucore.img)
$(UCOREIMG): $(kernel) $(bootblock) $(V)dd if=/dev/zero of=$@
count=10000 $(V)dd if=$(bootblock) of=$@ conv=notrunc $(V)dd
if=$(kernel) of=$@ seek=1 conv=notrunc
$(call create_target,ucore.img)
# >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>&