ps为什么复制不了图层:IA-32 地址空间和APIC

来源:百度文库 编辑:偶看新闻 时间:2024/04/29 10:47:15

从网上搜集的文档.

Intel的文档链接

这个链接,Intel的官方链接中,有Intel相关手册
http://www.doc88.com/p-58541389392.html

INTEL手册的下载连接看这里:
http://biosren.com/thread-92-1-1.html
APIC
部分在第三册A的 CHAPTER 10.

包括:
1Intel® 64 Architecture x2APIC Specification
2Intel® 64 and IA-32 Architectures Application Note
TLBs, Paging-Structure Caches, and Their Invalidation
3Intel® 64 and IA-32 Architectures Software Developer's Manual
Volume 1: Basic Architecture
4Intel® 64 and IA-32 Architectures Software Developer's Manual
Volume 2A: Instruction Set Reference, A-M
5Intel® 64 and IA-32 Architectures Software Developer's Manual
Volume 2B: Instruction Set Reference, N-Z
6Intel® 64 and IA-32 Architectures Software Developer's Manual
Volume 3A: System Programming Guide
7Intel® 64 and IA-32 Architectures Software Developer's Manual
Volume 3B: System Programming Guide
8Intel® 64 and IA-32 Architectures Optimization Reference Manual
9)Intel® SSE4 Programming Reference

http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html

APIC:

Intel APIC由一组中断输入信号,一个24*64bitProgrammable Redirection Table(PRT),一组register和用于从APIC BUS(FSB/QPI)上传送APIC MSG的部件组成,当南桥的IO device通过IOAPICinterrupt lines产生interruptIOAPIC将根据内部的PRT table格式化成中断请求信息,并将该信息发送给目标CPULAPIC,再由LAPIC通知CPU进行处理。下图是一个基于Intel APIC的连接示意图,如下图所示IOAPIC上有24interrupt pin,每一个pin都对应一个RTE,所以针对每一个interrupt pin都可以单独设定它的mask,触发方式(level edge trigger),中断管脚的极性,传送方式,传送状态,目的地,中断向量等。

Programmable Redirection Table详细格式如下所示: 

Bit Description:

[63:56] Destination Field—R/W.  If the Destination Mode of this entry is Physical Mode (bit 11=0), bits[59:56] contain an APIC ID. If Logical Mode is selected (bit 11=1), the Destination Field potentially defines a set of processors. Bits [63:56] of the Destination Field specify the logical destination address.

Destination Mode IOREDTBLx[11] Logical Destination Address

0, Physical Mode IOREDTBLx[59:56] = APIC ID

1, Logical Mode IOREDTBLx[63:56] = Set of processors
 
[55:17] Reserved.82093AA (IOAPIC)
 
[16] Interrupt Mask—R/W.  When this bit is 1, the interrupt signal is masked. Edge-sensitive interrupts signaled on a masked interrupt pin are ignored (i.e., not delivered or held pending).

Level-asserts or negates occurring on a masked level-sensitive pin are also ignored and have no side effects. Changing the mask bit from unmasked to masked after the interrupt is accepted by a local APIC has no effect on that interrupt. This behavior is identical to the case where the device withdraws the interrupt before that interrupt is posted to the processor. It is software's responsibility to handle the case where the mask bit is set after the interrupt message has been accepted by a local APIC unit but before the interrupt is dispensed to the processor. When this bit is 0, the interrupt is not masked. An edge or level on an interrupt pin that is not masked results in the delivery of the interrupt to the destination.
 
[15] Trigger Mode—R/W.  The trigger mode field indicates the type of signal on the interrupt pin that triggers an interrupt. 1=Level sensitive, 0=Edge sensitive.
 
[14] Remote IRR—RO.  This bit is used for level triggered interrupts. Its meaning is undefined for edge triggered interrupts. For level triggered interrupts, this bit is set to 1 when local APIC(s) accept the level interrupt sent by the IOAPIC. The Remote IRR bit is set to 0 when an EOI message with a matching interrupt vector is received from a local APIC.
 
[13] Interrupt Input Pin Polarity (INTPOL)—R/W.  This bit specifies the polarity of the interrupt signal. 0=High active, 1=Low active.
 
[12] Delivery Status (DELIVS)—RO.  The Delivery Status bit contains the current status of the delivery of this interrupt. Delivery Status is read-only and writes to this bit (as part of a 32 bit word) do not effect this bit. 0=IDLE (there is currently no activity for this interrupt). 1=Send Pending (the interrupt has been injected but its delivery is temporarily held up due to the APIC bus being busy or the inability of the receiving APIC unit to accept that interrupt at that time).
 
[11] Destination Mode (DESTMOD)—R/W.  This field determines the interpretation of the Destination field. When DESTMOD=0 (physical mode), a destination APIC is identified by its ID.

Bits 56 through 59 of the Destination field specify the 4 bit APIC ID. When DESTMOD=1 (logical mode), destinations are identified by matching on the logical destination under the control of the Destination Format Register and Logical Destination Register in each Local APIC.

Destination Mode IOREDTBLx[11] Logical Destination Address 0, Physical Mode IOREDTBLx[59:56] = APIC ID1, Logical Mode IOREDTBLx[63:56] = Set of processorsE 82093AA (IOAPIC)
 
[10:8]Delivery Mode (DELMOD)—R/W.  The Delivery Mode is a 3 bit field that specifies how the APICs listed in the destination field should act upon reception of this signal. Note that certain Delivery Modes only operate as intended when used in conjunction with a specific trigger Mode. These restrictions are indicated in the following table for each Delivery Mode.

Mode Description

000       Fixed Deliver the signal on the INTR signal of all processor cores listed in the destination. Trigger Mode for "fixed" Delivery Mode can be edge or level.

001       Lowest

Priority Deliver the signal on the INTR signal of the processor core that is executing at the lowest priority among all the processors listed in the specified destination. Trigger Mode for "lowest priority". Delivery Mode can be edge or level.

010       SMI System Management Interrupt. A delivery mode equal to SMI requires an edge trigger mode. The vector information is ignored but must be programmed to all zeroes for future compatibility.

011       Reserved

100       NMI Deliver the signal on the NMI signal of all processor cores listed in the destination. Vector information is ignored. NMI is treated as an edge triggered interrupt, even if it is programmed as a level triggered interrupt. For proper operation, this redirection table entry must be programmed to “edge” triggered interrupt.

101       INIT Deliver the signal to all processor cores listed in the destination by asserting the INIT signal. All addressed local APICs will assume their INIT state. INIT is always treated as an edge triggered interrupt, even if programmed otherwise. For proper operation, this redirection table entry must be programmed to “edge” triggered interrupt.

110       Reserved

111                ExtINT Deliver the signal to the INTR signal of all processor cores listed in the destination as an interrupt that originated in an externally connected (8259A-compatible) interrupt controller. The INTA cycle that corresponds to this ExtINT delivery is routed to the external controller that is expected to supply the vector. A Delivery Mode of "ExtINT"  requires an edge trigger mode.
 
[7:0] Interrupt Vector (INTVEC)—R/W:  The vector field is an 8 bit field containing the interrupt  vector for this interrupt. Vector values range from 10h to FEh.

APIC

以前看手册的时候没仔细看APIC这部分,最近要用到,所以又看了下。几分钟前刚看完,趁热打铁,把有印象的东西记录一下。免得自己以后忘记,也希望对新手有所帮助。不对的地方也欢迎指正。

正文:
APIC的全写是Advanced Programmable Interrupt Controller,用来管理中断的。注意不要和ACPI(Advanced Configuration and Power Interface电源管理)搞混。APIC的前身是PIC,比如8259A.不过现在已经很少用了。

APIC实际上分成2类。一类叫LOCAL APIC,直接连在PROCESSOR上,每个PROCESSOR一个。还有一类叫I/O APIC,用来管理外设过来的中断,一般一个机器里面就一个(即使是多核系统)。在INTEL IA32手册中讲的是LOCAL APIC,下面说的APIC都是指LOCAL APIC。所谓的LOCAL,应该是相对PROCESSOR而言的,因为离PROCESSOR比较近,所以叫LOCAL.

