我们已经准备好了,你呢?

2024我们与您携手共赢,为您的企业形象保驾护航!

linux是宏内核还是微内核_linux宏内核_linux 内核版本号宏

LINUX是全人类的选择。

今天是这样的,

这种情况在未来几十年内也不会改变。

对于软件工程师来说,

不用考虑是否需要学习LINUX。

就想着怎么学好LINUX吧...

>>>>>>>

独自登上高楼

LINUX代表着未来。我们今天选择了它,未来几十年它也不会改变。对于今天的程序员来说,我们正在经历这种变化。在桌面领域,它仍然占有比较大的份额,但我相信,正在进行的革命最终会让Linux成为一个越来越普遍的系统平台。

对于各位从事软件开发的朋友来说,我们当然应该走在普通用户的前面,按照技术发展的方向做好技术储备。所以,在我看来,今天你不用考虑要不要学Linux,你只需要考虑怎么学好Linux。

十几年前就有人问我为什么还在分享,从中可以看出十几年前就有人预测Linux会逐渐成为主流,我也认为这个预测是正确的。

受到国学大师王国维的启发,我把 Linux 的学习概括为六种境界。王国维曾在《人间话》中把做人、学习分为三种境界。对于软件设计来说,境界也是一个很重要的概念,甚至可以说是一种方法论。后面我会把我概括的六种境界和王国维总结的三种境界做个对比,我概括的前三种境界其实不算,我会把后三种境界对应到王国维总结的三种境界。

linux宏内核_linux是宏内核还是微内核_linux 内核版本号宏

如果你对人生的领悟和学术的研究没有达到一定的境界,就不会有这样的感悟。

“我独登高塔,望天涯路”是王国维眼中的第一个境界。所以我总结的前三个境界其实还是零十版,而不是第一个境界。

介绍的就这么多,现在我们进入第一个境界。

linux宏内核_linux是宏内核还是微内核_linux 内核版本号宏

linux宏内核_linux是宏内核还是微内核_linux 内核版本号宏

境界一

艺术

特点

linux 内核版本号宏_linux是宏内核还是微内核_linux宏内核

说到学习,很多人想到的就是“我要买书”。如今,关于Linux的书籍数不胜数。阅读当然是有益的,所以我们将其归为第一层次。买书是好事,但能否从书中有所收获,则取决于阅读的方法和认真程度。

除了书籍,如今网络时代的文章也很多,推荐大家去读一下Linux内核的官方文档,如果把Linux内核的官方文档分成不同的层级,有一些写得非常好的文档,比如:《Linux内核指南》。

这篇文档的标题很谦虚,意思是:我给你写了一份有点不靠谱的攻克Linux内核的指南。这种看似不靠谱的说法越是值得一读。

linux 内核版本号宏_linux是宏内核还是微内核_linux宏内核

本文作者是Rusty,我的一位澳大利亚同事,曾经在IBM的Linux技术中心工作过。在我看来,写作是一门需要很多方法的技能,不同的人写同样的内容有不同的方法。Rusty写过很多内核代码,他的文章也展现了一些很独特的观点,这些观点都非常简洁明了。

linux是宏内核还是微内核_linux宏内核_linux 内核版本号宏

在这篇并不太长的文档里,他写了很多理解内核的关键点。比如上面这段其实只有几十个字的文字,就写到了阅读内核代码需要了解的一个关键特性,即:返回值的约定。Linux 内核是用 C 语言编写的,简洁,强调简单而不是复杂。因此,Linux 内核代码没有太多杂七杂八的误判和太多冗余(比如:保留很多参数以备将来使用)。

Linux 内核代码尽可能简洁,这也体现在返回值上。Rusty 对返回值提出了两点:

成功时返回零,失败时返回负数。

这也是我很喜欢的一种做法,但是对于一些教条式的编码规范来说,返回值是无符号的,如果要表示错误,需要在参数中单独设置一个指针作为错误代码,很别扭。

如果函数返回的是指针,则不需要单独返回错误代码,只需将错误代码编码到指针中即可。因此,内核中有几个著名的宏:

