V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
kgdb00
V2EX  ›  Linux

有精通 Linux 内核内存管理的老哥能说说你是怎么学这一块的知识的吗?

  •  
  •   kgdb00 · 214 天前 · 4595 次点击
    这是一个创建于 214 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我在研究解决具体问题的时候看内核代码最容易看懂,但我目前还没遇到过哪些问题是必须得对内存管理非常熟悉才能解决的,学这个主要是想应付面试。

    目前我已经看懂了《深入理解 Linux 内核》这本书讲内存的第 2 ,8 ,9 章以及 Intel SDM 讲分段分页的部分,想继续深入研究只能靠看代码了,但我感觉看代码没有个方向,泛泛的看就只能有个很浅的了解,不知道怎么看才能达到精通的程度。

    我目前的办法是从 x86 系统启动的第一行代码开始看,搞懂每一行代码到底干了什么,最近看懂了一点 x86 bios (kvmtool 的实现)的代码,但我感觉这种方式学习效率太低了,请教大佬有没有什么好办法?
    50 条回复    2022-09-08 02:50:39 +08:00
    tinmody
        1
    tinmody  
       214 天前
    我不是大佬,爱莫能助。。。
    yuguorui96
        2
    yuguorui96  
       214 天前 via iPhone
    纯粹应付面试完全没必要,也确实无法深入。真是有兴趣可以写个 demo 驱动,解决问题才能深入结构。
    documentzhangx66
        4
    documentzhangx66  
       214 天前   ❤️ 7
    如果你不懂数学,给你 RSA 、DES 、MD5 等加密解密与哈希算法的代码,你是看不懂的。代码,只是实现数据结构与控制流程的方法,至于为啥要设计这种数据结构、为啥要用这种流程,它与协议以及更底层的知识相关。比如驱动里的一些缓存大小、循环间隔时间,它与下层电路逻辑有关。

    所以,你要学懂某一层次的东西,可能需要掌握其上层或下层的知识才行。

    到此,有两种学习方式,一种是学院派的至下而上,比如 数学 + 物理 -> 模拟电路 -> 数字电路 -> 组成原理 -> 汇编语言 -> C/C++ -> 操作系统,另一种是自上而下,比如以某种编程语言为主,来教你网络编程的书籍。两种学习方法各有优缺点,选择你喜欢的方式就好。
    hello2090
        5
    hello2090  
       214 天前   ❤️ 1
    @documentzhangx66 同学,你这就夸张了,还要物理?模电?模电就那点电容电阻啊,和编程有啥关系?
    disk
        6
    disk  
       214 天前
    @hello2090 面向硬件编程也是编程。。。
    hello2090
        7
    hello2090  
       214 天前
    @disk 那需要物理模电知识吗?
    detached
        8
    detached  
       214 天前
    @documentzhangx66 现代计算机之所以能够如此高速的发展,起着重要作用的一个概念就是抽象( abstraction )。抽象就是为了把你从“无用”的数学、物理中解脱出来,聚焦于更 specific 、subject-oriented 的问题。所以你不需要掌握“上层、下层”的知识,你只需要明白下层为你提供的接口与描述清楚你为上层提供的接口,例子:TCP/IP 网络结构。
    disk
        9
    disk  
       214 天前
    @hello2090 有些需要,特别是 dps 那块。
    disk
        10
    disk  
       214 天前
    @disk dsp
    thedrwu
        11
    thedrwu  
       214 天前 via Android
    自己写一遍 x86 进保护模式、设置分页的 demo ,再回头看
    documentzhangx66
        12
    documentzhangx66  
       214 天前
    @hello2090 举一个例子,程序运行的性能问题,是如何产生的。
    documentzhangx66
        13
    documentzhangx66  
       214 天前
    @detached
    站在工作分工与快速入门的角度来看,您说的很对。

    但如果是站在学习的角度,想学地透彻,就需要去学习其发展史,需要学习底层的构成,需要了解其上层的发展、应用与案例。

    举个简单的例子,java 程序员,去学习如何操作文件。从您的角度来说,去谷歌一下 java 文件 io 的相关例子与代码,就能学懂。但是,当 java 同时操作海量文件时,当 java 操作不同设备上的文件时,当 java 通过不同渠道操作文件时,当 java 绕着地球一圈操作文件时,所产生的的各种性能问题、各种错误问题,要分析这些问题,如何产生,能否解决,如何解决,各种解决方案的代价如何,这就不仅仅只是 java 这一门课程能学到的。
    wzxlovesy
        14
    wzxlovesy  
       214 天前 via Android
    如果从 Linux 开始太难入手的话,我推荐从 kvm-unit-tests 开始看。这个项目实现了一些内核里重要的功能,用于启动虚拟机后运行测试代码。

    这些功能的实现很大程度上来源于 Linux 内核,从这里你可以快速学到 page table, tlb 等等基础知识。

    大致搞懂之后再去看 Linux 会容易很多。
    hello2090
        15
    hello2090  
       214 天前 via iPhone
    @documentzhangx66 用得到什么物理知识?
    hello2090
        16
    hello2090  
       214 天前 via iPhone
    @disk 我不觉得 DSP 和模电有关系。
    Suddoo
        17
    Suddoo  
       214 天前
    @documentzhangx66 感觉这块跟公司里写业务代码是一样的,如果不清楚需求的话,根本不明白为什么这么写,所以,光看代码,没用的
    shayuvpn0001
        18
    shayuvpn0001  
       214 天前   ❤️ 1
    @hello2090 做过音频处理,射频处理,特别是通信系统里面的东西就知道了。同一个降噪算法,可以用纯模拟电路,ADC 然后 ASIC ,DSP 编程,FPGA+Verilog ,CPU+软件来实现,各种实现路径如何取舍。不仅要考虑效果,还要考虑性能,成本。
    hello2090
        19
    hello2090  
       214 天前
    @shayuvpn0001 那这里哪个需要物理呢?物理里的哪些知识呢?热胀冷缩吗?
    crackhopper
        20
    crackhopper  
       214 天前   ❤️ 1
    个人提供一个思路(我不是这个方向大佬):必须得想办法能调试系统,你才能更深入的理解。比如,在虚拟机中,通过日志调试或断点调试:比如创建堆上内存的系统调用这个场景下,在系统内核的相应代码中打印堆栈(或者用调试器打断点,我不清楚是否可行,可以自行查阅)。从堆栈中分析执行流程。从整体上建立一个认知,再去逐步看代码。看的过程中,自己加日志代码打印自己的猜想和理解。

    上来就用纯阅读的模式看代码,确实低效。
    shayuvpn0001
        21
    shayuvpn0001  
       214 天前
    @hello2090 振幅啊,频率啊,滤波器设计(高通滤波,低通滤波,带通滤波)

    你不会以为模电只是电容电阻这些吧。。。
    hello2090
        22
    hello2090  
       214 天前
    @shayuvpn0001 这和物理有关吗?而且 我问的是 5 楼对楼主 linux 内存管理的回复,学编程是 数学 + 物理 -> 模拟电路 -> 数字电路 -> 组成原理 -> 汇编语言 -> C/C++ -> 操作系统, 你都已经范围缩小到 DSP 了

    我也是 985 通讯本硕,模电数电通讯原理信号处理 DSP Verilog 都是专业课,这里面哪里有和物理有关的?振幅频率滤波器当然是数学啦。
    detached
        23
    detached  
       214 天前
    @documentzhangx66 不矛盾,正如你自己所说,Java 一门课肯定是学不到这么多东西。但是所有的问题仍然是在 computer science 这个学科范围内,并不会延伸到数学与物理。就算是对数学与物理有要求,也不过是高中或者大学一二年级通识教育中的内容。
    shayuvpn0001
        24
    shayuvpn0001  
       214 天前
    #16 @disk 我不觉得 DSP 和模电有关系。

    @hello2090 我觉得我们还是不要继续讨论下去比较好。。。
    basncy
        25
    basncy  
       214 天前
    做过相关工作, 抛砖引玉 https://www.zhihu.com/question/379177766
    所谓内存管理, 大约是物理内存与虚拟地址之间的各种游戏规则.
    iClass
        26
    iClass  
       214 天前 via Android   ❤️ 1
    看图并绘图 一张图片胜过千万行代码
    xsen
        27
    xsen  
       213 天前
    你需要先看 X86 体系结构——主要是涉及内存部分,然后结合代码你才看得懂
    简单点,Linux 内存管理部分可以当成是针对特定硬件(如 X86 )内存管理方面的驱动,那你就需要先阅读相应硬件的 datasheet ,不然很多概念你是无法理解的

    体系结构相当是操作硬件的规范,那你要操作管理内存,自然要根据规范
    documentzhangx66
        28
    documentzhangx66  
       213 天前
    @hello2090 我已经在前面举例子了,程序运行的性能问题,是如何产生的,你可以尝试逐层解析这个问题。

    如果觉得这个话题太宽泛,那你可以研究一下,一条指令的性能,是怎么产生的。
    hello2090
        29
    hello2090  
       213 天前 via iPhone
    @documentzhangx66 那研究一条指令的性能,需要哪些物理知识呢?
    documentzhangx66
        30
    documentzhangx66  
       213 天前
    @hello2090 你可能不太懂指令与物理知识之间的关系,所以建议你先研究试试。
    hello2090
        31
    hello2090  
       213 天前 via iPhone
    @documentzhangx66 你可以说说是哪方面的物理知识,我可以有的放矢嘛。热胀冷缩?速度加速度?作用力和反作用力?
    documentzhangx66
        32
    documentzhangx66  
       213 天前
    @hello2090

    请问你学过 C 语言吗?
    hello2090
        33
    hello2090  
       213 天前 via iPhone
    documentzhangx66
        34
    documentzhangx66  
       213 天前
    @hello2090
    已知 int a = 0;
    你有没有想过,对于 a++; 这行代码,每秒可以运行多少次,取决于什么?
    hello2090
        35
    hello2090  
       213 天前 via iPhone   ❤️ 2
    @documentzhangx66 取决于哪款 CPU ?而且还要考虑电脑是不是失重状态?加速度是多少? CPU 是 100%纯硅还是 99%硅? CPU 封装什么方式,阵脚散热性能够不够?太多知识点了

    没想到一句 int i = 0; 蕴含了这么多体系化结构性思维

    那 int i = 9 这行代码为什么在 X86 架构下运行速度比 int i = 0 快 0.00000781% 但是在 M1 下只快 0.00000663% 呢。确实架构的力量太有魔力了。

    你看 就理解 int i = 0 的性能方面,我的物理知识够了吗?还有哪些方面需要补充。相对论我没好好学过,对我分析性能是不是影响比较大,我是不是该把这门课啃下来?
    documentzhangx66
        36
    documentzhangx66  
       213 天前
    @hello2090
    1.取决于哪一款 CPU ,并不重要。你可以选一款你最熟悉、最常见的 CPU 进行分析,比如就选择你现在上网用的电脑的 CPU 。

    2.我说的不是 int a = 0;我说的是 a++; 因为这一行更简单,更容易分析。

    3.你可以想想,对于你现在手头上的电脑,执行 a++ ,每秒可以运行多少次,它的底层是怎么运行的?
    hello2090
        37
    hello2090  
       212 天前 via iPhone
    @documentzhangx66 可你不是说需要物理知识才能分析吗?我就是想问问需要具备哪些物理知识啊,指点指点我吧!
    documentzhangx66
        38
    documentzhangx66  
       212 天前
    @hello2090

    别急,先看看我上一条评论。
    hello2090
        39
    hello2090  
       212 天前 via iPhone
    @documentzhangx66 没有物理知识你让我怎么想嘛,想不出来啊!
    hhjuteman
        40
    hhjuteman  
       212 天前   ❤️ 2
    既然你已经看了 ULK ,那么看代码已经是一个比较好的选择了。
    https://www.kernel.org/doc/gorman/html/understand/

    这里有一份材料,相比 ULK 更加深入的介绍了 mm 的各个部分,但因为材料基于 2.6 ,作为看代码的辅料进行。

    https://github.com/chenshuo/linux-study

    我这里推荐使用这个项目来学习 Linux 内核,这个项目抽离 Linux 代码,使得 Linux 可以像程序一样编译调试,这样看起来会更加的清晰。

    后面是学习 Linux 内核最最最最重要的部分了:

    学习 Linux 内核,到底是在学习什么?什么是 Kernel ,我的理解是内核是一系列算法和模型的集合,这些算法和模型是用来调配硬件的,调配硬件不一定要懂硬件模型,因为内核中的算法和模型集合抽象程度已经相当高了。

    学习内核,及学习其中的算法,我举个例子,比如说学习 zfs ,我们吧 zfs 中的加到数据库的容灾中去,改造数据库,这是一个例子。比如说学习 mm ,mm 中的 slab 内存分配原理,再看看市面上另外优秀的内存分配算法实现,如 mimalloc ,从而定制更加精细的内存分配算法,这是一个点。你说从什么启动,什么 bootloader 开始学起,没有意义,舍近求远,因为 mm 和这些完全无关,这就是独立的算法和设计模块。很多市面上所谓的那种简易操作系统书,总喜欢大篇幅再 loader 上做文章,这也是舍近求远的做法。我们学习的是 modern os ,"modern"这个词至关重要。

    你可以根据我给的第一个 link ,结合第二个连接源码看看 Nodes ,Zones ,TLB ,Slab 等等结构,更多的精细算法我就没研究过了,我研究过 net 和 ext 部分。
    liuxu
        41
    liuxu  
       212 天前
    此贴 11 楼,26 楼,40 楼为正确答案。
    pierswu
        42
    pierswu  
       212 天前
    @hello2090 ntpdate time.ntp.org -> 时钟发生器 -> 时间振荡电路 -> 石英晶体振荡器 -> 压电效应

    如果不知道什么是压电效应,一样可以使用 ntpdate 命令去同步时间,但是压电效应就是计算机时间的物理基础
    hello2090
        43
    hello2090  
       212 天前 via iPhone
    @pierswu 那在写那些程序的时候需要把这些考虑进去呢?或者学习了这些知识可以帮助你在哪些方面把程序写得更好呢?
    pierswu
        44
    pierswu  
       212 天前
    @hello2090 是不需要学这种底层的东西。但是人生不一定就只有编程,就像 OP 想去学习内核内存管理是为了应付面试,我知道时钟发生器就可以给客户解释为什么他的服务器需要校准时钟
    hello2090
        45
    hello2090  
       212 天前 via iPhone
    @pierswu 当然有用,对人生来说哪有没用的东西。我这帖子里所有的回复都是针对 4 楼给出的学习编程的路径 “数学 + 物理 -> 模拟电路 -> 数字电路 -> 组成原理 -> 汇编语言 -> C/C++ -> 操作系统” 给出质疑而已。
    pierswu
        46
    pierswu  
       212 天前
    @hello2090 4 楼的观点是,要学懂某一层次的东西,可能需要掌握其上层或下层的知识才行,这个“数学 + 物理 -> 模拟电路 -> 数字电路 -> 组成原理 -> 汇编语言 -> C/C++ -> 操作系统” 是他举得例子。
    那学习模拟电路,不需要物理里面的电路知识吗
    hello2090
        47
    hello2090  
       212 天前 via iPhone
    @pierswu 那对一个要学习 Linux 内存管理的程序员来说,需要学习模拟电路吗?
    pierswu
        48
    pierswu  
       212 天前
    @hello2090 不需要,但是他只是举个例子,4 楼的内容也没说一定要学物理才搞得懂内存管理。
    那回到 op 提的问题,他要想学好 Linux 内存管理,那需要从 操作系统入手,或者从编程入手
    kgdb00
        49
    kgdb00  
    OP
       28 天前
    @hhjuteman 请问 https://github.com/chenshuo/linux-study 这个项目是要怎么用啊?

    这个项目没有任何文档说明,我使用 ./study/config.sh 编译出来的内核也没有 bzImage 镜像,不知道怎么运行,更不明白“像程序一样编译调试” 是怎么个情况,比如我想用这个项目去研究伙伴系统算法要怎么做?
    kgdb00
        50
    kgdb00  
    OP
       28 天前
    @hhjuteman 我切换到 4.9 分支后看到有个 build.sh 文件,study 目录下也比 master 多了几个文件,不过因为项目太老不能编译,我感觉这个项目应该只是用来测试一些比较高层次的函数,没办法用来研究伙伴系统,进程调度这些核心子系统,不知道这个项目的意义何在。
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   870 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 52ms · UTC 21:35 · PVG 05:35 · LAX 14:35 · JFK 17:35
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.