
- •Операционные системы. Часть 2 Учебное пособие
- •Содержание
- •6.1.1. Общие понятия 58
- •4.Память
- •4.1.Управление оперативной памятью
- •4.1.1.Виртуальная и физическая память
- •4.1.2.Схема управления памятью
- •4.1.3.Управление памятью в однозадачной системе
- •4.1.4.Управление памятью в многозадачной системе
- •4.1.5.Подкачка процессов целиком
- •4.1.6.Страничная подкачка
- •4.1.7.Управление виртуальной памятью
- •4.2.Носители памяти для долговременного хранения данных
- •4.2.1.Накопители на жестких дисках
- •4.2.2.Оптические диски
- •4.2.3.Голографические диски
- •4.2.4.Флэш-память
- •4.2.5.Перспективные носители информации
- •Контрольные вопросы
- •5.Разработка надстроек к операционным системам
- •5.1.Общие понятия
- •5.2.Многозадачная оболочка с синхронной заменой контекста
- •5.3.Многозадачная система с принудительной заменой контекста
- •5.4.Дополнения к асинхронной надстройке
- •Контрольные вопросы
- •6.Краткий обзор операционных систем
- •6.1. Операционная система unix
- •6.1.1.Общие понятия
- •6.1.2. Структура unix
- •6.2.Операционные системы реального времени
- •6.2.1.Понятие об операционной системе qnx
- •6.2.2.Введение в ос VX Works
- •6.3.Особенности ос для универсальных многопроцессорных систем
- •6.3.1.Операционная система helios
- •6.4.Операционная система Windows 2000
- •Варианты выпуска Windows 2000
- •Контрольные вопросы
- •Литература
- •Предметный указатель
5.3.Многозадачная система с принудительной заменой контекста
Нужно обладать большим воображением, чтобы найти область практического применения для представленной в предыдущем разделе многозадачной надстройки. Видимо, больше возможностей в этом плане может быть у системы с принудительной заменой контекста. Очевидно, что функция Создание нового процесса, назначение которой выделение памяти под контекст и записи в него адреса начала процесса, может быть написана в том формате. Такой же вывод в отношении функции Переключатель контекста не так очевиден, так как при асинхронном замещении контекста возникают проблемы с запоминанием точки «замораживания» процесса, отдающего управление системой. Немного подумав, можно придти к выводу, что единственная возможность принудительного переключения процесса – это осуществить её из обработчика аппаратного прерывания (чаще всего из обработчика прерывания по таймеру), что требует существенной перестройки процедуры переключения контекста. В действительности эту функцию, разработанную для оболочки с синхронной заменой контекста, в том же формате можно применить для принудительного замещения контекста. Разберёмся в этой ситуации подробнее.
В однопроцессорной системе в конце каждого тика таймером инициализируется аппаратное прерывание. В начале обработчика прерывания запоминаются в специальном системном стеке значения регистров, совокупностью которых вполне определяется контекст выполняемой задачи в точке «замораживания». Далее изменяется показание часов, восстанавливаются прежние значения регистров и управление обратно передается процессу (Рис. 5 .15а).
Рис. 5.15. Использование процессорного времени при запоминании контекста
Допустим, что удалось перестроить обработчик прерывания по таймеру таким образом, что в момент аппаратного прерывания Процесса 1 (см. Рис. 5 .15б) в нем вызывается макрос _Trancfer macro des1,des2, который в синхронной оболочке переключал бы с Процесса 1 на Процесс 2. Если Процесс 2 вызывается в первый раз, то он начнет выполняться сначала. Отличие от работы этого переключателя в синхронной оболочке заключается в запоминании точки в обработчике прерывания – Контекст 1(в des1). Если обработчик работал бы в штатном режиме, то из этой точки управление системой вернулось бы первому процессу. Чтобы из обработчика прерывания попасть в первый процесс, следует восстановить контекст, на который указывает des1. Говоря другими словами, достаточно запомнить соответствующую точку обработчика прерывания, что может быть осуществлено уже разработанным переключателем.
Таким образом, оболочку с асинхронной заменой контекста можно создать на основе оболочки с синхронной заменой, дополнив последнюю:
функцией Запуск диспетчера;
функцией Остановка диспетчера;
новым обработчиком прерывания по таймеру, который предназначен для перекрытия прежнего.
Запуск диспетчера. Эта функция связывает новый обработчик с аппаратным прерыванием по таймеру и переключает управление на первый процесс. Новый обработчик прерывания наряду с организацией переключения контекстов должен выполнять функции стандартного обработчика, связанные с изменением показания часов. В общем случае Запуск диспетчера состоит из 4-х операций:
запомнить прежнее значение обработчика, например, прерывания 61h ;
переключить прежний обработчик прерывания по таймеру на уровень 61h;
новый обработчик связать с прерыванием по таймеру;
переключить управление на первый процесс.
Первая операция является «данью корректности» – свободное прерывание 61h может быть уже использовано для некоторых целей, и после окончания работы надстройки целесообразно вернуться в исходное состояние. Вторая операция позволяет вызовом программы обработки прерывания int 61h из нового обработчика решить проблему с коррекцией текущего времени.
Остановка диспетчера. Если функция Запуск диспетчера запускает многозадачную надстройку, то процедура Остановка диспетчера осуществляет возвращение в однозадачную систему. Для этого достаточно процвести 3 операции:
возвратить прежнее значение адреса на уровень 61h;
возвратить прежнее значение адреса на уровень 08h;
переключить управление в контекст основной программы.
Новый обработчик. Новый обработчик прерывания по таймеру должен:
быть приемников прежнего обработчика и исправно изменять показания часов;
организовать последовательное переключение процессов.
Выполнение первой функция, как уже указывалось, осуществляется командой int 61h.
Вторую функцию можно реализовать несколькими способами. В данном варианте она строится на основе глобального счетчика и таблицы переходов, на основе которой, кстати, сконструирован в языке СИ оператор switch. Свойства таблицы переходов позволяют осуществлять переключение для любого количества вариантов одинаково быстро (см. далее текст программы). Схема переключения производится следующим образом:
при входе в обработчик прерывания значения глобального счетчика увеличивается на единицу;
полученное значение делится на число процессов и остаток от деления определяет вариант выбора;
по номеру варианта из таблицы переходов определяется коды, обрабатывающие этот вариант.
Такое переключение требует описания в обработчике прерывания всех вариантов, что увеличивает его объём. Однако, скорость обработки практически такая же, как и при одном варианте.
Использование очередей (см. дальше) позволяет в этой ситуации обойтись более коротким кодом.
Ниже приведена программа для оболочки с принудительной заменой контекста. Текст фрагментов программы, которые не претерпели изменения относительно предыдущей программы, не приводятся полностью, а только обозначаются. Прикладные программы здесь описаны в отдельных файлах.
;*******************************************************************
; Пример программы для многозадачной надстройки с асинхронной заменой контекста
;( принудительное ЗАМЕЩЕНИЕ КОНТЕКСТА)
;*******************************************************************
include macro.lib ;текст макроса не изменился
st1 segment stack
db 100h dup (?)
st1 ends
dan segment public
;****************************************************************
; <выделяется память под стеки и дескрипторы>
;****************************************************************
num_pr dw 2 ;число прикладных программ
dan ends
cd_1 segment public
assume ss:st1,cs:cd_1,ds:dan
;*******************************************************************
extrn pr1: far ;прикладные программы объявляем
extrn pr2: far ;как внешние
;*******************************************************************
Trancfer proc far ;текст подпрограммы остался неизменным
;*******************************************************************
trancfer endp
;*******************************************************************
; запустить диспетчер
;*******************************************************************
set_disp proc far
;сохранение прежнего значения прерывания 08н
cli
mov ax,3508h
int 21h
mov _08_cs,es
mov _08_ip,bx
sti
;сохранение прежнего значения прерывания 61н
cli
mov ax,3561h
int 21h
mov _61_cs,es
mov _61_ip,bx
sti
;устанавливаем 08н прерывание на 61н
push ds
mov dx,_08_ip
mov ax,_08_cs
mov ds,ax
mov ax,2561h
int 21h
pop ds
;устанавливаем новый обработчик на 08н
push ds
mov dx,offset handler
mov ax,seg handler
mov ds,ax
mov ax,2508h
int 21h
; переключаем на прикладной процесс
_Trancfer cont_main,cont_1
pop ds
retf
set_disp endp
;------------------------------------------------------------------------
; остановить диспетчер
;--------------------------------------------------------------------------}
s_disp proc far
;восстанавливаем прежний обработчик на 08н
cli
push ds
mov dx,_08_ip
mov ax,_08_cs
mov ds,ax
mov ax,2508h
int 21h
pop ds
sti
;восстанавливаем прежний обработчик на 61н
cli
push ds
mov dx,_61_ip
mov ax,_61_cs
mov ds,ax
mov ax,2561h
int 21h
_Trancfer cont_2,cont_main ; возвращаемся в основную программу
pop ds
retf
sti
s_disp endp
;------------------------------------------------------------------------
handler proc far
push ds
push ax
push dx
push si
mov ax,dan
mov ds,ax
int 61h
dec count1
; cmp count,7
; je @aa
; call s_disp
; jmp @b
@aa:
mov ax,count
mov dx,0
div num_pr
inc count
mov si,dx
shl si,1
jmp cs:jump_table[si]
jump_table dw foot1,foot2 ; таблица переходов
foot1:
_Trancfer cont_1,cont_2
jmp @b
foot2:
cmp count1,0
jnz @2
call s_disp
jmp @b
@2: _Trancfer cont_2,cont_1
@b:
mov al,20h ;сбрасываем через порт 20h контроллера
out 20h,al ;прерываний приоритет
;текущего прерывания (по таймеру)
pop si
pop dx
pop ax
pop ds
iret
handler endp
;*******************************************************************
main proc far ; программа ядра
begin:
mov ax,dan
mov ds,ax
;очистка экрана
;*******************************************************************
mov ax,0600h
mov bh,07h
mov cx,00h
mov dx,184fh
int 10h
;*******************************************************************
Newproc ar_1,cont_1,pr1 ;создание первого процесса
Newproc ar_2,cont_2,pr2 ;создание второго процесса
Newproc ar_g,cont_main,main ;создание главного процесса
call set_disp
mov ah,4ch
int 21h
main endp
cd_1 ends
end begin
;*******************************************************************
; Пример текста прикладной программы
; Прикладная программа теперь не содержит Переключателей контекста
;*******************************************************************
segment public
count1 dw 100h
d_1 ends
;****************************************************************
c_1 segment public
assume ds:d_1,cs:c_1
public pr1
; < ----тексты подпрограмм--------- >
pr1 proc far
; < ----текст основной подпрограммы--------- >
pr1 endp
c_1 ends
end
;*******************************************************************
;Аналогичным образом пишутся остальные прикладные программы, которые
;объединяются с системными функциями, обычными для ассемблера способами;
;*******************************************************************