为什么Linux内核有15+百万行代码?

为什么Linux内核有15+百万行代码?

这个整体代码库的内容是什么?

我了解处理器架构支持、安全性和虚拟化,但我无法想象它会超过 600,000 行左右。

驱动程序包含在内核代码库中的历史和当前原因是什么?

这 15+ 百万行是否包含每个硬件的每个驱动程序?如果是这样,那就引出了一个问题,为什么驱动程序嵌入到内核中,而不是从硬件 ID 自动检测和安装的单独软件包?

对于存储受限或内存受限的设备来说,代码库的大小是否是一个问题?

如果所有这些都被嵌入的话,对于空间有限的 ARM 设备来说,它的内核大小似乎会膨胀。预处理器是否剔除了很多行?你可以说我疯了,但我无法想象一台机器需要那么多逻辑来运行我所理解的内核的角色。

是否有证据表明,由于其看似不断增长的性质,其规模将在 50 多年后成为一个问题?

包括驱动程序意味着它会随着硬件的制造而增长。

编辑:对于那些认为这是内核本质的人,经过一些研究,我意识到事实并非总是如此。内核不需要像卡内基梅隆大学那样大微内核Mach 被列为“通常少于 10,000 行代码”的示例

答案1

根据克洛克针对 3.13 运行,Linux 大约有 1200 万行代码。

  • 700 万个驱动程序 LOC/
  • arch/ 200 万个 LOC/
  • 内核中只有 139,000 个 LOC/

lsmod | wc在我的 Debian 笔记本电脑上显示运行时加载了 158 个模块,因此动态加载模块是支持硬件的常用方法。

强大的配置系统(例如make menuconfig)用于选择要编译的代码(更重要的是,要编译哪些代码不是编译)。嵌入式系统.config仅使用它们关心的硬件支持(包括支持内置于内核或作为可加载模块的硬件)来定义自己的文件。

答案2

对于那些好奇的人来说,这里是 GitHub 镜像的行数细目:

=============================================
    Item           Lines             %
=============================================
  ./usr                 845        0.0042
  ./init              5,739        0.0283
  ./samples           8,758        0.0432
  ./ipc               8,926        0.0440
  ./virt             10,701        0.0527
  ./block            37,845        0.1865
  ./security         74,844        0.3688
  ./crypto           90,327        0.4451
  ./scripts          91,474        0.4507
  ./lib             109,466        0.5394
  ./mm              110,035        0.5422
  ./firmware        129,084        0.6361
  ./tools           232,123        1.1438
  ./kernel          246,369        1.2140
  ./Documentation   569,944        2.8085
  ./include         715,349        3.5250
  ./sound           886,892        4.3703
  ./net             899,167        4.4307
  ./fs            1,179,220        5.8107
  ./arch          3,398,176       16.7449
  ./drivers      11,488,536       56.6110
=============================================

drivers有助于很多行数。

答案3

驱动程序在内核中维护,因此当内核更改需要对某个功能的所有用户进行全局搜索和替换(或搜索和手动修改)时,由进行更改的人完成。让进行 API 更改的人员更新您的驱动程序是一个非常好的优势,而不必在驱动程序无法在更新的内核上编译时您自己进行更新。

另一种选择(这就是在树外维护的驱动程序所发生的情况),补丁必须由其维护者重新同步,以跟上任何更改。

快速搜索发现关于树内与树外的争论驱动程序开发。

Linux 的维护方式主要是将所有内容保留在主线存储库中。通过配置选项来控制小型精简内核的构建#ifdef。因此,您绝对可以构建微小的精简内核,这些内核仅编译整个存储库中代码的一小部分。

Linux在嵌入式系统中的广泛应用使得更好的与几年前 Linux 内核源代码树较小时相比,对省略某些内容的支持。超最小 4.0 内核可能比超最小 2.4.0 内核小。

答案4

Linux tinyconfig 编译源行数 tinyconfig 气泡图svg(小提琴)

外壳脚本要从内核构建创建 json,请使用 withhttp://bl.ocks.org/mbostock/4063269


编辑:事实证明unifdef有一些限制(-I被忽略且-include不受支持,后者用于包含生成的配置标头)此时使用cat并没有太大变化:

274692 total # (was 274686)

脚本和程序已更新。


除了驱动程序、架构等之外,还有很多条件代码编译或不编译,具体取决于所选的配置,代码不一定位于动态加载的模块中,而是内置于核心中。

所以,下载了linux-4.1.6 源代码,选取了小配置,它不启用模块,老实说我不知道​​它启用什么或者用户在运行时可以用它做什么,无论如何,配置内核:

# tinyconfig      - Configure the tiniest possible kernel
make tinyconfig

构建内核

time make V=1 # (should be fast)
#1049168 ./vmlinux (I'm using x86-32 on other arch the size may be different)

内核构建过程留下*.cmd用命令行调用的隐藏文件,该命令行也用于构建.o文件,处理这些文件并提取script.sh下面的目标和依赖项副本并将其与寻找:

find -name "*.cmd" -exec sh script.sh "{}" \;

.o这会为名为的目标的每个依赖项创建一个副本.o.c

.c代码

find -name "*.o.c" | grep -v "/scripts/" | xargs wc -l | sort -n
...
   8285 ./kernel/sched/fair.o.c
   8381 ./kernel/sched/core.o.c
   9083 ./kernel/events/core.o.c
 274692 total

.h 标头(已消毒)

make headers_install INSTALL_HDR_PATH=/tmp/test-hdr
find /tmp/test-hdr/ -name "*.h" | xargs wc -l
...
  1401 /tmp/test-hdr/include/linux/ethtool.h
  2195 /tmp/test-hdr/include/linux/videodev2.h
  4588 /tmp/test-hdr/include/linux/nl80211.h
112445 total

相关内容