Electronic Joint Business

Solution for E-Business

Binutils 移植指南 (一)

本文是对 binutils 现有文档的补充,旨在帮助那些第一次将 binutils 工具移植到新的硬件架构的软件工程师。本文是根据作者的实际经验编写的。难免会有疏漏,欢迎读者提出任何改善建议。1

一、 为什么编写本文?
虽然 binutils 项目包含了 100 多页的内部指南, 但本文主要针对那些初次进行 binutils 开发/移植的人。Binutils 内部指南存在一些缺陷:

  • 它倾向于对每个函数进行详细描述,但缺乏宏观大局。
  • 文档并不完整,有许多有用的章节尚待编写。(例如relocation详细信息) 。

因此,当工程师初次尝试将 binutils 移植到新的架构上时,他总要不断阅读源代码来弄明白 binutils 如何工作,进而了解如何移植到其他体系架构。

本文将讨论如何将紧凑 RISC (又称 CR16) 体系结构植入 binutils , 希望这些学习经验可以帮助到其他人, 特别是那些正在寻找将 binutils 工具移植到新架构的工程师。CR16 的相关代码可以在 binutils 中获得。

二、Binutils 文件的组织结构
binutils 源代码按目录进行组织,其中的一些组件是类库,在内部或其他项目中使用。比如 GNU GDB 调试器会用到 BDF 类库。这些类库大多有自己的顶层目录。主要的目录列举如下:

这些目录包含如下组件:

>>> 阅读全文

为 Windows containers 实现资源控制 (一) 作业对象

Windows 可以按容器或者按资源来实施资源控制。默认情况下, 运行的容器受 Windows 资源管理的约束, 以公平分配为原则, 但通过资源控制,开发人员或管理员可以限制或影响资源的使用。可控制的资源包括: CPU/处理器、内存/RAM、磁盘/存储、和网络/吞吐量等等。

Windows 容器利用作业对象(job objects)来对每个容器相关联的进程进行分组和跟踪。资源控制则在与容器关联的父作业对象上实施。 在 Hyper-V 隔离的情况下,系统同时对虚拟机和在虚拟机中运行的容器的作业对象进行自动资源控制,这样即使容器中运行的进程绕过了或逃脱了作业对象控制,虚拟机也会确保其无法越过定义的资源控制。

作业对象
Windows提供一个作业(job)内核对象,它允许我们将进程组合在一起并创建一个“沙箱”来限制进程能够做什么。作业对象允许将进程组作为一个单元进行管理。作业对象是可命名的(namable)、安全的、共享的对象, 可控制与之关联的进程的属性。对作业对象执行的操作会影响和作业对象相关联的所有进程。比如对工作集大小、进程优先级进行强制限制,或终止与作业关联的所有进程。你可以将作业对象想象成一个进程容器。但是,创建只包含一个进程的作业同样非常有用,因为这样可以对进程施加平时不能施加的限制。

作业对象 VS Linux 控制组 cgroups
Linux 的 cgroups 不等同于 Windows 和 VMS 的作业, 它缺乏作业机制的真正功能。这些年来人们一直在抱怨 Systemd 的这个问题,他们非常期待 cgroups 2.0 能提供真正的作业机制,因为现阶段的 Systemd 存在严重的错误,它无法自动终止控制组中的所有内容。

相反,提供“作业”抽象的操作系统内核一般都会提供了能取消/终止整个“作业”的方法,比如 Windows 的 TerminateJobObject()。而对于 Systemd,当其终止 cgroup 中的所有进程时, 它无法执行类似“终止作业”的系统调用,因为根本不存在这种机制。作为替代,Systemd 在应用模式下的某段循环代码中反复扫描 cgroup 中的所有进程 id,它重读一个 PID 列表文件, 并将信号发送到未列其中的新进程。这会带来几个问题:

>>> 阅读全文

, , ,

AI : 初学者的神经网络 (一)

本系列文章共有 3 个部分:

  • 第一部分: 介绍感知网络 (Perceptron network) 即单层神经网络。
  • 第二部分:介绍多层神经网络以及用反向传导训练法(back propogation 或 backword propogation) 来解决非线性分类问题, 如 XOR 逻辑门。这是感知网络不能解决的问题。
  • 第三部分:介绍如何使用遗传算法(GA)来训练多层神经网络来解决一些逻辑问题

从生物学说起
大脑中的神经细胞称为神经元。人类的大脑中估计有 10^10 到 10^13 个神经元。每个神经元都可以与其他成千上万的神经元进行接触。神经元是大脑用来处理信息的单位。

神经元是什么样子的?

神经元的组成包括一个细胞体(soma)和不同种类的突起(neurite)。大部分的突起为树突(dendrite),其中有一个更长的突起(process) 称为轴突(axon)。图1-1 中的虚线标记的地方是轴丘(axon hillock), 信号的传输就从这里开始。1

神经元的边界称为细胞膜(membrane)。膜内外有电压差 (膜电位)。

>>> 阅读全文

利用 Python 工具和库实现语法解析

想用 Python 来解析编程语言或者文档,一般有三种做法:1

  • 利用现成的库来支持语言的解析,如 XML 类库:对于那些使用广泛的语言如 XML 和 HTML,这是无疑是最好的选择。好的类库通常还会包括创建或修改语言的可编程 API,这要比基础解析器的功能多得多。不过只有最常见的语言才有这种类库。
  • 从头构造一个解析器:有时候你可能要自己构造解析器。比如语言无法用传统的解析器生成器来解析,或者生成器的功能无法满足性能需求或者无法和其他组件深度集成。
  • 利用工具或者库来帮助生成解析器,例如 ANTLR 可以为任何语言生成解析器。

在前两种选项之外的场合,生成器应该是默认的选择,因为它既灵活又可以大大缩短开发时间。这就是为什么本文重点关注此种类库和工具的原因。

用工具创建解析器
在后续的章节中我们会看到:

  • 利用工具来生成 Python 可用(或其他语言可用)的解析器
  • 用来创建解析器的 Python 类库

生成解析器代码的工具称一般为解析器生成器(parser generators)或者编译器的编译器(compiler compiler)。生成解析器的类库则称为解析器组合器(parser combinator)。

不管是生成器还是组合器都不是易上手的工具,你需要花时间学习它们的使用方法。请注意并不是所有生成器都适用于所有的语言。在这里, 我们列出了一些最常见的生成器并对它们逐一进行简单介绍。并且我们的目标语言定为 Python。这意味一般来说这些工具和库自身也是用 Python 编写的。

>>> 阅读全文

, , , , , ,

Linux 内核网络之邻接子系统

当两台或者多台设备通过物理链路连接在一起时候,就构成了网络。多个网络之间还可为了信息交换和服务的目的连接在一起,构成网间网。通信网络中的两台主机要进行通信时,发送方一般都需要知道接收方是哪一个站,以确保每一帧都能正确地送到目的站。接受方也应当知道发送方是哪一个站,以便对消息做出应答。为了确认通信主体,参与通信各方一般都用“地址”来进行标识,地址的本质是一种标识符,用来表示系统中的某一个对象。而同一个系统中不允许有 2 个地址相同的通信主体存在,这就是地址的唯一性。所有的网络都要求某种形式的寻址机制,以识别设备。寻址还可以确定网络本身,或者网络的一个网段(例如子网)。

在计算机通信中,每一层协议的编址方式都不同。1。网络、子网和设备可以由 OSI 参考模型的二、三层协议来确定。硬件寻址在数据链路层(第 2 层)来确定设备。例如以太网是以烧录在网络设备中的唯一识别码作为硬件地址,当网络设备从共享的线路侦听到数据帧时,它负责检出数据帧中的目的地址,并与自己的物理地址进行比较,如二者相符,则接收;否则丢弃。而诸如 IP、IPX 协议则工作在 OSI 协议层的网络层(第 3 层)以确定网络和子网。 网络地址是为了方便寻址人为划分的地址格式,也被称为逻辑地址,也被称为3层地址。

以太网址是一种不包含位置信息的简单标识,它只是对网络设备简单加以区分。这种无位置信息的地址对局域网来说就已经足够。但对于广域网这种复杂无规则,采用点到点连线构成的总体结构,有着庞大的主机数目,使用这种无位置的标识符作为地址就面临着巨大的挑战,无论是采用局域网的广播方式,还是逐一试探,无疑都是开销巨大、笨拙不堪的做法。所以广域网必须采用有结构的地址标识符,不但标识主机,还要指出主机的位置。

之所以存在两种寻址方式,这正是 OSI 参考模型的设计初衷之一:每一层的变化都不会影响到其他层。网络层协议也不用关心物理地址的差异,无论其下一层的物理地址是什么类型,都可以被统一到一致的 IP 地址形式上。而当存在一个附加层的地址寻址时,设备更易于移动。例如以太网交换机可以无需了解具体的网络层协议,无论网络采用 IP 协议还是 IPX 协议,都无需更换一台交换机。

为了标识数据链路层的众多设备,IEEE 为 802 协议族定义了如下的寻址方式:网络设备制造商在生产网络设备时,会为每个硬件分配一个全球唯一码,称为 MAC 地址,并被固化到硬件内部,因此也叫物理地址或硬件地址。当网络设备收到数据帧时,它负责检出数据帧中的目的地址,并与自己的物理地址进行比较,如二者相符,则接收;否则丢弃。

>>> 阅读全文

, , ,

Windows 网络驱动设计指南 (一)网络模型

现代计算机网络是由通信线路互相连接的许多自主工作的计算机构成的集合体,其网络通信的过程很复杂:数据以电子信号的形式穿越介质到达正确的计算机,然后转换成最初的形式,以便接收者能够阅读。各个部件之间以何种规则进行通信,就是网络模型研究的问题。现在广泛研究的网络模型一般是 OSI 七层参考模型和 TCP/IP 四层参考模型。本章主要讨论 OSI 七层参考模型。

一、OSI 七层参考模型
为了解决不同体系结构的网络的互联问题,国际标准化组织 ISO (注意不要与 OSI 搞混)于1981年制定了开放系统互连参考模型(Open System Interconnection Reference Model,OSI/RM)。这个模型把网络通信的工作分为 7 层,如图1-1 所示,由低到高分别是:

  • 1.物理层(Physical Layer)
  • 2.数据链路层(Data Link Layer)
  • 3.网络层(Network Layer)
  • 4.传输层(Transport Layer)
  • 5.会话层(Session Layer)
  • 6.表示层(Presentation Layer)
  • 7.应用层(Application Layer)。

模型中的每一层都完成网络传输中的一个独立任务。在发送端,用户数据自上而下经过以上七层的流水线,除了物理层之外,每一层都会在原始数据前添加一串属于自己的协议头,最后形成一串0、1组成的二进制流。然后根据物理介质是光纤、电缆、还是空气,二进制流转化为光信号、电信号、电磁波信号在物理介质(物理层)里传输,经过若干个中继交换机(链路层)的交换、经过若干个中继路由器(网络层)的转发,最终到达数据的终点。在接收端,自然有理解这些协议头的对端,逐层来剥离数据头,并最终将原始数据呈现给用户。数据的封装和解封装如图1-2 和图1-3 所示。

在深入讨论 OSI 各层的职责和功能之前,我们来了解一些常见的网络术语。

二、网络节点和链路
一个网络节点是一个连接点,表示一个再分发点 (redistribution point)或一个通信端点(一些终端设备)。节点的定义根据所提及的网络和协议层的不同而不同。

>>> 阅读全文

,

稀疏矩阵的存储格式

稀疏矩阵是指矩阵中的元素大部分是零的矩阵。现实问题中的大规模矩阵基本上都是稀疏矩阵,甚至有很多矩阵的稀疏度在 90% 甚至 99% 以上。而稀疏矩阵向量乘 (SpMV Sparse matrix-vector multiplication) 是线性迭代解法器常用的计算内核之一。而稀疏矩阵非零元的存储格式决定了 SpMV 实现时内存访问的效率。本文对几种经典的格式进行了总结和说明。

