linux是公开源码,对那些公开源代码的软件或操作系统(如Linux)怎样查看其源代码...
Linux内核的配置系统由三个部分组成,分别是:
Makefile:分布在 Linux 内核源代码中的 Makefile,定义 Linux 内核的编译规则;
配置文件(config.in):给用户提供配置选择的功能;
配置工具:包括配置命令解释器(对配置脚本中使用的配置命令进行解释)和配置用户界面(提供基于字符界面、基于 Ncurses 图形界面以及基于 Xwindows 图形界面的用户配置界面,各自对应于 Make config、Make menuconfig 和 make xconfig)。
这些配置工具都是使用脚本语言,如 Tcl/TK、Perl 编写的(也包含一些用 C 编写的代码)。本文并不是对配置系统本身进行分析,而是介绍如何使用配置系统。所以,除非是配置系统的维护者,一般的内核开发者无须了解它们的原理,只需要知道如何编写 Makefile 和配置文件就可以。所以,在本文中,我们只对 Makefile 和配置文件进行讨论。另外,凡是涉及到与具体 CPU 体系结构相关的内容,我们都以 ARM 为例,这样不仅可以将讨论的问题明确化,而且对内容本身不产生影响。
2. Makefile
2.1 Makefile 概述
Makefile 的作用是根据配置的情况,构造出需要编译的源文件列表,然后分别编译,并把目标代码链接到一起,最终形成 Linux 内核二进制文件。
由于 Linux 内核源代码是按照树形结构组织的,所以 Makefile 也被分布在目录树中。Linux 内核中的 Makefile 以及与 Makefile 直接相关的文件有:
Makefile:顶层 Makefile,是整个内核配置、编译的总体控制文件。
.config:内核配置文件,包含由用户选择的配置选项,用来存放内核配置后的结果(如 make config)。
arch/*/Makefile:位于各种 CPU 体系目录下的 Makefile,如 arch/arm/Makefile,是针对特定平台的 Makefile。
各个子目录下的 Makefile:比如 drivers/Makefile,负责所在子目录下源代码的管理。
Rules.make:规则文件,被所有的 Makefile 使用。
用户通过 make config 配置后,产生了 .config。顶层 Makefile 读入 .config 中的配置选择。顶层 Makefile 有两个主要的任务:产生 vmlinux 文件和内核模块(module)。为了达到此目的,顶层 Makefile 递归的进入到内核的各个子目录中,分别调用位于这些子目录中的 Makefile。至于到底进入哪些子目录,取决于内核的配置。在顶层 Makefile 中,有一句:include arch/$(ARCH)/Makefile,包含了特定 CPU 体系结构下的 Makefile,这个 Makefile 中包含了平台相关的信息。
位于各个子目录下的 Makefile 同样也根据 .config 给出的配置信息,构造出当前配置下需要的源文件列表,并在文件的最后有 include $(TOPDIR)/Rules.make。
Rules.make 文件起着非常重要的作用,它定义了所有 Makefile 共用的编译规则。比如,如果需要将本目录下所有的 c 程序编译成汇编代码,需要在 Makefile 中有以下的编译规则:
%.s: %.c
$(CC) $(CFLAGS) -S $< -o $@
有很多子目录下都有同样的要求,就需要在各自的 Makefile 中包含此编译规则,这会比较麻烦。而 Linux 内核中则把此类的编译规则统一放置到 Rules.make 中,并在各自的 Makefile 中包含进了 Rules.make(include Rules.make),这样就避免了在多个 Makefile 中重复同样的规则。对于上面的例子,在 Rules.make 中对应的规则为:
%.s: %.c
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$(*F)) $(CFLAGS_$@) -S $< -o $@
2.2 Makefile 中的变量
顶层 Makefile 定义并向环境中输出了许多变量,为各个子目录下的 Makefile 传递一些信息。有些变量,比如 SUBDIRS,不仅在顶层 Makefile 中定义并且赋初值,而且在 arch/*/Makefile 还作了扩充。
常用的变量有以下几类:
1) 版本信息
版本信息有:VERSION,PATCHLEVEL, SUBLEVEL, EXTRAVERSION,KERNELRELEASE。版本信息定义了当前内核的版本,比如 VERSION=2,PATCHLEVEL=4,SUBLEVEL=18,EXATAVERSION=-rmk7,它们共同构成内核的发行版本KERNELRELEASE:2.4.18-rmk7
2) CPU 体系结构:ARCH
在顶层 Makefile 的开头,用 ARCH 定义目标 CPU 的体系结构,比如 ARCH:=arm 等。许多子目录的 Makefile 中,要根据 ARCH 的定义选择编译源文件的列表。
3) 路径信息:TOPDIR, SUBDIRS
TOPDIR 定义了 Linux 内核源代码所在的根目录。例如,各个子目录下的 Makefile 通过 $(TOPDIR)/Rules.make 就可以找到 Rules.make 的位置。
SUBDIRS 定义了一个目录列表,在编译内核或模块时,顶层 Makefile 就是根据 SUBDIRS 来决定进入哪些子目录。SUBDIRS 的值取决于内核的配置,在顶层 Makefile 中 SUBDIRS 赋值为 kernel drivers mm fs net ipc lib;根据内核的配置情况,在 arch/*/Makefile 中扩充了 SUBDIRS 的值,参见4)中的例子。
4) 内核组成信息:HEAD, CORE_FILES, NETWORKS, DRIVERS, LIBS
Linux 内核文件 vmlinux 是由以下规则产生的:
vmlinux: $(CONFIGURATION) init/main.o init/version.o linuxsubdirs
$(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o
--start-group
$(CORE_FILES)
$(DRIVERS)
$(NETWORKS)
$(LIBS)
--end-group
-o vmlinux
可以看出,vmlinux 是由 HEAD、main.o、version.o、CORE_FILES、DRIVERS、NETWORKS 和 LIBS 组成的。这些变量(如 HEAD)都是用来定义连接生成 vmlinux 的目标文件和库文件列表。其中,HEAD在arch/*/Makefile 中定义,用来确定被最先链接进 vmlinux 的文件列表。比如,对于 ARM 系列的 CPU,HEAD 定义为:
HEAD := arch/arm/kernel/head-$(PROCESSOR).o
arch/arm/kernel/init_task.o
表明 head-$(PROCESSOR).o 和 init_task.o 需要最先被链接到 vmlinux 中。PROCESSOR 为 armv 或 armo,取决于目标 CPU。 CORE_FILES,NETWORK,DRIVERS 和 LIBS 在顶层 Makefile 中定义,并且由 arch/*/Makefile 根据需要进行扩充。 CORE_FILES 对应着内核的核心文件,有 kernel/kernel.o,mm/mm.o,fs/fs.o,ipc/ipc.o,可以看出,这些是组成内核最为重要的文件。同时,arch/arm/Makefile 对 CORE_FILES 进行了扩充:
# arch/arm/Makefile
# If we have a machine-specific directory, then include it in the build.
MACHDIR := arch/arm/mach-$(MACHINE)
ifeq ($(MACHDIR),$(wildcard $(MACHDIR)))
SUBDIRS += $(MACHDIR)
CORE_FILES := $(MACHDIR)/$(MACHINE).o $(CORE_FILES)
endif
HEAD := arch/arm/kernel/head-$(PROCESSOR).o
arch/arm/kernel/init_task.o
SUBDIRS += arch/arm/kernel arch/arm/mm arch/arm/lib arch/arm/nwfpe
CORE_FILES := arch/arm/kernel/kernel.o arch/arm/mm/mm.o $(CORE_FILES)
LIBS := arch/arm/lib/lib.a $(LIBS)
5) 编译信息:CPP, CC, AS, LD, AR,CFLAGS,LINKFLAGS
在 Rules.make 中定义的是编译的通用规则,具体到特定的场合,需要明确给出编译环境,编译环境就是在以上的变量中定义的。针对交叉编译的要求,定义了 CROSS_COMPILE。比如:
CROSS_COMPILE = arm-linux-
CC = $(CROSS_COMPILE)gcc
LD = $(CROSS_COMPILE)ld
......
CROSS_COMPILE 定义了交叉编译器前缀 arm-linux-,表明所有的交叉编译工具都是以 arm-linux- 开头的,所以在各个交叉编译器工具之前,都加入了 $(CROSS_COMPILE),以组成一个完整的交叉编译工具文件名,比如 arm-linux-gcc。
CFLAGS 定义了传递给 C 编译器的参数。
LINKFLAGS 是链接生成 vmlinux 时,由链接器使用的参数。LINKFLAGS 在 arm/*/Makefile 中定义,比如:
# arch/arm/Makefile
LINKFLAGS :=-p -X -T arch/arm/vmlinux.lds
6) 配置变量CONFIG_*
.config 文件中有许多的配置变量等式,用来说明用户配置的结果。例如 CONFIG_MODULES=y 表明用户选择了 Linux 内核的模块功能。
.config 被顶层 Makefile 包含后,就形成许多的配置变量,每个配置变量具有确定的值:y 表示本编译选项对应的内核代码被静态编译进 Linux 内核;m 表示本编译选项对应的内核代码被编译成模块;n 表示不选择此编译选项;如果根本就没有选择,那么配置变量的值为空。
2.3 Rules.make 变量
前面讲过,Rules.make 是编译规则文件,所有的 Makefile 中都会包括 Rules.make。Rules.make 文件定义了许多变量,最为重要是那些编译、链接列表变量。
O_OBJS,L_OBJS,OX_OBJS,LX_OBJS:本目录下需要编译进 Linux 内核 vmlinux 的目标文件列表,其中 OX_OBJS 和 LX_OBJS 中的 "X" 表明目标文件使用了 EXPORT_SYMBOL 输出符号。
M_OBJS,MX_OBJS:本目录下需要被编译成可装载模块的目标文件列表。同样,MX_OBJS 中的 "X" 表明目标文件使用了 EXPORT_SYMBOL 输出符号。
O_TARGET,L_TARGET:每个子目录下都有一个 O_TARGET 或 L_TARGET,Rules.make 首先从源代码编译生成 O_OBJS 和 OX_OBJS 中所有的目标文件,然后使用 $(LD) -r 把它们链接成一个 O_TARGET 或 L_TARGET。O_TARGET 以 .o 结尾,而 L_TARGET 以 .a 结尾。
linux是公开源码,对那些公开源代码的软件或操作系统(如Linux)怎样查看其源代码...相关推荐
- android吉凶信息查询代码,手机号码吉凶查询工具 公开源码,可任意修改
[C++] 纯文本查看 复制代码import win.ui; import win.clip; import inet.http; /*DSG{{*/ var winform = ..win.form ...
- PHP手机号码吉凶源码,手机号码吉凶查询工具 公开源码,可任意修改
[C++] 纯文本查看 复制代码import win.ui; import win.clip; import inet.http; /*DSG{{*/ var winform = ..win.form ...
- 自己帮别人写的网站可以公开源码吗_雷军靠写代码赚第一个 100 万,马化腾亲自写腾讯网,码农出身的大佬...
作者 | 夏弢 本文经授权转载自创业邦(ID:ichuangyebang) 一提到程序员,很多人脑海里马上会出现这些刻板标签: 可事实上,有一个词似乎更能概括: 改变世界 程序改变世界,已经有几十年了 ...
- 自己帮别人写的网站可以公开源码吗_专注爬虫:20个精心总结爬虫项目,爬虫技术这里强(附源码)...
写在前面 你想成为Python爬虫的高手么?你想爬取你想要的高质量数据么? 那么你得需要进行爬虫项目的演练,那样你才有可能在Python爬虫的道路上走的更远 小编在这里精心总结了20个爬虫项目的演练, ...
- 微信强制加入群软件!易语言协议版,公开源码
分享一款易语言开发的微信加群软件,利用了协议技术,当然协议技术我们是不会公开的,只提供部分代码,供大家参考,下面是软件的界面! 代码段: .版本 2 .支持库 iext.程序集 窗口程序集_启动窗口 ...
- c语言微信协议源码,微信强制加入群软件!易语言协议版,公开源码
分享一款易语言开发的微信加群软件,利用了协议技术,当然协议技术我们是不会公开的,只提供部分代码,供大家参考,下面是软件的界面! 代码段: .版本 2 .支持库 iext .程序集 窗口程序集_启动窗口 ...
- VS2010+.net4.0仿照苹果手机上的消除之星写了一个电脑版的功能简单 稍后将公开源码(一)
源码整理好后会公开 有问题联系QQ:519872449 或发邮件yc_xzh@163.com 下载链接http://download.csdn.net/detail/xzh1995/6461477
- (转)一个带自定义分页,排序功能的DATAGRID控件(公开源码)
因为项目需要,要弄个有这样功能的控件.要有自定意分页和排序的功能.在这个控件里面数据的绑定都是用DataView来实现,DataView放在Session里,如果大家有更灵活的方法可以留言给我.S ...
- 西数硬盘linux,SMR硬盘可靠性不再是问题 西数神油ZoneFS系统纳入Linux中
前段时间,西数.希捷及东芝三大HDD硬盘厂商都因为SMR混用一事卷入了网络争议中,这件事的根源就是SMR硬盘本身存在一些弊端.最终解决还得回到技术上来,Linux 5.6内核中已经融入了西数的Zone ...
- 第十期-Linux内核补丁源码分析(2)
作者:罗宇哲,中国科学院软件研究所智能软件研究中心 在上一期中,我们通过CAKE系统的实例介绍了一种对Linux内核补丁的初步分析方法,这一期我们将继续通过CAKE系统的例子介绍一种对补丁文件源码的分 ...
最新文章
- Cell Press | 研究人员致力于创建COVID-19病毒表位图
- php上传文件后定时删除,PHP根据条件定时删除文件代码
- Python大佬 | 菜鸟进阶必备的九大技能!
- Windows下Eclipse提交MR程序到HadoopCluster
- java 三大集合_java中的三大集合入门笔记(简单实用)
- [css] 在css中为什么说不建议使用@import?
- 语音识别学习日志 2019-7-14 语音识别基础知识准备2 {EM算法与混合高斯模型(Gaussian mixture model, GMM)}
- javascript框架比较(三)
- requestmapping里面的参数_golang web开发——参数绑定(上)之用Go实现简单的Trie
- 一款“灵动”的滑动按钮
- Swift中viewWeb执行JS
- Web数据挖掘小论文
- 整理的一些java基础知识点,欢迎补充指正
- python获取现在的日期和时间
- 根文件系统与文件系统的区别
- layui 数字步进器_光音移动设计规范 — 表单类
- Echarts制作横向坐标轴,并且文字名称和数值都在横向坐标轴的上面
- OpenSSL 最新版 快速安装 v3.0.2 v1.1.1n Windows系统
- 移动平台开发工程训练
- 视频直播应用的竞争分析
热门文章
- 两个有趣的统计学问题
- 举个栗子~Tableau 技巧(210):改变标签和列名称的位置
- ubuntu桌面安装
- 电容的基础知识和分类说明
- MMM CenterOS 7.5下Mysql cluster 高可用集群搭建
- MeeGo进度报告:A+ 还是 D-
- WPF 动画:同为控件不同命
- springboot毕设项目迅羽汽车零件销售系统的设计661l6(java+VUE+Mybatis+Maven+Mysql)
- UE5笔记【】操作细节记录:处理拉伸纹理形变;贴花厚度处理技巧;相框中添加照片;
- (Java毕业设计)大学生体质测试管理系统(基于java+springboot)