- •Раздел 4. Управление внешней памятью
- •4.1. Общие принципы управления внешней памятью
- •4.1.1. Причины необходимости управления внешней памятью
- •4.1.2. Диски с фиксированными головками чтения/записи
- •4.1.2. Диски с подвижными головками чтения/записи
- •4.2. Системное по для управления внешней памятью
- •4.2.1. Правила ввода-вывода на диски
- •4.2.2. Принципы программирования процедур управления диском
- •4.3. Управление внешней памятью в современных ос
- •4.3.1. Недостатки старых ос (msdos и WinNt по сравнению с Win2000) и базовая терминология
- •4.3.2. Структура динамического диска
- •4.3.3. Драйверы устройств внешней памяти
- •4.3.4. Управление составными томами
- •4.3.5. Ввод-вывод на томах
- •4.3.6. Порты завершения ввода-вывода
- •Заключение по разделу 4
4.2.2. Принципы программирования процедур управления диском
Рассмотрим случай одного буфера (N = 1), объем которого равен одной дорожке.
С буфером связано два признака:
ДОР_ЗАГР – номер загруженной дорожки (0, если пусто);
ИЗМ – ИСТИНА, если содержимое буфера изменялось после загрузки.
Интерфейс контроллера предлагает следующие функции:
ВЫБРАТЬ_ДИСКОВОД(ДВД) – выбирает дисковод в качестве рабочего устройства;
НАЙТИ_ДОРОЖКУ(НД) – подводит головку чтения-записи к дорожке нд;
ПЕРЕДАТЬ_СЕКТ(АДР, НД, НС, НАПР) – передает содержимое между сектором НС текущей дорожки, и памятью, начиная с адреса АДР, в зависимости от направления (чтение, запись);
ПЕРЕДАТЬ_ДОРОЖКУ(НД, АДР, НАПР) – передает содержимое между дорожкой и памятью, в зависимости от направления;
ПРОВЕРИТЬ (ТЕСТ) – позволяет проверить признаки ГОТОВ, КОНЕЦ, ОШИБКА в слове состояния контроллера.
Учитывая сделанные замечания, процедура ЗАПИСАТЬ_СЕКТОР(№ ДОРОЖКИ, № СЕКТОРА, ОТКУДА) должна включить параметр РЕЖИМ, который может принимать следующие значения:
нормальная_запись
непосредственная_запись
первая_запись
В случае сбоя передачи операция повторяется. Если ошибка, приводящая к сбою продолжает повторяться, то после ЧМАКС числа попыток драйвер осуществляет прерывание программы с выдачей сообщения об ошибке.
procedure ПЕРЕДАТЬ_СЕКТОР(АДР,НД,НСЕКТ,ЗНАЧЕНИЕ);
begin
НСЕКТ := СООТВ(НСЕКТ);
НПОПЫТКИ := 0;
СНОВА:case ЗНАЧЕНИЕ in
ЧТЕН: ПРОЧИТАТЬ_СЕКТ(АДР,НД,НСЕКТ);
ЗАП: ЗАПИСАТЬ_СЕКТ(АДР,НД,НСЕКТ);
end_case;
ТЕСТ: ПРОВЕРИТЬ;
if ОШИБКА then begin
НПОПЫТКИ := НПОПЫТКИ + 1;
if НПОПЫТКИ < НМАКС then begin
goto СНОВА;
end else begin
ПРИЧИНА := ФАТАЛЬНАЯ_ОШИБКА;
ВОЗБУДИТЬ_ИСКЛЮЧЕНИЕ;
end_if;
end_if;
if КОНЕЦ then begin
goto ТЕСТ;
end_if
end_procedure;
procedure ПЕРЕДАТЬ_ДОРОЖКУ(НД,БУФЕР,ЗНАЧЕНИЕ);
begin
НАЙТИ_ДОРОЖКУ(НД);
ТЕСТ: ПРОВЕРИТЬ;
if КОНЕЦ then begin
goto ТЕСТ;
end_if
for НС := 0 to КС-1 do begin
ПЕРЕДАТЬ_СЕКТОР(БУФЕР[НС],НД,НС,ЗНАЧЕНИЕ);
end_for;
ИЗМ := ЛОЖЬ;
if ЗНАЧЕНИЕ = ЧТЕН then begin
ДОР_ЗАГР := НД;
end_if;
end_procedure;
procedure ПРОЧИТАТЬ_СЕКТОР(НД,НСЕКТ,НАЗНАЧ);
begin
if НД <> ДОР_ЗАГР then begin
if ИЗМ then begin
ПЕРЕДАТЬ_ДОРОЖКУ(ДОР_ЗАГР,БУФЕР,ЗАП);
end_if;
ПЕРЕДАТЬ_ДОРОЖКУ(НД,БУФЕР,ЧТЕН);
end_if;
НАЗНАЧ := БУФЕР[НСЕКТ];
end_procedure;
procedure ЗАПИСАТЬ_СЕКТОР(НД,НСЕКТ,НАЧ,РЕЖИМ);
begin
if НД <> ДОР_ЗАГР then begin
if ИЗМ then begin
ПЕРЕДАТЬ_ДОРОЖКУ(ДОР_ЗАГР,БУФЕР,ЗАП);
end_if;
if РЕЖИМ = ПЕРВАЯ_ЗАПИСЬ then begin
ДОР_ЗАГР := НД;
end else begin
ПЕРЕДАТЬ_ДОРОЖКУ(НД,БУФЕР,ЧТЕН);
end_if;
end_if;
БУФЕР[НСЕКТ] := НАЧ;
if РЕЖИМ = НЕПОСРЕДСТВЕННАЯ_ЗАПИСЬ then begin
ПЕРЕДАТЬ_СЕКТОР(НАЧ,НД,НСЕКТ,ЗАП);
end else begin
ИЗМ := ЛОЖЬ;
end_if;
end_procedure;
Как видно, существуют еще более низкоуровневые функции:
ПРОЧИТАТЬ_СЕКТ(АДР,НД,НСЕКТ);
ЗАПИСАТЬ_СЕКТ(АДР,НД,НСЕКТ);
которые реализуются в самом контроллере диска.