SayoriOS  0.3.3
gdt.c
См. документацию.
1 
9 #include "sys/descriptor_tables.h"
10 #include "lib/string.h"
11 #include "io/ports.h"
12 
13 extern uint32_t init_esp;
14 
15 tss_entry_t tss;
16 
17 extern void gdt_flush(uint32_t);
18 extern void tss_flush(uint32_t tr_selector);
19 
20 gdt_entry_t gdt_entries[6];
21 gdt_ptr_t gdt_ptr;
22 
23 void gdt_set_gate(int32_t num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran){
24  /* Извлекаем нижнюю часть базы адреса (биты 0-15) */
25  gdt_entries[num].base_low = (base & 0xFFFF);
26  /* Извлекаем среднюю часть базы адреса (биты 16-23) */
27  gdt_entries[num].base_middle = (base >> 16) & 0xFF;
28  /* Извлекаем верхнюю часть базы (биты 24-31) */
29  gdt_entries[num].base_high = (base >> 24) & 0xFF;
30  /* Извлекаем нижнюю часть лимита (биты 0-15) */
31  gdt_entries[num].limit_low = (limit & 0xFFFF);
32  /* Granulary - это байт, который мы получаем,
33  сдвинув limit на два байта вправо, при этом
34  верхний полубайт будет содержать флаги (мы
35  учитываем это, когда формируем передавемый
36  в параметрах limit). На первом этапе мы
37  получам верхнюю часть limit */
38  gdt_entries[num].granularity = (limit >> 16) & 0xF;
39  /* Тепер полученные биты объединяем с верхним
40  полубайтом gran. С текущими передаваемыми
41  параметрами, мы приходим к тому, что
42  устанавливаются флаги G и D/B, что дает нам
43  размер страницы в четырехкилобайтовых единицах
44  и 32-двух разрядные смещения при доступе к ней */
45  gdt_entries[num].granularity |= gran & 0xF0;
46  /* Access переписываем без изменений */
47  gdt_entries[num].access = access;
48 }
49 
50 
51 void write_tss(int32_t num, uint32_t ss0, uint32_t esp0){
52  /* очищaем структуру tss */
53  memset(&tss, 0, sizeof(tss_entry_t));
54  /* Селектор сегмента стека (Stack Segment Selector)
55  для уровня привилегий 0 (кольцо 0). */
56  tss.ss0 = ss0;
57  /* Указатель стека для уровня привилегий 0 */
58  tss.esp0 = esp0;
59  /* Селектор сегмента кода */
60  tss.cs = 0x08;
61  /* Селектор сегментов DS, ES, FS, GS */
62  tss.ss = tss.ds = tss.es = tss.fs = tss.gs = 0x10;
63  /* iomap размером в байт и значением запрещающим все */
64  tss.iomap = 0xFF;
65  /* вычисляем адрес iomap */
66  tss.iomap_offset = (uint16_t) ( (uint32_t) &tss.iomap - (uint32_t) &tss );
67  /* база tss */
68  uint32_t base = (uint32_t) &tss;
69  /* limit tss */
70  uint32_t limit = sizeof(tss)-1;
71  /* Заполняем дескриптор TSS в GDT:
72  Создаем указатель на соответствующую запись в GDT для доступа и
73  инициализации отдельных полей дескриптора TSS */
74  tss_descriptor_t* tss_d = (tss_descriptor_t*) &gdt_entries[num];
75  /* Устанавливаем базу и лимит */
76  tss_d->base_15_0 = base & 0xFFFF;
77  tss_d->base_23_16 = (base >> 16) & 0xFF;
78  tss_d->base_31_24 = (base >> 24) & 0xFF;
79  tss_d->limit_15_0 = limit & 0xFFFF;
80  tss_d->limit_19_16 = (limit >> 16) & 0xF;
81  /* Заполняем другие биты */
82  tss_d->present = 1; /* Взводим бит присутствия сегмента */
83  tss_d->sys = 0; /* Это не системный сегмент */
84  tss_d->DPL = 0; /* Уровень привилегий сегмента - уровень ядра */
85  tss_d->type = 9; /* Тип сегмента - свободный 32-битный TSS */
86  tss_d->AVL = 0; /* Всегда ноль */
87  tss_d->allways_zero = 0; /* Всегда ноль */
88  tss_d->gran = 0; /* Бит гранулярности - ноль */
89 }
90 
91 /* Неиспользуется (пока?) */
92 
93 /* void set_kernel_stack_in_tss(uint32_t stack) { */
94 /* tss.esp0 = stack; */
95 /* } */
96 
97 /* uint32_t get_tss_esp0(){ */
98 /* return tss.esp0; */
99 /* } */
100 
101 #define GDT_NUMBER_OF_ELTS 6
102 
103 void init_gdt(void){
104  /* Устанавливается размер GDT в байтах. */
105  gdt_ptr.limit = ( sizeof(gdt_entry_t) * GDT_NUMBER_OF_ELTS ) - 1;
106  /* Устанавливается базовый адрес GDT */
107  gdt_ptr.base = (uint32_t)gdt_entries;
108 
109  /* p:0 dpl:0 s:0(sys)
110  type:0(Запрещенное значение)
111  Нулевой сегмент*/
112  gdt_set_gate(0, 0, 0, 0, 0);
113  /* p:1 dpl:0 s:1(user)
114  type:1010(Сегмент кода для выполнения/чтения)
115  Сегмент кода нулевого кольца */
116  gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
117  /* p:1 dpl:0 s:1(user)
118  type:0010(Сегмент данных для чтения/записи)
119  Сегмент данных нулевого кольца */
120  gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
121  /* p:1 dpl:3 s:1(user)
122  type:1010(Сегмент кода для выполнения/чтения)
123  Сегмент кода третьего кольца */
124  gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF);
125  /* p:1 dpl:3 s:1(user)
126  type:10(Сегмент данных для чтения/записи)
127  Сегмент данных третьего кольца */
128  gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF);
129 
130  /* Мы записываем TSS в последний 5-ый гейт */
131  /* Так как дескриптор стека (и данных) ядра имеет
132  индекс 2 в GDT, то его селектор, с учетом
133  RPL = 0 в GDT будет равен
134  stack_selector = 2*8 | RPL = 16
135  или 0x10 в hex */
136  write_tss(5, 0x10, init_esp);
137  /* Загружаем GDT */
138  gdt_flush( (uint32_t) &gdt_ptr);
139  /* Загружаем TSS
140  Поскольку дескриптор TSS имеет индекс 5 в GDT,
141  то его селектор, с учетом RPL = 0, будет равен
142  tss_selector = 5*8 | RPL = 40, или 0x28 в hes.
143  Именно это значение мы загружаем в TR */
144  tss_flush(0x28);
145 }
146 
147 extern void idt_flush(uint32_t);
148 
149 idt_entry_t idt_entries[256];
150 idt_ptr_t idt_ptr;
151 
152 void idt_set_gate(uint8_t num, uint32_t base, uint16_t selector, uint8_t flags){
153  idt_entries[num].base_low = base & 0xFFFF;
154  idt_entries[num].base_high = (base >> 16) & 0xFFFF;
155  idt_entries[num].selector = selector;
156  idt_entries[num].allways0 = 0;
157  idt_entries[num].flags = flags; /* - для пользовательского режима */
158 }
159 
160 void init_idt(void) {
161  /* Инициализация структуры указателя размером и адресом IDT */
162  idt_ptr.limit = sizeof(idt_entry_t)*256 - 1;
163  idt_ptr.base = (uint32_t)idt_entries;
164  /* Очистка памяти */
165  memset(idt_entries, 0, sizeof(idt_entry_t)*256);
166  /* Инициализация первого PIC и установка режима ICW1
167  (Initialization Command Word 1). */
168  outb(0x20, 0x11);
169  /* Инициализация второго PIC и установка режима ICW1. */
170  outb(0xA0, 0x11);
171  /* Установка базового вектора прерывания для первого PIC (ICW2). */
172  outb(0x21, 0x20);
173  /* Установка базового вектора прерывания для второго PIC (ICW2). */
174  outb(0xA1, 0x28);
175  /* Конфигурация мастер-системы (ICW3 для первого PIC). */
176  outb(0x21, 0x04);
177  /* Конфигурация слейв-системы (ICW3 для второго PIC). */
178  outb(0xA1, 0x02);
179  /* Установка режима работы (ICW4 для первого PIC). */
180  outb(0x21, 0x01);
181  /* Установка режима работы (ICW4 для второго PIC). */
182  outb(0xA1, 0x01);
183  /* Окончательная настройка маски прерываний для первого PIC. */
184  outb(0x21, 0x0);
185  /* Окончательная настройка маски прерываний для второго PIC. */
186  outb(0xA1, 0x0);
187 
188  /* Создание записей в таблице прерываний */
189  idt_set_gate(0, (uint32_t)isr0, 0x08, 0x8E);
190  idt_set_gate(1, (uint32_t)isr1, 0x08, 0x8E);
191  idt_set_gate(2, (uint32_t)isr2, 0x08, 0x8E);
192  idt_set_gate(3, (uint32_t)isr3, 0x08, 0x8E);
193  idt_set_gate(4, (uint32_t)isr4, 0x08, 0x8E);
194  idt_set_gate(5, (uint32_t)isr5, 0x08, 0x8E);
195  idt_set_gate(6, (uint32_t)isr6, 0x08, 0x8E);
196  idt_set_gate(7, (uint32_t)isr7, 0x08, 0x8E);
197  idt_set_gate(8, (uint32_t)isr8, 0x08, 0x8E);
198  idt_set_gate(9, (uint32_t)isr9, 0x08, 0x8E);
199  idt_set_gate(10, (uint32_t)isr10, 0x08, 0x8E);
200  idt_set_gate(11, (uint32_t)isr11, 0x08, 0x8E);
201  idt_set_gate(12, (uint32_t)isr12, 0x08, 0x8E);
202  idt_set_gate(13, (uint32_t)isr13, 0x08, 0x8E);
203  idt_set_gate(14, (uint32_t)isr14, 0x08, 0x8E);
204  idt_set_gate(15, (uint32_t)isr15, 0x08, 0x8E);
205  idt_set_gate(16, (uint32_t)isr16, 0x08, 0x8E);
206  idt_set_gate(17, (uint32_t)isr17, 0x08, 0x8E);
207  idt_set_gate(18, (uint32_t)isr18, 0x08, 0x8E);
208  idt_set_gate(19, (uint32_t)isr19, 0x08, 0x8E);
209  idt_set_gate(20, (uint32_t)isr20, 0x08, 0x8E);
210  idt_set_gate(21, (uint32_t)isr21, 0x08, 0x8E);
211  idt_set_gate(22, (uint32_t)isr22, 0x08, 0x8E);
212  idt_set_gate(23, (uint32_t)isr23, 0x08, 0x8E);
213  idt_set_gate(24, (uint32_t)isr24, 0x08, 0x8E);
214  idt_set_gate(25, (uint32_t)isr25, 0x08, 0x8E);
215  idt_set_gate(26, (uint32_t)isr26, 0x08, 0x8E);
216  idt_set_gate(27, (uint32_t)isr27, 0x08, 0x8E);
217  idt_set_gate(28, (uint32_t)isr28, 0x08, 0x8E);
218  idt_set_gate(29, (uint32_t)isr29, 0x08, 0x8E);
219  idt_set_gate(30, (uint32_t)isr30, 0x08, 0x8E);
220  idt_set_gate(31, (uint32_t)isr31, 0x08, 0x8E);
221  /* IRQs */
222  idt_set_gate(32, (uint32_t)irq0, 0x08, 0x8E);
223  idt_set_gate(33, (uint32_t)irq1, 0x08, 0x8E);
224  idt_set_gate(34, (uint32_t)irq2, 0x08, 0x8E);
225  idt_set_gate(35, (uint32_t)irq3, 0x08, 0x8E);
226  idt_set_gate(36, (uint32_t)irq4, 0x08, 0x8E);
227  idt_set_gate(37, (uint32_t)irq5, 0x08, 0x8E);
228  idt_set_gate(38, (uint32_t)irq6, 0x08, 0x8E);
229  idt_set_gate(39, (uint32_t)irq7, 0x08, 0x8E);
230  idt_set_gate(40, (uint32_t)irq8, 0x08, 0x8E);
231  idt_set_gate(41, (uint32_t)irq9, 0x08, 0x8E);
232  idt_set_gate(42, (uint32_t)irq10, 0x08, 0x8E);
233  idt_set_gate(43, (uint32_t)irq11, 0x08, 0x8E);
234  idt_set_gate(44, (uint32_t)irq12, 0x08, 0x8E);
235  idt_set_gate(45, (uint32_t)irq13, 0x08, 0x8E);
236  idt_set_gate(46, (uint32_t)irq14, 0x08, 0x8E);
237  idt_set_gate(47, (uint32_t)irq15, 0x08, 0x8E);
238  /* System calls */
239  idt_set_gate(0x50, (uint32_t)isr80, 0x08, 0xEF);
240  /* Загружаем */
241  idt_flush((uint32_t) &idt_ptr);
242 }
243 
244 void init_descriptor_tables(void){
245  init_gdt();
246  init_idt();
247 }
void * memset(void *ptr, char value, size_t num)
Заполнение массива указанными символами
Definition: string.c:203