《操作系统》的实验代码。

292 lines
7.6 KiB

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