本文最近更新于 2019 年 2 月 11 日「 星期一 」

牛津字典中对 kernel 一词的定义是:“较软的、通常是一个坚果可食用的部分。”当然还有第二种定义:“某个东西的核心或者最重要的部分。”对 Linux 来说,它的 Kernel 无疑属于第二种解释。

广义来说 Kernel 就是一个软件,它在硬件和运行在计算机上的应用程序之间提供了一个层。严格点从计算机科学的角度来说,Linux 中的 Kernel 指的是 Linus Torvalds 在 90 年代初期写的那点代码。

所有的我们在 Linux 各版本中看到的其他东西 —— Bash Shell、KDE 窗口管理器、Web 浏览器、X 服务器、Tux Racer 以及所有的其他,都不过是运行在 Linux 上的应用而已,而不是操作系统自身的一部分。为了给大家一个更加直观的感觉,来举个例子,比如 RHEL5 的安装大概要占据 2.5GB 的硬盘空间(具体多大当然视你的安装组件的选择情况),在这其中,Kernel 以及它的各个模块组件,只有 47MB,所占比例约为 2%。

什么是内核?

内核将应用程序与系统硬件隔离,并为它们提供基本系统服务,如输入/输出 (input/output,I/O) 管理、虚拟内存和调度,是操作系统最核心的部分。

GNU/Linux 操作系统的基本体系结构:

一般来说,内核特指某一个或者几个文件。对于 Windows 来说,内核文件是 \Windows\System32\ntoskrnl.exe;对于 Linux 来说,是内核镜像,一般在 boot 下面,具体是哪个要看配置情况。

安卓系统刷入内核,常指借助第三方 recovery 刷入 boot.img 文件。

内核的功能

内核有以下几个功能:

1) 进程管理

内核负责创建和销毁进程,并处理它们与外部世界的联系(输入和输出)。不同进程间通讯(通过信号,管道,或者进程间通讯原语)对整个系统功能来说是基本的,也由内核处理。

调度器,控制进程如何共享 CPU,是进程管理的一部分。

2) 内存管理

计算机的内存是主要资源之一,处理它所用的策略对系统性能至关重要。

3) 文件系统

Unix 在很大程度上基于文件系统的概念,几乎 Unix 中的任何东西都可看作一个文件,内核在非结构化的硬件之上建立了一个结构化的文件系统。另外,Linux 支持多个文件系统类型,就是说,物理介质上不同的数据组织方式。

4) 设备控制

几乎每个系统操作最终都映射到一个物理设备上,除了处理器,内存等,设备控制操作都由特定于要寻址的设备相关的代码来进行,这些代码称为设备驱动。

内核中必须嵌入系统中出现的每个外设的驱动。

5) 网络

网络必须由操作系统来管理,因为大部分网络操作不是特定于某一个进程——进入系统的报文是异步事件。报文在某一个进程接手之前必须被收集,识别,分发。

系统负责在程序和网络接口之间递送数据报文,它必须根据程序的网络活动来控制程序的执行。另外,所有的路由和地址解析问题都在内核中实现。

Linux 内核调教的一点底层

早期版本的 Linux Kernel 是整体式的,也就是说所有的部件都静态地连接成一个(很大的)执行文件。

相比较而言,现在的 Linux Kernel 是模块化的:许多功能包含在模块内,然后动态地载入 Kernel 中。这使得 Kernel 的内核很小,而且在运行 Kernel 时可以不必 reboot 就能载入和替代模块。

Kernel 的内核在 boot time 时从位于 /boot 目录的一个文件加载进存储中,通常这个 /boot 目录会被叫做 KERNELVERSION,KERNELVERSION 与 Kernel 版本有关(如果你想知道你的 Kernel 版本是什么,可以运行命令行显示系统信息 -r)。Kernel 的模块位于目录 /lib/modules/KERNELVERSION 之下,所有的组件都会在 Kernel 安装时被拷贝。

具体调教让我们举 /proc 系统文件为例。Linux Kernel 通过 /proc 系统文件展示了许多细节。为了说明 /proc,我们首先需要扩展我们对于文件的理解。除了认为文件就是存储在硬盘或者 CD 或者存储空间上的持久信息之外,我们还应当把它理解为任何可以通过传统系统调用如:打开、读、写、关闭等访问的信息,当然它也可以被常见的程序访问。

