您的位置:首页 > 其它

浅谈kernel的结构图及生成过程(转载)

2016-03-10 14:45 357 查看
转载链接:http://www.codesec.net/view/216828.html

注:本转载省略掉部分内容,还有很多不理解的地方,而且内核版本和目前所看的不同,内容有出入

makefile是管理整个工程的,那我们第二个要看的当然是Makefile了(哈哈,第一个要看的当然是README了,养成这个好习惯),在Makefile中的起始我们就能看到:

# To see a list of typical targets execute "make help"
# More info can be located in ./README


没错,看下Makefile当中的help:

1244 help:
1245 @echo 'Cleaning targets:'
1246 @echo ' clean - Remove most generated files but keep the config and'
1247 @echo ' enough build support to build external modules'
1248 @echo ' mrproper - Remove all generated files + config + various backup files'
1249 @echo ' distclean - mrproper + remove editor backup and patch files'
1250 @echo ''
1251 @echo 'Configuration targets:'
1252 @$(MAKE) -f $(srctree)/scripts/kconfig/Makefile help
1253 @echo ''
1254 @echo 'Other generic targets:'
1255 @echo ' all - Build all targets marked with [*]'
1256 @echo '* vmlinux - Build the bare kernel'
1257 @echo '* modules - Build all modules'
1258 @echo ' modules_install - Install all modules to INSTALL_MOD_PATH (default: /)'
1259 @echo ' firmware_install- Install all firmware to INSTALL_FW_PATH'
1260 @echo ' (default: $$(INSTALL_MOD_PATH)/lib/firmware)'
1261 @echo ' dir/ - Build all files in dir and below'
1262 @echo ' dir/file.[oisS] - Build specified target only'


比较多行就不全部罗列出来了,可以看到用make menuconfig来生成一个指示工程编译的配置文件.config。致于这个界面是如何产生的,然后又如何生成.config的,我还是说一下吧:还是看Makefile:

527 config: scripts_basic outputmakefile FORCE
528 $(Q)$(MAKE) $(build)=scripts/kconfig $@
529
530 %config: scripts_basic outputmakefile FORCE
531 $(Q)$(MAKE) $(build)=scripts/kconfig $@


对,是通过…/scripts/kconfig这个脚本来产生的(…代表源码树主目录)。大家会发现主目录下的子目录里都有一个Kconfig,它就是用于给menuconfig来配置编译信息的。既然这通过它来达到间接配置编译相关指示信息的,那就看看…/Kconfig:

mainmenu "Linux/$ARCH $KERNELVERSION Kernel Configuration"
config SRCARCH
string
option env="SRCARCH"
source "arch/$SRCARCH/Kconfig"


看到source后就进去看…/arch/$SRCARCH/Kconfig文件吧,它会把源码树中的所有要用到的Kconfig全包含进来。包含进来了哪些,大家看Kconfig吧,有好几百个呢。

那么它是怎么来接管bootloader(BIOS)的执行权呢?进入…/arch/arm/boot/compressed/目录下,看到了一个链接文件了没,名叫vmlinux.lds.S,对真正的kernel的二进制可执行文件vmlinux将会位于这(编译完内核可以看下),编译时你的终端会输出编译信息,通过查看这些信息你可以知道有哪些文件被编译进行内核中,一般会有下面这些:

arch/arm/kernel/head.o
arch/arm/kernel/init-atask.o
init
usr/built-in.o
arch/arm/kernel
arch/arm/mm
arch/arm/common
arch/arm/mach-ixp4xx
arch/arm/nwfpe
kernel
mm
fs
ipc
security
lib/lib.a
arch/arm/lib
lib
drivers
net


接着上面讲kernel在哪接管CPU的执行权的问题,也就是说kernel真正意义上的第一行代码到底在哪,注意:由于kernel是多平台的内核,所以这里讲和真正意义上的

第一行代码是去除了它之前的特定架构特定处理器的初始代码之后的首行代码。kernel真正的第一行代码是位于…/arch/$(SUBARCH)/kernel/head.S,在这里kernel会检测有效的architecture和processor,建立起初始页表入口,同时会使能MMU,然后真正起动kernel本身(跳转到…/init/main.c),说到这个main.c文件,这个文件是我们必须要好好看,好好理解它,通过它来慢慢切入到kernel当中,做到深度理解传说中的kernel。 之前不是一直强调kernel真正意义下的第一行代码吗,下面就来说说为什么吧,由于不同的处理器,一些处理器得先通过相应处理之后才能把CPU执行权交给kernel, 因此 不同的架构下,它们还有不同的head.S(位于…/arch/$(SUBARCH)/boot/compressed/),比如power pc下有:head_32.S,head_40x.S,head_44x.S等。bootloader通过这些汇编程序再 这把控制权交给kernel,在这的特定架构处理器的head.S程序会对processor进行一些处理,比如 进行关中断,使能processor的指令缓存和数据缓存,建立起一个适合C代码运行的环境。

大家也可以这样理解,把…/arch/$(SUBARCH)/kernel/head.S之前的操作看作第二个bootloader,它还可以对kernel进行校验,执行kernel的解压

(在…/arch/\$(SUBARCH)/boot/misc.c中实现此功能,函数为 decompress_kernel),和kernel在内存中的重定位。 不过有一些架构的处理器可以直接引导kernel,
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: