中断、异常和系统调用(2-3,2-4)

 2-3 课堂练习2.2:中断/异常的处理过程

2adb3fd8b71b48dc8ad0871ee3443d76.png

第一关第二关忘了保存具体的过程只提供了txt中的答案,第三关实验过程基本相同,我会在第三关补上

注意:第一关要解压缩exp1里的内核文件,第二、三关要解压缩exp2中的,只需操作一次即可,我第三关解压缩只为示范

 第1关除零异常分析

任务描述

分析版本 1.1 内核,回答下列问题: 1.在函数 main 的语句jiffies = jiffies/0;所对应的汇编指令片段中,有一个 idiv 指令,此指令的地址是多少? 2.在该 idiv 指令执行之前,当前指令位置(CS:EIP)和栈位置(SS:ESP)分别是多少? 3.使用 si 命令执行了该指令后,新指令位置和栈位置分别是多少?此时栈中保存的恢复点位置和用户栈位置分别是多少?

相关知识

为了完成本关任务,你需要掌握: 1.如何设置某版本的内核为分析对象; 2.如何开始用 gdb 调试内核; 3.查看 C 语句编译之后对应的汇编指令片段; 4.分析响应中断/异常时,CPU 做了哪些工作; 5.查看当前寄存器的状态; 6.查看当前栈顶的状态。

实验准备

本关卡使用版本 1.1 内核作为分析对象,内核文件存放在/data/workspace/myshixun/exp1文件夹中,可以将其解压到linux-0.11-lab下使用。

如何设置某版本的内核为分析对象

下面以版本1内核为例进行讲解。

首先解压版本1内核源码。使用cp命令将/data/workspace/myshixun/exp1中的1.1.tgz复制到~/os/目录下;

 

999b1e2dfa4a8f36d0483dbaf916d3e7.png

切换到~/os/linux-0.11-lab目录下,将1.1.tgz解压到当前目录下;

 

3a603d5b30a6bea396c4d212aa11a356.png

然后调整cur的指向。先使用rm -rf curcur删除,再使用ln命令创建符号链接。

 

f817a078e0dee351de7f5ae5ca1a43d5.png

如何开始用 gdb 调试内核

先关闭bochs虚拟机,然后打开两个终端,其中一个终端在linux-0.11-lab目录下运行rungdb脚本,以启动 bochs 虚拟机并等待 gdb 连接;

 

0a9fbd9c0eda12ba44ef06620c633f66.png

在另一个终端里切换到目录~/os/linux-0.11-lab/,然后启动脚本./mygdb,这个命令会启动 gdb 并读入内核符号信息,同时会通过执行0.gdb中的调试命令来连接到 bochs 虚拟机,并进而跟踪到 main 函数入口。

 

ad2758c0c025462af4b5dd27b2033c90.png

查看 C 语句编译之后对应的汇编指令片段

如果要查看某条 C 语句编译之后对应的汇编指令片段,可以在该 C 语句处设置断点,并跟踪到该断点,然后反汇编,所看到的当前指令之后的一段汇编指令就对应于该 C 语句。

例如,jiffies = jiffies/0;是文件 main.c 的第 147 行,可以如下方式查看:

 

f71f154488a060d2d5442394bf52ab89.jpeg

上面显示的汇编指令中,有一行前面有箭头标识,此即为当前指令,即马上将要执行的指令。

分析响应中断/异常时,CPU 做了哪些工作

  • 切换到核心栈,并在其中保存中断现场。

  • 转到中断处理程序去运行,并切换到核心态。

如下图所示:

 

191170f9899ade434ead937079e1e661.jpeg

上图显示了栈中中断现场的结构,(OLD SS:OLD ESP) 描述了用户栈顶的位置,(OLD CS:OLD EIP) 描述了恢复点的位置。

如何查看当前寄存器的状态

使用 gdb 调试命令 info registers 即可,如下所示:

 

25535aa441f717b46be4c56645e902f4.png

也可以单独查看某一个寄存器:

 

39d81b9955ec1e327d2ddc1f4815a13b.png

如何查看当前栈顶的状态

可以使用命令 x 来查看:

7f39a5279296643d46a894ddfbe1e420.png

上面显示了栈顶的 5 个长字,是某异常发生时的中断现场,其中存储的用户栈顶的位置是 0x17:0x2573c ,存储的恢复点的位置是 0xf:0x7967 。需要注意的是,x86 中栈是从高地址向低地址方向增长的,这里的栈顶位置是 0x1fa0c 。

编程要求

根据相关知识,回答问题:(将答案填写在/data/workspace/myshixun/第一关.txt中) 1.在函数 main 的语句jiffies = jiffies/0;所对应的汇编指令片段中,有一个 idiv 指令,此指令的地址是多少? 2.在该 idiv 指令执行之前,当前指令位置(CS:EIP)和栈位置(SS:ESP)分别是多少? 3.使用 si 命令执行了该指令后,新指令位置和栈位置分别是多少?此时栈中保存的恢复点位置和用户栈位置分别是多少?

答案

8fbe5069e94c43b884c44855d08a511b.png

第2关int指令分析

任务描述

分析版本1内核,回答下列问题: 1.函数 task1 的第一个int 0x81指令执行之前,当前指令位置(CS:EIP)和栈位置(SS:ESP)分别是多少? 2.使用 si 命令执行了该指令后,新指令位置和栈位置分别是多少?此时栈中保存的恢复点位置和用户栈位置分别是多少?

相关知识

为了完成本关任务,你需要掌握: 1.开始使用 gdb 调试内核; 2.跟踪到函数 task1 的第一个int 0x81指令; 3.响应中断/异常时,CPU 做的工作; 4.查看当前寄存器的状态; 5.查看当前栈顶的状态。

环境准备

本关卡使用版本 1 内核,文件存放在/data/workspace/myshixun/exp2/中,将版本 1 内核设置为分析对象。

开始使用 gdb 调试内核

先关闭bochs虚拟机,然后打开两个终端,其中一个终端在linux-0.11-lab目录下运行rungdb脚本,以启动 bochs 虚拟机并等待 gdb 连接;

 

bf92744f35f9dd6a93b9a5f601055241.png

在另一个终端里切换到目录~/os/linux-0.11-lab/,然后启动脚本./mygdb,这个命令会启动 gdb 并读入内核符号信息,同时会通过执行0.gdb中的调试命令来连接到 bochs 虚拟机,并进而跟踪到 main 函数入口。

 

1356d7fe5237c66939decf826812f956.png

跟踪到函数 task1 的第一个int 0x81指令

可以在函数task1入口处设置断点,跟踪到该处后再单步执行到第一个int 0x81指令,如下所示:

 

ea8b664453aaf4b34a7609afa063b2b1.jpeg

上面显示的汇编指令中,有一行前面有箭头标识,此即为当前指令,即马上将要执行的指令。

响应中断/异常时,CPU 做的工作

切换到核心栈,并在其中保存中断现场。

转到中断处理程序去运行,并切换到核心态。 如下图所示:

 

9f90a33f75c5e53a7f111a5822d264a0.png

上图显示了栈中中断现场的结构,(OLD SS:OLD ESP) 描述了用户栈顶的位置,(OLD CS:OLD EIP) 描述了恢复点的位置。

查看当前寄存器的状态

使用 gdb 调试命令 info registers 即可,如下所示:

 

8c3fa4d37bd4a4e7552a27ddb9b71efd.png

也可以单独查看某一个寄存器:

 

875f99108dc38fe5dded2c412f037749.png

查看当前栈顶的状态

可以使用命令 x 来查看:

 

cdf02625561cf1a28e7ee9afcdb59244.png

上面显示了栈顶的 5 个长字,是某异常发生时的中断现场,其中存储的用户栈顶的位置是 0x17:0x2573c ,存储的恢复点的位置是 0xf:0x7967 。需要注意的是,x86 中栈是从高地址向低地址方向增长的,这里的栈顶位置是 0x1fa0c 。

答案

8fbe5069e94c43b884c44855d08a511b.png

第3关iret指令分析

任务描述

本关任务回答问题: 1.函数 task1 的第一个int 0x81指令执行时,会转到对应的中断/异常处理程序去运行,请问在该处理程序的 iret 指令执行之前,指令位置(CS:EIP)和栈位置(SS:ESP)分别是多少?此时栈中保存的恢复点位置和用户栈位置分别是多少? 2.使用 si 命令执行了该 iret 指令后,新指令位置和栈位置分别是多少?

相关知识

为了完成本关任务,你需要掌握: 1.跟踪到函数 task1 的第一个int 0x81指令; 2.跟踪到一个中断/异常处理程序对应的 iret 指令; 3.iret 指令执行时,CPU 做的工作; 4.查看当前寄存器的状态; 5.查看当前栈顶的状态。

环境准备

本关卡使用版本 1 内核作为分析对象,请确认当前分析对象是否正确。

开启 gdb 调试,跟踪到 main 函数入口,方法与之前关卡一样。

跟踪到函数 task1 的第一个int 0x81指令

可以在函数task1入口处设置断点,跟踪到该处后再单步执行到第一个int 0x81指令,如下所示:

ea8b664453aaf4b34a7609afa063b2b1.jpeg

上面显示的汇编指令中,有一行前面有箭头标识,此即为当前指令,即马上将要执行的指令。

跟踪到一个中断/异常处理程序对应的 iret 指令

方法类似于中断/异常的恢复点分析。通过反汇编找到 iret 指令,然后跟踪过去。

中断/异常的恢复点分析

当一个中断/异常被 gdb 捕获时,通常正在运行中断处理程序,这时可以继续跟踪,直至回到恢复点指令。以时钟中断为例,为了从函数 do_timer 跟踪到恢复点,可以如下操作:

 

8b90ca3e6da08574a4af70be841780e9.png

由上图可见时钟中断处理程序的入口是 timer_interrupt 函数。 跟踪到当前函数(do_timer)执行完毕返回到 timer_interrupt 函数;

 

e189e08ea40abc75dac2a1846b707bb8.png

跟踪到 timer_interrupt 函数(用汇编语言写的)末尾的 iret 指令;

 

2257b2864ac59b956c8856fc1c1cf845.png

 

5e7c610ee9137adf66884b0f0f711149.png

 

8dbc61fdba8299eca5629c3bac47f004.png

 

9698fa017426f4aad359262da90ff63d.png

 

7d621f88459bbf1e39eda5a2d79214f7.png

执行该 iret 指令,返回到恢复点;

 

2b8ec31b40a79e7cff0479bdd22fb93f.png

通过反汇编命令:disas ,分析恢复点指令的地址。

 

e2f6a2f0581405f8b1dd4d656f96462b.png

iret 指令执行时,CPU 做的工作

从中断现场恢复使用用户栈,回到以前的 CPU 状态(一般是用户态),回到恢复点继续运行。是中断发生时 CPU 所做动作的逆过程。此时,核心栈里存放着中断现场,如下图所示:

9f90a33f75c5e53a7f111a5822d264a0.png

上图显示了栈中中断现场的结构,(OLD SS:OLD ESP) 描述了用户栈顶的位置,(OLD CS:OLD EIP) 描述了恢复点的位置。

如何查看当前寄存器的状态

使用 gdb 调试命令 info registers 即可,如下所示:

8c3fa4d37bd4a4e7552a27ddb9b71efd.png

也可以单独查看某一个寄存器:

875f99108dc38fe5dded2c412f037749.png

如何查看当前栈顶的状态

可以使用命令 x 来查看:

cdf02625561cf1a28e7ee9afcdb59244.png

上面显示了栈顶的 5 个长字,是某异常发生时的中断现场,其中存储的用户栈顶的位置是 0x17:0x2573c ,存储的恢复点的位置是 0xf:0x7967 。需要注意的是,x86 中栈是从高地址向低地址方向增长的,这里的栈顶位置是 0x1fa0c 。

编程要求

根据相关知识,回答问题:(将答案填写在/data/workspace/myshixun/第三关.txt中) 1.函数 task1 的第一个int 0x81指令执行时,会转到对应的中断/异常处理程序去运行,请问在该处理程序的 iret 指令执行之前,指令位置(CS:EIP)和栈位置(SS:ESP)分别是多少? 2.此时栈中保存的恢复点位置和用户栈位置分别是多少? 3.使用 si 命令执行了该 iret 指令后,新指令位置和栈位置分别是多少?

实验过程及答案

1a18dbe8aca64cd2ab95ddf448c5feec.pngf81c9fb8e0144df1824ba323252539ad.png3a78dae76c444109b1592f417c1f8d66.png3d1a682f2f914ad0829cb653884d54ed.pngd21584ecc58140ccb8a6e9fcfacd1acb.png57ad00f772ef44e0abb4729e6baa7ce5.png13e98dddc9804c75bf7c70e539268ebb.png

925a12f318de4f6896d217eee5053593.png打开一个新的终端

80750e9016d741729ba5bb0b79fae598.pngb471851141e84626853ef9d16e56d2d3.pngd47a30a228e645839d73cb3a43b0ef67.pngbfc44c0548184ff191cfee326f8fc839.png1395113d945e4b148af01cbadc90d387.png8f23219b721a45eb86bf31bbaa4ed847.png02418193da474310bb03c8856b929ffd.png535ac1e8f2fa422dbc5355ffa087dd83.png

8a009d735d5c40b3a2727282a565bee7.png

57bbc4b3ebc546d99ddddeab5a44fd50.pnge29a7d872ab249d7bc7e017b63816ef4.png77bc006914524f9b8a2bb88716878070.png

66ae79336712494f9b78b4008fe62204.png

2-4 课后作业2.2:中断/异常的处理过程


第1关陷入指令分析

ef49cd1bf83c4bd492e1cd8d048b008c.png

任务描述

分析版本1内核,回答下列问题: 1.在 0 号进程执行 fork 系统调用中的陷入指令(int 0x80)之前,当前指令位置(CS:EIP)和栈位置(SS:ESP)分别是多少? 2.使用 si 命令执行了该指令后,新指令位置和栈位置分别是多少? 3.此时栈中保存的恢复点位置和用户栈位置分别是多少?

相关知识

为了完成本关任务,你需要掌握: 1.跟踪到系统调用的陷入指令(int 0x80)执行之前; 2.响应中断/异常时,CPU 做了哪些工作; 3.查看当前寄存器的状态; 4.查看当前栈顶的状态

环境准备

本关卡使用版本 1 内核进行分析,设置方式与以前相同。

启用 gdb 进行调试,跟踪到 main 函数入口,方法与前面的实训相同。

跟踪到系统调用的陷入指令(int 0x80)执行之前

一般而言,可以在该系统调用处设置断点,跟踪到该断点,然后使用 si 命令单步执行到陷入指令。但是,对于 main 函数里的 fork 系统调用,不能这样操作(因为 gdb 有时断点设置不够准),可以先跟踪到前一行的 move_to_user_mode 语句,然后使用 n 单步执行,即可到达 fork 系统调用的开始,此时再反汇编,找到陷入指令:

 

cc56ea53dbd9889c0716fb9602e270b1.png

然后再通过 si 单步执行,跟踪到陷入指令 (int 0x80) 。

响应中断/异常时,CPU 做了哪些工作

从中断现场恢复使用用户栈,回到以前的 CPU 状态(一般是用户态),回到恢复点继续运行。是中断发生时 CPU 所做动作的逆过程。此时,核心栈里存放着中断现场,如下图所示:

9f90a33f75c5e53a7f111a5822d264a0.png

上图显示了栈中中断现场的结构,(OLD SS:OLD ESP) 描述了用户栈顶的位置,(OLD CS:OLD EIP) 描述了恢复点的位置。

如何查看当前寄存器的状态

使用 gdb 调试命令 info registers 即可,如下所示:

8c3fa4d37bd4a4e7552a27ddb9b71efd.png

也可以单独查看某一个寄存器:

875f99108dc38fe5dded2c412f037749.png

如何查看当前栈顶的状态

可以使用命令 x 来查看:

cdf02625561cf1a28e7ee9afcdb59244.png

上面显示了栈顶的 5 个长字,是某异常发生时的中断现场,其中存储的用户栈顶的位置是 0x17:0x2573c ,存储的恢复点的位置是 0xf:0x7967 。需要注意的是,x86 中栈是从高地址向低地址方向增长的,这里的栈顶位置是 0x1fa0c 。

编程要求

根据相关知识,回答问题:(将答案填写在/data/workspace/myshixun/第四关.txt中) 1.在 0 号进程执行 fork 系统调用中的陷入指令(int 0x80)之前,当前指令位置(CS:EIP)和栈位置(SS:ESP)分别是多少? 2.使用 si 命令执行了该指令后,新指令位置和栈位置分别是多少?此时栈中保存的恢复点位置和用户栈位置分别是多少?

实验过程及答案

 本关卡使用版本 1 内核进行分析,设置方式与以前相同。

启用 gdb 进行调试,跟踪到 main 函数入口,方法与前面的实训相同。

ls /data/workspace/myshixun/exp2
cp /data/workspace/myshixun/exp2/1.tgz ~/os

86ae9875e0a84dbabd8abdb0e9477dc0.png

cd os/linux-0.11-lab
tar -zxvf ../1.tgz 1

de0ebd3263cc4230a9de53bf430dcc0c.png

rm -rf cur
ln -s 1.1 cur
ls

f12d91d64d9c4b5db1cbd88daf504c59.png

cd 1/linux
make

ee35757477f1428b93032742a723085e.png

cd ../..
./rungdb

23f0bde27ee344dd940cda4d4cb7acf8.png

另开一个终端

cd os/linux-0.11-lab
./mygdb

164f5c0adaf1445daea419b6f8c24e68.png

b 145
c
n

a7526c86c3754388885137082f7a802f.png

x/5i $eip
si
x/5i $eip

1e58c1a5860d4ae484a8eb5132cb1bd6.png

第一题

info reg

da6f13432e82401d9040594b7e10a466.png

第二题

si
info reg

77e44299dd1c4bc59a9fb5c60ec8467e.png

第三题

x/5wx $esp

8b62cf5432ed4366ad961f0c9fb3fb4f.png

70d1ec22af5e4aeb92735fad89749f37.png

 

  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