()

()

如果是返回指针的函数,在指针处失败,则返回值也会被编码进去。为了提高可读性,定义了这些宏。

在Rusty的文章里,像这样简短精炼的总结就有十几个,文章也很短,用通俗的话说,真的都是有用的信息。

总结:学习内核的第一步就是阅读内核的文本,书籍,好文章,官方文档。

linux宏内核_linux是宏内核还是微内核_linux 内核版本号宏

领域 2

一代

代码

第二个层次是阅读代码。Linux内核是开源的,所以大家一定要抓住机会,利用它的开源特性,阅读它的源代码。

如果你还没有下载Linux内核源代码,请立即打开并下载一份源代码。我鼓励大家下载LTS(长期支持版本)。最新的LTS是6.1。在此之前,更常用的LTS是5.10或5.15。如果你目前在产品中使用5.10,则它被认为是相对较新的。上一个版本是4.19。下载LTS后,将其解压到你的电脑上,你可以随时打开它查看。

Linux内核的源代码是无价的,是全世界人类智慧的结晶。它是基于全世界程序员的共同努力才产生这样一套代码。因此,我们可以从这套代码中学到很多东西。

“广度比深度更重要”

——Linux目录树的定义原理

linux 内核版本号宏_linux是宏内核还是微内核_linux宏内核

首先Linux内核目录树的定义原则是目录宜多不宜过深。现实中很多软件项目做不好就是因为目录定义得太深,不利于浏览。浏览目录的时候相当于进入、进入、进入、再退出、进入、进入、进入、退出。

所以建议源代码目录的组织方式要宽而不深,同一层级的目录多也没关系,因为一目了然,可以知道这一层级里有什么。尽量避免一层层往下铺,比如最上面只有两个目录,然后就分开了,每一层级都扩展到多个目录。这样的目录树浏览起来非常不方便,无法一下子看到全貌。

阅读源代码

——以 Panic 函数为例

在阅读Linux内核源代码的时候,可以找出一些自己感兴趣的函数去读,比如Panic函数,这个函数很有趣,因为它很形象,我们可以直接打开panic.c,读到Panic函数的逻辑。

linux宏内核_linux 内核版本号宏_linux是宏内核还是微内核

它是Linux内核中一个很老的函数,早在0.1版本就有了。但是在0.1版本中Panic是一个死循环,在后续的发展中变得越来越复杂。和函数原型类似,Panic有固定的模板,后面可以跟不确定的参数。内核代码中很多地方都会调用它,调用时根据原型传递各种参数。如果分析Linux崩溃时,看一下Linux发生Panic时的源码,就可以一边研究源码一边了解Panic的原因。

结合工业界发展阅读内核代码

——以Arch子目录为例

内核源代码还可以结合业界发展来阅读,比如Arch目录,代表了CPU厂商的开发实力。

linux宏内核_linux是宏内核还是微内核_linux 内核版本号宏

从4.4内核到5.13,再从5.13到6.16,Arch子目录的变化巨大。

关于 Arch 子目录,我在庐山桃花源工作坊讨论的时候,有位博主提了一个非常好的问题:

“为什么ARM 32位和64位分为两个目录,而x86在一个目录中?”

linux是宏内核还是微内核_linux 内核版本号宏_linux宏内核

我觉得这个问题问的很好,代表着做同一件事的不同方式,或者说不同的人生态度。

ARM 分成两个品类,体现了它的年轻、无畏和勇于突破自我的精神。它认为老的 32 位系统存在很多问题,所以在发展到 64 位的时候,就创造了一个新的品类,把历史包袱都扔掉了。这就好比一个年轻人,如果不想干这份工作,干脆放弃,学一门新技术,从头再来。

x86 历史上有 IA-64 架构,Intel 希望 64 位就是 IA-64,但是 AMD 不同意,搞出了 AMD64。因为 AMD 的口号是 64 位和 32 位无缝兼容,所以没必要搞两个目录。x86 之所以重,是因为它背负了所有的历史包袱,所有的东西都混杂在一个目录里。

