这个整体代码库的内容是什么?
我了解处理器体系结构的支持,安全性和虚拟化,但是我无法想象超过60万行左右。 />
内核代码库中包含驱动程序的历史原因和当前原因是什么?
那15+百万行是否包括了每个硬件的每个驱动程序?如果是这样,那就引出了一个问题,为什么驱动程序嵌入在内核中,而不是将自动检测和安装的程序包与硬件ID分开?
对于受存储限制或受内存限制的设备,代码库的大小是否成问题?
如果将所有嵌入式设备都嵌入,似乎会占用空间有限的ARM设备的内核大小。预处理器会剔除很多行吗?叫我疯了,但是我无法想象一台机器需要那么多的逻辑来运行我所了解的是内核的角色。
是否有证据表明大小会在50多年后成为问题
编辑:对于那些认为这是内核的本质的人来说,经过一番努力之后,包含驱动程序意味着它会随着硬件的制造而增长。研究我发现并非总是如此。不需要这么大的内核,因为卡内基·梅隆(Carnegie Mellon)的微内核马赫(Mach)被列为示例,“通常在10,000行代码下”
#1 楼
驱动程序被维护在内核中,因此当内核更改需要对功能的所有用户进行全局搜索和替换(或搜索并手动修改)时,更改人员将完成更改。由人们进行API更改来更新驱动程序是一个很好的优势,而不是当它没有在较新的内核上编译时不必自己动手。替代方法(这是发生在驱动程序是在树外维护的),是补丁必须由其维护人员重新同步以跟上任何更改。
快速搜索引发了关于树内与.NET的争论。树外驱动程序开发。
Linux的维护方式主要是将所有内容保留在主线存储库中。 config选项支持控制
#ifdef
s的构建精简内核。因此,您绝对可以构建精简的精简内核,这些精简内核仅编译整个存储库中的一小部分代码。嵌入式系统中Linux的广泛使用已导致更好地支持将内容遗漏掉。 Linux早于内核源代码树较小的年份。极小的4.0内核可能小于极小的2.4.0内核。
评论
现在,这对于为什么将所有代码整合在一起是合乎逻辑的,对我来说很有意义,它以节省计算机资源和过多依赖关系为代价,节省了工时。
–乔纳森
15年8月19日在6:51
@JonathanLeaders:是的,它避免了维护不太活跃的驾驶员的麻烦。考虑核心更改时,将所有驱动程序代码都包含在内可能也很有用。搜索某些内部API的所有调用程序可能会以您未想到的方式使用它,从而可能会驱动您正在考虑的更改。
– Peter Cordes
15年8月19日在12:09
@JonathanLeaders出现在xd上,好像多余的行占用了很多额外的空间一样,在现代的将其安装在PC上的测量中。
– aga永
16-10-26在7:33
@Junaga:您意识到linux具有很好的可移植性和可扩展性,对吗?在32MB嵌入式系统上浪费1MB永久使用的内核内存是一件大事。源代码的大小并不重要,但是编译后的二进制大小仍然很重要。内核内存不会分页,因此即使有了交换空间,您也无法找回它。
– Peter Cordes
16-10-26在7:56
@Rolf:很大,但是不是意大利面。目前,它的架构非常好,在核心代码和驱动程序之间没有来回双向依赖。在不破坏核心内核的情况下,可以省去驱动程序。当重构内部函数或API时,驱动程序需要以不同的方式使用它,可能需要更改驱动程序,但这对于重构是正常的。
– Peter Cordes
18年8月28日在18:51
#2 楼
根据针对3.13运行的cloc,Linux大约有1200万行代码。驱动程序中有700万个LOC / arch中的200万个LOC /仅139个我的Debian笔记本电脑上的内核中的上千个LOC /
lsmod | wc
在运行时显示158个模块,因此动态加载模块是支持硬件的一种常用方法。系统(例如make menuconfig
)用于选择要编译的代码(更重要的是,要编译的代码)。嵌入式系统仅使用它们关心的硬件支持(包括支持内置于内核或作为可加载模块的硬件)来定义自己的.config
文件。评论
计数模块是不够的,很多可能是由config内置的
– Alex
15年8月17日在18:14
我认为由此可以得出结论,Linux内核之所以庞大,是因为它支持各种设备配置,而不是因为它过于复杂。我们在这里看到实际上只有1500万条线在使用。尽管几乎所有事物都可能过于复杂,但至少我们可以在知道原因的情况下在夜间入睡
–乔纳森
15年8月17日在18:22
@JonathanLeaders:是的-以及用于奇怪设备的模块,还有用于晦涩的文件系统,网络协议等的模块...
–psmears
15年8月17日在20:34
@JonathanLeader我记得Linux启动时-甚至使安装程序正常工作(如果它甚至有安装程序!)也很痛苦-仍然有一些发行版需要您手动选择鼠标驱动程序。进行网络之类的事情,或者禁止X窗口工作,真是一件乐事。在我的第一个Red Hat安装中,我必须编写自己的图形驱动程序,因为只有三个(!)驱动程序可用。默认情况下,使基础知识正常工作是成熟的标志-显然,在只有少数硬件组合的嵌入式系统上,您可以承受更多的调整。
–罗安
15年8月18日在7:25
@JonathanLeaders正如我认为您已经意识到的那样,源代码中的LOC或多或少都无关紧要。如果您想知道内核使用了多少内存,则有很多直接的方法。
–金锁
2015年8月18日14:32
#3 楼
对于任何好奇的人,以下是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
贡献了很多线数。评论
那很有意思。更有趣的是代码中潜在的弱点,这些点使程序员感到烦恼:grep -Pir“ \ x66 \ x75 \ x63 \ x6b” / usr / src / linux / | wc -l
– jimmij
15年8月17日在18:27
根据这项开创性的研究(如果过时),@ jimmij'\ x73 \ x68 \ x69 \ x74'可能更常见。
–尼克T
15年8月18日在8:33
随机事实:该文档更接近OP估计的600 000 LOC。
– Davidmh
15年8月18日在12:44
./documentation有超过500,000行代码? ....什么?
– C_B
15年8月18日在16:33
@drewbenn我更理解它为“文档不是空的吗?”
–伊兹卡塔
15年8月18日在18:13
#4 楼
到目前为止,答案似乎是“是,有很多代码”,没有人用最合乎逻辑的答案来解决这个问题:1500万+?所以呢? 1500万行源代码与鱼价有什么关系?是什么使它如此难以想象?Linux显然做了很多事情。比什么都重要……但是,您的一些观点表明,在构建和使用它时,您不尊重正在发生的事情。内核构建系统使您可以快速定义选择源代码集的配置。有些是实验性的,有些是古老的,有些不是每个系统都需要的。在
/boot/config-$(uname -r)
中查看make menuconfig
(在Ubuntu上),您将看到排除了多少。这是目标可变的桌面发行版。嵌入式系统的配置只会提取所需的内容。
并非所有内容都是内置的。在我的配置中,大多数内核功能都是作为模块构建的:打印出来,制成一个巨大的纸三明治。除非您为离散的硬件工作进行自定义构建(在这种情况下,您已经限制了这些项目的数量),否则这将毫无意义。
模块是动态加载的。即使系统具有成千上万的可用模块,该系统也将允许您仅加载所需的内容。比较以下内容的输出:
grep -c '=m' /boot/config-`uname -r` # 4078
grep -c '=y' /boot/config-`uname -r` # 1944
几乎没有加载任何内容。
微内核不是一回事。只需10秒钟,便可以查看链接到Wikipedia页面的主要图像,以突出显示它们的设计完全不同。
Linux驱动程序是内部化的(大部分是动态加载的模块),而不是用户空间,并且文件系统类似地是内部的。为什么这比使用外部驱动程序更糟糕?为什么Micro更适合用于通用计算?
这些评论再次强调您无法理解。如果要在离散硬件(例如航空航天,TiVo,平板电脑等)上部署Linux,则可以将其配置为仅构建所需的驱动程序。您可以使用
make localmodconfig
在桌面上执行相同的操作。最后,您得到的是一个微型的,针对目的的内核构建,灵活性为零。对于像Ubuntu这样的发行版,可以使用一个40MB的内核软件包。不,要解决这一问题,实际上,与将归档包保持4000多个浮动模块的大规模归档和下载方案相比,这实际上是更可取的。它为他们使用更少的磁盘空间,在编译时更易于打包,更易于存储,并且对他们的用户(拥有一个可以正常工作的系统)更好。(br />)还是一个问题。 CPU速度,磁盘密度/定价和带宽改进的速度似乎比内核的增长快得多。十年之内,一个200MB的内核软件包将不会终结。
这也不是一条路。如果不进行维护,代码确实会被踢出。
评论
关注的主要是嵌入式系统。如您所示,您的系统上有4,000个未使用的模块。在某些小型机器人技术或航空航天应用中(阅读:不是通用计算),这将是不可接受的浪费。
–乔纳森
15年8月18日在17:54
@JonathanLeaders我认为您可以安全地删除它们。在桌面安装中,如果您突然将某个端口插入USB端口或更改某些硬件配置等,它们就会存在。
– DiidierA。
15年8月18日在20:47
对,就是这样。我仍然对以下假设感到惊讶:“您可以随时插入USB设备,因此我们需要15m行代码”是在内核级别而不是发行版本级别写入的,因为在电话和各种操作系统中都使用了Linux。嵌入式设备。好吧,我想这个发行版确实可以自己删除列表。我只是认为对可插拔性的支持应该是加性的而不是减性的。发行版将通过添加软件包源来“选择加入”,这与嵌入式ARM配置相反,后者告诉内核其大小为当前大小的百分之一
–乔纳森
15年8月18日在21:02
@Jonathan带领您永远不要在嵌入式系统上运行为桌面配置的内核。我们的嵌入式系统有13个模块,并删除了我们不需要的所有硬件支持(以及许多其他自定义设置)。停止将台式机与嵌入式系统进行比较。 Linux运行良好,因为它支持所有内容,并且可以进行定制以仅包含您关心的内容。这些4k模块在台式机系统上确实很棒:当我的最后一台笔记本电脑死了时,我只是将硬盘驱动器安装在更新得多的笔记本电脑上,一切正常。
–user4443
15年8月18日在21:21
这个原本很好/很有价值的答案带有明显的愤怒和好斗的语气。 -1。
– TypeIA
18-4-24在20:01
#5 楼
tinyconfig气泡图svg(小提琴)
shell脚本从内核构建创建json,与http://bl.ocks.org/mbostock/4063269一起使用
编辑:原来
unifdef
有一些限制(-I
被忽略,-include
不被支持,后者用于包含生成的配置头),此时使用cat
并没有太大变化:274692 total # (was 274686)
脚本和过程已更新。
除了驱动程序,arch等外,根据选择的配置,是否编译了很多条件代码,代码不一定在动态加载的模块中,而是内置在内核中。
因此,下载了linux-4.1.6的源代码,选择了tinyconfig,它没有启用模块,老实说我不知道它启用或用户可以在运行时使用它做什么,无论如何,请配置内核:
# 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)
内核构建过程将隐藏f使用命令行也称为
*.cmd
的文件,还用于构建.o
文件,处理这些文件并提取目标文件和依赖项,并将其复制到下面的script.sh
中,并与find配合使用: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
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
评论
@JonathanLeaders从事这项工作很有趣,很高兴有人喜欢它
– Alex
15年8月21日在2:00
#6 楼
Tananbaum和Torvalds从一开始就在公众中讨论了整体内核的权衡问题。如果您不需要所有内容都进入用户空间,那么与内核的接口可以更简单。如果内核是单片的,则可以在内部对其进行优化(并且更加混乱!)。我们已经有一段时间作为折衷方案了。而且它还在继续进行DPDK之类的工作(将更多的网络功能移出内核)。添加的核心越多,避免锁定就越重要。因此更多的东西将进入用户空间,内核也会缩小。
请注意,单片内核不是唯一的解决方案。在某些体系结构上,内核/用户空间边界并不比任何其他函数调用都要昂贵,这使得微内核具有吸引力。
评论
“在某些架构上,内核/用户空间边界并不比任何其他函数调用都要昂贵” –有趣!那是什么建筑?如果您不仅仅放弃任何种类的内存保护,看起来很难实现。
– Voo
15年8月18日在18:03
我浏览了所有Ivan Goddard的millcomputing.com视频(磨/皮带CPU,非常类似于VLIW)。此特定声明是中心主题,在您观看安全视频之前,其含义并不明显。它是仿真中的POC架构,但可能不是唯一具有此属性的架构。
–Rob
15年8月18日在18:08
嗯,这解释了。根据我的经验(我将第一个承认我没有紧跟行业发展),有许多模拟架构,很少有人会在橡胶上路后立即兑现他们的要求,也就是说,在真正的硬件上。尽管它背后的想法在任何情况下都可能很有趣-并不是第一次提到特定的CPU。如果您发现具有此属性的现有体系结构,我将非常感兴趣。
– Voo
15年8月18日在18:11
顺便说一句,这是您提到的辩论的更多资源:en.wikipedia.org/wiki/Tanenbaum%E2%80%93Torvalds_debate
–乔纳森
15年8月18日在18:28
评论
早在2012年,仅司机就拥有500万条线路。 190万条线用于支持不同的处理器体系结构。更多信息h-online.com/open/features/…是的,我已经为一种语言编写了编译器,词法分析器和字节码生成器,并且正在进行完整的编码和递归操作,并且不需要10,000行。
(现在看,大约有2700条线)
您应该下载并配置make menuconfig,以查看在构建之前可以启用/禁用多少代码。
@JonathanLeaders:我已经用不到100行的语言编写了用于LISP的完整编译器(如语言),并渲染了Mandelbrots。始终取决于。