1. COO 格式(Coordinate Format)
COO 是最简单的存储格式。它采用三个数组 row、col 和 values 保存非零元素的信息。其中 values 保存元素的, 而元素的行坐标和列坐标,则依次分别保存在 row 和 col 中。一般来说,COO 主要用来创建矩阵,因为无法对矩阵的元素进行增删改等操作,一旦矩阵创建成功以后,会转化为其他形式的矩阵。

图1-1 中的矩阵用 COO 格式表示如下

import scipy.sparse as sp
row = [0,0,1,1,2,2,2,3,3]
col = [0,1,1,2,0,2,3,1,3]
values = [1,7,2,8,5,3,9,6,4]
print(sp.coo_matrix((values,(row,col)),shape=(4,4)).toarray())

用 coo_matrix 创建矩阵的时候,相同的行列坐标可以重复出现。当矩阵创建完成后,这些重复坐标的值会被相加。

2. LiL 格式 (List Of Lists)
LiL 格式用两个列表存储每一行的非零元素。一个列表保存每行中的非零元素的值, 另一个列表保存非零元素所在的列坐标。这些列表又作为 values 和 rows 这两个列表的元素来存储。

>>> 阅读全文

PyDAAL 简介 (1)数据结构

Intel DAAL 是在针对英特尔架构优化过构建模块上编写的, 为所有数据分析阶段提供了支持。通过 DAAL, 数据驱动决策获得了包括数据获取、预处理、转换、数据挖掘、建模和验证等等基础支撑。Python 用户可以通过称为 PyDAAL 的 Python API 获取这些基础支撑。 利用 Python 进行机器学习时,你可以通过一个简单的脚本 API 来访问 PyDAAL。此外, PyDAAL 提供了独特功能, 可以轻松地将 Python 脚本化的批处理分析扩展到在线 (流) 数据获取和/或分布式数学处理。

在本系列文章中, 我们将从最基础的部分开始,逐一介绍 PyDAAL 的基础知识。第一部分将介绍 Intel DAAL 的自定义数据结构、数值表和数据管理在 PyDAAL 世界里的表示。1

一、PyDAAL 数据管理
Intel DAAL 支持以下几种数据处理方式:

  • 批处理
  • 在线处理
  • 分布式处理
  • 复合处理(结合在线处理和分布式处理)

本文重点关注批处理方式。在线和分布式处理将在后面的文章中进行讨论。

Python 编程方面的一些思考
强类型:Python 脚本大量使用了动态类型 (鸭子类型) , 借助于 Python 解释器在运行时来进行类型推断。但对于内存占用敏感或进行混合代码部署的情况, 这种做法可能会导致问题。PyDAAL API 调用了用 C++ 和汇编语言编写的库, 这迫使用户使用混合代码环境。因此, PyDAAL 需要一致的类型, 其支持 numpy 类型 “np.float32”, “np.float64”, 和 “np.intc” 。静态/强类型不仅允许显式声明数据类型以实现最佳内存管理, 还可以在编译过程中强制进行类型检查, 大大缩短了运行时间。

>>> 阅读全文

, , , ,

探索 Windows 10 的控制流保护机制

得益于系统漏洞补强技术的持续改进,微软在其 Windows10 和 Windows 8.1 Update 3 中默认启用了一个新机制。其技术被称为控制流保护(Control Flow Guard 简称CFG)。1

与其它漏洞补强机制如地址空间布局随机化(ASLR)或者数据执行保护(DEP)一样,该技术提高了漏洞渗透的难度。无疑,它将引发攻击者渗透技术的改变。正如ALSR 催生了堆喷射技术,DEP 催生了return-oriented-programming 技术。

本文的测试程序是在 Windows 10 RS2 (build 15063) 以及 Visual Studio 2017 上编译的。要完全支持 CFG ,编译器和操作系统都必须被正确设置。由于漏洞渗透机制发生在系统层面,CFG 的实现要求编译器、操作系统用户态类库以及内核模块共同协作。MSDN 上有数篇文章介绍如何一步步启用 CFG. 2

微软 CFG 实现主要集中在对间接调用保护上。