/proc 之下的“文件”完全是 Kernel 虚拟的一个部分,给我们一个视角可以看到 Kernel 内部的数据结构。实际上,许多 Linux 的报告工具均能够很好地呈现在 /proc 下的文件中寻到的格式化版本的信息。比如,一列 /proc/modules 将展示一列当前加载的模块。

同样的,/proc/meminfo 提供了关于虚拟存储系统当前状态的更多细节信息,而类如 vmstat 的工具则是以一种更加可理解的方式提供了相同的一些信息。/proc/net/arp 显示了系统 ARP cache 的当前内容,从命令行来说,arp -a 显示的也是相同的信息。

尤其有意思的是 /proc/sys 下的“文件”。/proc/sys/net/ipv4/ip_forward 下的设置告诉我们 Kernel 是否将转发 IP 数据包,也就是说是否扮演网关的作用。现在,Kernel告诉我们这是关闭的:

1 $ cat /proc/sys/net/ipv4/ip_forward
2 0

当你发现你可以对这些文件写入的时候,你会觉得更加有意思。继续举例来说:

1 $ echo 1 > /proc/sys/net/ipv4/ip_forward

将在运行的 Kernel 中打开 IP 转发(IP forwarding)。

除了使用 catecho 来检查和更正 /proc/sys 下的设置以外,你也可以使用 sysctl 命令:

1 $ sysctl net.ipv4.ip_forward
2 net.ipv4.ip_forward = 0

这等同于:

1 $ cat /proc/sys/net/ipv4/ip_forward
2 0

也等同于:

1 $ sysctl -w net.ipv4.ip_forward=1
2 net.ipv4.ip_forward = 1

还等同于:

1 $ echo 1 > /proc/sys/net/ipv4/ip_forward

需要注意的是,以这种方式你所做的设置改变只能影响当前运行的 Kernel 的,当 reboot 的时候就不再有效。如果想让设置永久有效,将它们放置在 /etc/sysctl.conf 文件中。在 boot time 时,sysctl 将自动重新确定它在此文件下找到的任何设置。

/etc/sysctl.conf 下的代码行大概是这样的:

1 net.ipv4.ip_forward=1

另外关于性能调优(performance tuning),有这样一个说法:/proc/sys 下可写入的参数孕育了整个 Linux 性能调优的亚文化。我个人觉得这种说法有点过夸,但这里会有几个你确实很想一试的例子:

Oracle 10g 的安装说明(www.oracle.com/technology/obe/obe10gdb/install/linuxpreinst/linuxpreinst.htm)要求设置一组参数,包括:kernel.shmmax=2147483648 这将公用存储器的大小设置为 2GB。(公用存储器是处理期内的通信机制,允许存储单元在多个进程的地址空间内同时可用)

IBM ‘Redpaper’ 在 Linux 性能和调优方面的说明(www.redbooks.ibm.com/abstracts/redp4285.html)在调教 /proc/sys 下的参数方面给出了不少建议,包括:vm.swappiness=100 这个参数控制着存储页如何被交换到磁盘。

一些参数可以被设置从而提高安全性,如 net.ipv4.icmp_echo_ignore_broadcasts=1 它“告诉”Kernel 不必响应 ICMP 请求,从而使得你的网络免受类如 Smurf 攻击之类的拒绝服务器(denial-of-service)型攻击。

net.ipv4.conf.all.rp_filter=1 则是“告诉”Kernel 加强入站过滤(ingress filtering)和出站过滤(egress filtering)。

那么有没有一个说明能涵盖这所有的参数?好吧,这有一行命令:

1 $ sysctl -a

它将展示所有的参数名字和当前值。列表很长,但是你恐怕无法知道这些参数是做什么的。另外比较有用的参考是 Red Hat Enterprise Linux Reference Guide,对此有整章节的描述,你可以从 www.redhat.com/docs/manuals/enterprise 上下载。

为什么要调教内核?

手机内核是一个操作系统的核心,它负责管理系统的进程、内存、设备驱动程序、文件和网络系统,决定着系统的性能和稳定性。内核版本就是手机的硬件驱动集合体的版本号。内核以独占的方式执行最底层任务,保证系统正常运行。协调多个并发进程,管理进程使用的内存,使它们相互之间不产生冲突,满足进程访问磁盘的请求等等。

所以把内核比作手机的大脑也不为过,这也充分说明了它的重要性,可调性。有人不明白调试内核目的是什么,官方的内核给出只是一种模式,它可能并不是你所需要的模式。这时候,就要我们自己动手来调校它,让它更好的为我们工作。

刷入第三方内核可以体验到官方内核没有的功能,比如说,息屏解锁,CPU 核心的调配,init.d 支持等等。也是为了软硬件配合更好,更大程度发挥性能。

需要说明的是刷内核存在风险,例如耗电量增加,系统不稳定,手机屏幕亮度无法调节,文件管理器不能访问文件等严重问题。不建议新手轻易尝试!

刷入内核(备份/恢复)

刷入内核的方法分为两种:

务必在刷入三方内核前备份原生内核!

推荐去 XDA 论坛寻找适合自己手机的优秀三方内核。

如果三方内核失败又没有备份原生内核备份,这时只能尝试通过下载线刷包或者卡刷包,提取里面的 boot.img 文件(boot.img 里面就是内核),通过第三方 recovery 选择 boot 分区刷入,然后重启手机恢复原生内核。建议不要用其他的工具比如工具侠刷 boot.img,虽然也可以刷入 img 文件,但是刷入的是 recovery 分区,就要用电脑再刷一次三方 recovery。

恢复官方原生内核通常不会导致手机出现异常问题,除非第三方内核卡刷包里面修改了其他的文件,比如 WIFI 模块,当恢复官方内核后发现 WIFI 和热点均不能使用,不是原生内核的问题,而是第三方内核的作者把原生 WIFI 模块替换了(注意:该模块在备份内核时并不会被备份下来,需要另外手动备份,具体方法见下文)。

如果在恢复内核时遇到了 WIFI 不能使用的问题,一个解决办法是可以下载原生 ROM 刷机包,提取其中的 WIFI 模块(例如有的 ROM 的 WIFI 模块文件在 /system/lib/modules/wlan.ko,根据 ROM 的不同,具体的 WIFI 模块路径也不一样),然后导入手机中相应的路径下,并修改文件属性,通过这样的方法把 WIFI 模块恢复为原生版本。

所以为了避免恢复内核时的一些问题,建议我们在刷入内核前先查看该三方内核的构成,了解其将要修改哪些文件并事先做好备份。继续以 WIFI 模块文件为例,先解压所刷入的三方内核,查看其文件构成。例如下面的内核文件构成:

 1 $ tree . /F
 2 C:\TEMP\KERNEL-EXAMPLE
 3 │  anykernel.sh
 4 │  device.prop
 5 │  zImage
 6  7 ├─META-INF
 8 │  └─com
 9 │      └─google
10 │          └─android
11 │                  update-binary
12 │                  updater-script
13 14 ├─modules
15 │      ansi_cprng.ko
16 │      backlight.ko
17 │      br_netfilter.ko
18 │      evbug.ko
19 │      generic_bl.ko
20 │      lcd.ko
21 │      mmc_block_test.ko
22 │      mmc_test.ko
23 │      rdbg.ko
24 │      spidev.ko
25 │      test-iosched.ko
26 │      ufs_test.ko
27 │      wil6210.ko
28 29 ├─patch
30 │      Script.sh
31 32 ├─qca_cld
33 │      qca_cld_wlan.ko
34 35 ├─ramdisk
36 │      init.animation.sh
37 │      init.floppy.rc
38 │      init.spectrum.rc
39 │      init.spectrum.sh
40 41 └─tools
42         ak2-core.sh
43         busybox
44         lz4
45         mkbootimg
46         unpackbootimg
47         xz

根据名字我们可以发现里面的 qca_cld_wlan.ko 应该就是 WIFI 模块文件。知道了这个信息后我们就可以在手机上找到该文件进行备份。以 MIUI 为例,我们可以在 /system/vendor/lib/modules/qca_cld 路径下找到该 WIFI 模块文件,将该文件复制一份到安全的备份路径,同时也记录下该文件的属性:用户组为 root,执行权限 rw-r--r--

这样一来,如果在恢复至原生内核后遇到 WIFI 不能使用的情况时,我们还原该原生文件和属性就可以了。

网友的经验:

  • 如果现在是官方内核,直接通过三方 recovery 刷入想用的第三方内核,切记:不要清 cache!刷入前后都不要清!清了的话也能刷入内核也能进系统也可以正常使用,但是会卡顿。而且用幸运破解器破解 apk 最后会失败,提示你的系统运行 art 环境有 bug。

  • 第三方内核升级或者换刷别的内核时,每次刷之前先刷一次官方内核,然后不需要重启 recovery 直接再刷一次你需要刷入的第三方内核,还是不要清任何 cache!同样,没有先刷官方内核的话,直接刷了第三方内核也能进系统也可以正常使用,但是会卡顿。而且用幸运破解器破解 apk 最后会失败,提示你的系统运行 art 环境有 bug。

内核调教的应用

推荐一个内核调教应用是 Kernel Adiutor,需要 root 权限。

下载地址:Google Play

应用本身开源,代码库地址:github.com/Grarak/KernelAdiutor

内核调教参数

关于 CPU 的设置:

其中有一个很有意思的设置是「CPU Governor」。

ondemand/按需模式

按需调节 CPU 频率,不操作手机的时候控制在最低频率,滑屏或进入应用后会迅速提升至最高频率,当空闲时迅速降低频率。性能较稳定,但因频率变化幅度过大,省电方面只有一般的水平。是一种在电池和性能之间趋向平衡的默认模式,但是对于智能手机来说,ondemand 在性能表现方面略有欠缺。

interactive/交互模式

和 ondemand 相似,规则是“快升慢降”,注重响应速度、性能,当有高需求时迅速跳到高频率,当低需求时逐渐降低频率,相比 ondemand 费电。据说这是小米的默认设置。这个模式算是高性能版的 ondemand,电量自然也是要多费一点。

conservative/保守模式

和 ondemand 相反,规则是“慢升快降”,注重省电,当有高需求时逐渐提高频率,当低需求时迅速跳至低频率。性能较低,省电程度略好于 ondemand,总体不推荐。

userspace/用户模式

任何情况下都会控制 CPU 运行在配置的频率范围内,配置中的范围是由用户自己添加的。在此情景模式下,如果降低 CPU 最大运行频率可以延长电池待机时间,但同时也会降低机器的唤醒速度。严格来说它并不是一个模式,是允许非内核进程控制 CPU 频率的设置,SetCPU 官方的建议是——“不要使用此选项”。

powersave/省电模式

按设定最低频率运行,日常没有使用价值,除非配合 SetCPU 情景模式,关屏睡眠时使用此调节模式,省电但系统响应速度慢。

performance/高性能模式

高性能模式,按设定范围的最高频率运行,即使系统负载非常低 CPU 的频率也为最高。性能很好,因为 CPU 本身不需要资源去调整频率,但是电量消耗较快,温度也高一些。

还有一个设置叫「Multicore Power Saving」,多核节电处理。原理是尽量将处理任务交给尽可能少的处理核心处理。

I/O 调度的设置模块:

里面有一个设置是「Internal Storage Scheduler」,用来设置设备的处理 I/O 请求算法。

noop

这个调度模式会把所有的数据请求直接合并到一个简单的队列里。不适合有机械结构的存储器,因为没有优化顺序,会增加额外的寻道时间。属于最简单的一个调度模式,无视 IO 操作优先级和复杂性,执行完一个再执行一个,如果读写操作繁多的话,就会造成效率降低。

deadline

顾名思义,用过期时间来排序 IO 操作顺序,保证先出现的 IO 请求有最短的延迟时间,相对于写操作,给读操作更优先的级别。是比较好的一个调度模式。比如你在一个较短的时间里,先后在手机上打开了 2 个应用 A 和 B,A 应用打开总共需要 10 秒,而 B 应用打开只需要 1 秒。这时,deadline 模式会优先让 B 应用先运行——虽然你是先点击的 A 应用。

cfq

完全公平队列,是 anticipatory 模式的替代品,没有过多的做预测性调度,而是根据给定的进程 IO 优先级,直接来分配操作的顺序。这个模式在 Linux 上表现良好,但也许并不是最适合 Android 的 IO 调度模式,太强调均衡,而降低了连续读写数据的性能。简单说就是,先服务系统级应用,再服务普通应用。普通应用也要根据谁的优先级高就先服务谁。

ROW

ROW = Read Over Write。这个调度器的解释可以总结为:最大限制减少 IO 响应时间,并且重排执行操作,直接进行读写操作,给予 IO 最高优先值。简单的说就是优先处理数据的读取,然后再处理数据的写入。比如:你打开了一个应用(打开应用需要读取数据),这个应用还在打开的过程中,你等不及了,又打开相机拍了张照片(照片需要保存,所以需要数据写入)。这时,按 row 模式的“先读后写”原则,会先让你点击的应用打开,之后再保存你刚刚拍摄的照片(相机此时可能会卡住一段时间)。