LOCAL APIC可以处理以下的中断来源:
1)本地相连的I/O设备。比如直接连在LINT0,LINT1管脚上的设备。不过我不知道一般什么样的设备是这么连的。
2)外部的I/O设备。这些设备产生的中断先经过I/O APIC,然后再通过LOCAL APIC到达处理器。
3)Inter-processor interrupts (IPIs) 处理器之间的中断。现在多处理器结构已经很常见了。当一个处理器想中断另外一个的时候,就可以用IPI。
4)APIC定时器中断。APIC上自带了定时器,这个在OS中也是很常用的。
5)Performance monitoring counter interrupts,性能监视计数器中断。看来INTEL还是很替软件开发人员考虑的,直接在硬件上作了个性能监视计数器。
6)温度传感器中断。估计是防止CPU温度过高用的。在PENTIUM 4 AND XEON的处理器上有。
7)APIC内部错误中断。

APIC可以看成是一个独立的硬件,有自己的一堆寄存器,叫做local vector table or LVT。可以进行读写来控制APIC的某些特性和设置。

APIC实际上又可以细分为3个版本。(这里插一句,以前只觉得软件版本特别多,对硬件没啥很深的感触。现在看看INTEL的东西,版本也不少。)最早的P6家族用的是APIC。PENTIUM 4 AND XEON 用的是xAPIC,然后还有个x2APIC。以后不知道是不是再出什么x4APIC OR x8APIC。

检测APIC版本可以用CPUID指令。

在xAPIC模式中,它的寄存器是通过内存映射的方式映射到一段物理地址。有一个默认值。为了防止同其他地址冲突,这个基地址又可以重新指定到另外一个地方。估计BIOS开发人员在对付APIC时会用到这个功能。

在x2APIC模式中,取消了内存映射方式来读取APIC的寄存器,而是采用了MSR的方式。MSR的全写是Model-specific register。也就是每个型号特有的寄存器。这样的好处是不用再担心内存地址的冲突问题。

不同的APIC模式的开启,关闭以及状态切换之间又有一些规则。如果你要自己改这些地方,就要按照规定来。同时注意在x2APIC模式下,写入寄存器的时候不保证顺序,所以要自己小心,比如用个BARRIER之类的。

最后说下MSI(MESSAGE SIGNALLED INTERRUPTS). 在PCI 3.0中已经有了MSI,不过是可选的。到了PCI EXPRESS,这个就变成必须支持的了。实现的方式主要靠2个寄存器:a Message Data Register(MDR) and a Message Address Register(MAR)。当要发送MSI的时候,PCI设备往MAR写一个MDR规定好的数据即可。具体的含义可以看手册。

 

 

1.       可以看系统有多少个中断? 设备管理器,按资源分类,如果有中断号大于15表示是APIC,否则应该是PIC.
2.ASL代码的_PIC(),OS传入的参数,0-PIC 1-APIC, 2-SAPIC ...

这个是要Firmware和OS配合的,现在BIOS一般都支持PIC/APIC,还要看OS的支持程度。

 

IA-32 逻辑地址到线性地址

一、逻辑地址转线性地址

    机器语言指令中出现的内存地址,都是逻辑地址,需要转换成线性地址,再经过MMU(CPU中的内存管理单元)转换成物理地址才能够被访问到。

我们写个最简单的hello world程序,用gcc编译,再反汇编后会看到以下指令:

mov    0x80495b0, %eax

这里的内存地址0x80495b0 就是一个逻辑地址,必须加上隐含的DS 数据段的基地址,才能构成线性地址。也就是说 0x80495b0 是当前任务的DS数据段内的偏移。

x86保护模式下,段的信息(段基线性地址、长度、权限等)即段描述符8个字节,段信息无法直接存放在段寄存器中(段寄存器只有2字节)。Intel的设计是段描述符集中存放在GDTLDT中,而段寄存器存放的是段描述符在GDTLDT内的索引值(index)

Linux中逻辑地址等于线性地址。为什么这么说呢?因为Linux所有的段(用户代码段、用户数据段、内核代码段、内核数据段)的线性地址都是从 0x00000000 开始,长度4G,这样 线性地址=逻辑地址+ 0x00000000,也就是说逻辑地址等于线性地址了。

这样的情况下Linux只用到了GDT,不论是用户任务还是内核任务,都没有用到LDTGDT的第1213项段描述符是 __KERNEL_CS __KERNEL_DS,第1415项段描述符是 __USER_CS __USER_DS。内核任务使用__KERNEL_CS __KERNEL_DS,所有的用户任务共用__USER_CS __USER_DS,也就是说不需要给每个任务再单独分配段描述符。内核段描述符和用户段描述符虽然起始线性地址和长度都一样,但DPL(描述符特权级)是不一样的。__KERNEL_CS __KERNEL_DS DPL值为0(最高特权),__USER_CS __USER_DSDPL值为3

