FreeBSD内核文件编译分析
在网上找了好久,一点可用的文章都没有找到,FreeBSD的官网的文章也没有给出说法,只能自己在/usr/src和/usr/src/sys和/usr/src/sys/conf下面疯狂的grep,找文件,找引用,才有了自己的一些理解。先说说Linux的内核文件的编译关联吧,Linux的每个文件的编译和是kconfig配置关联在一起的,kconfig在经过make menuconfig之后,得到一个.config文件,然后每个文件夹下面的Makefile,会check这个全局的.config文件,来决定哪些文件该编译,哪些不用编译。多说无益,参考代码即可。
FreeBSD的做法有些不一样了,Linux把哪些文件要编译分散到了每个文件夹,然后check Makefile。FreeBSD是做两个总的文件,决定哪些文件该编译哪些不该,这两个文件分别是这个路径下:
ztz0223@BTazuo:/usr/src/sys/conf % pwd
/usr/src/sys/conf
的两个文件:files,files.i386
files是与架构无关的,也就是不管代码在什么平台上面编译,i386或者power pc上面都靠这个文件控制编译。对应的files.i386,就是特定平台的编译控制。
我们来看一下,这两个文件里面是什么吧,首先是files:
2082 dev/xe/if_xe.c optional xe
2083 dev/xe/if_xe_pccard.c optional xe pccard
2084 dev/xl/if_xl.c optional xl pci
2085 dev/xl/xlphy.c optional xl pci
2086 fs/coda/coda_fbsd.c optional vcoda
2087 fs/coda/coda_psdev.c optional vcoda
2088 fs/coda/coda_subr.c optional vcoda
2089 fs/coda/coda_venus.c optional vcoda
2090 fs/coda/coda_vfsops.c optional vcoda
2091 fs/coda/coda_vnops.c optional vcoda
2092 fs/deadfs/dead_vnops.c standard
2093 fs/devfs/devfs_devs.c standard
2094 fs/devfs/devfs_dir.c standard
2095 fs/devfs/devfs_rule.c standard
2096 fs/devfs/devfs_vfsops.c standard
2097 fs/devfs/devfs_vnops.c standard
2098 fs/fdescfs/fdesc_vfsops.c optional fdescfs
2099 fs/fdescfs/fdesc_vnops.c optional fdescfs
2100 fs/fifofs/fifo_vnops.c standard
2101 fs/hpfs/hpfs_alsubr.c optional hpfs
2102 fs/hpfs/hpfs_lookup.c optional hpfs
"files" [readonly] 3544 lines --57%--
再看files.i386:
417 i386/i386/minidump_machdep.c standard
418 i386/i386/mp_clock.c optional smp
419 i386/i386/mp_machdep.c optional native smp
420 i386/xen/mp_machdep.c optional xen smp
421 i386/i386/mp_watchdog.c optional mp_watchdog smp
422 i386/i386/mpboot.s optional smp native
423 i386/xen/mptable.c optional apic xen
424 i386/i386/perfmon.c optional perfmon
425 i386/i386/pmap.c optional native
426 i386/xen/pmap.c optional xen
427 i386/i386/ptrace_machdep.c standard
428 i386/i386/stack_machdep.c optional ddb | stack
429 i386/i386/support.s standard
430 i386/i386/swtch.s standard
431 i386/i386/sys_machdep.c standard
432 i386/i386/trap.c standard
433 i386/i386/uio_machdep.c standard
434 i386/i386/vm86.c standard
435 i386/i386/vm_machdep.c standard
436 i386/ibcs2/ibcs2_errno.c optional ibcs2
437 i386/ibcs2/ibcs2_fcntl.c optional ibcs2
438 i386/ibcs2/ibcs2_ioctl.c optional ibcs2
439 i386/ibcs2/ibcs2_ipc.c optional ibcs2
440 i386/ibcs2/ibcs2_isc.c optional ibcs2
"files.i386" [readonly] 537 lines --71%--
对于上面的files,我要说的就是,后面带有standard的表明该文件一定会编译,不管是快速编译指定模块,还是全部完全编译。 二 optional xxx标识当xxx选项开启的时候,才会编译对应的文件。
上面files.i386可以看出:
436 i386/ibcs2/ibcs2_errno.c optional ibcs2 只有在ibcs2选项开启的时候才会编译
而:
432 i386/i386/trap.c standard 在i386架构平台下编译的话,一定要编译的。
OK,说到这里,已经知道文件如何编译的了,那么在指定快速编译的时候,就是在make.conf里面指定编译的模块,就如官网文档所示:
------------------------------
联编内核
1. 进入 /usr/src 目录:
# cd /usr/src
2. 编译内核:
# make buildkernel KERNCONF=MYKERNEL
3. 安装新内核:
# make installkernel KERNCONF=MYKERNEL
注意: 使用这种方法联编内核时, 需要安装完整的 FreeBSD 源代码。
提示: 默认情况下, 在联编您所定制的内核时, 全部 内核模块也会同时参与构建。 如果您希望更快地升级内核, 或者只希望联编您所需要的模块, 则应在联编之前编辑 /etc/make.conf:
MODULES_OVERRIDE = linux acpi sound/sound sound/driver/ds1 ntfs
这个变量的内容是所希望构建的模块列表。
WITHOUT_MODULES = linux acpi sound ntfs
这个变量的内容是将不在联编过程中编译的顶级模块列表。 如果希望了解更多与构建内核有关的变量, 请参见 make.conf(5) 联机手册。
------------------------------
比如,我在/etc/make.conf里面指定:
MODULES_OVERRIDE = xfs
那么是不是仅仅编译xfs的文件吗?
当然不是,当我们执行
# make buildkernel KERNCONF=MYKERNEL
开始编译的时候,会发现打印里面有
cc -c -O -pipe -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/cam/ata/ata_all.c
但是我们可以从files里面看出来:
110 cam/ata/ata_all.c optional scbus
scbus开启才会编译这个文件。
为什么他会编译?
很简单,我们看
# make buildkernel KERNCONF=MYKERNEL
的最开始有一些打印,是删除中间文件的:
--------------------------------------------------------------
>>> stage 2.1: cleaning up the object tree
--------------------------------------------------------------
cd /usr/obj/usr/src/sys/GENERIC_20130217; MAKEOBJDIRPREFIX=/usr/obj MACHINE_ARCH=i386 MACHINE=i386 CPUTYPE= GROFF_BIN_PATH=/usr/obj/usr/src/tmp/legacy/usr/bin GROFF_FONT_PATH=/usr/obj/usr/src/tmp/legacy/usr/share/groff_font GROFF_TMAC_PATH=/usr/obj/usr/src/tmp/legacy/usr/share/tmac _SHLIBDIRPREFIX=/usr/obj/usr/src/tmp _LD
补充:综合编程 , 其他综合 ,