《操作系统》的实验代码。
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.

269 lines
7.1 KiB

12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
  1. PROJ := challenge
  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-elf-objdump -i 2>&1 | grep '^elf32-i386$$' >/dev/null 2>&1; \
  11. then echo 'i386-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-elf version of GCC/binutils." 1>&2; \
  16. echo "*** Is the directory with i386-elf-gcc in your PATH?" 1>&2; \
  17. echo "*** If your i386-elf toolchain is installed with a command" 1>&2; \
  18. echo "*** prefix other than 'i386-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. CTYPE := c S
  56. LD := $(GCCPREFIX)ld
  57. LDFLAGS := -m $(shell $(LD) -V | grep elf_i386 2>/dev/null)
  58. LDFLAGS += -nostdlib
  59. OBJCOPY := $(GCCPREFIX)objcopy
  60. OBJDUMP := $(GCCPREFIX)objdump
  61. COPY := cp
  62. MKDIR := mkdir -p
  63. MV := mv
  64. RM := rm -f
  65. AWK := awk
  66. SED := sed
  67. SH := sh
  68. TR := tr
  69. TOUCH := touch -c
  70. OBJDIR := obj
  71. BINDIR := bin
  72. ALLOBJS :=
  73. ALLDEPS :=
  74. TARGETS :=
  75. include tools/function.mk
  76. listf_cc = $(call listf,$(1),$(CTYPE))
  77. # for cc
  78. add_files_cc = $(call add_files,$(1),$(CC),$(CFLAGS) $(3),$(2),$(4))
  79. create_target_cc = $(call create_target,$(1),$(2),$(3),$(CC),$(CFLAGS))
  80. # for hostcc
  81. add_files_host = $(call add_files,$(1),$(HOSTCC),$(HOSTCFLAGS),$(2),$(3))
  82. create_target_host = $(call create_target,$(1),$(2),$(3),$(HOSTCC),$(HOSTCFLAGS))
  83. cgtype = $(patsubst %.$(2),%.$(3),$(1))
  84. objfile = $(call toobj,$(1))
  85. asmfile = $(call cgtype,$(call toobj,$(1)),o,asm)
  86. outfile = $(call cgtype,$(call toobj,$(1)),o,out)
  87. symfile = $(call cgtype,$(call toobj,$(1)),o,sym)
  88. # for match pattern
  89. match = $(shell echo $(2) | $(AWK) '{for(i=1;i<=NF;i++){if(match("$(1)","^"$$(i)"$$")){exit 1;}}}'; echo $$?)
  90. # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  91. # include kernel/user
  92. INCLUDE += libs/
  93. CFLAGS += $(addprefix -I,$(INCLUDE))
  94. LIBDIR += libs
  95. $(call add_files_cc,$(call listf_cc,$(LIBDIR)),libs,)
  96. # -------------------------------------------------------------------
  97. # kernel
  98. KINCLUDE += kern/debug/ \
  99. kern/driver/ \
  100. kern/trap/ \
  101. kern/mm/
  102. KSRCDIR += kern/init \
  103. kern/libs \
  104. kern/debug \
  105. kern/driver \
  106. kern/trap \
  107. kern/mm
  108. KCFLAGS += $(addprefix -I,$(KINCLUDE))
  109. $(call add_files_cc,$(call listf_cc,$(KSRCDIR)),kernel,$(KCFLAGS))
  110. KOBJS = $(call read_packet,kernel libs)
  111. # create kernel target
  112. kernel = $(call totarget,kernel)
  113. $(kernel): tools/kernel.ld
  114. $(kernel): $(KOBJS)
  115. @echo + ld $@
  116. $(V)$(LD) $(LDFLAGS) -T tools/kernel.ld -o $@ $(KOBJS)
  117. @$(OBJDUMP) -S $@ > $(call asmfile,kernel)
  118. @$(OBJDUMP) -t $@ | $(SED) '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > $(call symfile,kernel)
  119. $(call create_target,kernel)
  120. # -------------------------------------------------------------------
  121. # create bootblock
  122. bootfiles = $(call listf_cc,boot)
  123. $(foreach f,$(bootfiles),$(call cc_compile,$(f),$(CC),$(CFLAGS) -Os -nostdinc))
  124. bootblock = $(call totarget,bootblock)
  125. $(bootblock): $(call toobj,$(bootfiles)) | $(call totarget,sign)
  126. @echo + ld $@
  127. $(V)$(LD) $(LDFLAGS) -N -e start -Ttext 0x7C00 $^ -o $(call toobj,bootblock)
  128. @$(OBJDUMP) -S $(call objfile,bootblock) > $(call asmfile,bootblock)
  129. @$(OBJCOPY) -S -O binary $(call objfile,bootblock) $(call outfile,bootblock)
  130. @$(call totarget,sign) $(call outfile,bootblock) $(bootblock)
  131. $(call create_target,bootblock)
  132. # -------------------------------------------------------------------
  133. # create 'sign' tools
  134. $(call add_files_host,tools/sign.c,sign,sign)
  135. $(call create_target_host,sign,sign)
  136. # -------------------------------------------------------------------
  137. # create ucore.img
  138. UCOREIMG := $(call totarget,ucore.img)
  139. $(UCOREIMG): $(kernel) $(bootblock)
  140. $(V)dd if=/dev/zero of=$@ count=10000
  141. $(V)dd if=$(bootblock) of=$@ conv=notrunc
  142. $(V)dd if=$(kernel) of=$@ seek=1 conv=notrunc
  143. $(call create_target,ucore.img)
  144. # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  145. $(call finish_all)
  146. IGNORE_ALLDEPS = clean \
  147. dist-clean \
  148. grade \
  149. touch \
  150. print-.+ \
  151. handin
  152. ifeq ($(call match,$(MAKECMDGOALS),$(IGNORE_ALLDEPS)),0)
  153. -include $(ALLDEPS)
  154. endif
  155. # files for grade script
  156. TARGETS: $(TARGETS)
  157. .DEFAULT_GOAL := TARGETS
  158. .PHONY: qemu qemu-nox debug debug-nox
  159. qemu-mon: $(UCOREIMG)
  160. $(V)$(QEMU) -no-reboot -monitor stdio -hda $< -serial null
  161. qemu: $(UCOREIMG)
  162. $(V)$(QEMU) -no-reboot -parallel stdio -hda $< -serial null
  163. log: $(UCOREIMG)
  164. $(V)$(QEMU) -no-reboot -d int,cpu_reset -D q.log -parallel stdio -hda $< -serial null
  165. qemu-nox: $(UCOREIMG)
  166. $(V)$(QEMU) -no-reboot -serial mon:stdio -hda $< -nographic
  167. TERMINAL :=gnome-terminal
  168. debug: $(UCOREIMG)
  169. $(V)$(QEMU) -S -s -parallel stdio -hda $< -serial null &
  170. $(V)sleep 2
  171. $(V)$(TERMINAL) -e "gdb -q -tui -x tools/gdbinit"
  172. debug-nox: $(UCOREIMG)
  173. $(V)$(QEMU) -S -s -serial mon:stdio -hda $< -nographic &
  174. $(V)sleep 2
  175. $(V)$(TERMINAL) -e "gdb -q -x tools/gdbinit"
  176. .PHONY: grade touch
  177. GRADE_GDB_IN := .gdb.in
  178. GRADE_QEMU_OUT := .qemu.out
  179. HANDIN := proj$(PROJ)-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 dist-clean handin packall tags
  190. clean:
  191. $(V)$(RM) $(GRADE_GDB_IN) $(GRADE_QEMU_OUT) cscope* tags
  192. -$(RM) -r $(OBJDIR) $(BINDIR)
  193. dist-clean: clean
  194. -$(RM) $(HANDIN)
  195. handin: packall
  196. @echo Please visit http://learn.tsinghua.edu.cn and upload $(HANDIN). Thanks!
  197. packall: clean
  198. @$(RM) -f $(HANDIN)
  199. @tar -czf $(HANDIN) `find . -type f -o -type d | grep -v '^\.*$$' | grep -vF '$(HANDIN)'`
  200. tags:
  201. @echo TAGS ALL
  202. $(V)rm -f cscope.files cscope.in.out cscope.out cscope.po.out tags
  203. $(V)find . -type f -name "*.[chS]" >cscope.files
  204. $(V)cscope -bq
  205. $(V)ctags -L cscope.files