OBJS=\bio.o\console.o\exec.o\file.o\fs.o\ide.o\ioapic.o\kalloc.o\kbd.o\lapic.o\log.o\main.o\mp.o\picirq.o\pipe.o\proc.o\sleeplock.o\spinlock.o\string.o\swtch.o\syscall.o\sysfile.o\sysproc.o\timer.o\trapasm.o\trap.o\uart.o\vectors.o\vm.o\定义了一个变量OBJS,内容为等号后面的内容,‘\’为换行符,方便阅读#Cross-compiling(e.g.,onMacOSX)#TOOLPREFIX=i386-jos-elf#Usingnativetools(e.g.,onX86Linux)#TOOLPREFIX=#TrytoinferthecorrectTOOLPREFIXifnotset如果变量TOOLPERFIX为空那么为TOOLPREFIX赋个值objdump命令是:查看目标文件/可执行文件的构成的gcc工具/反汇编如果都不是,则将echo错误信息信息“***Error:Couldn'tfindani386-*-elfversionofGCC/binutils......”本来是从标准输出-赋给变量,重定向到了标准错误里ifndefTOOLPREFIXTOOLPREFIX:=$(shellifi386-jos-elf-objdump-i2&1|grep'^elf32-i386$$'/dev/null2&1;\thenecho'i386-jos-elf-';\elifobjdump-i2&1|grep'elf32-i386'/dev/null2&1;\thenecho'';\elseecho***1&2;\echo***Error:Couldn'tfindani386-*-elfversionofGCC/binutils.1&2;\echo***Isthedirectorywithi386-jos-elf-gccinyourPATH?1&2;\echo***Ifyouri386-*-elftoolchainisinstalledwithacommand1&2;\echo***prefixotherthan'i386-jos-elf-',setyourTOOLPREFIX1&2;\echo***environmentvariabletothatprefixandrun'make'again.1&2;\echo***Toturnoffthiserror,run'gmakeTOOLPREFIX=...'.1&2;\echo***1&2;exit1;fi)endif如果变量QEMU为空,那么给QEMU赋值前面加个shell意为要执行shell脚本了如果能够在当前路径找到可执行文件qemu,那么首先不输出(因为/dev/null了),并把该路径赋给变量QEMU,退出。如果在当前路径下能够找到可执行文件qemu-system-i386,那么不输出(因为/dev/null了),把该路径赋给变量QEMU,退出。如果qemu和qemu-system-i386的路径都为空,那么把qemu的值设为/Applications/Q.app/Contents/MacOS/i386-softmmu.app/Contents/MacOS/i386-softmmu检测qemu文件是否存在且可执行权限如果存在,则将变量QEMU设为/Applications/Q.app/Contents/MacOS/i386-softmmu.app/Contents/MacOS/i386-softmmu,并且退出。如果上面没有退出——即上面的if没进去,那么执行下面,$(echo'错误信息'),并且由于是1&2,本来是从标准输出-赋给变量,重定向到了标准错误里#Ifthemakefilecan'tfindQEMU,specifyitspathhere#QEMU=qemu-system-i386#TrytoinferthecorrectQEMUifndefQEMUQEMU=$(shellifwhichqemu/dev/null;\thenechoqemu;exit;\elifwhichqemu-system-i386/dev/null;\thenechoqemu-system-i386;exit;\else\qemu=/Applications/Q.app/Contents/MacOS/i386-softmmu.app/Contents/MacOS/i386-softmmu;\iftest-x$$qemu;thenecho$$qemu;exit;fi;fi;\echo***1&2;\echo***Error:Couldn'tfindaworkingQEMUexecutable.1&2;\echo***IsthedirectorycontainingtheqemubinaryinyourPATH1&2;\echo***orhaveyoutriedsettingtheQEMUvariableinMakefile?1&2;\echo***1&2;exit1)endifCC=$(TOOLPREFIX)gcc定义变量CC,值为——TOOLPREFIX的值gcc(从下文可知,gcc在CFALGS中只承担了-E预编译的的任务,即完成了第一步预编译)AS=$(TOOLPREFIX)gas定义变量AS,值为——TOOLPREFIX的值gas(gas为汇编器,实现了汇编这一步骤)LD=$(TOOLPREFIX)ld定义变量LD,值为——TOOLPREFIX的值ld(ld命令是把一定量的目标文件(.o文件)和档案文件,并重定位她们的数据,链接符号的引用,最后生成一个可执行文件即程序中预处理、编译、汇编、链接中的链接。)OBJCOPY=$(TOOLPREFIX)objcopy定义变量OBJCOPY,值为——TOOLPREFIX的值objcopy(objcopy命令是:将不同类型的文件之间进行拷贝)OBJDUMP=$(TOOLPREFIX)objdump定义变量OBJCOPY,值为——TOOLPREFIX的值objdump(objdump命令是:查看目标文件/可执行文件的构成的gcc工具/反汇编)所以综上所述,我们其实可以看出来,TOOLPREFIX其实就是一个前缀,为了让本脚本能在交叉编译环境不出错,起主要作用的还是后面的东西。CFLAGS=-fno-pic-static-fno-builtin-fno-strict-aliasing-O2-Wall-MD-ggdb-m32-Werror-fno-omit-frame-pointer定义变量CFLAGS值为“-fno-pic-static-fno-builtin-fno-strict-aliasing-O2-Wall-MD-ggdb-m32-Werror-fno-omit-frame-pointer”#CFLAGS=-fno-pic-static-fno-builtin-fno-strict-aliasing-fvar-tracking-fvar-tracking-assignments-O0-g-Wall-MD-gdwarf-2-m32-Werror-fno-omit-frame-pointerCFLAGS+=$(shell$(CC)-fno-stack-protector-E-xc/dev/null/dev/null2&1&&echo-fno-stack-protector)追加变量,追加的值为shell脚本“$(CC)-fno-stack-protector-E-xc/dev/null/dev/null2&1&&echo-fno-stack-protector”执行的输出值CC为调用gcc编译器,各个编译选项为:对于'&&'运算符,即只有左边的被执行成功了右边才会执行——echo'-fno-stack-protector'即将-fno-stack-protector追加到变量CFLAGS里面(因为该$()的意思就是把shell脚本的输出结果赋给变量)ASFLAGS=-m32-gdwarf-2-Wa,-divide定义变量ASFLAGS,#FreeBSDldwants``elf_i386_fbsd''LDFLAGS+=-m$(shell$(LD)-V|grepelf_i3862/dev/null|head-n1)变量LDFLAGS追加-m选项和后面shell脚本的输出值#shell脚本里面:ld-v:显示ld的版本号,同时列出支持的模拟器,通过管道作为后面的grep匹配的输入——看一下他支持的模拟有没有匹配'elf_i386'的,并且若有错误,抛出到黑洞——不输出得到的匹配的模拟器中的第一个追加到LDFLAGS后面xv6.img:bootblockkernelfs.imgddif=/dev/zeroof=xv6.imgcount=10000ddif=bootblockof=xv6.imgconv=notruncddif=kernelof=xv6.imgseek=1conv=notrunc想要生成xv6.img需要的东西有:bootblock(主板上的引导快——bios上烧的一段程序),linux的“kernal”文件,及fs.img/dev/zero是一个无穷的null二进制流,用来初始化文件的执行的命令有:dd命令:用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换xv6memfs.img:bootblockkernelmemfsddif=/dev/zeroof=xv6memfs.imgcount=10000ddif=bootblockof=xv6memfs.imgconv=notruncddif=kernelmemfsof=xv6memfs.imgseek=1conv=notrunc想要生成xv6memfs.img需要的东西有:bootblock(主板上的引导快)kernelmemfsbootblock:bootasm.Sbootmain.c$(CC)$(CFLAGS)-fno-pic-O-nostdinc-I.-cbootmain.c$(CC)$(CFLAGS)-fno-pic-nostdinc-I.-cbootasm.S$(LD)$(LDFLAGS)-N-estart-Ttext0x7C00-obootblock.obootasm.obootmain.o$(OBJDUMP)-Sbootblock.obootblock.asm$(OBJCOPY)-S-Obinary-j.textbootblock.obootblock./sign.plbootblock生成bootblock需要的东西有bootasm.Sbootmain.c除了以上编译选项外,还有CFLAGS指定的编译选项除了以上链接ld选项外,还有LDFLAGS指定的编译选项链接bootasm.obootmain.o,并指定输出文件为bootblock.o输出bootblock.o的C源代码和反汇编出来的指令对照,并重定向输出到bootblock.asmobjcopy:将输入文件bootblock.o拷贝至bootblock执行文件sign.pl并将bootblock作为参数传进去entryother:entryother.S$(CC)$(CFLAGS)-fno-pic-nostdinc-I.-centryother.S$(LD)$(LDFLAGS)-N-estart-Ttext0x7000-obootblockother.oentryother.o$(OBJCOPY)-S-Obinary-j.textbootblockother.oentryother$(OBJDUMP)-Sb