linux程序关联文件,图解 Linux 程序的链接原理

3ac0fd7eaa31

将 C 或 C++ 源代码编译成可执行文件分成两步:第一步是将每个源代码文件分别编译成可重定位文件(relocatable,扩展名为 .o),第二步是将所有的可重定位文件链接成可执行文件。在 Linux 中,可重定位文件和可执行文件的格式都是 ELF(Executable and Linkable Format)。

本文面向对 ELF 文件格式不熟悉的读者,通过图解的形式讲解 ELF 文件的链接方式,重点分析为什么要引入各种数据结构,以便读者对 ELF 的链接过程有形象化的认识。如果读者对这部分内容已经有所了解,可以直接跳到文章末尾的《参考文献》部分,直接阅读这些深入讲解 ELF 文件格式的文章和文档。

本文涉及的概念包括段(segment)、节(section)、符号表(symbol table)、字符串表(string table)和重定位表(relocation table)。重点讲解这些概念是如何互相配合,以服务于 ELF 链接过程的,而不详细说明这些概念在文件中的二进制格式。

为了减少复杂性,本文中的 ELF 程序都不使用共享对象(shared object)和动态加载技术(dynamic loading)。

1 段(segment)

从操作系统的视角来看,将程序加载到内存中的最简单方法是:将程序从文件中直接拷贝到内存的指定位置上,然后跳转到程序入口处。

因为程序在内存中的位置是预先约定好的,所以,每一个函数和全局变量在内存中的位置也都是可以事先知道的。程序的代码不需要任何修改就可以直接被执行。

3ac0fd7eaa31

在实际的操作系统中,内存是以页(page)为单位管理的。一页为 4096 字节(十六进制表示为 0x1000),每个内存页都可以设置访问权限。在 x86 中,内存页可以设置写入和执行两种权限。

出于系统安全的目的,代码所在的内存页可以执行,但不可以写入,数据所在的内存页可以写入,但不可以执行。如果有一段内存既可以写入,又可以执行,攻击者就可以利用程序的 bug 在这个位置写入攻击代码,然后执行它,从而达到破坏操作系统的目的。

在 ELF 文件中,内存访问属性相同的内容在文件中也连续存储,称为段(segment)。代码存放在代码段(text segment)中,数据存放在数据段(data segment)中。

除了在文件中的位置和长度,一个段还需要说明它在内存中的位置和长度,以及它所需的内存属性。这些信息记录在程序头(program header)中。段和程序头一一对应。

程序头以数组的形式连续地存储在 ELF 文件中,这个数组称为程序头表(program header table)。通常,程序头表在 ELF 头之后,但也可以在文件的其他位置。程序头表的在文件中的具体位置记录在 ELF 头之中。

3ac0fd7eaa31

操作系统根据 ELF 头记录的信息找到程序头表。在找到程序头表之后,操作系统按照每个程序头的信息,将对应的段加载到内存中的相应位置,最后跳转到程序入口处开始执行程序。

因为内存页以 4K 为单位,所以代码段和数据段的长度必须是 4K 的整数倍。如果通过在段末尾补 0 的方式凑齐 4K 的整数倍,就会有空间浪费。为了避免这种浪费,ELF 文件的各个段之间是紧密相连的,只是在加载到内存中的时候,才映射到不同的内存区域。又因为通过内存映射(memory mapping)加载文件时必须以 4K 为单位,所以在内存中数据段的开头会有一小部分代码,而代码段的末尾也会有一小部分数据。

3ac0fd7eaa31

2 节(section)

操作系统最关心的问题是如何将文件加载到内存中,因此,段所记录的信息是:

段在文件中的位置和长度;

段在内存中的位置和长度;

段的内存属性。

而从链接器的视角触发,第二点和第三点都不是链接器所关心的问题。链接器更关心 ELF 文件中各个部分的功能,以及如何按功能将多个可重定位文件合并成一个文件。

