Защищенный режим процессоров Intel


Пример мультизадачного монитора - часть 2


С помощью функции с названием Init_And_Protected_Mode_Entry() мы попадаем в защищённый режим и выводим сообщение на экран о том, что в главной задаче установлен защищённый режим. Регистр TR загружается селектором главной задачи при помощи функции load_task_register().

Сразу после этого программа переключается на выполнение задачи TASK_1. Эта задача просто выводит сообщение о своём запуске на экран и возвращает управление главной задаче. Цель этой процедуры - продемонстрировать процесс переключения задач с помощью команды JMP.

После возврата в главную задачу программа размаскирует прерывания от клавиатуры и таймера. Как только начинают поступать и обрабатываться прерывания таймера, оживают остальные задачи, определённые при инициализации системы.

Начиная с этого момента главная задача разделяет процессорное время наравне с остальными задачами. Что же она делает?

Главная задача сбрасывает семафор с номером 0, вслед за чем ожидает его установку. Этот семафор устанавливается задачей, которая занимается вводом символов с клавиатуры и выводит на экран скан-коды клавиш, а также состояние переключающих клавиш. Как только окажется нажатой клавиша ESC, задача ввода символов с клавиатуры устанавливает семафор 0, что и приводит к завершению работы главной задачи.

Перед тем, как завершить работу, главная задача устанавливает реальный режим работы процессора, стирает экран и возвращает управление операционной системе.

