c - Using Task State Segment to handle ring 0 int -


i've been working time on easy os kernel. far i've setup idt 1 int (software). next step try ring 3 of kernel. dane me using 'trick' iret ring switch successful, state of segment register indicate. problems occurred when tried use int $20 switch ring 0 handle interrupt. of course have setup tss able such action. here code: function encodes descriptor (i've enclosed because think can problem encoding)

    void register_descriptor(unsigned entryidx, uint32_t base, uint32_t limit, uint16_t flag)     {         uint64_t descriptor;         descriptor  =  limit       & 0x000f0000;                  descriptor |= (flag <<  8) & 0x00f0ff00;                  descriptor |= (base >> 16) & 0x000000ff;                  descriptor |=  base        & 0xff000000;                  descriptor <<= 32;         descriptor |= base  << 16;                                descriptor |= limit  & 0x0000ffff;                        gdt[entryidx] = descriptor;     } 

tss loading gdt (zerotss() set members of tss struct 0):

static void write_tss(unsigned num, uint16_t ss0, uint32_t esp0) {    register_descriptor(num, (uint32_t) &tss_entry, sizeof(tss_entry), (tss));    zerotss();     tss_entry.ss0  = ss0;     tss_entry.esp0 = esp0;     tss_entry.cs   = 0x18;    tss_entry.ss = tss_entry.ds = tss_entry.es = tss_entry.fs = tss_entry.gs = 0x20; } 

tss flush(my gdt have 6 entries (null+tss+4 segment)):

    .global flush_tss     flush_tss:         mov $0x28, %ax         ltr %ax     ret 

and interupt handler register:

    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 

finally print form bochs:

    [cpu0  ] interrupt(): soft_int && (gate.dpl < cpl)     [cpu0  ] interrupt(): gate descriptor not valid sys seg (vector=0x0d)     [cpu0  ] interrupt(): gate descriptor not valid sys seg (vector=0x08)     [cpu0  ] cpu 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 

i mention before introducing 2 privilege levels interrupt handler working.


Comments

Popular posts from this blog

angularjs - ADAL JS Angular- WebAPI add a new role claim to the token -

php - CakePHP HttpSockets send array of paramms -

node.js - Using Node without global install -