У меня тут проблема , не могу перейти на Ring 3.
Какие условия должны быть выполнены для перехода ?
У меня :
Code segment DPL3
Data segment DPL3
Selector -- пробовал и RPL0 и RPL3
И все равно Ring 0 !
#include <sched.h>
#include <system.h>
#define DWORD unsigned long
#define TYPE_CODE_DESCR 0x18
#define TYPE_DATA_DESCR 0x10
#define TYPE_TSS_DESCR 0x01
#define TYPE_CALL_GATE 0x04
#define TYPE_TASK_GATE 0x85
#define TYPE_INTERRUPT_GATE 0x86
#define TYPE_TRAP_GATE 0x87
#define SEG_WRITABLE 0x02
#define SEG_READABLE 0x02
#define SEG_PRESENT_BIT 0x80
unsigned int t_num=5;
unsigned long g_gdtr[2];
unsigned int sel_init,sel_idle;
extern unsigned long *page_directory;
extern unsigned long *page_table;
extern unsigned long *page_directory2;
typedef void (func_ptr)(void);
#define TSS_SIZE (sizeof(tts))
unsigned long* gdt=(unsigned long*) GDT_MAIN;
unsigned long* gdt_s=(unsigned long*) 0x20000;
struct TSS
{
DWORD back_link;
DWORD ESP0;
DWORD SS0;
DWORD ESP1;
DWORD SS1;
DWORD ESP2;
DWORD SS2;
DWORD CR3;
DWORD EIP;
DWORD EFLAGS;
DWORD EAX;
DWORD ECX;
DWORD EDX;
DWORD EBX;
DWORD ESP;
DWORD EBP;
DWORD ESI;
DWORD EDI;
DWORD ES;
DWORD CS;
DWORD SS;
DWORD DS;
DWORD FS;
DWORD GS;
DWORD LDT;
DWORD offset_andT;
DWORD IOPB;
};
struct TSS* tss;
void gdt_install()
{
gdt[0]=0; // not used
gdt[1]=0;
/*-------------*/
gdt[2]=0x0000FFFF; // code 8
gdt[3]=0x00CF9A00;
/*-------------*/
gdt[4]=0x0000FFFF; // data 10
gdt[5]=0x00CF9200;
/*-------------*/
gdt[6]=((TSS_KERNEL_MAIN<<16)&0xFFFF0000)|((sizeof(struct TSS))&0x0000FFFF); //18
gdt[7]=(TSS_KERNEL_MAIN&0xFF000000)|0x8900|((TSS_KERNEL_MAIN>>16)& 0x000000FF);
/*-------------*/
gdt[8]=0x0025FFFF; // code 20
gdt[9]=0x00CFFA00;
/*-------------*/
gdt[10]=0x0025FFFF; // data 28
gdt[11]=0x00CFF200;
/*-------------*/
//gdt[12]=((TSS_APP<<16)&0xFFFF0000)|((sizeof(struct TSS))&0x0000FFFF); //30
//gdt[13]=(TSS_APP&0xFF000000)|0x8900|((TSS_APP>>16)&0x000000FF);
/*-------------*/
// gdt[14]=((TSS_APP2<<16)&0xFFFF0000)|((sizeof(struct TSS))&0x0000FFFF); //38
// gdt[15]=(TSS_APP2&0xFF000000)|0x8900|((TSS_APP2>>16)&0x000000FF);
// TSS app
g_gdtr[0]=(GDT_MAIN<<16)|0xFFFF;
g_gdtr[1]=(GDT_MAIN>>16)&0xFFFF;
gdt_flush();
asm("lgdt g_gdtr");
//fork();
asm("mov $0x18, %eax\n ltr %ax");
unsigned long* plist=(unsigned long*) 0x30000;
unsigned long* slist=(unsigned long*) 0x35000;
plist[0]=0;
}
extern void init();extern void idle();
extern void mdd();
void v_test(){
put(0xed);
}
void init_TSS()
{
#define TSS_APP (TSS_KERNEL_MAIN+0x1000)
#define TSS_APP2 (TSS_KERNEL_MAIN+0x3000)
sel_idle=new_kthread(210000,0x2000,&idle,0);
//new_kthread(220000,0x2200,&qq2);
//new_kthread(230000,0x2400,&qq2);
//new_kthread(240000,0x2600,&mdd,1);
//new_kthread(250000,0x2800,&qq);
//new_kthread(260000,0x3000,&qq2);
//new_kthread(270000,0x3200,&qq2);
//new_kthread(280000,0x3400,&qq);
//new_kthread(290000,0x3600,&qq);
//new_kthread(300000,0x3800,&qq2);
//new_kthread(310000,0x4000,&qq2);
sel_init=new_kthread(0x250000,0x410000,&init,1);
//set_status(sel_init,1);
//new_kthread(330000,0x4400,&v_test);
/*int sel_;
sel_=tss_add_0_(6,TSS_APP,0x8900);
add_to_plist(sel_,1);
sel_=tss_add_0_(7,TSS_APP2,0x8900);
add_to_plist(sel_,1);
init_TSS_custom_0_(tss,&qq,0x2000);
init_TSS_custom_0_(tss2,&qq2,0x3000);
*/
}
unsigned short int tss_add_0_(int num_,int addr_,int flags_){
unsigned short int selector;
gdt[num_*2]=((addr_<<16)&0xFFFF0000)|((sizeof(struct TSS))&0x0000FFFF); //38
gdt_s[(num_-6)]=(addr_&0xFF000000)|flags_|((addr_>>16)&0x000000FF) ;
selector=num_*0x8;
tss_no_busy(selector);
return selector;
}
void tss_no_busy(int selector){
int num_=selector/0x8;
gdt[(num_*2)+1]=gdt_s[(num_-6)];
}
unsigned int add_to_plist(int selector,int status){
unsigned long* plist=(unsigned long*) 0x30000;
unsigned long* slist=(unsigned long*) 0x35000;
plist[0]++;
plist[plist[0]]=selector;
slist[plist[0]]=status;
return plist[0];
}
void init_TSS_custom_0_(int address,int EIP,int stack_)
{
struct TSS* t=(struct TSS*)address;
t->back_link=0x0;
t->ESP0=0x5000;
t->SS0=0x10;
t->ESP1=0;
t->SS1=0;
t->ESP2=0;
t->SS2=0;
t->EAX=0;
t->ECX=0;
t->EDX=0;
t->EBX=0;
t->EBP=0;
t->ESI=0;
t->EDI=0;
t->EIP=EIP;
t->ESP=stack_;
t->EFLAGS=0x3202;//IF=1
t->ES=0x28|0x3;
t->CS=0x20|0x3;
t->SS=0x28|0x3;
t->DS=0x28|0x3;
t->FS=0x0;
t->GS=0x0;
t->LDT=0;
t->offset_andT=0;
t->IOPB=0xFFFFFFFF;
t->CR3=page_directory2;
}
unsigned int new_kthread(unsigned int tss,unsigned int stack,unsigned int ENTRY,int stat__){
int sel_;
t_num++;
sel_=tss_add_0_(t_num,tss,0x8900);
add_to_plist(sel_,stat__);
init_TSS_custom_0_(tss,ENTRY,stack);
return sel_;
}
int selector2num(int _sel_){
unsigned long* plist=(unsigned long*) 0x30000;
int i_;
for (i_=1;i_<(plist[0]+1);i_++)
if (_sel_==plist[i_])return i_;
return -1;
}
int set_status(int sel_,int stat_){
int num_=selector2num(sel_);
unsigned long* slist=(unsigned long*) 0x35000;
if (num_<0) return -10;
slist[num_]=stat_;
return 10;
}