linux宏内核_linux是宏内核还是微内核_linux 内核版本号宏

第三境界

接下来的第三境界是读“信”。信的英文是 ,还有消息()和电子邮件(Mail),广义上可以称为信件。我上大学的时候,很流行写信。下课后,大家都盼望着收到信。

为什么读一封信和读一本书的感觉不同?

因为书信篇幅较短,且有特定的场景,所以更有针对性和沉浸感。对于一本厚厚的书,我们往往坚持不下去,不知道作者在说什么,也不知道先读什么,后读什么。但对于一封信,你读的时候通常不会有这种感觉,因为你能够很快进入到信的场景中,立刻明白信中所描述的问题,所以很快就能看懂。所以,学习Linux内核的第三个境界,就是读懂内核写给我们的信。

内核是怎样写字母的?

内核中有一个著名的功能,这是Linux内核开发者Linus最先依赖的调试方法。

linux宏内核_linux 内核版本号宏_linux是宏内核还是微内核

linux 内核版本号宏_linux是宏内核还是微内核_linux宏内核

我统计了一下 Linux 3.12 内核的行数,有 6 万多行。到今天可能已经突破 10 万行了。也就是说,内核中有 10 万行主干代码。同时这些行中还有大量的变量,因为它们可以包含变量信息,所以在不同的场景下执行到这里都会打印一条消息。把这些消息积累在一起,就像内核的时钟在记录它走过的路。它此刻的心情就像朋友之间写信,我们读信的时候,能感受到对方的经历,以及写信时的心情。

阅读内核打印的这些消息,我们也能感受到:

为什么我们要关注内核消息?

内核消息是一个非常生动的内核数据。如果你在不同的系统上启动,你会发现很多不同。例如在 x86 上,你会看到一些 x86 的特性,而且固件和设备与 ARM 也不同。因此,每当我接触到一个新的 Linux 系统时,我都喜欢用 dmesg 查看内核消息,而且每次都有收获。

当然内核消息不仅仅在启动时显示,当你在进行某些操作的时候,内核也会打印出消息,这时候打印出来的消息也是非常有用的。

linux宏内核_linux是宏内核还是微内核_linux 内核版本号宏

第四境界

一代

代码

第四境界是写代码。前三境界的第一个动词是“读”,但第四境界不再是“读”,而是“写”。我们不用动手,用眼睛就能读,但要想写代码,就需要动手,把代码打进去,编译执行,还要经历这样一个过程。

linux宏内核_linux 内核版本号宏_linux是宏内核还是微内核

这里我想引用我非常敬佩的丹尼斯·里奇的一句话,他是C语言的发明者,也是UNIX操作系统最重要的两位先驱之一,他说:“学习一门编程语言的唯一方法就是用它编写程序。”

我很相信这句话,要学好编程,就得写代码,同样,要学好内核,也得写代码,所以我会用 的话来描述学习内核:“学习内核的捷径就是写代码,然后在内核里跑起来。”

内核中代码该如何写?

一种方法是修改内核编译,但是这种方法需要较多的技巧和时间。

还有一种方式就是写驱动程序,因为驱动程序也是运行在内核空间的。由于驱动程序是模块化的,我们可以先写一个小的驱动程序运行在内核空间,这样可以体会内核编程的不同,探索如何与内核交互,如何编写内核代码,体会做内核的不易——内核虽然很强大,但是也有不少的难处。

在环境中,如果想在内核空间运行自己的代码,已经有一些限制了,如果想在内核空间运行代码,就必须对代码进行签名。从Vista开始微软就要求内核空间的代码必须签名,这样就不是很方便了。如果要做测试签名,还需要重新开启禁止签名强制执行的功能。所以,我今天逐渐转向Linux。因为环境越来越不适合开发者了,规矩太多,太守规矩的系统缺乏生机和活力,所以,我鼓励大家像我一样转向Linux。在Linux环境中,你可以轻松地加载驱动程序而不需要签名。当然,如果要搭建一个构建驱动程序的环境,就有点困难了,需要做一些准备工作,比如:安装内核头文件。

