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

264 lines
7.0 KiB

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