Java高级程序设计 第2章 异常处理 Java高级程序设计(第二版)--第2章-异常处理全文共19页,当前为第1页。 第2章 异常处理 2.1 什么是异常 2.2 处理异常 2.3 自定义异常与throw关键字 2.4 throws关键字 2.5 Java的内置异常 Java高级程序设计(第二版)--第2章-异常处理全文共19页,当前为第2页。 本章目标 理解异常及其作用 使用try-catch-finally语句捕获和处理异常 使用throw、throws关键字 Java高级程序设计(第二版)--第2章-异常处理全文共19页,当前为第3页。 本章任务 任务1 识别异常 任务2 处理异常 任务3 自定义百分制分数异常 任务4 使用throws关键字 Java高级程序设计(第二版)--第2章-异常处理全文共19页,当前为第4页。 2.1 什么是异常 任务1 识别异常 编程实现整数除法运算:接收用户输入的2个整数,除法运算后输出结果。根据用户的不同输入,可能产生如图所示的不同结果。 Java高级程序设计(第二版)--第2章-异常处理全文共19页,当前为第5页。 知识点:异常的概念、异常处理机制 一、异常的概念 程序开发中一般会出现两种问题: 第一种,在编译期间被检测出来的错误,我们称之为语法错误,比如关键字拼写错误、语句丢失分号、变量名未定义等。如果程序中存在这类错误,将不能编译通过,不能生成字节码。 Java高级程序设计(第二版)--第2章-异常处理全文共19页,当前为第6页。 第二种,没有语法错误编译成功了,但在程序运行期间出现错误,我们称之为运行错误,比如被访问对象没有正常初始化、访问数组元素时下标值超出范围等等。这种运行错误如果没有得到及时的处理,可能会造成程序提前中断、数据遗失乃至系统崩溃等问题。这种运行错误也就是我们所说的"异常"。 Java高级程序设计(第二版)--第2章-异常处理全文共19页,当前为第7页。 二、异常处理机制 为了解决这种需要由程序员承担程序出错情况判断的不正规处理模式所带来的困难和阻碍,Java引入了异常处理机制,通过代码运行到出现错误的时候由系统抛出一个运行时异常,Java程序可以很容易地捕获并处理发生的异常情况。 Java高级程序设计(第二版)--第2章-异常处理全文共19页,当前为第8页。 Java的异常类层次结构 Java高级程序设计(第二版)--第2章-异常处理全文共19页,当前为第9页。 2.2 处理异常 任务2 处理异常 完善任务1中的IntDivide程序,对除法运算中除数为0的异常进行处理,即使用户输入0值不能进行除法运算时也不会再粗鲁地直接中断程序执行了,运行效果如图所示。 Java高级程序设计(第二版)--第2章-异常处理全文共19页,当前为第10页。 知识点:try-catch-finally语句处理异常 try{ //需要监视异常的代码块,该区域如果发生异常就匹配catch来决定程序如何处理 } catch(异常类型1 异常的变量名1){ //处理异常语句组1 } catch(异常类型2 异常的变量名2){ //处理异常语句组2 } …… finally{ //最终执行的语句组 } Java高级程序设计(第二版)--第2章-异常处理全文共19页,当前为第11页。 2.3 自定义异常与throw关键字 任务3 自定义百分制分数异常 编程实现:根据用户输入的分数判定成绩等级并输出。分数规定为百分制,一旦用户输入的分数不符合百分制分数要求,则请用户重新输入,直至输入分数正确,判定等级并输出为止。运行效果如图所示。 Java高级程序设计(第二版)--第2章-异常处理全文共19页,当前为第12页。 知识点:自定义异常、throw关键字 一、自定义异常 <class> <自定义异常类名> <extends> <Exception>{ // 变量、构造方法、成员方法 } 二、throw关键字 <throw> <异常对象>; Java高级程序设计(第二版)--第2章-异常处理全文共19页,当前为第13页。 2.4 throws关键字 任务4 使用throws关键字 编程实现与任务3相同的根据分数判定等级并输出的功能。 代码要求:将根据分数判等级的功能定义为方法,且方法内部不处理分数异常,而是将异常抛出给其调用者来进行处理。 Java高级程序设计(第二版)--第2章-异常处理全文共19页,当前为第14页。 知识点:throws关键字为方法声明异常 方法声明 <throws> <异常类1>,<异常类2>,…<异常类n> { //方法体,抛出异常 } Java高级程序设计(第二版)--第2章-异常处理全文共19页,当前为第15页。 2.5 Java的内置异常 在核心语言包java.lang中
本文详细介绍 Python 3.8 中的新功能,以及和与 3.7 相比的一些不同点。 新功能 编译的字节码文件的并行文件系统缓存新的 PYTHONPYCACHEPREFIX设置(也可用 )将隐式字节码缓存配置为使用单独的并行文件系统树,而不是每个源目录中的默认子目录。-X pycache_prefix__pycache_报告缓存的位置sys.pycache_prefix(None表示pycache子目录中的默认位置)。 其他语言变更 一个continue说法是非法finally条款因与实施问题。在Python 3.8中,这一限制被取消了。 该int类型现在具有as_integer_ratio()与现有float.as_integer_ratio()方法兼容的新方法。 增加了对\N{name}的支持。 Dict和dictviews现在可以使用反向插入顺序进行迭代 reversed()。 函数调用中允许关键字名称的语法进一步受到限制。特别是,f((keyword)=arg)不再允许。它从来没有打算在关键字参数赋值术语的左侧允许多于一个裸名称。见bpo-34641。 现在允许Iterable解包,而不使用括号yield 和return语句。(由David Cuthbert和Jordan Chapman在bpo-32117中提供。) 不是有效转义序列的反斜杠字符对DeprecationWarning从Python 3.6开始生成。在Python 3.8中它生成了一个SyntaxWarning代替。(由Serhiy Storchaka供稿于bpo-32912。) SyntaxWarning在某些情况下,编译器会在元组或列表之前错过逗号时生成。例如: 1data = [ 2 (1, 2, 3) # oops, missing comma! 3 (4, 5, 6) 4] 子类之间的算术运算datetime.date或 datetime.datetime与datetime.timedelta对象现在返回子类的实例,而不是基类。这也会影响其实现(直接或间接)使用datetime.timedelta算术的操作的返回类型,例如 datetime.datetime.astimezone()。 当Python解释器被Ctrl-C(SIGINT)中断并且KeyboardInterrupt未捕获到的结果异常时,Python进程现在通过SIGINT信号或正确的退出代码退出,以便调用进程可以检测到它因Ctrl而死亡-C。POSIX和Windows上的shell使用它来正确终止交互式会话中的脚本。 改进的模块 现在的_asdict()方法collections.namedtuple()返回一个dict而不是一个collections.OrderedDict。这是有效的,因为自Python 3.7以来,常规dicts已经保证了排序。如果需要额外的功能OrderedDict,建议的补救措施是将结果转换为所需的类型:OrderedDict(nt._asdict())。该unicodedata模块已升级为使用Unicode 12.0.0 版本。 ASYNCIO 在Windows上,现在是默认的事件循环ProactorEventLoop。 gettext 添加pgettext()及其变体。
目 录 译者序 前言 第1章 概述 1 1.1 引言 1 1.2 分层 1 1.3 TCP/IP的分层 4 1.4 互联网的地址 5 1.5 域名系统 6 1.6 封装 6 1.7 分用 8 1.8 客户-服务器模型 8 1.9 端口号 9 1.10 标准化过程 10 1.11 RFC 10 1.12 标准的简单服务 11 1.13 互联网 12 1.14 实现 12 1.15 应用编程接口 12 1.16 测试网络 13 1.17 小结 13 第2章 链路层 15 2.1 引言 15 2.2 以太网和IEEE 802封装 15 2.3 尾部封装 17 2.4 SLIP:串行线路IP 17 2.5 压缩的SLIP 18 2.6 PPP:点对点协议 18 2.7 环回接口 20 2.8 最大传输单元MTU 21 2.9 路径MTU 21 2.10 串行线路吞吐量计算 21 2.11 小结 22 第3章 IP:网际协议 24 3.1 引言 24 3.2 IP首部 24 3.3 IP路由选择 27 3.4 子网寻址 30 3.5 子网掩码 32 3.6 特殊情况的IP地址 33 3.7 一个子网的例子 33 3.8 ifconfig命令 35 3.9 netstat命令 36 3.10 IP的未来 36 3.11 小结 37 第4章 ARP:地址解析协议 38 4.1 引言 38 4.2 一个例子 38 4.3 ARP高速缓存 40 4.4 ARP的分组格式 40 4.5 ARP举例 41 4.5.1 一般的例子 41 4.5.2 对不存在主机的ARP请求 42 4.5.3 ARP高速缓存超时设置 43 4.6 ARP代理 43 4.7 免费ARP 45 4.8 arp命令 45 4.9 小结 46 第5章 RARP:逆地址解析协议 47 5.1 引言 47 5.2 RARP的分组格式 47 5.3 RARP举例 47 5.4 RARP服务器的设计 48 5.4.1 作为用户进程的RARP服务器 49 5.4.2 每个网络有多个RARP服务器 49 5.5 小结 49 第6章 ICMP:Internet控制报文协议 50 6.1 引言 50 6.2 ICMP报文的类型 50 6.3 ICMP地址掩码请求与应答 52 6.4 ICMP时间戳请求与应答 53 6.4.1 举例 54 6.4.2 另一种方法 55 6.5 ICMP端口不可达差错 56 6.6 ICMP报文的4.4BSD处理 59 6.7 小结 60 第7章 Ping程序 61 7.1 引言 61 7.2 Ping程序 61 7.2.1 LAN输出 62 7.2.2 WAN输出 63 7.2.3 线路SLIP链接 64 7.2.4 拨号SLIP链路 65 7.3 IP记录路由选项 65 7.3.1 通常的例子 66 7.3.2 异常的输出 68 7.4 IP时间戳选项 69 7.5 小结 70 第8章 Traceroute程序 71 8.1 引言 71 8.2 Traceroute 程序的操作 71 8.3 局域网输出 72 8.4 广域网输出 75 8.5 IP源站选路选项 76 8.5.1 宽松的源站选路的traceroute 程序示例 78 8.5.2 严格的源站选路的traceroute 程序示例 79 8.5.3 宽松的源站选路traceroute程序 的往返路由 80 8.6 小结 81 第9章 IP选路 83 9.1 引言 83 9.2 选路的原理 84 9.2.1 简单路由表 84 9.2.2 初始化路由表 86 9.2.3 较复杂的路由表 87 9.2.4 没有到达目的地的路由 87 9.3 ICMP主机与网络不可达差错 88 9.4 转发或不转发 89 9.5 ICMP重定向差错 89 9.5.1 一个例子 90 9.5.2 更多的细节 91 9.6 ICMP路由器发现报文 92 9.6.1 路由器操作 93 9.6.2 主机操作 93 9.6.3 实现 93 9.7 小结 94 第10章 动态选路协议 95 10.1 引言 95 10.2
这是书的光盘。共分为两个部分,这是第一部分。 本书由浅入深、循序渐进地介绍了Windows驱动程序的开发方法与调试技巧。本书共分23章,内容涵盖了 Windows操作系统的基本原理、NT驱动程序与WDM驱动程序的构造、驱动程序中的同步异步处理方法、驱 动程序中即插即用功能、驱动程序的各种调试技巧等。同时,还针对流行的PCI驱动程序、USB驱动程序 、虚拟串口驱动程序、摄像头驱动程序、SDIO驱动程序进行了详细的介绍,本书最大的特色在于每一节 的例子都是经过精挑细选的,具有很强的针对性。力求让读者通过亲自动手实验,掌握各类Windows驱动 程序的开发技巧,学习尽可能多的Windows底层知识。   本书适用于中、高级系统程序员,同时也可用做高校计算机专业操作系统实验课的补充教材。 原创经典,威盛一线工程师倾力打造。深入驱动核心,剖析操作系统底层运行机制,通过实例引导,快 速学习编译、安装、调试的方法。   从Windows最基本的两类驱动程序的编译、安装、调试入手讲解,非常容易上手,用实例详细讲解 PCI、USB、虚拟串口、虚拟摄像头、SDIO等驱动程序的开发,归纳了多种调试驱动程序的高级技巧,如 用WinDBG和VMWARE软件对驱动进行源码级调试,深入Windows操作系统的底层和内核,透析Windows驱动 开发的本质。 本书是作者结合教学和科研实践经验编写而成的,不仅详细介绍了Windows内核原理,而且介绍了编程技 巧和应用实例,兼顾了在校研究生和工程技术人员的实际需求,对教学、生产和科研有现实的指导意义 ,是一本值得推荐的专著。              ——中国工程院院士   院士推荐   目前,电子系统设计广泛采用通用操作系统,达到降低系统的设计难度和缩短研发周期。实现操作 系统与硬件快速信息交换是电子系统设计的关键。   通用操作系统硬件驱动程序的开发,编写者不仅需要精通硬件设备、计算机总线,而且需要Windows 操作系统知识以及调试技巧。学习和掌握Windows硬件驱动程序的开发是电子系统设计人员必备的能力。   本书是作者结合教学和科研实践经验编写而成的,不仅详细介绍了Windows内核原理,并且介绍了编 程技巧和应用实例,兼顾了在校研究生和工程技术人员的实际需求,对教学、生产和科研有现实的指导 意义,是一本值得推荐的专著。 第1篇 入门篇 第1章 从两个最简单的驱动谈起 本章向读者呈现两个最简单的Windows驱动程序,一个是NT式的驱动程序,另一个是WDM式的驱动程序。 这两个驱动程序没有操作具体的硬件设备,只是在系统里创建了虚拟设备。在随后的章节中,它们会作 为基本驱动程序框架,被本书其他章节的驱动程序开发所复用。笔者将带领读者编写代码、编译、安装 和调试程序。   1.1 DDK的安装   1.2 第一个驱动程序HelloDDK的代码分析    1.2.1 HelloDDK的头文件    1.2.2 HelloDDK的入口函数    1.2.3 创建设备例程    1.2.4 卸载驱动例程    1.2.5 默认派遣例程   1.3 HelloDDK的编译和安装    1.3.1 用DDK环境编译HelloDDK    1.3.2 用VC集成开发环境编译HelloDDK    1.3.3 HelloDDK的安装   1.4 第二个驱动程序HelloWDM的代码分析    1.4.1 HelloWDM的头文件    1.4.2 HelloWDM的入口函数    1.4.3 HelloWDM的AddDevice例程    1.4.4 HelloWDM处理PNP的回调函数    1.4.5 HelloWDM对PNP的默认处理    1.4.6 HelloWDM对IRP_MN_REMOVE_DEVICE的处理    1.4.7 HelloWDM对其他IRP的回调函数    1.4.8 HelloWDM的卸载例程   1.5 HelloWDM的编译和安装    1.5.1 用DDK编译环境编译HelloWDM    1.5.2 HelloWDM的编译过程    1.5.3 安装HelloWDM   1.6 小结  第2章 Windows操作驱动的基本概念  驱动程序被操作系统加载在内核模式下,它与Windows操作系统内核的其他组件进行密切交互。本章主 要介绍Windows操作系统内核的基本概念,同时还介绍应用程序和驱动程序之间的通信方法。   2.1 Windows操作系统概述    2.1.1 Windows家族    2.1.2 Windows特性    2.1.3 用户模式和内核模式    
教学内容与要求   1掌握处理器在进程地址空间上的三种运行位置,了解内核编程不能使用C库函数和FPU,以及可能产生内存故障、核心栈溢出和四种内核竞争情形的原因。(2学时)   2熟悉进程描述符的组织,进程上下文和进程状态转换,和fork,exec,wait,exit,clone,linux线程和内核线程的实现原理和应用。了解COW和避免出现孤儿进程技术。(4小时)   3介绍支持SMP的O(1)调度,用户和内核抢占和进程上下文切换,了解优先级复算,睡眠和唤醒机制,SMP的负载均衡。(4小时)   4掌握在x86体系结构上系统调用的具体实现原理,接口参数传递,用户地址空间和核心地址空间之间的数据传输,和增加新的系统功能的方法。(2小时)   5熟悉在x86体系结构上Linux中断异常的处理原理,中断注册、共享、控制,和中断上下文的意义,中断和设备驱动程序的关系,以及设备驱动程序结构和用户接口。(4小时)   6中断处理程序被分解为top half和bottom half的原因,介绍linux的softirq,tasklet,ksoftirqd和work queue,分析进程与top half,bottom half的竞争情形和同步。(4小时)   7掌握内核同步原理和方法:原子操作,自旋锁,(读—写)信号量,完成变量,bkl,seqlock和延迟内核抢占。了解指令“路障”。(4小时)   8介绍系统时钟和硬件定时器,单处理器和多处理器上的linux计时体系结构,定时的时间插补原理,单处理器和多处理器上的时钟中断处理,动态定时器的数据结构和算法原理,定时器竞争情形,延迟函数。Time,gettimeofday,adjtimex,setitimer,alarm的实现原理和应用。(4小时)   9熟悉进程地址空间的区和页,分配和释放物理页,物理地址与逻辑地址、虚地址之间的映射,slub分配原理和方法,高端物理内存的映射。(4小时)   10介绍VFS原理,超级块,inode结构和方法,dentry结构和方法,file结构和方法,以及进程打开文件表,linux中的文件系统。(2小时)   11讲解块设备缓冲,bio结构,I/O请求队列,和有最终期限的块I/O调度算法。(2小时)   12熟悉进程地址空间的分区,mm_struct结构,vm_area_struct结构和操作,,进程的页表文件映射接口mmap原理和方法。(2小时)   13熟悉页cache和radix_tree,缓冲区cache,和pdflush内核线程原理。(2小时)
目 录 译者序 前言 第1章 概述 1 1.1 引言 1 1.2 分层 1 1.3 TCP/IP的分层 4 1.4 互联网的地址 5 1.5 域名系统 6 1.6 封装 6 1.7 分用 8 1.8 客户-服务器模型 8 1.9 端口号 9 1.10 标准化过程 10 1.11 RFC 10 1.12 标准的简单服务 11 1.13 互联网 12 1.14 实现 12 1.15 应用编程接口 12 1.16 测试网络 13 1.17 小结 13 第2章 链路层 15 2.1 引言 15 2.2 以太网和IEEE 802封装 15 2.3 尾部封装 17 2.4 SLIP:串行线路IP 17 2.5 压缩的SLIP 18 2.6 PPP:点对点协议 18 2.7 环回接口 20 2.8 最大传输单元MTU 21 2.9 路径MTU 21 2.10 串行线路吞吐量计算 21 2.11 小结 22 第3章 IP:网际协议 24 3.1 引言 24 3.2 IP首部 24 3.3 IP路由选择 27 3.4 子网寻址 30 3.5 子网掩码 32 3.6 特殊情况的IP地址 33 3.7 一个子网的例子 33 3.8 ifconfig命令 35 3.9 netstat命令 36 3.10 IP的未来 36 3.11 小结 37 第4章 ARP:地址解析协议 38 4.1 引言 38 4.2 一个例子 38 4.3 ARP高速缓存 40 4.4 ARP的分组格式 40 4.5 ARP举例 41 4.5.1 一般的例子 41 4.5.2 对不存在主机的ARP请求 42 4.5.3 ARP高速缓存超时设置 43 4.6 ARP代理 43 4.7 免费ARP 45 4.8 arp命令 45 4.9 小结 46 第5章 RARP:逆地址解析协议 47 5.1 引言 47 5.2 RARP的分组格式 47 5.3 RARP举例 47 5.4 RARP服务器的设计 48 5.4.1 作为用户进程的RARP服务器 49 5.4.2 每个网络有多个RARP服务器 49 5.5 小结 49 第6章 ICMP:Internet控制报文协议 50 6.1 引言 50 6.2 ICMP报文的类型 50 6.3 ICMP地址掩码请求与应答 52 6.4 ICMP时间戳请求与应答 53 6.4.1 举例 54 6.4.2 另一种方法 55 6.5 ICMP端口不可达差错 56 6.6 ICMP报文的4.4BSD处理 59 6.7 小结 60 第7章 Ping程序 61 7.1 引言 61 7.2 Ping程序 61 7.2.1 LAN输出 62 7.2.2 WAN输出 63 7.2.3 线路SLIP链接 64 7.2.4 拨号SLIP链路 65 7.3 IP记录路由选项 65 7.3.1 通常的例子 66 7.3.2 异常的输出 68 7.4 IP时间戳选项 69 7.5 小结 70 第8章 Traceroute程序 71 8.1 引言 71 8.2 Traceroute 程序的操作 71 8.3 局域网输出 72 8.4 广域网输出 75 8.5 IP源站选路选项 76 8.5.1 宽松的源站选路的traceroute 程序示例 78 8.5.2 严格的源站选路的traceroute 程序示例 79 8.5.3 宽松的源站选路traceroute程序 的往返路由 80 8.6 小结 81 第9章 IP选路 83 9.1 引言 83 9.2 选路的原理 84 9.2.1 简单路由表 84 9.2.2 初始化路由表 86 9.2.3 较复杂的路由表 87 9.2.4 没有到达目的地的路由 87 9.3 ICMP主机与网络不可达差错 88 9.4 转发或不转发 89 9.5 ICMP重定向差错 89 9.5.1 一个例子 90 9.5.2 更多的细节 91 9.6 ICMP路由器发现报文 92 9.6.1 路由器操作 93 9.6.2 主机操作 93 9.6.3 实现 93 9.7 小结 94 第10章 动态选路协议 95 10.1 引言 95 10.2

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ItsNorth

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值