注:本分类下文章大多整理自《深入分析linux内核源代码》一书,另有参考其他一些资料如《linux内核完全剖析》、《linux c 编程一站式学习》等,只是为了更好地理清系统编程和网络编程中的一些概念性问题,并没有深入地阅读分析源码,我也是草草翻过这本书,请有兴趣的朋友自己参考相关资料。此书出版较早,分析的版本为2.4.16,故出现的一些概念可能跟最新版本内核不同。
在之前的文章中Linux从头学10:三级跳过程详解-从 bootloader 到 操作系统,再到应用程序,由于当时没有引入特权级的概念,用户程序和操作系统都工作在相同的特权级,因此可以直接通过[段选择子:偏移量] 的方式,来调用属于操作系统代码段中的函数,如下所示:
该文介绍了中断和异常的基本概念、分类,以及Linux 中中断和异常的处理方式,包括硬件中断、软件中断和异常的分类和处理。
至此,我们已经理解了X86架构如何在硬件层面如何处理中断和异常,那么接下来,我们看看Linux内核管理这些中断和异常。
中断控制是计算机发展中一种重要的技术,最初它是为克服对 I/O 接口控制采用程序查询所带来的处理器低效率而产生的。
本文涉及的硬件平台是X86,如果是其他平台的话,如ARM,是会使用到MMU,但是没有使用到分段机制; 最近在学习Linux内核,读到《深入理解Linux内核》的内存寻址一章。原本以为自己对分段分页机制已经理解了,结果发现其实是一知半解。于是,查找了很多资料,最终理顺了内存寻址的知识。现在把我的理解记录下来,希望对内核学习者有一定帮助,也希望大家指出错误之处。
与硬件相关的代码全部放在 arch(architecture 一词的缩写,即体系结构相关)目录下。
中断,英文名为Interrupt,计算机的世界里处处都有中断,任何工作都离不开中断,可以说整个计算机系统就是由中断来驱动的。那么什么是中断?简单来说就是CPU停下当前的工作任务,去处理其他事情,处理完后回来继续执行刚才的任务,这一过程便是中断。
---- 保护模式 什么实模式和保护模式 这是CPU的两种工作模式,解析指令的方式不同。 在实模式下,16位寄存器需要通过段:偏移的方法才能达到1MB的寻址能力。 物理地址 = 段值 x 16 + 偏移 此时段值还可以看成地址的一部分,段值为XXXXh表示以XXXX0h开始的一段内存。 在保护模式下,CPU有着巨大的寻址能力,并为操作系统提供了虚拟内存和内存保护。 虽然物理地址的仍然用上面的公式表示,但此时“段”的概念发生了变化,它变成了一个索引,指向一个数据结构的一个表项,表项中详细定义了段的
经过多篇文章的介绍,我们实现了从实地址模式跳转到保护模式,并在 IA-32 硬件系统中实现了代码的编写与执行。 进军保护模式 保护模式进阶 — 再回实模式
中断描述符表简单来说说是定义了发生中断/异常时,CPU按这张表中定义的行为来处理对应的中断/异常。
中断是硬件和软件交互的一种机制,可以说整个操作系统,整个架构都是由中断来驱动的。中断的机制分为两种,中断和异常,中断通常为 $IO$ 设备触发的异步事件,而异常是 $CPU$ 执行指令时发生的同步事件。本文主要来说明 $IO$ 外设触发的中断,总的来说一个中断的起末会经历设备,中断控制器,$CPU$&$OS$ 三个阶段:设备产生中断,中断控制器接收和发送中断,$CPU$&$OS$ 来实际处理中断。
在上一篇文章中,我们已经了解了中断和异常的一些概念,对于中断和异常也有了大概的理解。那么,系统中硬件到底是如何处理中断和异常的呢?本文我们就以常见的X86架构为例,看看中断和异常的硬件工作原理。
中断描述符表是保护模式下用于存储中断处理程序的数据结构。CPU在接收到中断时,会根据中断向量在中断描述符表中检索对应的描述符。
之前所说 GDT表 中存储了一些段描述符. 比如有调用门 段描述符. 代码段段描述符. 数据段段描述符 TSS段段描述符
前段时间,我连续写了十来篇CPU底层系列技术故事文章,有不少读者私信我让我写一下CPU的寄存器。
当异常发生时,Linux内核给造成异常的进程发送一个信号,告知其发生了异常。比如,如果一个进程尝试除零操作,CPU会产生除法错误异常,相应的异常处理程序发送SIGFPE信号给当前进程,然后由其采取必要的步骤,恢复还是中止(如果该信号没有对应的处理程序,则中止)。
理论上来讲,可以把那些可靠性介于操作系统和应用程序之间的程序安排在这两个特权级上。
但是长跳转只限于 段间跳转. 也就是一个段中. 因为在一个段中. 最后的偏移 加 段描述符.base才能构成真正的跳转地址.
在前面文章图解中断 | 中断从产生到消失的一生中提到了中断的整个生命周期,其中有一个关键的环节是CPU在接收到中断向量号后是如何找到对应的中断服务程序的,今天我们就来一探究竟。
Linux操作系统概述 Q1.什么是GNU?Linux与GNU有什么关系? A: 1)GNU是GNU is Not Unix的递归缩写,是自由软件基金会(Free Software Foundation,FSF)的一个项目,该项目已经开发了许多高质量的编程工具,包括emacs编辑器、著名的GNU C和C++编译器(gcc和g++); 2)Linux的开发使用了许多GNU工具,Linux系统上用于实现POSIX.2标准的工具几乎都是由GNU项目开发的;Linux内核、GNU工具以及其它一些自由软件组成
德国科技管理专家斯坦门茨早年移居美国,他以非凡的才能成为美国企业界的佼佼者。一次,美国著名的福特公司的一组电机发生故障,在束手无策之时,公司请斯坦门茨出马解决问题。
PS:原先实模式下的各个段寄存器作为保护模式下的段选择器,80486中有6个(即CS,SS,DS,ES,FS,GS)80位的段寄存器。由选择器CS对应表示的段仍为代码段,选择器SS对应表示的段仍为堆栈段。
知乎上搜到一个比较有意思的话题:如何理解「进入内核态」,要回答好这个问题需要对内存管理及程序的运行机制有比较深刻的了解,比如你需要了解内存的分段,分页,中断,特权级等机制,信息量比较大,本文将会从 Intel CPU 的发展历史讲起,循序渐近地帮助大家彻底掌握这一概念,相信大家看了肯定有帮助,本文目录如下
socket 的原意是“插座”,在计算机通信领域,socket 被翻译为“套接字”,它是计算机之间进行通信的一种约定或一种方式。通过 socket 这种约定,一台计算机可以接收其他计算机的数据,也可以向其他计算机发送数据。 我们把插头插到插座上就能从电网获得电力供应,同样,为了与远程计算机进行数据传输,需要连接到因特网,而 socket 就是用来连接到因特网的工具。
门描述符的作用就是描述某个子程序的入口. 用门内的选择子.还有偏移.利用Call或者Jmp可以调用.
作为即时通讯技术的开发者来说,高性能、高并发相关的技术概念早就了然与胸,什么线程池、零拷贝、多路复用、事件驱动、epoll等等名词信手拈来,又或许你对具有这些技术特征的技术框架比如:Java的Netty、Php的workman、Go的nget等熟练掌握。但真正到了面视或者技术实践过程中遇到无法释怀的疑惑时,方知自已所掌握的不过是皮毛。
以上就是对GDT表或者 LDT表的描述 总结来说 GDT或者LDT 就是一块内存. 也可以看成一个数组. 数组的每一项其实保存的都是段描述符 段选择子就是下标 3.1.2 GDTR寄存器与GDT表了解. 根据Inter手册所属. GDTR寄存器 保存了 GDT的 32位基地址 和16位表界限 基地址指的就是GDT从0字节开始的线性地址.可以理解为就是数组首地址. 表界限.可以理解为就是数组的大小. 所以说GDTR 寄存器是一个48位寄存器 按照C语言结构来来表是就如下 struct GDTR { DWORD *GdtBase, SHORT limit; } LGDT 与SGDT 汇编指令 分别是用来获取和保存 GDTR寄存器的. 电脑开机之后,通电之后.GDT就开始初始化了. 总结:
所以idt的内容是一个单位是8字节,长度是256的数组。linux0.11分为中断、系统、陷阱门。系统在启动的时候设置idt。
接下来我们要做的当然就是在内核中创建进程并且调度起来,但在这之前,我们要问,到底应该如何调度进程呢?
黑入服务器很少会是通过账号密码的方式进入,因为这很难破解密码和很多服务器都做了限制白名单。
上一篇文章中,我们详细介绍了操作系统特权级,以及利用调用门、TSS 实现不同特权级之间的跳转。 利用调用门实现特权级间跳转 — 原理篇
进入保护模式以后,数据段、代码段等内存段不再是通过段寄存器获得段基址就可以使用,我们需要把段定义好,并且登记好,全局描述符表便是用来记录这些段信息的数据结构。
CS部分后面又4个0,相当于是左移了4位。总之就是要让CS左移4位之后加上EIP来得到要跳转的地址。
以只写的方式打开1.txt。如果文件不存在就创建,如果文件存在就清空。
上一篇文章中,我们详细介绍了保护模式下的中断和异常以及他们的硬件基础结构 — 可编程中断控制器 8259A,以及他的初始化和中断的屏蔽与打开: 保护模式下的中断和异常(上) — 硬件原理篇
此前我们对操作系统中的分段、分页机制以及虚拟地址、逻辑地址、线性地址、物理地址进行了较为详细的介绍。 操作系统的内存管理 — 分段与分页、虚拟地址、逻辑地址、线性地址、物理地址
经过一系列的文章,我们通过汇编语言,体验了保护模式下分段、分页、特权级跳转、中断、异常等机制。 那么,事到如今,你是否已经深谙保护模式的设计之道了呢?究竟什么是保护模式,保护模式又在“保护”什么呢?他为了什么诞生,又和实模式有什么区别呢? 本文我们就来详细总结一下。
按照中断的来源分类,来自CPU外部的中断称为外部中断,来自CPU内部的称为内部中断;细分的话,外部中断根据严重程度,分为可屏蔽中断和不可屏蔽中断;内部中断按照是否正常分为软中断和异常。
学习Windows程序设计也有一些时间了,为了记录自己的学习成果,以便以后查看,我希望自己能够坚持写下一系列的学习心得,对自己学习的内容进行总结,同时与大家交流。因为刚学习所以可能有的地方写不不正确,希望大家能够指出。
说到进程,恐怕面试中最常见的问题就是线程和进程的关系了,那么先说一下答案:在 Linux 系统中,进程和线程几乎没有区别。
准备工作:下载ucorelab在的master分支(注意不是main分支),需要用到的资料以及答案都在里面。
我们知道程序代码和数据必须驻留在内存中才能得以运行,然而系统内存数量很有限,往往不能容纳一个完整程序的所有代码和数据,更何况在多任务系统中,可能需要同时打开子处理程序,画图程序,浏览器等很多任务,想让内存驻留所有这些程序显然不太可能。因此首先能想到的就是将程序分割成小份,只让当前系统运行它所有需要的那部分留在内存,其它部分都留在硬盘。当系统处理完当前任务片段后,再从外存中调入下一个待运行的任务片段。的确,老式系统就是这样处理大任务的,而且这个工作是由程序员自行完成。但是随着程序语言越来越高级,程序员对系统体系的依赖程度降低了,很少有程序员能非常清楚的驾驭系统体系,因此放手让程序员负责将程序片段化和按需调入轻则降低效率,重则使得机器崩溃;再一个原因是随着程序越来越丰富,程序的行为几乎无法准确预测,程序员自己都很难判断下一步需要载入哪段程序。因此很难再靠预见性来静态分配固定大小的内存,然后再机械地轮换程序片进入内存执行。系统必须采取一种能按需分配而不需要程序员干预的新技术。
虽然计算机相关专业,操作系统和计算机组成原理是必修课。但是大学时和真正从事相关专业工作之后,对于知识的认知自然会发生变化。还很有可能,一辈子呆在学校的老师们只是照本宣科,自己的理解也不深。所以今天我站在真正排查解决问题时的需要层面,用白话说一说linux操作系统的那些知识。
在系统启动时,会在sched_init(void)函数中调用set_system_gate(0x80,&system_call),设置中断向量号0x80的中断描述符:
今天来了解一下linux里面的一些小知识,学习一下linux里面的最大进程数,最大文件描述,最大线程数的问题。下面依次介绍: (一)Linux系统中最大可以起多少个进程? (1)32位系统中最多可以起
Linux的核心思想之一就是”一切皆文件”。即Linux中所有的内容都是以文件的形式保存和管理的,它为不同类型的文件提供了统一的操作接口,对于不同类型的文件,我们都可以使用fopen()/fclose()/fwrite()/fread()等对这些文件进行读写处理。在Linux中,普通文件、目录、链接文件、字符设备、块设备以及网络套接字等等都以文件的形式存在。
上一节,我们开发了一个流氓程序,当他运行起来后,能够把自己的数据写入到另一个进程的数据内存中。之所以产生这样的漏洞,是因为被入侵进程的数据段所对应的全局描述符在全局描述符表中。恶意程序通过在全局描述符表中查找,当找到目标程序的内存描述符后,将对应的描述符加载到自己的ds寄存器里,于是恶意程序访问内存时,就相当于读写目标程序的内存。 要防范此类入侵,最好的办法是让恶意程序无法读取自己内存段对应的描述符,但是如果不把自己的内存描述符放置在全局描述符表中的话,还能放哪里呢?Intel X86架构还给我们提供了另一
领取专属 10元无门槛券
手把手带您无忧上云