请看下面测试代码:

>>> 阅读全文

, ,

为 QEMU 虚拟设备编写 Linux PCI 设备驱动

本文将以 QEMU 的 ivshmem 虚拟设备作为硬件平台,逐步演示如何为其编写 Linux PCI 设备驱动。该驱动通过的测试环境为 QEMU 版本V1.0,主机操作系统 Ubuntu 12.04,客户机(VM)操作系统 Linux v3.x,此外它在 QEMU v1.0.1, v2.2.0 和 v2.7.0-rc4 中也表现良好。例子中所引用的头文件和其他源文件如 drivers/pci/pci.c 是以 Linux 内核源文件的根目录为搜索路径的。如 即意指 include/linux/pci.h。

背景
要特别强调的是虚拟平台不能替代实际的物理硬件。但在演示、培训、实验等场景,虚拟平台就特别适合:配置虚拟硬件则相当便捷,且可提供一个一致的可供使用的硬件平台。而且添加、扩展或者移除虚拟平台组件也十分方便。 1

本文选用的是 InterVM SHared MEMory (ivshmem) 这个 QEMU PCI 设备。选择该设备的原因有很多, 包括设备构造简单,可以在主机上使用代码和它进行交互和测试。主机 SHM 共享内存被映射为客户机的 MMIO 区域,通过模拟的物理设备(ivshmem 设备)的 MMIO 访问,客户机操作系统就可以访问主机上的 POSIX SHM 共享内存。此外 ivshmem 框架还允许其他启用 ivshmem 的客户机 (或主机上的程序) 通过 eventfd (2) 机制将 irq 发送给虚拟机。如图1-1 所示。

由于 ivshmem 不是默认启用的 QEMU PC 字符设备, 因此需要在 QEMU 启动命令行中指定相应的设备选项。要查看所支持的设备的列表, 请运行 (以 X64 为例):

$ qemu-system-x86_64 -device ?

注: 编写 PCI 设备驱动所用的 Linux API 通常可以支持 PCI 族,包括 PCI, PCI-X 和 PCI-E。ivshmem 设备模拟的是 PCI 设备。

>>> 阅读全文

, , ,

机器学习(1)数据挖掘 机器学习 和人工智能的区别

本文主要分为两部分,第一部分阐述数据挖掘(data mining)、机器学习(machine learning)和人工智能(AI)之间的区别。这三者的区别主要是目的不同,其手段(算法,模型)有很大的重叠,所以容易混淆。第二部分主要阐述以上的技能与数据科学(data science)的关系,以及数据科学(data science)和商业分析(business analytics)之间的关系。

数据挖掘 VS. 机器学习VS. 人工智能
数据挖掘 (data mining): 有目的地从现有大数据中提取数据的模式 pattern 和模型 model。
关键字:模式提取,大数据。

数据挖掘是从现有的信息(existing information)中提取数据的模式(pattern)和模型(model),即精选出最重要的信息,以用于未来机器学习和 AI 的数据使用。其核心目的是找到数据变量之间的关系。其发展出来的主要原因是大数据的发展,用传统的数据分析的方式已经无能处理那么多大量的看似不相关的数据的处理,因此需要数据挖掘技术去提取各种数据和变量之间的相互关系,从而精炼数据。

数据挖掘本质上像是机器学习和人工智能的基础,他的主要目的是从各种各样的数据来源中,提取出超集(superset)的信息,然后将这些信息合并让你发现你从来没有想到过的模式和内在关系。这就意味着,数据挖掘不是一种用来证明假说的方法,而是用来构建各种各样的假说的方法。数据挖掘不能告诉你这些问题的答案,他只能告诉你,A 和 B 可能存在相关关系,但是它无法告诉你 A 和 B 存在什么相关关系。

机器学习(machine learning): 自动地从过往的经验中学习新的知识。
关键字:关键字: 自动化,自我优化,预测,training data,推荐系统

>>> 阅读全文

, ,

将 Win32 枚举型 APIs 转换为 STL 迭代器

原文1

操作系统都有许多 API 用于存取实体集合的,比方说 Unix 的 opendir()/readdir() 函数。Win32 API 也提供了许多函数用来枚举集合内的元素,通常采用的模型无外乎下面几种:回调函数 (如 EnumChildWindows), get-first/get-next (取第一个/取下一个 比如FindFirst/NextFile), 或 get-nth (取第n个 如 RegEnumValue) — 其语义和前二者完全不同。

现在 C++ 社区正在逐步朝着符合 STL 的通用编码格式迈进,如使用容器 (序列和关联)、迭代器、泛函 (或函子或函数对象)、算法和适配器等等。这一做法的最大好处是可以采用一种通用的方法操纵不同的实体, 大大减少开发者的工作量, 同时提高健壮性、可维护性和重用。

STL 技术未被广泛运用的原因之一是除了标准库所提供的类和函数 (list, vector, for_each 等) 之外, 缺少可用的 STL 兼容库, 特别对于操作系统 API。原因之一是这涉及编程模型之间迁移转换的复杂性, 特别是对于集合和序列。本文通过将两种 Win32 枚举模型实际转换 STL 序列, 创建封装了 Win32 API 的轻量级序列类, 并提供了可按 STL 标准算法来操纵枚举实体的迭代器。

本文所演示的类是 WinSTL 库的一部分,WinSTL 则是 STLSoft 的子项目。STLSoft 是个开源组织,一直致力于将 STL 概念运用到多种技术和操作系统中去。

>>> 阅读全文

, , , ,

WDF 驱动程序开发

设备驱动程序是硬件设备连接到计算机系统的软件接口,任何设备都必须有相应的驱动程序才能在计算机系统上正常工作。设备驱动程序的优劣直接关系到整个系统的性能和稳定性,因此,设计和开发稳定高效的驱动程序具有重要意义。

WDF (Windows Driver Foundation) 是微软新一代驱动程序模型,它在 WDM (Windows Driver Model) 的基础上发展而来,支持面向对象、事件驱动的驱动程序开发,提供了比 WDM 更高层次的抽象,是高度灵活、可扩展、可诊断的驱动程序框架。WDF 框架接管了驱动和操作系统内核的大多数交互,驱动和操作系统的交互交给框架内封装的方法(函数)完成,从而对二者进行了隔离,这样驱动开发者只需专注处理硬件的行为即可。另外 WDF 还将大多数驱动中都需要处理的 PnP (即插即用)和电源管理封装进了框架,成为了公用的驱动程序功能。

WDF 可以开发内核模式驱动, 也可以开发用户模式驱动,二者采用同一套对象模型构建,即 WDF。对于内核模式对象和用户模式对象来说,WDF 是它们的父对象。换言之两者都是从 WDF 派生而来的。针对内核模式派生出来的对象称为 KMDF;针对于户模式派生出来的对象称为 UMDF。无论何种模式的框架,其内部封装的方法、执行的行为其实还是用 WDM 来完成的。

本文主要针对 KMDF 框架展开讨论。

KMDF 对象模型
KMDF 驱动程序模型支持面向对象、事件驱动。它定义了一系列的对象用于表示设备、驱动、中断等,每个对象有其相应的属性、方法和事件。驱动程序利用这些方法创建对象、设置属性和响应事件。该框架定义的主要对象有:

>>> 阅读全文

, , ,

SPB 设备和驱动简介

现在有许多文章介绍 Windows 8 操作系统层级的功能。其中之一就是支持简单外设总线 (SPB) 连接的设备。SPB 总线具有低成本、低功耗、低速度的特点,经常用于连接如传感器之类的相对简单的外设。Windows 8 支持的 SPB 设备包括 I2C 和 SPI。之前这类设备受到 BIOS 的限制而很少使用。从 Windows 8 开始,支持这些设备则成为了主流。

如果你对 SPB 总线以及如何编写 SPB 设备驱动感兴趣,可以跟随本文1来深入探讨这些话题。

SPB 总线 — 拓扑和设备枚举
和 SCSI、 SATA 和 USB 总线一样,SPB 是协议式(protocol-based ) 总线。也就是说,有一个控制器会根据总线定义的规则使用正确的协议来请求开关总线。连接到协议式总线上的设备被称为客户端设备,简称客户端。如图1-1.

