FreeBSD 9.1编译内核的优化选项分析

FreeBSD编译内核的优化选项

1、默认的编译优化选项为-O2,可以修改为-O,如下:

在/etc/make.conf里面添加:
COPTFLAGS=-O
之后的make.conf文件如下:
COPTFLAGS=-O
MODULES_OVERRIDE=xfs

COPTFLAGS只专门给内核编译的优化flag设置。

那么就可以看到编译的完整过程都是-O了:
cc -c -O -std=c99 -g -Wall -Wredundant-decls -Wnested-externs -Wstrict-prototypes  -Wmissing-prototypes -Wpointer-arith -Winline -Wcast-qual  -Wundef -Wno-pointer-sign -fformat-extensions  -Wmissing-include-dirs -fdiagnostics-show-option   -nostdinc  -I. -I/usr/src/sys -I/usr/src/sys/contrib/altq -D_KERNEL -DHAVE_KERNEL_OPTION_HEADERS -include opt_global.h -fno-common -finline-limit=8000 --param inline-unit-growth=100 --param large-function-growth=1000  -mno-align-long-strings -mpreferred-stack-boundary=2 -mno-mmx -mno-sse -msoft-float -ffreestanding -fstack-protector -Werror  /usr/src/sys/netinet/sctp_output.c
cc -c -O  -std=c99 -g -Wall -Wredundant-decls -Wnested-externs -Wstrict-prototypes  -Wmissing-prototypes -Wpointer-arith -Winline -Wcast-qual  -Wundef -Wno-pointer-sign -fformat-extensions  -Wmissing-include-dirs -fdiagnostics-show-option   -nostdinc  -I. -I/usr/src/sys -I/usr/src/sys/contrib/altq -D_KERNEL -DHAVE_KERNEL_OPTION_HEADERS -include opt_global.h -fno-common -finline-limit=8000 --param inline-unit-growth=100 --param large-function-growth=1000  -mno-align-long-strings -mpreferred-stack-boundary=2 -mno-mmx -mno-sse -msoft-float -ffreestanding -fstack-protector -Werror  /usr/src/sys/netinet/sctp_pcb.c

但是,在上面make.conf文件中指定的:
MODULES_OVERRIDE=xfs
额外编译则依旧是使用-O2:ex 
cc -O2 -pipe -fno-strict-aliasing -D_KERNEL -DKLD_MODULE -nostdinc   -DHAVE_KERNEL_OPTION_HEADERS -include /usr/obj/usr/src/sys/GK_0219/opt_global.h -I. -I@ -I@/contrib/altq -finline-limit=8000 --param inline-unit-growth=100 --param large-function-growth=1000 -fno-common -g -I/usr/obj/usr/src/sys/GK_0219  -mno-align-long-strings -mpreferred-stack-boundary=2 -mno-mmx -mno-sse -msoft-float -ffreestanding -fstack-protector -std=iso9899:1999 -fstack-protector -Wall -Wredundant-decls -Wnested-externs -Wstrict-prototypes  -Wmissing-prototypes -Wpointer-arith -Winline -Wcast-qual  -Wundef -Wno-pointer-sign -fformat-extensions  -Wmissing-include-dirs -fdiagnostics-show-option    -I/usr/src/sys/modules/xfs/../../gnu/fs/xfs/FreeBSD  -I/usr/src/sys/modules/xfs/../../gnu/fs/xfs/FreeBSD/support  -I/usr/src/sys/modules/xfs/../../gnu/fs/xfs -c /usr/src/sys/modules/xfs/../../gnu/fs/xfs/FreeBSD/xfs_stats.c

因为xfs的编译已经不属于完整内核编译的范围了,我们可以看到最后部分的打印输出,在===> xfs (all)之后才是编译xfs:
rm -f hack.c
MAKE=make sh /usr/src/sys/conf/newvers.sh GENERIC
cc -c -O  -std=c99 -g -Wall -Wredundant-decls -Wnested-externs -Wstrict-prototypes  -Wmissing-prototypes -Wpointer-arith -Winline -Wcast-qual  -Wundef -Wno-pointer-sign -fformat-extensions  -Wmissing-include-dirs -fdiagnostics-show-option   -nostdinc  -I. -I/usr/src/sys -I/usr/src/sys/contrib/altq -D_KERNEL -DHAVE_KERNEL_OPTION_HEADERS -include opt_global.h -fno-common -finline-limit=8000 --param inline-unit-growth=100 --param large-function-growth=1000  -mno-align-long-strings -mpreferred-stack-boundary=2 -mno-mmx -mno-sse -msoft-float -ffreestanding -fstack-protector -Werror  vers.c
linking kernel.debug
   text        data         bss         dec         hex     filename
12978478     1095628     795904     14870010     e2e5fa     kernel.debug
objcopy --only-keep-debug kernel.debug kernel.symbols
objcopy --strip-debug --add-gnu-debuglink=kernel.symbols kernel.debug kernel
cd /usr/src/sys/modules; MAKEOBJDIRPREFIX=/usr/obj/usr/src/sys/GK_0219/modules KMODDIR=/boot/kernel MACHINE_CPUARCH=i386 MODULES_OVERRIDE="xfs" DEBUG_FLAGS="-g" MACHINE=i386 KERNBUILDDIR="/usr/obj/usr/src/sys/GK_0219" SYSDIR="/usr/src/sys" make  all
===> xfs (all)
cc -O2 -pipe -fno-strict-aliasing -D_KERNEL -DKLD_MODULE -nostdinc   -DHAVE_KERNEL_OPTION_HEADERS -include /usr/obj/usr/src/sys/GK_0219/opt_global.h -I. -I@ -I@/contrib/altq -finline-limit=8000 --param inline-unit-growth=100 --param large-function-growth=1000 -fno-common -g -I/usr/obj/usr/src/sys/GK_0219  -mno-align-long-strings -mpreferred-stack-boundary=2 -mno-mmx -mno-sse -msoft-float -ffreestanding -fstack-protector -std=iso9899:1999 -fstack-protector -Wall -Wredundant-decls -Wnested-externs -Wstrict-prototypes  -Wmissing-prototypes -Wpointer-arith -Winline -Wcast-qual  -Wundef -Wno-pointer-sign -fformat-extensions  -Wmissing-include-dirs -fdiagnostics-show-option    -I/usr/src/sys/modules/xfs/../../gnu/fs/xfs/FreeBSD  -I/usr/src/sys/modules/xfs/../../gnu/fs/xfs/FreeBSD/support  -I/usr/src/sys/modules/xfs/../../gnu/fs/xfs -c /usr/src/sys/modules/xfs/../../gnu/fs/xfs/xfs_alloc.c


至于为什么默认kernel部分(非modules部分),是-O2的属性呢?
那是因为这块的控制是在/usr/src/sys/conf下面的三个文件控制的:
-rw-r--r--  1 root  wheel    5028 Dec  4 06:11 kern.mk
-rw-r--r--  1 root  wheel    9774 Dec  4 06:11 kern.post.mk
-rw-r--r--  1 root  wheel    5263 Feb 21 15:53 kern.pre.mk

Makefile.i386开头处会包含(include) kern.prev.mk,结尾处会包含后面的kern.post.mk,而kern.post.mk的开头处又会包含,而在kern.post.mk里面有这么一段:

.if defined(DEBUG)
_MINUS_O=       -O
CTFFLAGS+=      -g
.else
.if ${MACHINE_CPUARCH} == "powerpc"
_MINUS_O=       -O      # gcc miscompiles some code at -O2
.else
_MINUS_O=       -O2
.endif
.endif
.if ${MACHINE_CPUARCH} == "amd64"
.if ${MK_CLANG_IS_CC} == "no" && ${CC:T:Mclang} != "clang"
COPTFLAGS?=-O2 -frename-registers -pipe
.else
COPTFLAGS?=-O2 -pipe
.endif
.else
COPTFLAGS?=${_MINUS_O} -pipe
.endif
一旦DEBUG宏开启,那么一定就是使用不优化编译了,否则使用-O2优化级别编译。还可以看出make.conf文件里面的COPTFLAGS定义对优化的影响,如果定义了取定义的,没有的话取前面定义的.makefile里面的?=的意思就是,如果前面的变量没有定义,就用后面的设置。

2、再说一点就是,前面编译的是内核的一些东西,比如kernel kernel.debug kernel.symbols
linking kernel.debug
   text        data         bss         dec         hex     filename
