一、kernel目录架构
linux内核是一个庞大的开源软件,针对arm,x86,mipi等等架构,内有不同平台的驱动代码,和与不同架构soc相关的核心代码
他们是如何进行编译的?
如下,输入 make ARCH=arm CROSS_COMPILE=arm-hisiv500-linux- uImage,可知,针对的是arm架构的,那么只会选择arm
架构的代码进行编译,那么顶层Makefile,Kconfig,.config,子目录kconfig,Makefile,kbuild,到底是如何知道完成编译的呢?
记录一下自己理解。
可以在网站直接浏览。
或下载一份kernel 源代码,目录如下。
1、Makefile,kconfig,kbuild
主目录下或根目录下,想要编译它,是通过顶层makefile,kconfig,来组织的,主kconfig一个主菜单,指导哪些文件可以编译,我们选中哪些功能,就编译哪些功能进入系统。kconfig的内容如下,
会根据我们选中的arch结构,比如arm,x86,选中一种SOC来编译。 当输入make ARCH=arm,上面的srcarch会被赋值arm,就会选中
arch/arm下的kconfig。
进入arm目录下,看到有一个kconfig文件,这就是make menuconfig 配置菜单时,真正执行的文件,会跟据树根下的选项显示到主菜单上,
主kconfig里,有很多主菜单选项,后面每一个主选项,会有子选项,犹如树干,有很多树杈,如下语句,执行树杈子目录的kconfig,加载选项到子菜单显示。如果我们要添加一种文件,比如sound音频驱动就在主目录下,也是在这个kconfig下,加入sound相关的kconfig。
在kernel主根目录下,输入make menuconfig命令,出来如下面主菜单界面。
选中我们需要的soc,如三星的s5pv210,hisi的soc,和其他和cpu核心代码相关的代码,这些是设计cpu的厂家,如华为,三星做的事,外部人配置是很麻烦的事,因为很多不开放,我熟悉的代码,只有他们才知道,当他们配置好后,会保存配置到.congfig文件,在内核主根目录下,ls -a命令,可以看到这个文件,这个就是soc厂家配置好的,发布内核时,给我们的,我们一般在此基础上开发我们自己需要的驱动。
官网的kernel一般不会有.config文件,需要我们自己复制一份。或者厂家给我们的代码里有。进入arch/arm/configs目录下,
官方一般很少,厂家给我们时,会有很多配置好的不同soc的,不同领域的,不一样,比如我以前在海思做自动驾驶,就有很多config文件,和kbuild,做音视频的,又不一样,因为不同组做的,起的名字不一样,功能也不一样。
找一个hisi3520的默认config,把它拷贝出来到.config。
cp arch/arm/configs/hi3521d_full_defconfig .config
make ARCH=arm CROSS_COMPILE=arm-hisiv500-linux- menuconfig
2、子kconfig
举一个例子,进入driver里,kconfig里,会去执行子kconfig,加载各个模块的配置。
3、主Makefile
Makefile出厂了,上面配置好后,当输入make命令后,会根据规则去编译某某目录下的文件,如果有配置宏,会根据.config的配置判读是否需要编译为ko,还是直接编译进内核。
下面是直接把核心core直接编译。
ifeq ($(KBUILD_EXTMOD),)
core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
vmlinux-dirs := ( p a t s u b s t (patsubst %/,%, (patsubst(filter %/, $(init-y) $(init-m)
$(core-y) $(core-m) $(drivers-y) $(drivers-m)
$(net-y) $(net-m) $(libs-y) $(libs-m)))
vmlinux-alldirs := $(sort $(vmlinux-dirs) ( p a t s u b s t (patsubst %/,%, (patsubst(filter %/,
$(init-) $(core-) $(drivers-) $(net-) $(libs-))))
init-y := $(patsubst %/, %/built-in.o, $(init-y))
core-y := $(patsubst %/, %/built-in.o, $(core-y))
drivers-y := $(patsubst %/, %/built-in.o, $(drivers-y))
net-y := $(patsubst %/, %/built-in.o, $(net-y))
libs-y1 := $(patsubst %/, %/lib.a, $(libs-y))
libs-y2 := $(patsubst %/, %/built-in.o, $(libs-y))
libs-y := $(libs-y1) $(libs-y2)
4、子Makefile
举一个例子,进入driver里,Makefile,编写了编译规则,根据.config配置,选择是否需要编进系统。
5、kbuild
后面再说吧,这个很重要,还有Makefile里,很多cflag,如何传参。还有如何开发驱动时,添加kconfig,