您好,欢迎进入江南娱乐手机客户端 官方网站!
人总是对未知的事物充满恐惧!就像航海一样,在面对危难的时候,船员和船长是一样心中充满恐惧的!只是船员始终充满恐惧,而船长却能压抑恐惧并从当前找出突破口!
我没有船长之能,但也算入行两年的老船员,我会追随船长一起寻找突破口!而内核如此庞然大物不知从何入手这真的很正常,那么应该的入口在哪里?其实我也不知道,一千个读者就有一千个哈姆雷特。每个人都入口的理解都不一样,有人说是必须有着良好的C编程经验,有人说必须有着对Linux发行版等必要的操作经验,也有的人说一定要数据结构理解的很好,还有的人说你必须的对各种架构的汇编了如指掌!眼花撩乱的知识你又掌握了多少呢?
1.必须有着良好的C语言理解能力,尤其是指针(灵魂嘛)
2.数据结构确实的能看懂,尤其是链表
3.一定要有着非常浓厚的兴趣,不成魔,不成活
第3点尤其最重要,因为兴趣才是王道
假设你已经对上述内容有了一定的了解或者已经是个老手了!想急需的去更深入的研究内核!
那么我们就开始吧!
顶层目录
├── arch -- 体系架构相关代码,内核支持市面上所有的主流架构以及N多种CPU
├── block -- 块设备子系统
├── crypto -- 加密解密库函数
├── Documentation -- 说明文档
├── drivers -- 设备驱动
├── firmware -- 第三方设备固件
├── fs -- 文件系统子系统(VFS)
├── include -- 公共头文件
├── init -- 启动初始化子系统(如挂载initrd)
├── ipc -- 进程通信子系统
├── Kbuild -- 顶层链接文件
├── Kconfig -- 顶层配置配置
├── kernel -- 内核核心代码(基本与架构无关,包括调度子系统)
├── lib -- 公共LIB库函数
├── Makefile -- 顶层编译文件
├── mm -- 内存管理子系统
├── net -- 不包括网络设备驱动的网络子系统
├── README -- 你懂得
├── samples -- Demo 代码
├── scripts -- 编译脚本以及工具
├── security -- 模块安全相关(SELinux)
├── sound -- 音频驱动子系统
├── tools -- 内核辅助工具
├── usr -- 用户程序(目前只有一个用于initramfs的cpio打包程序)
└── virt -- 虚拟化相关
├── REPORTING-BUGS -- Bug 上报流程
├── MAINTAINERS -- 主要维护者(向社区致敬)
├── CREDITS -- 贡献者(请牢记伟大的程序员)
内核真是太庞大了,目前这个版本的代码量已经到了几百万行之多,那么问题来了,这么多的内容我们应该如何取舍?
Linux 核心功能分为五大子系统(进程管理,内存管理,虚拟文件系统,网络子系统,进程间通信)!
Ps.下面是网上找了一张图片
Ps…对了,还忘了说一个非常非常重要的核心,那就是体系架构,因为我当前是Mips,所以首先的熟悉MIPS架构中的一些最基本的处理方式,并且内核中有很多关于MIPS的汇编以及GUN混合MIPS的伪汇编,都需要去啃啊,瞬间好头大!深吸一口气,慢慢来吧!这部分内容作为整体穿插的时候在进行脑补吧!!!!
好吧,下一节就要进行实战了,这里先脑补一下Makefile.
Makefile作为构建内核的引线,穿插在各个目录中!那么对它的语法先简单的了解下!
基本的 make流程 其实是根据文件的时间戳来更新(读取Makefile) 文件的编译工作
从一个样例来说明Makefile.
main:main.o name.o age.o
gcc main.o name.o age.o -o main
main.o:main.c
gcc -c main.c -o main.o
name.o:name.c
gcc -c name.c -o name.o
age.o:age.c
gcc -c age.c -o age.o
clean:
rm *.o main
基本格式为: 目标生成文件名:源文件
生成过程(得到结果)
clean 作为方便的清除Makefike生成的编译文件
看上述的主文件
main.c
#include <stdio.h>
extern void name();
extern void age();
int main()
{
name();
age();
return 0;
}
name.c
#include <stdio.h>
void name()
{
printf("My name is Xw. \n");
}
age.c
#include <stdio.h>
void age()
{
printf("My age is 22........\n");
}
杂种Shell + Makefile的演变
当我们的可编译文件越来越多时候,那么即时可能你少了一个.o文件那也直接导致程序崩溃。
所以这个时候我们的杂种Shell(其实严谨的说不是shell相似而已)就有用了。我们大可以用一个变量去代替你的源文件、也可以代替我们的编译器。如下
CC=gcc //变量代替你的编译器
OBJS=main.o name.o age.o //源文件
main:$(OBJS)
$(CC) $^ -o $@
main.o:main.c
$(CC) -c $^ -o $@
name.o:name.c
$(CC) -c $^ -o $@
age.o:age.c
$(CC) -c $^ -o $@
clean:
rm *.o main
表示所有不重复的依赖包名称以空格隔开如上述main.omain.c分别可以做依赖包、因为依赖和被依赖仅仅是方向不一样。其实是可以转化的。当然上述还可以写成。表示所有不重复的依赖包名称以空格隔开如上述main.omain.c分别可以做依赖包、因为依赖和被依赖仅仅是方向不一样。其实是可以转化的。当然上述还可以写成。(CC) -c OBJS−omain.oOBJS−omain.o<表示第一个依赖包名称
Ps.上述仅仅是Makefile 最基本的使用,在内核里完全是另外一回事,但是基本语法是一样的!
*下一节我们就开始内核的Makefile以及其它编译规则的分析*