12823834     1086444     784256     14694534     e03886     kernel.debug
objcopy --only-keep-debug kernel.debug kernel.symbols
objcopy --strip-debug --add-gnu-debuglink=kernel.symbols kernel.debug kernel
cd /usr/src/sys/modules; MAKEOBJDIRPREFIX=/usr/obj/usr/src/sys/GK_0217/modules KMODDIR=/boot/kernel MACHINE_CPUARCH=i386 DEBUG_FLAGS="-g" MACHINE=i386 KERNBUILDDIR="/usr/obj/usr/src/sys/GK_0217" SYSDIR="/usr/src/sys" make  all
而这些东西,在前面的make.conf里面,指定COPTFLAGS=-O,仅仅对这个编译有效果,但是不会对后面的模块编译产生效果,后面的这些:
===> xfs (all)
cc -O2 -pipe -fno-strict-aliasing -D_KERNEL -DKLD_MODULE -nostdinc   -DHAVE_KERNEL_OPTION_HEADERS -include /usr/obj/usr/src/sys/GK_0219/opt_global.h -I. -I@ -I@/contrib/altq -finline-limit=8000 --param inline-unit-growth=100 --param large-function-growth=1000 -fno-common -g -I/usr/obj/usr/src/sys/GK_0219  -mno-align-long-strings -mpreferred-stack-boundary=2 -mno-mmx -mno-sse -msoft-float -ffreestanding -fstack-protector -std=iso9899:1999 -fstack-protector -Wall -Wredundant-decls -Wnested-externs -Wstrict-prototypes  -Wmissing-prototypes -Wpointer-arith -Winline -Wcast-qual  -Wundef -Wno-pointer-sign -fformat-extensions  -Wmissing-include-dirs -fdiagnostics-show-option    -I/usr/src/sys/modules/xfs/../../gnu/fs/xfs/FreeBSD  -I/usr/src/sys/modules/xfs/../../gnu/fs/xfs/FreeBSD/support  -I/usr/src/sys/modules/xfs/../../gnu/fs/xfs -c /usr/src/sys/modules/xfs/../../gnu/fs/xfs/xfs_alloc.c
就是做模块,那么他的编译选项在哪里呢?
他的编译选项在/usr/src/share/mk 这里,具体是在文件sys.mk文件里面指定的。
45   
46 .if defined(%POSIX)      
47 CC      ?=  c89          
48 CFLAGS      ?=  -O       
49 .else
50 CC      ?=  cc
51 .if ${MACHINE_CPUARCH} == "arm" || ${MACHINE_CPUARCH} == "mips"                                                                                                             
52 CFLAGS      ?=  -O -pipe 
53 .else
54 CFLAGS      ?=  -O2 -pipe
55 .endif
56 .if defined(NO_STRICT_ALIASING)
"sys.mk" [Modified][readonly] 373 lines --14%--    

在上面的“cc -O2 -pipe ”是不是就一致了。

3、最后说一点,就是如果编译完整的内核而不是在make.conf里面指定:
MODULES_OVERRIDE=xxx
那么在:
linking kernel.debug
   text        data         bss         dec         hex     filename
12823834     1086444     784256     14694534     e03886     kernel.debug
objcopy --only-keep-debug kernel.debug kernel.symbols
objcopy --strip-debug --add-gnu-debuglink=kernel.symbols kernel.debug kernel

之后就是开始编译所有的modules,比如:

cd /usr/src/sys/modules; MAKEOBJDIRPREFIX=/usr/obj/usr/src/sys/GK_0217/modules KMODDIR=/boot/kernel MACHINE_CPUARCH=i386 DEBUG_FLAGS="-g" MACHINE=i386 KERNBUILDDIR="/usr/obj/usr/src/sys/GK_0217" SYSDIR="/usr/src/sys" make  all
===> 3dfx (all)
cc -O2 -pipe -fno-strict-aliasing -Werror -D_KERNEL -DKLD_MODULE -nostdinc   -DHAVE_KERNEL_OPTION_HEADERS -include /usr/obj/usr/src/sys/GK_0217/opt_global.h -I. -I@ -I@/contrib/altq -finline-limit=8000 --param inline-unit-growth=100 --param large-function-growth=1000 -fno-common -g -I/usr/obj/usr/src/sys/GK_0217  -mno-align-long-strings -mpreferred-stack-boundary=2 -mno-mmx -mno-sse -msoft-float -ffreestanding -fstack-protector -std=iso9899:1999 -fstack-protector -Wall -Wredundant-decls -Wnested-externs -Wstrict-prototypes  -Wmissing-prototypes -Wpointer-arith -Winline -Wcast-qual  -Wundef -Wno-pointer-sign -fformat-extensions  -Wmissing-include-dirs -fdiagnostics-show-option   -c /usr/src/sys/modules/3dfx/../../dev/tdfx/tdfx_pci.c
ld  -d -warn-common -r -d -o 3dfx.kld tdfx_pci.o
:> export_syms
awk -f /usr/src/sys/conf/kmod_syms.awk 3dfx.kld  export_syms | xargs -J% objcopy % 3dfx.kld
ld -Bshareable  -d -warn-common -o 3dfx.ko.debug 3dfx.kld
objcopy --only-keep-debug 3dfx.ko.debug 3dfx.ko.symbols
objcopy --strip-debug --add-gnu-debuglink=3dfx.ko.symbols 3dfx.ko.debug 3dfx.ko
===> 3dfx_linux (all)
cc -O2 -pipe -fno-strict-aliasing -Werror -D_KERNEL -DKLD_MODULE -nostdinc   -DHAVE_KERNEL_OPTION_HEADERS -include /usr/obj/usr/src/sys/GK_0217/opt_global.h -I. -I@ -I@/contrib/altq -finline-limit=8000 --param inline-unit-growth=100 --param large-function-growth=1000 -fno-common -g -I/usr/obj/usr/src/sys/GK_0217  -mno-align-long-strings -mpreferred-stack-boundary=2 -mno-mmx -mno-sse -msoft-float -ffreestanding -fstack-protector -std=iso9899:1999 -fstack-protector -Wall -Wredundant-decls -Wnested-externs -Wstrict-prototypes  -Wmissing-prototypes -Wpointer-arith -Winline -Wcast-qual  -Wundef -Wno-pointer-sign -fformat-extensions  -Wmissing-include-dirs -fdiagnostics-show-option   -c /usr/src/sys/modules/3dfx_linux/../../dev/tdfx/tdfx_linux.c
ld  -d -warn-common -r -d -o 3dfx_linux.kld tdfx_linux.o
:> export_syms
awk -f /usr/src/sys/conf/kmod_syms.awk 3dfx_linux.kld  export_syms | xargs -J% objcopy % 3dfx_linux.kld
ld -Bshareable  -d -warn-common -o 3dfx_linux.ko.debug 3dfx_linux.kld
objcopy --only-keep-debug 3dfx_linux.ko.debug 3dfx_linux.ko.symbols
objcopy --strip-debug --add-gnu-debuglink=3dfx_linux.ko.symbols 3dfx_linux.ko.debug 3dfx_linux.ko
===> aac (all)

上面的:
cd /usr/src/sys/modules; MAKEOBJDIRPREFIX=/usr/obj/usr/src/sys/GK_0217/modules KMODDIR=/boot/kernel MACHINE_CPUARCH=i386 DEBUG_FLAGS="-g" MACHINE=i386 KERNBUILDDIR="/usr/obj/usr/src/sys/GK_0217" SYSDIR="/usr/src/sys" make  all
就是说要进入cd /usr/src/sys/modules路径,然后编译,就是根据Makefile做编译了,那么看看部分的Makefile:

ztz0223@BTazuo:/usr/src/sys/modules % vim Makefile

  1 # $FreeBSD: release/9.1.0/sys/modules/Makefile 237795 2012-06-29 15:57:25Z obrien $
  2                          
  3 .include <bsd.own.mk>
  4 
  5 # Modules that include binary-only blobs of microcode should be selectable by
  6 # MK_SOURCELESS_UCODE option (see below).
  7   
  8 SUBDIR= \                
  9     ${_3dfx} \           
10     ${_3dfx_linux} \     
11     ${_aac} \            
12     accf_data \          
13     accf_dns \           
14     accf_http \          
15     ${_acpi} \           
16     ae \
17     ${_aesni} \          
18     age \
19     ${_agp} \          

那么从subdir目录就可以看出,编译顺序也是3dfx,3dfx_linux,aac。。。。。。完全的编译所有的subdir里面的文件夹,也就是这些modules

如果指定了  MODULES_OVERRIDE=xxx,那么Makefile里面还有说明:
799 .if defined(MODULES_OVERRIDE) && !defined(ALL_MODULES)
800 SUBDIR=${MODULES_OVERRIDE}
801 .endif
重新限定了编译的子目录,也就是限定的modules。
另外,可以置空,也就是MODULES_OVERRIDE=,后面不带任何模块名,则,系统仅仅做kernel不会,不会做模块。
 

你可能感兴趣的:(FreeBSD 9.1编译内核的优化选项分析)