《操作系统》的实验代码。
Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.

281 righe
7.1 KiB

  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