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


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


задачи main() load_task_register(MAIN_TASK_SELECTOR); // Переключаемся на задачу TASK_1 jump_to_task(TASK_1_SELECTOR); // После возврата в главную задачу выдаём сообщение vi_print(0, y++ ," Вернулись в главную задачу", 0x7f); y++; // Запускаем планировщик задач vi_print(0, y++ ," Запущен планировщик задач", 0x70); enable_interrupt(); // разрешаем прерывание таймера // Ожидаем установки семафора с номером 0. После того, // как этот семафор окажется установлен, возвращаемся // в реальный режим. // Семафор 0 устанавливается задачей, обрабатывающей ввод с // клавиатуры, которая работает независимо от // главной задаче. vi_print(0, y++ ," Для возврата в реальный режим нажмите ESC", 0x70); sem_clear(0); // сброс семафора 0 sem_wait(0); // ожидание установки семафора 0 // Возврат в реальный режим, стирание экрана и // передача управления MS-DOS real_mode(); textcolor(WHITE); textbackground(BLACK); clrscr(); } // ----------------------------------- // Функция инициализации сегмента TSS // ----------------------------------- void init_tss(tss *t, word cs, word ds, unsigned char *sp, func_ptr ip) { t->cs = cs; // селектор сегмента кода t->ds = ds; // поля ds, es, ss устанавливаем t->es = ds; // на сегмент данных t->ss = ds; t->ip = (word)ip; // указатель команд t->sp = (word)sp; // смещение стека t->bp = (word)sp; } // ------------------------------------------------- // Функция инициализации дескриптора в таблице GDT // ------------------------------------------------- void init_gdt_descriptor(descriptor *descr, unsigned long base, word limit, unsigned char type) { // Младшее слово базового адреса descr->base_lo = (word)base; // Старший байт базового адреса descr->base_hi = (unsigned char)(base >> 16); // Поле доступа дескриптора descr->type_dpl = type; // Предел descr->limit = limit; // Зарезервированное поле, должно быть // сброшено в 0 descr->reserved = 0; } // ----------------------------------------------- // Инициализация всех таблиц и вход // в защищённый режим // ----------------------------------------------- void Init_And_Protected_Mode_Entry(void) { union REGS r; // Инициализируем таблицу GDT, элементы с 1 по 5 init_gdt_descriptor(&gdt[1], MK_LIN_ADDR(_CS, 0), 0xffffL, TYPE_CODE_DESCR | SEG_PRESENT_BIT | SEG_READABLE); init_gdt_descriptor(&gdt[2], MK_LIN_ADDR(_DS, 0), 0xffffL, TYPE_DATA_DESCR | SEG_PRESENT_BIT | SEG_WRITABLE); init_gdt_descriptor(&gdt[3], MK_LIN_ADDR(_DS, &task_1_tss), (unsigned long)TSS_SIZE-1, TYPE_TSS_DESCR | SEG_PRESENT_BIT); init_gdt_descriptor(&gdt[4], MK_LIN_ADDR(_DS, &task_2_tss), (unsigned long)TSS_SIZE-1, TYPE_TSS_DESCR | SEG_PRESENT_BIT); init_gdt_descriptor(&gdt[5], MK_LIN_ADDR(_DS, &main_tss), (unsigned long)TSS_SIZE-1, TYPE_TSS_DESCR | SEG_PRESENT_BIT); // Инициализируем TSS для задач TASK_1, TASK_2 init_tss(&task_1_tss, CODE_SELECTOR, DATA_SELECTOR, task_1_stack+ sizeof(task_1_stack), task1); init_tss(&task_2_tss, CODE_SELECTOR, DATA_SELECTOR, task_2_stack+ sizeof(task_2_stack), task2); // Инициализируем элемент 6 таблицы GDT - // дескриптор для сегмента видеопамяти // Определяем видеорежим r.h.ah=15; int86(0x10,&r,&r); // Инициализация для монохромного режима if(r.h.al==MONO_MODE) init_gdt_descriptor(&gdt[6], MONO_VID_MEM, 3999, TYPE_DATA_DESCR | SEG_PRESENT_BIT | SEG_WRITABLE); // Инициализация для цветного режима else if(r.h.al == BW_80_MODE r.h.al == COLOR_80_MODE) init_gdt_descriptor(&gdt[6], COLOR_VID_MEM, 3999, TYPE_DATA_DESCR | SEG_PRESENT_BIT | SEG_WRITABLE); else { printf("\nИзвините, этот видеорежим недопустим."); exit(-1); } // Инициализация элементов 7 и 8 таблицы GDT init_gdt_descriptor(&gdt[7], MK_LIN_ADDR(_DS, &idt), (unsigned long)IDT_SIZE-1, TYPE_DATA_DESCR | SEG_PRESENT_BIT | SEG_WRITABLE); init_gdt_descriptor(&gdt[8], MK_LIN_ADDR(_DS, &keyb_task_tss), (unsigned long)TSS_SIZE-1, TYPE_TSS_DESCR | SEG_PRESENT_BIT); // Инициализация TSS для задачи KEYB_TASK init_tss(&keyb_task_tss, CODE_SELECTOR, DATA_SELECTOR, keyb_task_stack + sizeof(keyb_task_stack), keyb_task); // Инициализация элемента 9 таблицы GDT init_gdt_descriptor(&gdt[9], MK_LIN_ADDR(_DS, &keyb_tss), (unsigned long)TSS_SIZE-1, TYPE_TSS_DESCR | SEG_PRESENT_BIT); // Инициализация TSS для задачи KEYB обработки ввода с клавиатуры init_tss(&keyb_tss, CODE_SELECTOR, DATA_SELECTOR, keyb_stack + sizeof(keyb_stack), Keyb_int); // Инициализация элемента 10 таблицы GDT init_gdt_descriptor(&gdt[10], MK_LIN_ADDR(_DS, &flipflop_tss), (unsigned long)TSS_SIZE-1, TYPE_TSS_DESCR | SEG_PRESENT_BIT); // Инициализация TSS для задачи FLIP_TASK init_tss(&flipflop_tss, CODE_SELECTOR, DATA_SELECTOR, flipflop_stack + sizeof(flipflop_stack), flipflop_task); // Загрузка регистра IDTR load_idtr(MK_LIN_ADDR(_DS, &idt), IDT_SIZE); // Вход в защищённый режим protected_mode(MK_LIN_ADDR(_DS, &gdt), sizeof(gdt), CODE_SELECTOR, DATA_SELECTOR); }

Файл tasks.c содержит тексты программ, которые будут работать в режиме разделения времени (кроме задачи TASK_1, эта задача запускается только один раз).




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