百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

【Linux随笔】用户空间到底跟内核空间共享页表吗?

ahcoder 2025-02-03 11:13 13 浏览

1、这个问题其实不重要

这个问题其实不重要,你知道这个问题答案,也不能为你找到更好的工作,或者说明你编程能力有多牛,你甚至在工作中用不到这个结论。但是为什么要写这篇文章呢?

因为,通过这个问题,我感觉到了解决问题的过程好像比知道问题的答案更有趣。

2、如果我们没有google怎么解决这个问题?

很多人包括我,当遇到问题的时候,发现bug的时候,总是习惯第一时间去google、百度。因为,快速,因为不需要动脑子,因为,可以抄答案,这种解决问题的方式带来的快感跟占了大便宜是一个道理。但是这样真的好吗?也许不好。

2.1、为什么有这个问题呢?

因为,我吃饭的时候突然想起一个问题,既然用户与内核都使用虚拟内存,都要经过页表才能找到最后的物理页,那么为什么在进程切换的代码中找不到内核切换的代码?只是切换了mm?压根就没提内核空间。我没有多想,就把这个问题记录下来了,回头仔细查查代码。

2.2、问题探索过程

我也是这个套路,一顿google下来,没发现什么有价值的信息。其实,真正的技术问题,或者有价值的技术问题,很难找到答案,大家可以思考下为什么。

大家,可以试试,Linux很多的问题,你要想通过google找到答案非常难,如果找到了,只能说明,可能这个问题比较简单,你自己仔细想想也能想清楚。

那么,只有一条路了,好好看代码。

2.3、看代码之前

在过去的1年里,我读了很多的Linux源代码,我本能就非常不想这样,一是,代码不好读,二是,因为当你读代码的时候会发现更多你不懂的问题。就像一个深度优先遍历一样,越来越多的问题把你的问题栈压垮,让你没有信心再看下去。

这次,我打算改变一下。

3、问题驱动

对,就像标题,以我看内核代码的经验,这个方式似乎是最好的。但是,也是最虐心的。

方法是,

  • 1、先在脑海里自己给出不同的答案,然后推导他们的可能性。比如这个问题,无非就是两个答案:1是,2不是。
  • 2、根据答案,推导下看是不是合理。

比如:

  • 如果是共享的,那么意味着一个进程的页表就包含了用户态页表与内核态页表两个部分,但是,内核态的地址空间是所有进程共享的,这不是个矛盾吗?如果一个进程在陷入内核后新建了很多内核对象,那其他进程怎么看到?而且,这么重的内存分配发生在频繁的进程创建与销毁上,这不是linux的哲学啊。比如在fork->dup_mm中就会为新的进程分配mm,伴随着mm->pgd的分配。shell执行命令频繁,这个操作感觉比较重。
    • 后来,我突然想到了copy_to_user这个函数,意思是从内核拷贝数据到用户态,看看有没有cr3的切换?
    • 发现并没有,大概率是共享的:源代码长这样



  • 如果不共享。似乎也有道理,内核与用户态本来就不是一路的,分开的话对体系结构更友好。而且,在书上也经常可以看到内核页表的字眼,比如:

虽然我觉得,大概率会共享,因为内核要频繁访问、写入用户空间数据,比如,网络连接要写入用户态缓冲区等等,不能每次要写数据就切换cr3,这个更加违背linux的哲学;但是,这个kernel page table是啥?

3.1、问题变成了这样

现在不再是去找内核与用态是否共享页表这个问题的答案了,现在只需要明确这个问题:

  • 如果共享页表,那么内核的页表在哪里?在哪里初始化的?应该在fork里面吧,因为,这里创建了新进程的mm;
  • 而Kernel Page Tables是什么鬼?

问题的搜索难度是不是降低了?嗯,这个过程类似于数学证明,将原问题,分解成很多难度更低的小问题,解决小问题就解决了等价的大问题。难度其实是降低了。

4、开始翻代码

最后其实是找到了一个我平时忽略了的函数pgd_ctorarch/x86/mm/pgtable.c底下。这个函数就是给用户态页表附上内核页表的过程,调用地方大概是在fork->dup_mm->init_mm->pgd_alloc->pgd_ctor这个不重要。

函数长这个样子:

这个函数一下子解决了上面提出的两个问题:

  • 确实,每个进程都单独有自己的内核页表存在,这使得copy_to_user成为可能;
  • 内核页表也是存在的就是swapper_pg_dir,其实是init进程的mm,这就是所谓的kernel pagetables了(由init0号进程创建的页表);



  • 其实,确实是所有的进程都有自己的内核页表,但是大部分是共享的,各自备份的只有pgd顶级页目录而已,其他的下级目录,都是共享的。相当于只共享了一个指针,通过这个指针可以找到内核的数据页(内核中的直接映射区、vmemmap都在下面的映射中,完全共享,全局唯一)。而拷贝一个‘指针’当然代价很小啦(当然实际并不是个指针这么小)。
  • 现在确实体会到了页表这个结构的妙处,方便共享数据也是个好的用途。

5、总结

我感觉,Linux内核代码的学习不能跟着在线课去学,尽管有很多这样的课程。因为,答案立马就知道了,你体会不到这里面的深意,牵着鼻子走,听完了也跟没听一样,好像懂了,好像又问题一堆。

主要是因为没有去思考问题,如果要真的看懂Linux内核源代码,要带着问题去看代码,遇到问题先想想如果是自己设计内核,会怎么实现?然后去找答案,这是一个比较好的方式。

亲测,有效!

相关推荐

如何在 Linux 中使用 which 命令?

在Linux的江湖中,每天都有成千上万的命令被执行。当你在终端输入python时,系统可能同时存在Python2.7和Python3.10;当你运行java命令时,可能意外调用了非预期的版本。这时...

linux CentOS检查见后门程序的shell

#CentOS检查后门程序的Shell脚本以下是一个用于检查CentOS系统中潜在后门程序的BashShell脚本,包含多项安全检查:```bash#!/bin/bash#检查后门...

Linux磁盘满了-服务器不打日志df&rm

大家好,我是「Bigder」、今天再说一个有意思的命令「df」,也是踩过坑的、怎么看磁盘占用情况?「df-h」命令用来显示磁盘占用率,截图里面可用是:17G、被使用11%,Use%达到100应用系统...

Linux写脚本经常用到的测试命令(linux硬件测试脚本)

介绍一个Linux写脚本经常用到的测试命令testtest命令用于检查文件类型和比较值。Test用于条件执行。一、test常用于1.文件属性比较2.执行字符串比较3.基本的算术比较二、关系运算符...

Linux History命令:如何显示命令执行的日期和时间

在Linux系统中,history命令是一个简单却强大的工具,它允许用户查看和重用之前执行过的命令。然而,默认情况下,history命令的输出仅显示命令的序号和内容,并不包含命令执行的日期和时间。这对...

判断Linux服务器架构是32位/64位

作为一个Unix系统的新手用户,我可以怎么判断我的Unix服务器安装的是32位或者64位的操作系统呢?你可以使用如下的命令来获取关于Unix内核和CPU架构的信息。getconf命令:显示机器硬件...

linux服务器被黑快速排查(linux服务器被ddos攻击记录日志)

已更新:windows服务器被黑快速排查一般来说linux系统服务器被黑比较少,若怀疑服务器被黑了,可通过下述方法快速排查。下面是小梁的一些总结,可供大家参考。如有问题,欢迎大家在评论区留言交流。感谢...

linux系统磁盘IO性能检测教程(linux磁盘io性能指标)

Linux系统中检测磁盘IO性能的教程在Linux系统中,监控和优化磁盘IO性能对系统的稳定性和效率至关重要,尤其是在高负载环境中。通过使用合适的工具,您可以检测系统的读写速度、IO等待时间以及每个进...

Linux系统Shell脚本语言之循环及判断语句

摘要:在日常工作中或多或少都会接触到shell脚本,可以说会shell脚本是一位后端维护及开发的基本功。shell是一种编程语言,而学习一门编程语言语法,最基本的无外乎就是语言中的数据类型定义,for...

如何快速摸清LINUX系统的应用部署情况和正在运行的服务

作为运维人员或开发者,当接手一台新的Linux服务器时,第一要务就是摸清系统上已经安装部署了哪些应用和服务。本文将以CentOS7为例,详细介绍如何系统地排查已安装的应用和服务,包括它们的安装方...

Linux服务器中毒?教你一步步精准判断和快速处置!

在当今网络安全威胁日益严峻的环境下,Linux虽然以其安全性著称,但也并非“刀枪不入”。许多黑客利用服务器漏洞、弱口令、过期软件等方式,渗透并植入恶意代码。一旦服务器被攻陷,可能导致数据泄露、资源...

Linux-如何区分不同文件类型(linux怎么区分文件类型)

理解Linux一切皆文件的理念,掌握Linux下区分不同文件类型的多种方法(包括:通过颜色、用过文件类型字符、通过file命令及通过stat命令等方法)1.通过观察颜色可以最直观在命令行模式下区分不...

在Linux中输入一行命令后究竟发生了什么?

Linux,这个开源的操作系统巨人,以其强大的命令行界面而闻名。无论你是初学者还是经验丰富的系统管理员,理解在Linux终端输入一条命令并按下回车后发生的事情,都是掌握Linux核心的关键。从表面上看...

如何在 Linux 上设置和管理 VPN?

在Linux上设置和管理VPN是一个相对直接的过程,但需要一些基本的系统管理知识。这里,我们将探讨如何使用OpenVPN这个流行的VPN软件来实现这一目标。1.了解VPN的基本概念VPN,即虚拟私人...

从按下电源到登录界面!Linux启动全流程深度拆解,运维人必看

你要是用过Linux系统,肯定知道开机的时候,不是按个电源键,等着屏幕亮起来那么简单。背后的操作可复杂了,就像一场精心安排的大合唱,每个部分都在该出声的时候出声。今天,咱就来好好讲讲Linux...