linux conforming code segment nonconforming code segment

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 JMP
THEN
   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 CPL

TASK-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 .

BitsDescription
0-15first 16 bits of a pointer to a kernel function which need to be invoked when this gate is hit
16-31indicates the index of segment descriptor in GDT (Global Descriptor Table)
32-36these bits are reserved and are not currently used
37-39always 000, not used
40-43specify entry type (its value for interrupt gate is 1110)
44always 0, not used
45-46this specifies the DPL (Descriptor Previlege Level) level of gate entry
47specifies 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


BitsDescription
0-15first 16 bits of a pointer to a kernel function which need to be invoked when this gate is hit
16-31indicates the index of segment descriptor in GDT (Global Descriptor Table)
32-36these bits are reserved and are not currently used
37-39always 000, not used
40-43specify entry type(its value for trap gate is 1111)
44always 0, not used
45-46this specifies the DPL (Descriptor Previlege Level) level of gate entry
47specifies 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的段描述符格式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值