linux是宏内核还是微内核_linux宏内核_linux 内核版本号宏

这里我们具体以幽蓝为例,幽蓝是格物科技推出的一款专门为程序员打造的笔记本,拿到手就能构建内核驱动,各位拥有幽蓝的格物朋友可以马上试用,测试成功后再进行一些修改,修改完之后再编译加载,不断重复这个过程,对内核就会越来越熟悉。

演示:使用 构建内核驱动程序

linux宏内核_linux 内核版本号宏_linux是宏内核还是微内核

说到这里,我们再来回顾一下王国维总结的三种境界,他总结的第一种境界是“昨夜西风凋绿树,独上高楼望天涯路。”

很多接触Linux的人根本没有这种感受。在我看来,只有自己写过一些内核代码之后才会有这种感受,体会到内核的难度,内核代码的独特性,知道内核代码面临的真正挑战——代码量巨大,各方面负担巨大,所以做好是非常困难的。

linux宏内核_linux是宏内核还是微内核_linux 内核版本号宏

5 级

里面

尝试

第五层级是用调试器调试内核。当你真正写完内核代码之后,你会越来越了解内核,会发现还有很多东西需要学习,这就好比“独攀高楼,望天涯路”,处处辽阔,你想去探索,但时间有限,所以要提高效率。

如何提高效率?

调试器是提高效率的好方法。

回顾我这么多年在技术上的探索,其实对我帮助最大的就是调试器了。所以每次学习一个新技术,我们都会尝试使用调试器。这几年我转向ARM+Linux,开发了好几个调试器,比如硬件调试器Swing Code Gun,软件调试器Nano Code。出差的时候,我经常会带着这些东西。

linux是宏内核还是微内核_linux 内核版本号宏_linux宏内核

上面这张图是我出差的时候拍的,码枪有两把,一把是GDK3(用来调试ARM的M核),一把是GDK8(用来调试ARM的A核,里面也包含Linux)。

linux宏内核_linux是宏内核还是微内核_linux 内核版本号宏

这个截图是在WiFi发包函数里设置的断点,断点命中之后可以看到这是来自用户空间的调用,一步步往上层,进入网络协议栈,再进入电路层到设备驱动,设备驱动最后送到物理层进行物理传输。

很多人对网络感兴趣,不管是学安全的,还是做通信的。如何把网络学得活灵活现?调试器肯定是一个非常高效的方法。为什么我们把代码阅读仅仅看作是第二层级呢?因为在阅读代码的时候,你往往读不到真正需要的代码,读到的都是死代码。只有在调试的时候,你才能读到活的代码,因为这个代码是真实运行的,你设置一个断点之后,才能真正看到它。

通过内核调试,我们可以提高理解内核的效率,通过设置断点,我们可以立刻发现很多问题。

当然,我们也可以用这样的方式来看待调度。

Child-SP          RetAddr           Call Siteffffff80`0f08bb00 ffffff80`090a060c lk!__switch_to+0x8 [arch/arm64/kernel/process.c @ 544]ffffff80`0f08bb90 ffffff80`090a10d8 lk!__schedule+0x2f4 [kernel/sched/core.c @ 3437]ffffff80`0f08bbb0 ffffff80`08082fa0 lk!preempt_schedule_irq+0x38 [./arch/arm64/include/asm/irqflags.h @ 62]ffffff80`0f08bbb0 00000000`9200004f lk!el1_preempt+0x8 [arch/arm64/kernel/entry.S @ 665]

dt prev -y commLocal var @ 0 Type task_struct*   +0x768 comm : [16]char[]  "Chrome_HistoryT"

dt next -y commLocal var @ 0 Type task_struct*   +0x768 comm : [16]char[]  "migration/0"

这是一个抢占式调度的执行过程,实际上就是将CPU上下文从一个线程切换到另一个线程。

自愿放弃行政权力

Child-SP          RetAddr           Call Siteffffff80`0a313d30 ffffff80`090a060c lk!cpu_switch_to [arch/arm64/kernel/entry.S @ 1067]ffffff80`0a313de0 ffffff80`090a0c80 lk!__schedule+0x2f4 [kernel/sched/core.c @ 3437]ffffff80`0a313e00 ffffff80`080e5f00 lk!schedule+0x38 [kernel/sched/core.c @ 4171]ffffff80`0a313e60 ffffff80`080e147c lk!smpboot_thread_fn+0x258 [kernel/smpboot.c @ 160]ffffff80`0a313ec0 ffffff80`08085db0 lk!kthread+0x12c [kernel/kthread.c @ 260]ffffff80`0a313ec0 00000000`00000000 lk!ret_from_fork+0x10 [arch/arm64/kernel/entry.S @ 1104]

线程切换的场景有很多种,有时候主动让出执行权,有时候主动把执行权交给调度器,由调度器负责切换。

由于等待信号量而切换线程

Child-SP          RetAddr           Call Siteffffff80`0d8abbb0 ffffff80`090a060c lk!cpu_switch_to [arch/arm64/kernel/entry.S @ 1067]ffffff80`0d8abc60 ffffff80`090a0c80 lk!__schedule+0x2f4 [kernel/sched/core.c @ 3437]ffffff80`0d8abc80 ffffff80`090a47b8 lk!schedule+0x38 [kernel/sched/core.c @ 4171]ffffff80`0d8abd40 ffffff80`090a30e8 lk!schedule_timeout+0x1e0 [kernel/time/timer.c @ 1795]ffffff80`0d8abdc0 ffffff80`0811a4cc lk!__down_interruptible+0xa0 [kernel/locking/semaphore.c @ 221]ffffff80`0d8abdf0 ffffff80`011c1134 lk!down_interruptible+0x54 [kernel/locking/semaphore.c @ 85]ffffff80`0d8abe60 ffffff80`080e147c bcmdhd!dhd_rxf_thread+0x9c [drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux.c @ 6614]ffffff80`0d8abec0 ffffff80`08085db0 lk!kthread+0x12c [kernel/kthread.c @ 260]ffffff80`0d8abec0 00000000`00000000 lk!ret_from_fork+0x10 [arch/arm64/kernel/entry.S @ 1104]

有时候会进入等待,比如这里就是在等待一个信号量,当信号量调用down函数的时候就进入等待,触发线程切换。

从空闲线程中抛出工作

Child-SP          RetAddr           Call Siteffffff80`0a323e70 ffffff80`090a060c lk!cpu_switch_to [arch/arm64/kernel/entry.S @ 1067]ffffff80`0a323f20 ffffff80`090a104c lk!__schedule+0x2f4 [kernel/sched/core.c @ 3437]ffffff80`0a323f40 ffffff80`080f4f50 lk!schedule_idle+0x24 [./include/asm-generic/bitops/non-atomic.h @ 106]ffffff80`0a323fb0 ffffff80`080f5224 lk!do_idle+0x168 [kernel/sched/idle.c @ 292]ffffff80`0a323fd0 ffffff80`08097c38 lk!cpu_startup_entry+0x24 [kernel/sched/idle.c @ 370]ffffff80`0a324000 00000000`00000000 lk!secondary_start_kernel+0x150 [arch/arm64/kernel/smp.c @ 255]

另一种情况是从空闲线程切换到新线程。

如果你对内核调试感兴趣,我推荐你使用代码枪加GDK8,这是性价比非常高的内核调试方案。如果要自己搭建内核调试环境,无论是连接串口还是重新编译内核使用网络,都需要花费不少时间。代码枪加GDK8相当于拿到手后立刻连接,五分钟内断开内核,设置好符号后进入状态。

linux是宏内核还是微内核_linux宏内核_linux 内核版本号宏

我把内核调试看作是学习Linux内核的第五个境界,这对应着王国维所说的第二个境界:“衣裳渐宽,我终不悔,为她憔悴。”当你达到这个境界的时候,你就会把学习内核看作是一种爱好,看作是一件理所当然的事情。

linux宏内核_linux是宏内核还是微内核_linux 内核版本号宏

第六境界

相互

伴侣

最后一种状态很特殊,它有好几个名字,我现在写的这个名字比较优雅,叫陪伴。夫妻相伴到老。陪伴是一种很高的状态,我们和Linux内核之间的最高状态也是陪伴。

这种心态其实源自于NT内核。在NT内核开发的最后阶段,开发小组开始把这个正在开发的内核当成自己的工作机器。当然,最初也派了好几位专家去做这个任务,他们先把自己的机器换上正在开发的NT内核,然后自己用,马上就发现了大量Bug。作为一个软件工程师,你把你实际开发的系统当成你使用的系统,体会你写的代码是什么样的,感受你开发的产品是好是坏,有多差,有多好。如果你能达到这种心态,那是很了不起的。

目前对于整个Linux系统来说,它的可用性还是有些欠缺,所以很多人还是比较依赖桌面或者Mac。在我看来,如果你真的想学好Linux,决定投身Linux内核,为什么不干脆把工作机换成Linux呢?我今天就是干这个,所以最近一直背着两台电脑,虽然有点重,但其实没关系。上面那台是Linux的,很薄,因为无风扇,所以轻很多。

linux是宏内核还是微内核_linux宏内核_linux 内核版本号宏

这个过程是需要付出一些努力的,但是这个努力的过程恰恰是我们学习的过程,在这个过程当中,我们才能更好的学习内核,因为在这个过程中,我们能够立刻感受到Linux环境当中存在的一些不足。

对于我来说,很多时间都是在Linux上开发一些代码,所以我在努力将自己的开发环境切换到Linux,也鼓励大家和我一起这样做。有人说:“我不要当实验鼠,不要这样,等大家都体验好了,我再切换到Linux。”这不是开发者的心态,而是普通用户的心态。作为一名程序员,你要时刻站在技术的最前沿,学习新技术,遇到各种问题,就去解决。当然,我这样说并不是为了让大家在没有问题的时候发现问题,而是要有一个真实的环境,这样你遇到的问题才很有代表性,有意义,有价值,代表着趋势,然后你去钻研这些问题,就是为了顺应这个趋势。

linux 内核版本号宏_linux是宏内核还是微内核_linux宏内核

进入这种状态,我想只要坚持,就能达到王国维总结的第三种境界——“我千方百计于众人之中寻他,回头在灯火阑珊处寻他”。坚持下去,昼夜陪伴在Linux环境里,今天学一点,明天学一点,你输入的每一个命令,你进行的每一个操作,你点击的每一个鼠标按钮,你都在感受Linux、学习Linux、与内核对话。这时候你的进步是一点一滴的,无形中你在向前走。有了这样的日常陪伴,相信有一天你回头一看,会发现自己的水平不一样了,自然而然就会明白内核的各种机制了。

linux宏内核_linux是宏内核还是微内核_linux 内核版本号宏

通过购买幽兰密码本,您可以成为幽兰社的一员,与众多技术高手一起成长。

您可以前往淘宝歌友店购买:

【圣歌塾】

真诚诚实,研究事物以获得知识

用人文情怀审视软件,用软件技术改变生活

格友公众号

圣歌居小程序

扫描上方二维码或在微信搜索“圣歌书”小程序

二维码
扫一扫在手机端查看

本文链接:https://by928.com/2444.html     转载请注明出处和本文链接!请遵守 《网站协议》
我们凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设、网站改版、域名注册、主机空间、手机网站建设、网站备案等方面的需求,请立即点击咨询我们或拨打咨询热线: 13761152229,我们会详细为你一一解答你心中的疑难。

项目经理在线

我们已经准备好了,你呢?

2020我们与您携手共赢,为您的企业形象保驾护航!

在线客服
联系方式

热线电话

13761152229

上班时间

周一到周五

公司电话

二维码
微信
线