linux conforming code segment nonconforming code segment

来源:互联网 发布:百度搜索mac 版本 编辑:程序博客网 时间:2024/05/01 12:58

When I read the book linux 内核源代码剖析, I confused by the defination of conforming code segment & nonconforming code segment. I referrenced many website,but I couldn't get a clear answer. The following only stand for my opinion.

When I am researching the demo  in chapter 4.9. There is a timmer interrupt handling function.  Notice the instructinos "ljmp  $TSS1_SEL,$0 and  ljmp $TSS2_SEL,$0".
It presents that cpu will execute a intersegment jump. The following action will be perform by cpu .

IF instruction = relative JMP   (* i.e. operand is rel8, rel16, or rel32 *)THEN   EIP := EIP + rel8/16/32;   IF OperandSize = 16   THEN EIP := EIP AND 0000FFFFH;   FI;FI;IF instruction = near indirect JMP   (* i.e. operand is r/m16 or r/m32 *)THEN   IF OperandSize = 16   THEN      EIP := [r/m16] AND 0000FFFFH;   ELSE (* OperandSize = 32 *)      EIP := [r/m32];   FI;FI;IF (PE = 0 OR (PE = 1 AND VM = 1)) (* real mode or V86 mode *)   AND instruction = far JMP   (* i.e., operand type is m16:16, m16:32, ptr16:16, ptr16:32 *)THEN GOTO REAL-OR-V86-MODE;   IF operand type = m16:16 or m16:32   THEN (* indirect *)      IF OperandSize = 16      THEN         CS:IP := [m16:16];         EIP := EIP AND 0000FFFFH; (* clear upper 16 bits *)      ELSE (* OperandSize = 32 *)         CS:EIP := [m16:32];      FI;   FI;   IF operand type = ptr16:16 or ptr16:32   THEN      IF OperandSize = 16      THEN         CS:IP := ptr16:16;         EIP := EIP AND 0000FFFFH; (* clear upper 16 bits *)      ELSE (* OperandSize = 32 *)         CS:EIP := ptr16:32;      FI;   FI;FI;IF (PE = 1 AND VM = 0) (* Protected mode, not V86 mode *)   AND instruction = far JMPTHEN   IF operand type = m16:16 or m16:32   THEN (* indirect *)      check access of EA dword;      #GP(0) or #SS(0) IF limit violation;   FI;   Destination selector is not null ELSE #GP(0)   Destination selector index is within its descriptor table limits ELSE#GP(selector)   Depending on AR byte of destination descriptor:      GOTO CONFORMING-CODE-SEGMENT;      GOTO NONCONFORMING-CODE-SEGMENT;      GOTO CALL-GATE;      GOTO TASK-GATE;      GOTO TASK-STATE-SEGMENT;   ELSE #GP(selector); (* illegal AR byte in descriptor *)FI;CONFORMING-CODE-SEGMENT:   Descriptor DPL must be <= CPL ELSE #GP(selector);   Segment must be present ELSE #NP(selector);   Instruction pointer must be within code-segment limit ELSE #GP(0);   IF OperandSize = 32   THEN Load CS:EIP from destination pointer;   ELSE Load CS:IP from destination pointer;   FI;   Load CS register with new segment descriptor;NONCONFORMING-CODE-SEGMENT:   RPL of destination selector must be <= CPL ELSE #GP(selector);   Descriptor DPL must be = CPL ELSE #GP(selector);   Segment must be present ELSE # NP(selector);   Instruction pointer must be within code-segment limit ELSE #GP(0);   IF OperandSize = 32   THEN Load CS:EIP from destination pointer;   ELSE Load CS:IP from destination pointer;   FI;   Load CS register with new segment descriptor;   Set RPL field of CS register to CPL;CALL-GATE:   Descriptor DPL must be >= CPL ELSE #GP(gate selector);   Descriptor DPL must be >= gate selector RPL ELSE #GP(gate selector);   Gate must be present ELSE #NP(gate selector);   Examine selector to code segment given in call gate descriptor:      Selector must not be null ELSE #GP(0);      Selector must be within its descriptor table limits ELSE         #GP(CS selector);      Descriptor AR byte must indicate code segment         ELSE #GP(CS selector);      IF non-conforming      THEN code-segment descriptor, DPL must = CPL      ELSE #GP(CS selector);      FI;      IF conforming      THEN code-segment descriptor DPL must be <= CPL;      ELSE #GP(CS selector);      Code segment must be present ELSE #NP(CS selector);      Instruction pointer must be within code-segment limit ELSE #GP(0);      IF OperandSize = 32      THEN Load CS:EIP from call gate;      ELSE Load CS:IP from call gate;      FI;   Load CS register with new code-segment descriptor;   Set RPL of CS to CPLTASK-GATE:   Gate descriptor DPL must be >= CPL ELSE #GP(gate selector);   Gate descriptor DPL must be >= gate selector RPL ELSE #GP(gate     selector);   Task Gate must be present ELSE #NP(gate selector);   Examine selector to TSS, given in Task Gate descriptor:   Must specify global in the local/global bit ELSE #GP(TSS selector);   Index must be within GDT limits ELSE #GP(TSS selector);   Descriptor AR byte must specify available TSS (bottom bits 00001);      ELSE #GP(TSS selector);   Task State Segment must be present ELSE #NP(TSS selector);SWITCH-TASKS (without nesting) to TSS;Instruction pointer must be within code-segment limit ELSE #GP(0);TASK-STATE-SEGMENT:   TSS DPL must be >= CPL ELSE #GP(TSS selector);   TSS DPL must be >= TSS selector RPL ELSE #GP(TSS selector);   Descriptor AR byte must specify available TSS (bottom bits 00001)      ELSE #GP(TSS selector);   Task State Segment must be present ELSE #NP(TSS selector);   SWITCH-TASKS (without nesting) to TSS;   Instruction pointer must be within code-segment limit ELSE #GP(0);


Now you can image that when task0 is executing, then it's cpu slice time is finished.It must be generate an  timer interrupt. The register of  EIP,CS,Flags will be sotre in the kernel stack.Remeber that the CPL will not be change,because the interrupt gate descriptor in the  interrupt vector table indicate the timer_interrupt function is a conforming code segment. It's easy to find that the format of the trap gate ,interrupt gate .

BitsDescription0-15first 16 bits of a pointer to a kernel function which need to be invoked when this gate is hit16-31indicates the index of segment descriptor in GDT (Global Descriptor Table)32-36these bits are reserved and are not currently used37-39always 000, not used40-43specify entry type (its value for interrupt gate is 1110)44always 0, not used45-46this specifies the DPL (Descriptor Previlege Level) level of gate entry47specifies if this entry is valid or not (1 - valid, 0 - invalid)48-63last 16 bits of a pointer to a kernel function which need to be invoked when this gate is hit

BitsDescription0-15first 16 bits of a pointer to a kernel function which need to be invoked when this gate is hit16-31indicates the index of segment descriptor in GDT (Global Descriptor Table)32-36these bits are reserved and are not currently used37-39always 000, not used40-43specify entry type(its value for trap gate is 1111)44always 0, not used45-46this specifies the DPL (Descriptor Previlege Level) level of gate entry47specifies if this entry is valid or not (1 - valid, 0 - invalid)48-63last 16 bits of a pointer to a kernel function which need to be invoked when this gate is hit
The type fields value are 1110(trap gate)  and 1111(interrupt gate). The following is the segment descriptor format.

                           DATA SEGMENT DESCRIPTOR  31                23                15                7               0 +-----------------+-+-+-+-+---------+-+-----+---------+-----------------+ |#################|#|#|#|A| LIMIT   |#|     |  TYPE   |#################| |###BASE 31..24###|G|B|0|V| 19..16  |P| DPL |         |###BASE 23..16###| 4 |#################|#|#|#|L|         |#|     |1|0|E|W|A|#################| |-----------------+-+-+-+-+---------+-+-----+-+-+-+-+-+-----------------| |###################################|                                   | |########SEGMENT BASE 15..0#########|        SEGMENT LIMIT 15..0        | 0 |###################################|                                   | +-----------------+-----------------+-----------------+-----------------+                        EXECUTABLE SEGMENT DESCRIPTOR  31                23                15                7               0 +-----------------+-+-+-+-+---------+-+-----+---------+-----------------+ |#################|#|#|#|A| LIMIT   |#|     |  TYPE   |#################| |###BASE 31..24###|G|D|0|V| 19..16  |P| DPL |         |###BASE 23..16###| 4 |#################|#|#|#|L|         |#|     |1|0|C|R|A|#################| |-----------------+-+-+-+-+---------+-+-----+-+-+-+-+-+-----------------| |###################################|                                   | |########SEGMENT BASE 15..0#########|        SEGMENT LIMIT 15..0        | 0 |###################################|                                   | +-----------------+-----------------+-----------------+-----------------+                         SYSTEM SEGMENT DESCRIPTOR  31                23                15                7               0 +-----------------+-+-+-+-+---------+-+-----+-+-------+-----------------+ |#################|#|#|#|A| LIMIT   |#|     | |       |#################| |###BASE 31..24###|G|X|0|V| 19..16  |P| DPL |0| TYPE  |###BASE 23..16###| 4 |#################|#|#|#|L|         |#|     | |       |#################| |-----------------+-+-+-+-+---------+-+-----+-+-------+-----------------| |###################################|                                   | |########SEGMENT BASE 15..0#########|       SEGMENT LIMIT 15..0         | 0 |###################################|                                   | +-----------------+-----------------+-----------------+-----------------+        A   - ACCESSED                              E   - EXPAND-DOWN        AVL - AVAILABLE FOR PROGRAMMERS USE         G   - GRANULARITY        B   - BIG                                   P   - SEGMENT PRESENT        C   - CONFORMING                            R   - READABLE        D   - DEFAULT                               W   - WRITABLE        DPL - DESCRIPTOR PRIVILEGE LEVEL

There are five bits in data segment descriptor and executable segment descriptor,and the first bit is 1 in both ,it means this is the user-define descriptor ,but four bits in system segment descriptor,and it's left bit is 0.

I infer the second bit of the type meaning is Conforming code segment.

Section 2

.quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */
00对应的是基址:16-23位
c对应的是G位,D/B位,0(系统默认) AVL(系统软件可用位)
f对应的是段限长的第16-19位
9对应的是:P|DPL|S 第一位表示P,P=1表示段在内在中, 第二三位表示DPL,DPL=00表示运行在系统0级,第四位表示S,s=0表示该段为系统段。 
a对应的是type字段:1100表示一致性代码段
00对应的是基址24-31位
0000对应的是基址0-15位
ffff对应的是段限长

但是以下写法要注意:

.word  0x68,tss0,0xe900,0x,0    #TSS0的段描述符格式

原创粉丝点击