一个段可以包含多种需要区别对待的功能:在代码段中,普通的代码和全局初始化代码应该区别对待;在数据段中,有初始值的全局变量和没有初始值的全局变量也应该区别对待。这样一段连续的相同功能的区域称为节(section)。与段不同,每个节都有名称。

与代码和数据相关的节包括:

节名称

描述

在可执行文件中放在哪个段中

.text

一般的代码

代码段

.init

初始化代码,在程序运行的最开始执行

代码段

.fini

清理代码,在程序退出前执行

代码段

.data

有初始值的全局数据

数据段

.bss

没有初始值的全局数据,初始值为 0

数据段

.rodata

只读的全局数据

代码段,因为在内存属性上与代码段最接近

3ac0fd7eaa31

描述节的结构是节头(section header)。节头以数组的形式连续地存放在文件中,这个数组被称为节头表(section header table)。节头表通常放置于 ELF 文件的末尾,它的具体位置记录在 ELF 头中。

值得注意的是,节不是段的子结构,而是与段的地位相同的结构。段是从操作系统的视角来看 ELF 文件的方式,节是从链接器的视角来看 ELF 文件的方式。它们都是 ELF 文件的可选部分:可重定位文件没有段,而可执行文件也可以没有节(但大部分可执行文件都有节)。

3ac0fd7eaa31

在链接过程中,相同名称的节会合并成一个节。以 .text 节为例,每个可重定位文件都有一个 .text 节,它们被链接器合并成一个大的 .text 节,并存放在输出的可重定位文件或者可执行文件中。

3 符号表(symbol table)和字符串表(string table)

在写程序时,一个文件可以访问另一个文件中定义的变量和函数。这些变量和函数统称为符号(symbol)。其他文件可以访问的符号称为全局符号(global symbol),只有文件内部可以访问的符号称为本地符号(local symbol)。这与 C 语言的 static 关键字的功能是相同的。

如果一个文件引用了另一个文件的符号,这个符号也会被记录在引用者中,称为未定义符号(undefined symbol)。在最终链接成可执行程序时,所有的未定义符号都应该可以找到同名的全局符号,否则就会链接失败。

一个符号除了需要记录它的名字,以便其他文件引用,还需要记录它出现在哪个节中和它在节中的偏移量。这些信息以数组的形式连续地存储在文件中,这个数组称为符号表(symbol table)。符号表是一种特殊的节,它的名字是 .sym。

3ac0fd7eaa31

到目前为止,我们发现 ELF 文件中有两处需要存储字符串,一处是节的名字,另一处是符号的名字。因为字符串的长度是可变的,如果将其直接存在节头和符号表中,就需要预先分配足够的空间,这会造成大量空间被浪费。为了节约字符串的存储空间,ELF 文件中的所有字符串都存放在一个特殊的节中,称作字符串表(string table),它的节名是 .str。

3ac0fd7eaa31

所有的字符串都是以 0 结尾的 C 风格字符串,它们在字符串表中连续存储。其他地方通过它们在字符串表中的下标来引用它们:ELF 头记录了字符串表在节头表中的下标,节头记录了节名称在字符串表中的下标;每个符号表都与一个字符串表关联,每个符号都记录了它的名称在关联的字符串表中的下标。通过这些信息,链接器就可以找到节名和符号名。

4 重定位表(relocation table)

虽然我们现在可以引用其他文件中定义的符号,但我们仍未解决一个重要的问题。

访问全局变量的操作通常会被编译器翻译成访问内存地址的指令。然而,可重定位文件中的节只记录了它在文件中的位置,而不像段一样记录它在内存中的位置,因此我们并不知道文件中定义的全局变量的内存地址。除此之外,如果一个文件引用了另一个文件定义的全局变量,那么直到将它们链接起来之前,我们都不可能知道这个全局变量的内存地址。

进一步地说,直到最终链接成可执行文件时,我们才能知道全局变量和函数的内存地址,在此之前我们始终无法生成访问它们的指令。

ELF 文件的做法是:仍然按照正常的流程生成访问这些全局变量和函数的指令,但是在内存地址部分填写 0,并且将这些占位 0 的出现的位置记录在 ELF 文件中。在确定了所有这些符号的内存地址后,将占位 0 改成正确的内存地址。

如果访问的是全局数组中的某个元素或者全局结构的某个成员,我们会将元素或成员的偏移量当作占位符写在内存地址出现的地方。在确定了符号的内存地址后,将这两者相加就可以得到正确的内存地址。这个偏移量被称作 addon 。

3ac0fd7eaa31

记录这些占位符出现位置的结构称为重定位表(relocation table)。它也是一种特殊的节,而且在文件中不只有一个。每个需要重定位的节都有一个与之对应的重定位表,重定位表的名字就是在被重定位的节名前加上 .rel 或者 .rela。.text 的重定位表是 .rel.text 或者 .rela.text。

之所以有这两种命名方式,是因为重定位表有两种略有不同的格式。.rel 格式的重定位表将 addon 写在内存地址出现的位置,当作占位符,如同前面描述的一样;而 .rela 格式的重定位表将 addon 写在重定位表中,而不是被重定位的位置上。

因为重定位需要符号的内存地址,所以每个重定位表除了与被重定位的节相关联,也与符号表相关联。综合来说,重定位表的每个表项(entry)都记录了四种信息:需要重定位的占位符在节中的偏移量、所引用符号在符号表中的下标、重定位时的地址计算方式和addon。

常见的地址计算方式有两种:

名称

计算方式

R_386_32

符号的内存地址 + Addon

R_386_PC32

符号的内存地址 + Addon - PC

PC 指的是程序计数器,该寄存器记录了当前指令所在的内存地址。R_386_PC32 用于相对于 PC 的寻址,通常用于生成位置无关代码(PIC)。

3ac0fd7eaa31

在链接成可执行文件时,链接器首先合并相同的节,然后确定节在内存中的位置,组成段。这时候,链接器就可以计算出所有的符号在内存中的地址。接下来链接器遍历所有的重定位表,将每个需要重定位的位置改写为真正的内存地址,就完成了重定位操作。这样生成的程序就可以被操作系统加载到内存中执行了。

5 小结

记录如何将程序加载到内存的结构是段。每个段有如下属性:

段在文件中的位置和长度

段在内存中的位置和长度

段的内存权限

记录 ELF 文件中各个部分的结构是节。每个节有如下属性:

节的名称

节的类型

节在文件中的位置

与它关联的其他的节的下标

符号表与字符串表关联

重定位表与符号表和被重定位的节关联

全局变量和函数统称为符号。

符号有名称

每个符号对应一个节和节内偏移

按类型,符号可以分成:对象(变量)和函数

按作用域,符号可以分成:全局符号和局部符号

只是引用而未定义的符号称为未定义符号

节名和符号名存储在字符串表中。

用于将程序中的占位符改写为内存地址的结构称为重定位表。

每个需要重定位的节都有一个与之对应的重定位表

每个重定位表项与节中的偏移量和一个符号对应

重定位的两种计算方式

R_386_32 = 符号地址 + Addon

R_386_PC32 = 符号地址 + Addon - PC

6 参考文献

ELF Format 是描述 ELF 文件格式的文档,只有 60 页但面面俱到地讲解了静态链接和动态加载的原理,是了解 ELF 文件的必读材料。然而这个版本已经略有过时,如果按照这个文档去分析现在的 ELF 文件,会发现一些新的属性在文档中是缺失的。尽管如此,因为这个本手册比较薄,所以它的可读性很好,建议在阅读更详细的文档前先读一下这个文档。

Oracle 的 ELF 文档 是描述 ELF 文件格式最详细和最新的文档,适合当作手册来查阅。

Eli Bendersky 的 Load-Time Relocation of Shared Libraries 是讲解共享对象加载原理的文章。共享对象按照代码是否是位置无关的分成两种,本文讲解的是没有开启 PIC (位置无关代码)选项下共享对象的加载方式,它在原理上与链接是相同的。本文有代码和反汇编等实例,适合读者去更加深入而具体地了解链接的过程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
XXXX有限公司 服务器运维管理手册 XXXX有限公司 运维服务部 2012/8/30 一、 文档简介 2 二、 文档目的 3 三、 文档范围 3 四、 事件处理流程 4 五、 具体操作说明 4 1) 服务器硬件管理 4 2) 服务器系统管理 9 1. Windows系统管理 10 2. Linux系统管理 11 六、 相关文档 15 文档简介 本文档根据桑菲消费通信服务器硬件设备与系统应用管理需求,针对日常维护内容进 行技术归类于总结,描述具体操作步骤与操作方法,积累服务器事件处理能力,使之服 务运维能力更为主动可控。 文档目的 标准服务器故障处理方法指引,服务器管理知识库积累。 文档范围 服务器硬件故障判断与标准处理操作 服务器系统日常性能检测与标准检测 事件处理流程 具体操作说明 服务器硬件管理 1. 检查与故障判断: 服务器硬件的主动检查方式主要分三种: 设备面板指示灯检查 硬件系统日志检查 第三方工具检查 1) 面板指示灯检查 IBM服务器上面有,电源指示灯,硬盘/IDE设备活动指示灯,网卡指示灯,系统过热报 警灯.硬盘槽还有硬盘指示灯。HP服务器上面指示灯一般为UID,内部和外部健康灯 ,其他就是电源网口灯了,DELL的机种有的上面有风扇,内存,CPU,指示灯情况 ,图标都是很直观的,其它服务器与IBM,HP的差不多。 图示说明 详细描述: 2) 系统日志检查 "检查内容 " "硬件历史异常报错信息 " "计算机管理->系统工具->事件查看器,查看系统日志 " "重点关注:红色高危事件信息、日常频繁硬件报错信息 " "备注:查看硬件历史异常故障情况,分析硬件性能与使用生命周期 " 3) 第三方检测工具检查 "检查内容 " "硬件历史异常报错信息 " "HP 诊断工具: " "打开开始——程序——HP System Tools——HP Insight Diagnostics online " "Edition for Windows——HP Insight Diagnostics online Edition for " "Windows。 " "DELL诊断工具: " "第三方硬件设备诊断工具 " "IBM诊断工具: " "IBM Systems Director 、 IBM Systems Director Active Energy " "Manager、IBM ServerGuide " 相关图解: 进入诊断网页,在第一选项卡Survey中,上部有2个下拉项,左侧选择Advanced,右侧选 择All,会显示出更多硬件信息,点击右下的Save按钮保存。 此界面可以看到服务器所有硬件信息。 2. 硬件设备变更操作标准: 判断并确定最快恢复时间 判断是否有做冗余设置 判断是否需要关机操作 磁盘设备检测并确定阵列信息,确定有做数据备份 是否对其它关联应用有影响 制定回退方案,保证数据与应用的可用性 设备变更操作 设备兼容性测试 应用系统运行测试 设备变更后正式应用 3. 相关巡检记录单: 备注:《服务器信息列表》 《服务器指示灯巡检表》 服务器系统管理 服务器系统管理主要分为: Windows系统管理 Linux系统管理 Windows系统管理 1. 磁盘空间使用 计算机管理——磁盘管理 磁盘空间使用率是否已经到达80% 2. 进程监控 任务管理器——进程 查看进程的CPU使用率和内存使用率是否超阀值 3. CPU性能 任务管理器——性能 查看CPU最高峰值与一般使用率是否超阀值 4. 内存性能 任务管理器——性能 查看内存最高峰值与一般使用率是否超阀值 5. 网络查看 任务管理器——联网 检查是否能正常访问站点页面 6. 日志 记录错误报警信息 ——应用程序日志 由应用程序或者系统程序记录的事件 ——安全性日志 查看有效和无效的登录尝试事件,以及资源使用相关的事件 ——系统日志 Windows系统组件记录的事件 Linux系统管理 1. 2. 1. 平均负载(uptime) 描述: uptime命令过去只显示系统运行多久。现在,可以显示系统运行多久、当前有多 少的用户登录、在过去的1,5,15分钟里平均负载时多少。 2. 磁盘空间使用率(df -h) 描述: Filesystem 文件系统 Size 文件系统容量 Used文件系统已经使用的容量 Use%文件系统使用百分比 Mounted on挂载的目录 3. 进程监控(ps –ef " grep java) 查看应用程序启动进程数是否正常 4. 内存监控(free -m) 描述: total:总计物理内存的大小 used:已使用多大 free:可用有多少 shared:多个进程共享的内存总额 buffers/cached:磁盘缓存的大小。 第三行(-/+ buf
PHP是最流行的Web脚本语言之一,它运行在Web服务器端,根据用户请求或服务器端的数据产生动态网页;它功能强大,和HTML脚本融合在一起,并内建访问数据库的能力;它能够作为Apache Web 服务器的模块执行,也使得其执行效率要高于普通的CGI程序。本书作者是一位经验丰富的程序员,在书中使用了大量的、有一定使用价值的例子来深入浅出地讲解PHP语言及Web编程需要了解的方方面面。尤其值得注意的是,书中使用了多个“中场”章节,以便在学习过一定知识之后,通过实际例子来对所学的知识进行巩固,这些章节介绍的内容具有很强的实用价值。因此本书不仅对Web编程的入门者,即使对于有一定经验的Web程序员来讲,也是非常有用的。 目 录 译者序 前言 第1章 什么是PHP 1 1.1 起源 1 1.2 特性 1 1.3 PHP需要花费多少钱 2 1.4 PHP语言可以嵌入HTML中 2 1.5 PHP语言是在Web服务器端运行 3 1.6 PHP无处不在 3 1.7 PHP和C或Java相似吗 3 1.8 PHP比ColdFusion、Active Server Pages 或Java Server Pages更好吗 3 1.9 总结 4 第2章 安装PHP 5 2.1 基本概念 6 2.2 编译前的准备工作 7 2.3 编译C编译器gcc 8 2.4 编译MySQL 8 2.5 测试MySQL 9 2.6 编译iODBC和MyODBC 12 2.7 编译PHP 12 2.8 安装PHPLIB 15 2.9 测试Linux环境下的ODBC 18 2.10 总结 18 第3章 PHP中的数据处理 19 3.1 数值 19 3.1.1 数字 19 3.1.2 文本 20 3.2 变量 23 3.2.1 标量 23 3.2.2 数组变量 24 3.2.3 多维数组 27 3.2.4 变量替换 28 3.2.5 动态变量名 31 3.3 常量 31 3.4 操作符 31 3.4.1 操作符的优先级 32 3.4.2 三重操作符 33 3.4.3 算术操作符 34 3.4.4 条件操作符 35 3.4.5 一元操作符 35 3.4.6 位操作符 37 3.4.7 字符串连操作符 38 3.4.8 逻辑操作符 38 3.4.9 赋值操作符 40 3.5 总结 41 第4章 程序控制 43 4.1 表达式 43 4.1.1 简单表达式 43 4.1.2 有副作用的简单表达式 43 4.1.3 复杂表达式 44 4.2 语句 44 4.3 函数 55 4.3.1 函数返回值 56 4.3.2 向函数传递参数 58 4.3.3 给函数赋予缺省值 59 4.3.4 控制变量的作用域 60 4.3.5 嵌套函数调用 61 4.3.6 递归函数 61 4.4 总结 65 第5章 中场一:数据库连 67 5.1 开端 67 5.2 创建连 67 5.3 获取HTML表单信息 69 5.4 使用HTML表单信息 70 5.5 common.inc文件 72 5.6 总结 73 第6章 数据库和SQL 74 6.1 信息和数据有何不同 74 6.2 从信息向数据库转移 74 6.3 创建唯一的记录 75 6.4 每个记录的重要字段 75 6.5 有关字段数据类型的一两句话 76 6.6 设计能存储电子邮件消息的字段 76 6.7 SQL介绍 76 6.7.1 SQL Create Table语句 77 6.7.2 SQL Alter Table语句 79 6.7.3 SQL 的删除表语句 82 6.7.4 SQL的插入语句 83 6.7.5 SQL 的更新语句 83 6.7.6 SQL的查询语句 84 6.8 SQL Delete 语句 90 6.9 字段定义及修正 91 6.9.1 使用索引或关键字段来加快查询 91 6.9.2 使用自动增量创建键 92 6.10 总结 92 第7章 中场二:列表维护 94 7.1 列表维护的规范 94 7.2 创建连代码 94 7.3 创建phpuser用户名 95 7.4 创建数据库表 96 7.5 修改menu.php3文件 97 7.6 插入记录 97 7.6.1 定义插入表单 97 7.6.2 处理插入动作 99 7.6.3 检查动态SQL的建立 100 7.6.4 验证插入 101 7.7 显示记录 101 7.7.1 增加排序记录的能力 104 7.7.2 同时显示五个记录 106 7.7.3 删除记录 109 7.7.4 编辑记录 111 7.7.5 复制记录 113 7.8 为新表配置应用程序 116 7.9 总结 116 第8章 phpMyAdmin:开放源码的 MySQL前端 117 8.1 phpMyAdmin的特性 117 8.2 安装phpMyAdmin 118 8.3 防止“网络机器人” 118 8.4 用密码保护phpMyAdmin目录 119 8.5 使用phpMyAdmin 119 8.6 函数变量:转储表中数据 120 8.7 Query By Example,构造用户自 定义页面 122 8.8 构建多语言网站 124 8.9 常见问题 127 8.10 总结 127 第9章 模式匹配 129 9.1 正则表达式定义 129 9.1.1 方括号表达式 130 9.1.2 转义字符 130 9.2 POSIX风格的函数 131 9.2.1 ereg 和eregi 131 9.2.2 ereg_replace 和eregi_replace 132 9.2.3 Split 133 9.3 PERL风格函数 134 9.3.1 模式定界符 134 9.3.2 模式选项 135 9.3.3 PERL风格转义字符 136 9.3.4 扩展模式记号 136 9.3.5 preg_match 函数 138 9.3.6 preg_match _all 函数 139 9.3.7 preg_replace函数 141 9.3.8 preg_split函数 143 9.3.9 模式举例 143 9.3.10 匹配举例 144 9.3.11 替换举例 148 9.3.12 分割举例 150 9.4 MySQL …151 9.4.1 LIKE 151 9.4.2 RLIKE 152 9.5 总结 152 第10章 面向对象 154 10.1 了解类的知识 154 10.1.1 继承 155 10.1.2 抽象 155 10.1.3 多态 156 10.1.4 封装 157 10.2 对象和PHP 157 10.2.1 使用命名参数 158 10.2.2 使用继承 160 10.2.3 存取类属性 160 10.2.4 多态性函数 161 10.2.5 在类中定义类 162 10.2.6 引用:所指的值就是我的数据 165 10.2.7 有用的类函数 166 10.3 总结 166 第11章 中场三:生成HTML模块 168 11.1 HTML类的设计目的 168 11.2 生成一个基类 169 11.3 继续进行下一步 171 11.4 巩固通用函数 172 11.5 添加head支持 173 11.6 添加body支持 175 11.7 添加title支持 179 11.8 添加注释支持 180 11.9 添加对通用标签的支持 183 11.10 添加缺省值支持 183 11.11 缓存HTML代码 184 11.12 总结 187 第12章 什么是CGI 189 12.1 CGI应用程序和Java Applet 189 12.2 CGI应用程序和JavaScript 190 12.3 自己编写脚本 190 12.4 CGI是如何工作的 190 12.5 调用CGI程序 190 12.6 HTTP标题 191 12.7 CGI和环境变量 192 12.8 URL编码和解码 194 12.8.1 使用rawurlencode函数 194 12.8.2 自动解码 194 12.9 安全性 195 12.10 cookie 195 12.10.1 cookie安全性 196 12.10.2 如何设置和读取cookie 196 12.10.3 客户端浏览器支持cookie吗 197 12.11 调试CGI程序 198 12.11.1 把输出发送到服务器日志 文件中 198 12.11.2 生成错误处理HTML页面 199 12.12 表单处理 200 12.12.1 HTML简介 200 12.12.2 HTML表单 201 12.12.3 传递表单信息 203 12.13 总结 203 第13章 认证 205 13.1 HTTP认证 205 13.2 htaccess 认证 208 13.2.1 用户文件 208 13.2.2 配置apache服务器 208 13.2.3 简单数据库认证 210 13.3 总结 213 第14章 深入了解SQL 214 14.1 表关联 214 14.2 创建数据库表 215 14.3 通过连生成虚拟表 218 14.4 使用链表 219 14.5 几种连类型 222 14.5.1 左连 222 14.5.2 正则左连 223 14.5.3 Using选项 223 14.6 处理空值 224 14.7 完整性 225 14.8 总结 226 第15章 中场四:管理并发访问 228 15.1 问题:一个用户能覆盖另一 个用户的更改 228 15.1.1 创建并发数据库 228 15.1.2 程序图解 228 15.2 解决方案:阻止多用户编辑 235 15.2.1 跟踪编辑会话 236 15.2.2 设计解决方案 236 15.3 总结 248 第16章 XML 249 16.1 为什么使用XML 249 16.1.1 混合结构和显示 250 16.1.2 异类浏览器 250 16.1.3 不适合非Web用途 250 16.1.4 在数据交换方面不实用 251 16.2 XML解决方法 251 16.2.1 HTML和XML的差异 251 16.2.2 XML分析器的作用 252 16.3 XML核心 252 16.3.l 标识和文本 252 16.3.2 注解 256 16.3.3 总体文档结构 256 16.3.4 有效及形式好的文档 257 16.4 文档类型定义(DTD) 258 16.4.1 一般形式 258 16.4.2 ELEMENT关键字 258 16.4.3 ATTLIST关键字 260 16.4.4 ENTITY关键字 262 16.4.5 NOTATION关键字 263 16.5 XML应用程序 264 16.5.1 DocBook 264 16.5.2 同步多媒体集成语言(SMIL) 264 16.6 XML是什么样的 265 16.7 进一步研究 267 16.8 总结 267 第17章 用PHP处理XML 269 17.1 得到电影信息 269 17.1.1 与XML分析器协作 270 17.1.2 从XML到PHP 273 17.2 总结 276 附录A Internet资源 277 附录B ASCII表 282 附录C SQL语言参考 288 附录D PHP函数清单 307 附录E CD-ROM的内容 332
Linux操作系统默认使用的文件系统有EXT2和EXT3,其中EXT3是日志文件系统。此外,Linux系统还支持其他文件系统如xfs、jfs等。对于交换分区,Linux系统一般使用swap文件系统,其大小通常设置为主机系统内存的2倍。在Linux中,可以读写FAT文件系统,但是只能读取NTFS文件系统,不能写入。 虽然Linux系统有多种不同的文件系统,但它们的基本设计思想是相似的,即有效地管理硬盘数据。了解MINIX文件系统的设计可以帮助我们理解其他不同的文件系统。 关于Linux文件系统的原理,有些文章通过对源码的分析来讲解,但这种方式可能对新手不太友好。所以,本次解释主要采用图文的方式,以更形象地讲解Linux文件系统的原理,避免陷入源代码的深渊。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [【图文解析 】Linux文件系统,我竟然看懂了,很好奇啊!](https://blog.csdn.net/qq_42246689/article/details/83476921)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [图解 Linux 文件系统](https://blog.csdn.net/u011164819/article/details/117520229)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值