ROW stands for “READ Over WRITE” which is the main requests dispatch policy of this algorithm. The ROW IO scheduler was developed with the mobile devices needs in mind. In mobile devices we favor user experience upon everything else, thus we want to give READ IO requests as much priority as possible. In mobile devices we won’t have as much parallel threads as on desktops. Usually it’s a single thread or at most 2 simultaneous working threads for read & write. Favoring READ requests over WRITEs decreases the READ latency greatly.

test-iosched

The test scheduler allows testing a block device by dispatching specific requests according to the test case and declare PASS/FAIL according to the requests completion error code.

内核调教的基本规则

关于 CPU 的设置:

注重性能的玩家:ondemand,interactive

注重电量的玩家:conservative

关于 IO 的调度:

noop 是最简单的 IO 调度策略,本质上就是先来先服务,意思就是哪个进程先请求 IO 系统就先为哪个进程服务,有最好的连续存取性能。

cfq 会均衡考虑各进程 IO 请求的任务量,适当调整完成 IO 请求的顺序(也就是说服务顺序和请求顺序不一样),保进程在最短时间内能得到 IO 响应(但不保证每次响应都能完成),也就是有最好的随机存取,延时低。

noop 不考虑 IO 请求的任务量(通俗点说就是不考虑读写的文件是大还是小),按照 IO 请求的顺序依次进行服务。这种策略在 PC 上的执行过程中主要有两个问题,第一个是 IO 请求任务量很大(要读写的某个文件很大)造成其他 IO 请求长时间得不到响应,第二个是相邻两次的 IO 请求涉及的文件在磁盘上的物理位置较远时会造成处理这次 IO 请求时磁头需要频繁移动导致性能严重降低。

第一个应该很好理解,IO 任务量不管大小依次排队,当处理到一个很大的任务时,系统将一直处理下去,后面的请求就得不到响应了;第二个问题举个例子,有 4 个相邻的 IO 请求分别涉及 1、2、3、4 这四个文件,而 1、2、3、4 分别位于磁盘的内圈、外圈、内圈、外圈,也是说处理这 4 个请求时磁盘上的磁头必须先移到内圈,然后移到外圈,接着移到内圈再移到外圈,如此反复导致大量的时间用于移动磁头造成性能降低。

再来看手机,一般手机上的 IO 任务都不会很大,很少有需要连续读几百兆甚至更大文件的情况,即便要读通常也是正在玩游戏需要读数据文件(通常手机上不会有一边上网聊 QQ,手机后台还有个程序需要连续读几百兆文件的情况),这时用户通常希望系统尽快把文件读完从而继续玩游戏。

由于 noop 在处理大任务时会使后续的 IO 请求得不到响应,因此具有较好的连续性能,这个特点正好满足了上面这类用户的需求。

关于上面说的第二个问题,由于手机上用的是闪存芯片,也就不存在磁头移动的问题,像其他策略那样考虑磁头的移动问题对于采用闪存芯片的存储介质完全是浪费,所以对于随机性能很好的闪存芯片来说 noop 是最好的 IO 调度策略。

下面看 bfq,bfq 指的是 budget fair queuing,从名字上就能看出来这个策略对于各 IO 请求是公平的(fair),不会有上面说的 noop 的第一种问题。

这里指的公平就是尽量使各进程的 IO 请求都能得到尽快响应不会长期搁置,但因为系统资源有限,所以只能保证尽快响应但不保证可以尽快完成。

不难看出 bfq 适合多进程同时发出多 IO 请求的状况,因为它不会像 noop 那样无视后续的 IO 请求。直观的看就是手机程序开的很多时系统还能对各进程有不错的响应速度,这就是为什么 bfq 适合多进程,可以均衡协调前后台任务性能的原因。bfq 实际上是 cfq 的改进!

几个高效的三方内核及调教方案

下面推荐几个高效的三方内核及调教方案,包括:

  • 小米 5 三方内核
  • 小米 5s 三方内核
  • 小米 5s plus 三方内核
  • 小米 Mix 三方内核
  • 小米 Note 2 三方内核
  • 高通骁龙 821 调教方案
  • 高通骁龙 835 调教方案

详情:


会员专享内容

点击查看
「安卓果酱」会员计划

扩展阅读: