C 使用任务状态段处理环0 int
我已经在easy os内核上工作了一段时间。到目前为止,我已经用一个INT(软件)正确地设置了IDT。 下一步是尝试进入内核的第3环。这是dane,我使用了C 使用任务状态段处理环0 int,c,exception-handling,x86,kernel,low-level,C,Exception Handling,X86,Kernel,Low Level,我已经在easy os内核上工作了一段时间。到目前为止,我已经用一个INT(软件)正确地设置了IDT。 下一步是尝试进入内核的第3环。这是dane,我使用了iret的“技巧”ring switch成功了,因为 段寄存器的状态指示。当我试图使用int$20切换到环0以处理此中断时出现问题。 当然,我已经设置了TSS,以便能够执行此类操作。下面是一些代码: 此函数对描述符进行编码(我将其包含在内,因为我认为这可能是编码的问题) TSS刷新(我的GDT有6个条目(NULL+TSS+4段)): 和中断处
iret的“技巧”
ring switch成功了,因为
段寄存器的状态指示。当我试图使用int$20
切换到环0以处理此中断时出现问题。
当然,我已经设置了TSS,以便能够执行此类操作。下面是一些代码:
此函数对描述符进行编码(我将其包含在内,因为我认为这可能是编码的问题)
TSS刷新(我的GDT有6个条目(NULL+TSS+4段)):
和中断处理程序寄存器:
IDTEntry fillIDTEntry(uint32_t intHandler,
uint16_t selector,
uint8_t type_attr)
{ IDTEntry newEntry;
newEntry.offset_low = LOW_FUN_ADDR(intHandler);
newEntry.selector = selector;
newEntry.zero = 0;
newEntry.type_attr = type_attr;
newEntry.offset_up = UP_FUN_ADDR(intHandler);
return newEntry;
}
extern void _lidt(_IDT_PTR* idtPtr);
void loadIDT()
{
zeroIDT();
_IDT_PTR idtPtr;
idtPtr.idtSize = sizeof(struct __InteruptDescriptorTableEntry)*256 - 1;
idtPtr.idtBaseAddr = (uint32_t) &InteruptDescriptorTable;
IDTEntry printOnScreenInt = fillIDTEntry((uint32_t)interupt_pritnOnScreen, 0x18, 0x8e);
registerInterupt(printOnScreenInt, 32);
_lidt(&idtPtr);
}
.global _lidt
_lidt:
push %ebp
mov %esp,%ebp
mov 8(%esp), %eax
lidt (%eax)
leave
ret
最后打印表格Bochs:
[CPU0 ] interrupt(): soft_int && (gate.dpl < CPL)
[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x0d)
[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x08)
[CPU0 ] CPU is in protected mode (active)
[CPU0 ] CS.mode = 32 bit
[CPU0 ] SS.mode = 32 bit
[CPU0 ] EFER = 0x00000000
[CPU0 ] | EAX=00100d48 EBX=001058b4 ECX=00000720 EDX=001058c2
[CPU0 ] | ESP=0010589c EBP=0010589c ESI=00101000 EDI=00000000
[CPU0 ] | IOPL=0 ID vip vif ac vm RF nt of df if tf sf zf af PF cf
[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
[CPU0 ] | CS:000b( 0001| 0| 3) 00000000 ffffffff 1 1
[CPU0 ] | DS:0013( 0002| 0| 3) 00000000 ffffffff 1 1
[CPU0 ] | SS:0013( 0002| 0| 3) 00000000 ffffffff 1 1
[CPU0 ] | ES:0013( 0002| 0| 3) 00000000 ffffffff 1 1
[CPU0 ] | FS:0013( 0002| 0| 3) 00000000 ffffffff 1 1
[CPU0 ] | GS:0013( 0002| 0| 3) 00000000 ffffffff 1 1
[CPU0 ] | EIP=001008ed (001008ed)
[CPU0 ] | CR0=0x60000011 CR2=0x00000000
[CPU0 ] | CR3=0x00000000 CR4=0x00000000
[CPU0 ] 0x001008ed>> int 0x20 : CD20
[CPU0]中断():soft_int&&(gate.dpl>内部0x20:CD20
在引入两个特权级别之前,我只想提到这个中断处理程序正在工作。IDT项的DPL需要大于或等于CPL,才能不出现异常。真的,就是这样吗?:)是的,我仍然对cpl/dpl/rpl机制有点困惑。现在我被困在传递参数以中断:)好的,进行编辑。我们来看看。
.global flush_tss
flush_tss:
mov $0x28, %ax
ltr %ax
ret
IDTEntry fillIDTEntry(uint32_t intHandler,
uint16_t selector,
uint8_t type_attr)
{ IDTEntry newEntry;
newEntry.offset_low = LOW_FUN_ADDR(intHandler);
newEntry.selector = selector;
newEntry.zero = 0;
newEntry.type_attr = type_attr;
newEntry.offset_up = UP_FUN_ADDR(intHandler);
return newEntry;
}
extern void _lidt(_IDT_PTR* idtPtr);
void loadIDT()
{
zeroIDT();
_IDT_PTR idtPtr;
idtPtr.idtSize = sizeof(struct __InteruptDescriptorTableEntry)*256 - 1;
idtPtr.idtBaseAddr = (uint32_t) &InteruptDescriptorTable;
IDTEntry printOnScreenInt = fillIDTEntry((uint32_t)interupt_pritnOnScreen, 0x18, 0x8e);
registerInterupt(printOnScreenInt, 32);
_lidt(&idtPtr);
}
.global _lidt
_lidt:
push %ebp
mov %esp,%ebp
mov 8(%esp), %eax
lidt (%eax)
leave
ret
[CPU0 ] interrupt(): soft_int && (gate.dpl < CPL)
[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x0d)
[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x08)
[CPU0 ] CPU is in protected mode (active)
[CPU0 ] CS.mode = 32 bit
[CPU0 ] SS.mode = 32 bit
[CPU0 ] EFER = 0x00000000
[CPU0 ] | EAX=00100d48 EBX=001058b4 ECX=00000720 EDX=001058c2
[CPU0 ] | ESP=0010589c EBP=0010589c ESI=00101000 EDI=00000000
[CPU0 ] | IOPL=0 ID vip vif ac vm RF nt of df if tf sf zf af PF cf
[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
[CPU0 ] | CS:000b( 0001| 0| 3) 00000000 ffffffff 1 1
[CPU0 ] | DS:0013( 0002| 0| 3) 00000000 ffffffff 1 1
[CPU0 ] | SS:0013( 0002| 0| 3) 00000000 ffffffff 1 1
[CPU0 ] | ES:0013( 0002| 0| 3) 00000000 ffffffff 1 1
[CPU0 ] | FS:0013( 0002| 0| 3) 00000000 ffffffff 1 1
[CPU0 ] | GS:0013( 0002| 0| 3) 00000000 ffffffff 1 1
[CPU0 ] | EIP=001008ed (001008ed)
[CPU0 ] | CR0=0x60000011 CR2=0x00000000
[CPU0 ] | CR3=0x00000000 CR4=0x00000000
[CPU0 ] 0x001008ed>> int 0x20 : CD20