gdb调试程序的时候,用info reg 显示当前寄存器的值:

cs             0x73     115

ss             0x7b     123

ds             0x7b     123

es             0x7b     123

可以看到ds值为0x7b, 转换成二进制为 00000000 01111011TI字段值为0,表示使用GDTGDT索引值为 01111,即十进制15,对应的就是GDT内的__USER_DS用户数据段描述符。

从上面可以看到,Linuxx86的分段机制上运行,却通过一个巧妙的方式绕开了分段。

Linux主要以分页的方式实现内存管理。

二、线性地址转物理地址

前面说了Linux中逻辑地址等于线性地址,那么线性地址怎么对应到物理地址呢?这个大家都知道,那就是通过分页机制,具体的说,就是通过页表查找来对应物理地址。

准确的说分页是CPU提供的一种机制,Linux只是根据这种机制的规则,利用它实现了内存管理。

在保护模式下,控制寄存器CR0的最高位PG位控制着分页管理机制是否生效,如果PG=1,分页机制生效,需通过页表查找才能把线性地址转换物理地址。如果PG=0,则分页机制无效,线性地址就直接做为物理地址。

分页的基本原理是把内存划分成大小固定的若干单元,每个单元称为一页(page),每页包含4k字节的地址空间(为简化分析,我们不考虑扩展分页的情况)。这样每一页的起始地址都是4k字节对齐的。为了能转换成物理地址,我们需要给CPU提供当前任务的线性地址转物理地址的查找表,即页表(page table)。注意,为了实现每个任务的平坦的虚拟内存,每个任务都有自己的页目录表和页表

为了节约页表占用的内存空间,x86将线性地址通过页目录表和页表两级查找转换成物理地址。

32位的线性地址被分成3个部分:

最高10 Directory 页目录表偏移量,中间10 Table是页表偏移量,最低12Offset是物理页内的字节偏移量。

页目录表的大小为4k(刚好是一个页的大小),包含1024项,每个项4字节(32位),项目里存储的内容就是页表的物理地址。如果页目录表中的页表尚未分配,则物理地址填0

页表的大小也是4k,同样包含1024项,每个项4字节,内容为最终物理页的物理内存起始地址。

每个活动的任务,必须要先分配给它一个页目录表,并把页目录表的物理地址存入cr3寄存器。页表可以提前分配好,也可以在用到的时候再分配

还是以 mov    0x80495b0, %eax 中的地址为例分析一下线性地址转物理地址的过程。

前面说到Linux中逻辑地址等于线性地址,那么我们要转换的线性地址就是0x80495b0。转换的过程是由CPU自动完成的,Linux所要做的就是准备好转换所需的页目录表和页表(假设已经准备好,给页目录表和页表分配物理内存的过程很复杂,后面再分析)。

内核先将当前任务的页目录表的物理地址填入cr3寄存器。

线性地址 0x80495b0 转换成二进制后是 0000 1000 0000 0100 1001 0101 1011 0000,最高100000 1000 00的十进制是32CPU查看页目录表第32项,里面存放的是页表的物理地址。线性地址中间1000 0100 1001 的十进制是73,页表的第73项存储的是最终物理页的物理起始地址。物理页基地址加上线性地址中最低12位的偏移量,CPU就找到了线性地址最终对应的物理内存单元。

我们知道Linux中用户进程线性地址能寻址的范围是 3G,那么是不是需要提前先把这3G虚拟内存的页表都建立好呢?一般情况下,物理内存是远远小于3G的,加上同时有很多进程都在运行,根本无法给每个进程提前建立3G的线性地址页表。Linux利用CPU的一个机制解决了这个问题。进程创建后我们可以给页目录表的表项值都填0CPU在查找页表时,如果表项的内容为0,则会引发一个缺页异常,进程暂停执行,Linux内核这时候可以通过一系列复杂的算法给分配一个物理页,并把物理页的地址填入表项中,进程再恢复执行。当然进程在这个过程中是被蒙蔽的,它自己的感觉还是正常访问到了物理内存。