《操作系统》的实验代码。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

281 lines
7.1 KiB

12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
  1. PROJ := 5
  2. EMPTY :=
  3. SPACE := $(EMPTY) $(EMPTY)
  4. SLASH := /
  5. V := @
  6. # try to infer the correct GCCPREFX
  7. ifndef GCCPREFIX
  8. GCCPREFIX := $(shell if i386-ucore-elf-objdump -i 2>&1 | grep '^elf32-i386$$' >/dev/null 2>&1; \
  9. then echo 'i386-ucore-elf-'; \
  10. elif objdump -i 2>&1 | grep 'elf32-i386' >/dev/null 2>&1; \
  11. then echo ''; \
  12. else echo "***" 1>&2; \
  13. echo "*** Error: Couldn't find an i386-ucore-elf version of GCC/binutils." 1>&2; \
  14. echo "*** Is the directory with i386-ucore-elf-gcc in your PATH?" 1>&2; \
  15. echo "*** If your i386-ucore-elf toolchain is installed with a command" 1>&2; \
  16. echo "*** prefix other than 'i386-ucore-elf-', set your GCCPREFIX" 1>&2; \
  17. echo "*** environment variable to that prefix and run 'make' again." 1>&2; \
  18. echo "*** To turn off this error, run 'gmake GCCPREFIX= ...'." 1>&2; \
  19. echo "***" 1>&2; exit 1; fi)
  20. endif
  21. # try to infer the correct QEMU
  22. ifndef QEMU
  23. QEMU := $(shell if which qemu > /dev/null; \
  24. then echo 'qemu'; exit; \
  25. elif which i386-ucore-elf-qemu > /dev/null; \
  26. then echo 'i386-ucore-elf-qemu'; exit; \
  27. else \
  28. echo "***" 1>&2; \
  29. echo "*** Error: Couldn't find a working QEMU executable." 1>&2; \
  30. echo "*** Is the directory containing the qemu binary in your PATH" 1>&2; \
  31. echo "***" 1>&2; exit 1; fi)
  32. endif
  33. # eliminate default suffix rules
  34. .SUFFIXES: .c .S .h
  35. # delete target files if there is an error (or make is interrupted)
  36. .DELETE_ON_ERROR:
  37. # define compiler and flags
  38. HOSTCC := gcc
  39. HOSTCFLAGS := -g -Wall -O2
  40. GDB := $(GCCPREFIX)gdb
  41. CC := $(GCCPREFIX)gcc
  42. CFLAGS := -fno-builtin -Wall -ggdb -m32 -gstabs -nostdinc $(DEFS)
  43. CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector)
  44. CTYPE := c S
  45. LD := $(GCCPREFIX)ld
  46. LDFLAGS := -m $(shell $(LD) -V | grep elf_i386 2>/dev/null)
  47. LDFLAGS += -nostdlib
  48. OBJCOPY := $(GCCPREFIX)objcopy
  49. OBJDUMP := $(GCCPREFIX)objdump
  50. COPY := cp
  51. MKDIR := mkdir -p
  52. MV := mv
  53. RM := rm -f
  54. AWK := awk
  55. SED := sed
  56. SH := sh
  57. TR := tr
  58. TOUCH := touch -c
  59. TAR := tar
  60. ZIP := gzip
  61. OBJDIR := obj
  62. BINDIR := bin
  63. ALLOBJS :=
  64. ALLDEPS :=
  65. TARGETS :=
  66. include tools/function.mk
  67. listf_cc = $(call listf,$(1),$(CTYPE))
  68. # for cc
  69. add_files_cc = $(call add_files,$(1),$(CC),$(CFLAGS) $(3),$(2),$(4))
  70. create_target_cc = $(call create_target,$(1),$(2),$(3),$(CC),$(CFLAGS))
  71. # for hostcc
  72. add_files_host = $(call add_files,$(1),$(HOSTCC),$(HOSTCFLAGS),$(2),$(3))
  73. create_target_host = $(call create_target,$(1),$(2),$(3),$(HOSTCC),$(HOSTCFLAGS))
  74. cgtype = $(patsubst %.$(2),%.$(3),$(1))
  75. objfile = $(call toobj,$(1))
  76. asmfile = $(call cgtype,$(call toobj,$(1)),o,asm)
  77. outfile = $(call cgtype,$(call toobj,$(1)),o,out)
  78. symfile = $(call cgtype,$(call toobj,$(1)),o,sym)
  79. # for match pattern
  80. match = $(shell echo $(2) | $(AWK) '{for(i=1;i<=NF;i++){if(match("$(1)","^"$$(i)"$$")){exit 1;}}}'; echo $$?)
  81. # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  82. # include kernel/user
  83. INCLUDE += libs/
  84. CFLAGS += $(addprefix -I,$(INCLUDE))
  85. LIBDIR += libs
  86. $(call add_files_cc,$(call listf_cc,$(LIBDIR)),libs,)
  87. # -------------------------------------------------------------------
  88. # kernel
  89. KINCLUDE += kern/debug/ \
  90. kern/driver/ \
  91. kern/trap/ \
  92. kern/mm/ \
  93. kern/libs/ \
  94. kern/sync/
  95. KSRCDIR += kern/init \
  96. kern/libs \
  97. kern/debug \
  98. kern/driver \
  99. kern/trap \
  100. kern/mm \
  101. kern/sync
  102. KCFLAGS += $(addprefix -I,$(KINCLUDE))
  103. $(call add_files_cc,$(call listf_cc,$(KSRCDIR)),kernel,$(KCFLAGS))
  104. KOBJS = $(call read_packet,kernel libs)
  105. # create kernel target
  106. kernel = $(call totarget,kernel)
  107. $(kernel): tools/kernel.ld
  108. $(kernel): $(KOBJS)
  109. @echo + ld $@
  110. $(V)$(LD) $(LDFLAGS) -T tools/kernel.ld -o $@ $(KOBJS)
  111. @$(OBJDUMP) -S $@ > $(call asmfile,kernel)
  112. @$(OBJDUMP) -t $@ | $(SED) '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > $(call symfile,kernel)
  113. $(call create_target,kernel)
  114. # create kernel_nopage target
  115. kernel_nopage = $(call totarget,kernel_nopage)
  116. $(kernel_nopage): tools/kernel_nopage.ld
  117. $(kernel_nopage): $(KOBJS)
  118. @echo + ld $@
  119. $(V)$(LD) $(LDFLAGS) -T tools/kernel_nopage.ld -o $@ $(KOBJS)
  120. @$(OBJDUMP) -S $@ > $(call asmfile,kernel_nopage)
  121. @$(OBJDUMP) -t $@ | $(SED) '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > $(call symfile,kernel_nopage)
  122. $(call create_target,kernel)
  123. # -------------------------------------------------------------------
  124. # create bootblock
  125. bootfiles = $(call listf_cc,boot)
  126. $(foreach f,$(bootfiles),$(call cc_compile,$(f),$(CC),$(CFLAGS) -Os -nostdinc))
  127. bootblock = $(call totarget,bootblock)
  128. $(bootblock): $(call toobj,boot/bootasm.S) $(call toobj,$(bootfiles)) | $(call totarget,sign)
  129. @echo + ld $@
  130. $(V)$(LD) $(LDFLAGS) -N -T tools/boot.ld $^ -o $(call toobj,bootblock)
  131. @$(OBJDUMP) -S $(call objfile,bootblock) > $(call asmfile,bootblock)
  132. @$(OBJCOPY) -S -O binary $(call objfile,bootblock) $(call outfile,bootblock)
  133. @$(call totarget,sign) $(call outfile,bootblock) $(bootblock)
  134. $(call create_target,bootblock)
  135. # -------------------------------------------------------------------
  136. # create 'sign' tools
  137. $(call add_files_host,tools/sign.c,sign,sign)
  138. $(call create_target_host,sign,sign)
  139. # -------------------------------------------------------------------
  140. # create ucore.img
  141. UCOREIMG := $(call totarget,ucore.img)
  142. $(UCOREIMG): $(kernel) $(bootblock) $(kernel_nopage)
  143. $(V)dd if=/dev/zero of=$@ count=10000
  144. $(V)dd if=$(bootblock) of=$@ conv=notrunc
  145. $(V)dd if=$(kernel) of=$@ seek=1 conv=notrunc
  146. $(call create_target,ucore.img)
  147. # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  148. $(call finish_all)
  149. IGNORE_ALLDEPS = gdb \
  150. clean \
  151. distclean \
  152. grade \
  153. touch \
  154. print-.+ \
  155. handin
  156. ifeq ($(call match,$(MAKECMDGOALS),$(IGNORE_ALLDEPS)),0)
  157. -include $(ALLDEPS)
  158. endif
  159. # files for grade script
  160. targets: $(TARGETS)
  161. .DEFAULT_GOAL := targets
  162. QEMUOPTS = -hda $(UCOREIMG)
  163. .PHONY: qemu qemu-nox gdb debug debug-mon debug-nox
  164. qemu: targets
  165. $(V)$(QEMU) -parallel stdio $(QEMUOPTS) -serial null
  166. qemu-nox: targets
  167. $(V)$(QEMU) -serial mon:stdio $(QEMUOPTS) -nographic
  168. gdb:
  169. $(V)$(GDB) -q -x tools/gdbinit
  170. debug: targets
  171. $(V)$(QEMU) -S -s -parallel stdio $(QEMUOPTS) -serial null
  172. debug-mon: targets
  173. $(V)$(QEMU) -S -s -monitor stdio $(QEMUOPTS) -parallel null -serial null
  174. debug-nox: targets
  175. $(V)$(QEMU) -S -s -serial mon:stdio $(QEMUOPTS) -nographic
  176. .PHONY: grade touch
  177. GRADE_GDB_IN := .gdb.in
  178. GRADE_QEMU_OUT := .qemu.out
  179. HANDIN := lab2-handin.tar.gz
  180. TOUCH_FILES := kern/trap/trap.c
  181. MAKEOPTS := --quiet --no-print-directory
  182. grade:
  183. $(V)$(MAKE) $(MAKEOPTS) clean
  184. $(V)$(SH) tools/grade.sh
  185. touch:
  186. $(V)$(foreach f,$(TOUCH_FILES),$(TOUCH) $(f))
  187. print-%:
  188. @echo $($(shell echo $(patsubst print-%,%,$@) | $(TR) [a-z] [A-Z]))
  189. .PHONY: clean distclean handin tags
  190. clean:
  191. $(V)$(RM) $(GRADE_GDB_IN) $(GRADE_QEMU_OUT) cscope* tags
  192. $(V)$(RM) -r $(OBJDIR) $(BINDIR)
  193. distclean: clean
  194. $(V)$(RM) $(HANDIN)
  195. handin: distclean
  196. $(V)$(TAR) -cf - `find . -type f -o -type d | grep -v '^\.$$' | grep -v '/CVS/' \
  197. | grep -v '/\.git/' | grep -v '/\.svn/' | grep -v "$(HANDIN)"` \
  198. | $(ZIP) > $(HANDIN)
  199. tags:
  200. @echo TAGS ALL
  201. $(V)rm -f cscope.files cscope.in.out cscope.out cscope.po.out tags
  202. $(V)find . -type f -name "*.[chS]" >cscope.files
  203. $(V)cscope -bq
  204. $(V)ctags -L cscope.files