Листинг 6. Программа мультизадачного монитора. Файл tos.c ----------------------------------------------------------- #include <stdio.h> #include <stdlib.h> #include <dos.h> #include <conio.h> #include "tos.h" // -------------------------------- // Определения вызываемых функций // -------------------------------- void Init_And_Protected_Mode_Entry(void); void protected_mode(unsigned long gdt_ptr, unsigned int gdt_size, word cseg, word dseg); word load_task_register(word tss_selector); void real_mode(void); void jump_to_task(word tss_selector); void load_idtr(unsigned long idt_ptr, word idt_size); void Keyb_int(void); void Timer_int(void); void Int_30h_Entry(void); extern word kb_getch(void); void enable_interrupt(void); void task1(void); void task2(void); void flipflop_task(void); void keyb_task(void); void init_tss(tss *t, word cs, word ds, unsigned char *sp, func_ptr ip); void init_gdt_descriptor(descriptor *descr, unsigned long base, word limit, unsigned char type); void exception_0(void); //{ prg_abort(0); } void exception_1(void); //{ prg_abort(1); } void exception_2(void); //{ prg_abort(2); } void exception_3(void); //{ prg_abort(3); } void exception_4(void); //{ prg_abort(4); } void exception_5(void); //{ prg_abort(5); } void exception_6(void); //{ prg_abort(6); } void exception_7(void); //{ prg_abort(7); } void exception_8(void); //{ prg_abort(8); } void exception_9(void); //{ prg_abort(9); } void exception_A(void); //{ prg_abort(0xA); } void exception_B(void); //{ prg_abort(0xB); } void exception_C(void); //{ prg_abort(0xC); } void exception_D(void); //{ prg_abort(0xD); } void exception_E(void); //{ prg_abort(0xE); } void exception_F(void); //{ prg_abort(0xF); } void exception_10(void); //{ prg_abort(0x10); } void exception_11(void); //{ prg_abort(0x11); } void exception_12(void); //{ prg_abort(0x12); } void exception_13(void); //{ prg_abort(0x13); } void exception_14(void); //{ prg_abort(0x14); } void exception_15(void); //{ prg_abort(0x15); } void exception_16(void); //{ prg_abort(0x16); } void exception_17(void); //{ prg_abort(0x17); } void exception_18(void); //{ prg_abort(0x18); } void exception_19(void); //{ prg_abort(0x19); } void exception_1A(void); //{ prg_abort(0x1A); } void exception_1B(void); //{ prg_abort(0x1B); } void exception_1C(void); //{ prg_abort(0x1C); } void exception_1D(void); //{ prg_abort(0x1D); } void exception_1E(void); //{ prg_abort(0x1E); } void exception_1F(void); //{ prg_abort(0x1F); } void iret0(void); void iret1(void); // -------------------------------------- // Глобальная таблица дескрипторов GDT // -------------------------------------- descriptor gdt[11]; // -------------------------------------- // Дескрипторная таблица прерываний IDT // -------------------------------------- gate idt[] = { // Обработчики исключений { (word)&exception_0, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 0 { (word)&exception_1, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 1 { (word)&exception_2, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 2 { (word)&exception_3, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 3 { (word)&exception_4, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 4 { (word)&exception_5, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 5 { (word)&exception_6, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 6 { (word)&exception_7, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 7 { (word)&exception_8, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 8 { (word)&exception_9, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 9 { (word)&exception_A, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // A { (word)&exception_B, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // B { (word)&exception_C, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // C { (word)&exception_D, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // D { (word)&exception_E, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // E { (word)&exception_F, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // F { (word)&exception_10, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 10 { (word)&exception_11, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 11 { (word)&exception_12, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 12 { (word)&exception_13, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 13 { (word)&exception_14, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 14 { (word)&exception_15, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 15 { (word)&exception_16, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 16 { (word)&exception_17, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 17 { (word)&exception_18, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 18 { (word)&exception_19, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 19 { (word)&exception_1A, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 1A { (word)&exception_1B, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 1B { (word)&exception_1C, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 1C { (word)&exception_1D, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 1D { (word)&exception_1E, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 1E { (word)&exception_1F, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 1F // Обработчик прерываний таймера { (word)&Timer_int, CODE_SELECTOR, 0, TYPE_INTERRUPT_GATE, 0 }, // 20 // Вентиль задачи, запускающейся по прерыванию от клавиатуры { 0, KEYB_TASK_SELECTOR, 0, TYPE_TASK_GATE, 0 }, // 21 // Заглушки для остальных аппаратных прерываний { (word)&iret0, CODE_SELECTOR, 0, TYPE_INTERRUPT_GATE, 0 }, // 22 { (word)&iret0, CODE_SELECTOR, 0, TYPE_INTERRUPT_GATE, 0 }, // 23 { (word)&iret0, CODE_SELECTOR, 0, TYPE_INTERRUPT_GATE, 0 }, // 24 { (word)&iret0, CODE_SELECTOR, 0, TYPE_INTERRUPT_GATE, 0 }, // 25 { (word)&iret0, CODE_SELECTOR, 0, TYPE_INTERRUPT_GATE, 0 }, // 26 { (word)&iret0, CODE_SELECTOR, 0, TYPE_INTERRUPT_GATE, 0 }, // 27 { (word)&iret1, CODE_SELECTOR, 0, TYPE_INTERRUPT_GATE, 0 }, // 28 { (word)&iret1, CODE_SELECTOR, 0, TYPE_INTERRUPT_GATE, 0 }, // 29 { (word)&iret1, CODE_SELECTOR, 0, TYPE_INTERRUPT_GATE, 0 }, // 2A { (word)&iret1, CODE_SELECTOR, 0, TYPE_INTERRUPT_GATE, 0 }, // 2B { (word)&iret1, CODE_SELECTOR, 0, TYPE_INTERRUPT_GATE, 0 }, // 2C { (word)&iret1, CODE_SELECTOR, 0, TYPE_INTERRUPT_GATE, 0 }, // 2D { (word)&iret1, CODE_SELECTOR, 0, TYPE_INTERRUPT_GATE, 0 }, // 2E { (word)&iret1, CODE_SELECTOR, 0, TYPE_INTERRUPT_GATE, 0 }, // 2F // Обработчик для программного прерывания, которое // используется для ввода с клавиатуры { (word)&Int_30h_Entry, CODE_SELECTOR, 0, TYPE_INTERRUPT_GATE, 0 }, // 30 // Вентиль задачи FLIP_TASK { 0, FLIP_TASK_SELECTOR, 0, TYPE_TASK_GATE, 0 } // 31 }; // ------------------------------------------- // Сегменты TSS для различных задач // ------------------------------------------- tss main_tss; // TSS главной задачи tss task_1_tss; // TSS задачи TASK_1 tss task_2_tss; // TSS задачи TASK_2 tss keyb_task_tss; // TSS задач обслуживания tss keyb_tss; // клавиатуры tss flipflop_tss; // TSS задачи FLIP_TASK // ------------------------------------------- // Стеки для задач // ------------------------------------------- unsigned char task_1_stack[1024]; unsigned char task_2_stack[1024]; unsigned char keyb_task_stack[1024]; unsigned char keyb_stack[1024]; unsigned char flipflop_stack[1024]; word y=0; // номер текущей строки для вывода на экран // ------------------------------------------- // Начало программы // ------------------------------------------- void main(void) { // Стираем экран textcolor(BLACK); textbackground(LIGHTGRAY); clrscr(); // Входим в защищённый режим Init_And_Protected_Mode_Entry(); // Выводим сообщение vi_hello_msg(); y=3; vi_print(0, y++, " Установлен защищённый режим в главной задаче", 0x7f); // Загружаем регистр TR селектором главной задачи // т.е.


Начало  Назад  Вперед