SPB 总线最让人困惑的地方是如何发现和枚举总线上的设备。 SPB 总线无法动态枚举,这意味着在运行时接上 SPB 总线的设备都无法被发现。那么 Windows PnP 过程如何侦测 SPB 客户端的呢?答案很简单:哪个 SPB 设备挂在哪条 SPB 总线,这些描述被静态添加到一个表中,作为 ACPI BIOS 一部分。所以,枚举 SPB 客户端是由 ACPI 驱动而不是 SPB 控制器驱动负责的。SPB 控制器是典型的背板总线(backplane-bus )类型的设备,总被 PCI 总线驱动所枚举。详细可以参考图1-2 和图1-3。

包含该描述的 ACPI 表格被称为差异系统描述符表(Differentiated System Descriptor Table)简称 DSDT。DSDT 通常由系统集成商(一般是 OEM ) 随 ROM 一起提供的。由于 SPB 设备通常都被永久集成在系统平台上 — 大部分被焊在主板上,所以无法动态枚举不会有任何问题。 少数情况下,SPB 设备可能会被动态地接上系统(比如平板电脑的 I2C 键盘),此时设备信息仍由 ACPI BIOS 提供并由 ACPI 驱动枚举。

>>> 阅读全文

, , , , ,

 SCTP (一) 概览和消息编码

SCTP 是传输层协议,它的功能和 TCP 协议类似,并有一些独特的补充。虽然 SCTP 在互联网世界中不是很常见,但是该协议在电信网络中扮演z着重要角色。它被用做各种 SIGTRAN 协议的传输层,而且还是 EPC 的默认传输协议。

Wikipedia 上的文章 简单地介绍了 SCTP 的功能。另外 Randal Stewart, Michael Tuxen 和 Peter Lei 等著的《SCTP: What is it, and how to use it?》 也是不错的参考。本文将从网络开发者的角度来简述 SCTP ,这意味着我们要深入了解规范的某些内容。接下来我们将过一遍我最感兴趣的部分,以及相关的SCTP 规范 — RFC4960的章节引用。1

SCTP 关键术语和缩写
SCTP 协议第1.3节 和第1.4节介绍了一些关键术语和缩写。对初学者来说,最重要的是:“关联 association”、 “流 stream”和“块 chunk”。

  • 关联(Association):和 TCP 类似, SCTP 是面向连接的协议。两个点(peer)之间的逻辑连接被称为“关联”。和 TCP 不同的,两点间的 SCTP 关联可以建立在多个 IP 地址之上。如图1-1 所示, 主机 A 有三个以太网接口及三个不同的 IP 地址,主机 B 也有三个接口,但只有两个被用于关联。接口及部分关联在图中以浅蓝色表示。在建立关联的期间,每个端点的地址集将被公布,并作为下一次 POST 的主题。很重要的一点:同一个端点的 IP 地址的 SCTP 端口号是相同的 — 称为 “多方持有 multi-homing”。
  • 流(stream): 流是关联间的逻辑单向通道。具体通道数目在建立关联时确定,且每个方向上可以不同。如图1-1,从主机 A 到主机 B 的流有 7个,而从主机 B 向主机 A 的流只有 3 个。流的目的是提供逻辑通道以便按顺序传输数据/邮件。这意味着,即时流 X 中的消息丢失需要重新发送,流 Y 中的消息也不会被延迟,因为它们逻辑上独立。不过流 X 中的(丢失的消息之后)其他消息将被推迟,直到重新发送结束。这种效应称为线路头阻塞(head-of-line blocking),是 TCP 协议的主要问题之一。
  • 块(Chunk):块是 SCTP 包内的信息单元。

SCTP 规范第 1.5 节介绍了该协议的功能概述。比如如何使用流,在流中如何Section 1.5 provides functional overview of the protocol. It describes how streams are used, how in-order delivery is achieved within a stream, how data messages are acknowledged and so on.

, ,

Previous Posts