00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "src/common/shared.hpp"
00019 #include "src/arch/x86/gdt.hpp"
00020
00021 namespace Arch {
00022 namespace x86 {
00023 namespace GDT {
00024
00025
00026
00027 gdt_t kernel_gdt;
00028
00029
00030 void init()
00031 {
00032 gdt_t *ptr = &kernel_gdt;
00033 ptr->init();
00034
00035 code_sel_kernel = ptr -> new_sel(0xFFFFF, 0, 0x9A, 0xc0);
00036 data_sel_kernel = ptr -> new_sel(0xFFFFF, 0, 0x92, 0xc0);
00037 code_sel_user = ptr -> new_sel(0xBFFFF, 0, 0xFA, 0xc0)+3;
00038
00039 data_sel_user = ptr -> new_sel(0xBFFFF, 0, 0xF2, 0xc0)+3;
00040
00041 tss_sel_kernel = ptr -> new_sel(103, (uint32) &kernel_tss, 0x89, 0x0);
00042 tss_sel_kernel_df = ptr -> new_sel(103, (uint32) &kernel_tss_df, 0x89, 0x0);
00043 tss_sel_kernel_sf = ptr -> new_sel(103, (uint32) &kernel_tss_sf, 0x89, 0x0);
00044
00045
00046 ptr -> lgdt();
00047
00048
00049 __asm__ __volatile__ ("ltr %%ax" : : "a" (tss_sel_kernel) );
00050 kernel_tss.ss0 = data_sel_kernel;
00051 kernel_tss.esp0 = (uint32) &temp_tss_stack+0x100;
00052
00053
00054 kernel_tss_sf.ss=kernel_tss_df.ss=data_sel_kernel;
00055 kernel_tss_sf.esp=kernel_tss_df.esp= (uint32) &temp_tss_stack+0x100;
00056 kernel_tss_sf.cs=kernel_tss_df.cs = code_sel_kernel;
00057 kernel_tss_sf.ds=kernel_tss_df.ds = data_sel_kernel;
00058 kernel_tss_sf.es=kernel_tss_df.es = data_sel_kernel;
00059 kernel_tss_sf.fs=kernel_tss_df.fs = data_sel_kernel;
00060 kernel_tss_sf.gs=kernel_tss_df.gs = data_sel_kernel;
00061 kernel_tss_sf.eflags=kernel_tss_df.eflags = 0;
00062 asm volatile ("mov %%cr3, %%eax" :"=a" (kernel_tss_df.cr3));
00063 asm volatile ("mov %%cr3, %%eax" :"=a" (kernel_tss_sf.cr3));
00064 }
00065
00066
00067 uint32 code_sel_kernel = 0;
00068 uint32 data_sel_kernel = 0;
00069 uint32 code_sel_user = 0;
00070 uint32 data_sel_user = 0;
00071 uint32 tss_sel_kernel = 0;
00072 uint32 tss_sel_kernel_df;
00073 uint32 tss_sel_kernel_sf;
00074
00075
00076 tss_t kernel_tss;
00077 tss_t kernel_tss_df;
00078 tss_t kernel_tss_sf;
00079 char temp_tss_stack[0x100];
00080
00081
00082 void gdt_t::init()
00083 {
00084 gdtr.s_limit=7;
00085 gdtr.s_base = gdt;
00086 segm_count = 0;
00087 }
00088
00089
00090 short gdt_t::new_sel(int limit, int base, char attr, char flags)
00091 {
00092 union
00093 {
00094 long l;
00095 short s[2];
00096 char c[4];
00097 } uu;
00098
00099 segm_count++;
00100
00101 if ((uint32)segm_count+1 >= DEF_MAXSEGMS) return -1;
00102
00103 uu.l = base;
00104 gdt[segm_count].s_base0_15 = uu.s[0];
00105 gdt[segm_count].s_base16_23 = uu.c[2];
00106 gdt[segm_count].s_base24_31 = uu.c[3];
00107
00108 uu.l = limit;
00109 gdt[segm_count].s_limit0_15 = uu.s[0];
00110 gdt[segm_count].s_limit16_19 = uu.c[2] + flags;
00111
00112 gdt[segm_count].s_attr = attr;
00113
00114 gdtr.s_limit+=8;
00115
00116 return segm_count * 8;
00117 }
00118
00119
00120 void gdt_t::lgdt()
00121 {
00122 __asm__ __volatile__ ("lgdt (%%ebx)": : "b" ((long) &gdtr) );
00123 __asm__ __volatile__ (
00124 ".byte 0xea\n"
00125 ".int reload_cs\n"
00126 ".short 0x8\n"
00127 "reload_cs:\n"
00128 "mov $0x10, %ax\n"
00129 "mov %ax, %ss\n"
00130 "mov %ax, %ds\n"
00131 "mov %ax, %es\n"
00132 "mov %ax, %fs\n"
00133 "mov %ax, %gs\n"
00134 );
00135 }
00136
00137
00138 };
00139 };
00140 };
00141
00142
00143
00144
00145
00146
00147