Операционные системыОПЕРАЦИОННАЯ СИСТЕМА MS-DOS Методические указания к лабораторным работам для студентов 2 и 3 курса Способы обращения к ОС MS-DOS Программы, составленные на языке С, обращаются к прерываниям MS-DOS с помощью таких функций как intdos, int86, intdosx и т.д. Для передачи параметров используются структуры REGS, WORDREGS, BYTEREGS, SREGS, описанные в файле dos. h. Программа записывает параметры в поля структуры, соответствующие регистрам процессора, а затем вызывает одну из перечисленных выше функций, передавая ей адрес структуры. После выполнения прерывания результат записывается в эту же или другую структуру. Например: union REGS inregs, outregs; struct SREGS segregs;...... inregs. h. ah. = 0x3a; segregs. ds = FP_SEG(dir_name) ; inregs. x. dx = FP_OFF(dir_name) ; intdosx(&inregs, &outregs, &segregs) ;..... В этом фрагменте кода вызывается функция 3Ah прерывания INT 21h, для чего используется функция intdosx, которая входит в стандартную библиотеку системы разработки С++. Номер функции записывается в поле h. ah объединения inregs, параметры функции (передаваемые через регистры DS: DX) соответственно поле ds структуры segregs и в поле x. dx объединения inregs. Функция intdosx записывает содержимое регистров процессора поле выполнения программного прерывания в объединение outregs. Объединение REGS определено в файле dos. h следующим образом: UNION REGS { struct WORDREGS x; struct BYTEREGS h; }; В нем имеется две структуры - WORDREGS и BYTEREGS. Первая из этих структур предназначена для работы с 16-зфззядными регистрами. Она определена так: struct WORDREGS { unsigned int ax, bx, cx, dx, si. di, cflag, flags; }; В этой структуре поля ax, bx, cx, dx, si, di соответствуют одноименным регистрам центрального процессора. Значение флага переноса записывается в переменную cflag, поле flags предназначено для остальных флагов процессора. С помощью структуры BYTEREGS можно задавать и определять содержимое 8-разрядных регистров процессора: struct BYTEREGS { unsigned char al, ah, bl, bh, cl, ch, dl, dh; }; Для работы с сегментными регистрами предназначена структура SREGS, определенная следующим образом: struct SREGS { unsigned int es; unsigned int cs; unsigned int ss, unsigned int ds; }; Для использования перечисленных выше структур программа должна одержать следующую строку: #include <dos. h> Поле вызова программного прерывания программа должна проверить флаг переноса, который сохраняется в поле cflag. Проверка поля cflag может быть выполнена, например, следующим образом: union REGS inregs, outregs;..... intdos(&inregs, &outregs) ; if(outregs. x. cflags! = 0) error() ;...... Код ошибки при этом записывается в переменную outregs. x. ax. Лабораторная работа № 1 Исследование логической структуры диска в MS-DOS Цель работы Изучение логической структуры диска ОС MS-DOS Общие положения Диски ОС MS-DOS организованы по довольно жесткой схеме. Каждый диск включает в себя помимо области файлов еще несколько управляющих областей фиксированного размера. Первый сектор логического диска (сектор 1, дорожка 0, головка 0) содержит загрузочную запись - программу начальной загрузки ОС. Кроме программы начальной загрузки в загрузочной записи находятся параметры, описывающие характеристики данного логического диска. Эти параметры располагаются в самом начале сектора. Формат загрузочной записи
Со смещением 11 располагается расширенный блок параметров BIOS. Этот блок содержит некоторые характеристики логического диска.
Байт описания среды - media может служит для идентификации носителя данных, например, он содержит значение F8h для жесткого диска любой емкости или значение F0h для диска размером 3,5 дюйма и емкостью 1440 Кб. Прерывания для работы с логическим диском Для работы с логическим диском (или дискетой) на уровне логических номеров секторов MS-DOS программам два прерывания - INT 25h (чтение сектора по его логическому номеру) и INT 26h (запись сектора по его логическому номеру) . Для вызова этих прерываний используется следующий формат: INT 25h - чтение сектора по его логическому адресу На входе: AL - Адрес НГМД или НМД (0-A:, 1-B:, и т.д. CX - количество секторов, которые нужно прочитать DX - логический номер начального сектора DS: BX - адрес буфера для чтения На выходе: AH - код ошибки при неуспешном завершении операции CF 1, если произошла ошибка; 0, если ошибки нет. INT 26h - запись сектора по его логическому номеру На входе: AL - Адрес НГМД или НМД (0-A:, 1-B:, и т.д. CX - количество секторов, которые нужно записать DX - логический номер начального сектора DS: BX - адрес буфера, содержащего данные На выходе: AH - код ошибки при неуспешном завершении операции CF 1, если произошла ошибка; 0, если ошибки нет. В программах на языке С для работы с указанными прерываниями может быть использован следующий фрагмент программы:... union REGS reg; struct SREGS segreg; reg. x. ax. = drive; reg. x. bx = FP_OFF (buff) ; segreg. ds = FP_SEG (buff) ; reg. x. x. = 1; reg. x. dx. = 0; int86x(0x25, ®, ®, &segreg) ;... где buff - адрес буфера, в который считывается (записывается) логический сектор. Замечание: после вызова прерывания должна обязательно следовать команда: asm POP AX Порядок выполнения лабораторной работы Изучить логическую структуру дика MS-DOS. Составить программу, читающую загрузочный сектор диска и выводящую на экран основные характеристики диска из BPB. Содержание отчета Цель работы. Описание логической структуры диска MS-DOS. Характеристики логического диска, полученные в результате работы составленной в ходе выполнения лабораторной работы программы. Контрольные вопросы Принципы записи информации на дисковые накопители. Методы разделения дискового пространства между пользователями (“справочник файлов” ) . Методы распределения дискового пространства для файлов. Логическая структура диска MS-DOS. Литература Г. Дейтел. Введение в операционные системы. Том 1,2. М: Мир, 1987. А. В. Фролов, Г. В. Фролов MS-DOS для программиста. Библиотека системного программиста, Том 19, М: ДИАЛОГ-МИФИ, 1995.
Лабораторная работа №2 Исследование таблицы размещения файлов (FAT - таблицы) ОС MS-DOS Цель работы Изучить структуру и назначение FAT таблицы ОС MS-DOS Общие положения Сразу вслед за загрузочным сектором на логическом диске находятся секторы, содержащие таблицу размещения файлов (FAT - таблица) . FAT - таблица используется для хранения информации о распределении файлам секторов диска. Сектор диска - это часть диска, в которой обычно хранится 512 байт информации, относящейся к файлу. Весь диск разбивается операционной системой на участки одинакового размера, называемые кластерами. Кластер может одержать несколько смежных секторов. Для каждого кластера в FAT таблице есть своя индивидуальная ячейка, в которой хранится информация об использовании кластера, т.е. FAT - таблица - это массив, содержащий информацию о кластерах. Размер этого массива равен общему количеству кластеров на логическом диске. В FAT - таблице находятся списки кластеров, распределенных файлам.. Таким образом, если файл занимает несколько кластеров на диске, то эти кластеры связаны в список. При этом элементы FAT - таблицы содержат номера следующих используемых данным файлом кластеров. Конец списка отмечен в таблице специальным значением. Номер первого кластера, распределенного файлу, хранится в элементе каталога, описывающего данный файл. Пример использования FAT таблицы приведен на рис. 1. Корневой каталог диска C:
FAT - таблица
Пример распределения кластеров для файлов autoexec. bat b config. sys FAT - таблица может иметь 12- или 16-битовый формат. При этом в таблице для хранения информации об одном кластере диска используется соответственно 12 или 16 бит. 12-битовый формат удобен для дискет с небольшим количеством секторов - вся FAT - таблица помещается в одном секторе. Первый байт FAT - таблицы называется описателем среды. Он имеет такое же значение, как и байт - описатель среды, находящийся в загрузочном секторе дика. Следующие 5 байт для 12-битового формата или 7 байт для 16-битового формата всегда содержат значение 0FFh. Остальная часть FAT таблицы состоит из 12- или 16-битовых ячеек. Каждая ячейка соответствует одному кластеру диска. Эти ячейки могут содержать следующие значения:
Обычно FAT - таблица располагается после загрузочного сектора. Для точного определения начального сектора FAT - таблицы следует прочитать в память загрузочный сектор и проанализировать содержимое блока параметров BIOS. В поле ressect записано количество зарезервированных секторов, которые располагаются перед FAT. Поле fat_size содержит размер FAT в секторах. Кроме того, следует учитывать, что на диске может находиться несколько копий FAT. Операционная система использует только первую копию FAT, но обновляет вторую. Вторая копия нужна для утилит восстановления содержимого диска. Количество копий FAT находится в поле fat_cnt загрузочного сектора. Общая схема использования FAT такова: Получаем номер первого кластера файла, для которого необходимо определить его расположение на диске. Используем номер первого кластера как индекс в FAT - таблице для извлечения номера следующего кластера. Повторяем предыдущую процедуру до тех пор, пока извлеченное из FAT - таблицы значение не будет соответствовать концу файла. Процедура извлечения номера кластера из FAT - таблицы зависит от формата FAT - таблицы. 16-битовую FAT - таблицу можно представить как массив 16-битовых чисел. Для определения номера следующего кластера надо просто извлечь 16-битовое значение из FAT - таблицы, использовав в качестве индекса номер предыдущего кластера. Для 12-битовой FAT таблицы процедура значительно сложнее. Необходимо выполнить следующие действия: умножить номер начального кластера на 3; разделить результат на 2; прочитать 16-битовое слово из FAT - таблицы, используя в качестве смещения значение, полученное после деления на 2; если номер начального кластера четный, на выбранное из FAT слово нужно наложить маску 0FFFh, оставив младшие 12 бит; если же номер начального кластера нечетный, выбранное из FAT значение необходимо сдвинуть вправо на 4 бита, оставив старшие 12 бит; полученный результат это номер следующего кластера в цепочке. Используя описанную выше процедуру можно определить для каждого файла цепочку занимаемых им кластеров. Для нахождения первого кластера, распределенного файлу необходимо прочитать информацию из каталога., в котором содержится данный файл. Для этого необходимо сначала прочитать корневой каталог, а затем все подкаталоги из пути каталогов к данному файлу. Корневой каталог находится сразу за последней копией FAT. Перед корневым каталогом находится один загрузочный сектор и fat_cnt*fat_size секторов FAT таблицы. Размер корневого каталога можно определить исходя из значения поля root_size. При форматировании дика в это поле записывается максимальное количество файлов и каталогов, которые могут быть в корневом каталоге. Для каждого элемента в каталоге отводится 32 байта, поэтому корневой каталог имеет длину 32*root_size байт. Корневой каталог занимает непрерывную область фиксированного размера. Любой каталог одержит 32-байтовыу дескрипторы, описывающие файлы и другие каталоги. Дескриптор имеет следующий формат:
В любом каталоге, кроме корневого, два первых дескриптора имеют специальное назначение. Первый дескриптор содержит в поле имени строку “.” . Этот дескриптор указывает на одержащий его каталог, т.е. каталог имеет ссылку на самого себя. Второй специальный дескриптор содержит в поле имени строку “..” . Это дескриптор указывает на каталог более высокого уровня Если в поле номера первого занимаемого кластера для дескриптора с именем “..” находится нулевое значение, это означает, что данный каталог содержится в корневом каталоге. Порядок выполнения работы Изучить структуру FAT таблицы и структуру корневого каталога логического дика ОС MS-DOS. Расширить возможности программы из лабораторной работы № 1 таким образом, чтобы она выводила на экран номера всех кластеров, распределенных файлу, указанному преподавателем. Содержание отчета Цель работы. Структура FAT - таблицы и дескриптора файлов и каталогов. Результаты выполнения лабораторной работы. Контрольные вопросы Распределение дискового пространства с использованием цепочки блоков. Распределение дискового пространства с использованием цепочки индексных блоков. Распределение дискового пространства с использование таблиц отображения файлов. Организация каталогов ОС MS-DOS. Литература Г. Дейтел. Введение в операционные системы. Том 1,2. М: Мир, 1987. А. В. Фролов, Г. В. Фролов MS-DOS для программиста. Библиотека системного программиста, Том 19, М: ДИАЛОГ-МИФИ, 1995.
Лабораторная работа № 3 Исследование векторной таблицы связи MS-DOS Цель работы Изучить назначение и структуру векторной таблицы связи основных управляющих блоков ОС MS-DOS. Общие положения Операционная система MS-DOS содержит векторную таблицу связи основных управляющих блоков. Зная адрес этой таблицы, можно получить доступ к внутренним структурам данных операционной системы. Основные структуры данных ОС МS-DOS организованы в виде дерева. Корнем этого дерева является векторная таблица связи, которая содержит адреса всех остальных структур: список блоков управления памятью MCB, список блоков управления устройствами MS-DOS, таблицу файлов, дисковые буферы и т.д. Информация, содержащаяся в векторной таблице связи открывает доступ практически ко всем внутренним структурам данных операционной системы. Поля векторной таблицы связи
Функция 52h возвращает адрес поля dev_cb. Для того чтобы получить адрес слова, содержащего сегмент первого блока памяти MCB, необходимо уменьшить значение смещения, полученного от функции на 2. Поле mcb_seg содержит сегментную компоненту адреса первого блока MCB. Зная это значение можно проследить и изменить структуру блоков памяти. В поле dev_cb векторной таблицы связи хранится указатель на список блоков управления дисковыми устройствами MS-DOS. Каждый такой блок содержит описание характеристик устройства, а также указатель на драйвер, обслуживающий устройство. Программа может использовать блок управления дисковыми устройствами для доступа к диску на низком уровне или для получения справочной информации об устройстве. Поле file_tab содержит адрес таблицы файлов MS-DOS. В этой таблице для каждого открытого файла хранится разнообразная информация, такая, как количество назначенных файлу идентификаторов(т.е. сколько раз файл был открыт) , режим использования файла, номер первого кластера диска, распределенного файлу и т.д. Эта информация может потребоваться для организации доступа к файлам на уровне кластеров, например в системах защиты файлов от несанкционированного доступа. С помощью полей clock_dr и con_dr программа может получить доступ соответственно к драйверу CLOCK$ и драйверу консоли CON. Это может понадобиться для организации вызова драйвера непосредственно из программы. Поле max_btbl содержит размер блока устройств, которые выполняют обмен данными отдельными блоками (для MS-DOS размер блока равен 512 байтам. Поле drv_info содержит указатель на массив, в котором хранится информация о дисковых устройствах. В этом массиве можно найти текущий путь доступа для каждого диска, номер первого кластера диска, распределенного каталогу, и адрес соответствующего блока управления дискового устройства. В поле fcb_tabl находится указатель на таблицу FCB. Размер этой таблицы записан в поле fcb_size и определяется параметром fcbs=xx, расположенном в файле cjnfig. sys. Поле lastdriv содержит значение параметра lastdrive, расположенного в файле config. sys. Его можно использовать для определения максимального количества дисковых устройств в системе. В поле num_bdev хранится количество действительно используемых дисковых устройств. Поле nul_dr само по себе не содержит никакой полезной информации. Имеет значение лишь его адрес - в этом месте расположен самый первый в цепочке драйвер MS-DOS. Для получения адреса векторной таблицы связи можно воспользоваться следующей программой на языке С: #include <stdio. h> #include <conio. h> #include <dos. h> typedef struct { unsigned mcb_seg; void far *dev_cb; void far *file_tab; void far *clock_dr; void far *con_dr; unsigned max_btbl; void far *disk_buf; void far *drv_info; void far *fcb_tabl; unsigned fcb_size; unsigntd char num_bdev; unsigned char lastdriv; }CVT; typedef CVT far* LPCVT; void main(void) { union REGS regs; struct SREGS sregs; LPCVT lpCVT; // Получаем адрес векторной таблицы связи resgs. h. ah = 0x52h; indosx(®s, ®s, &sregs) ; // Передвигаем указатель на поле mb_seg lpCVT = (LPCVT) VK_FP(sregs. es, resg. x. bx - 2) ; // Выводим адрес векторной таблицы связи printf(“\nАдрес CVT: %Fp” (LPCVT) lpCVT) ; getch() ; } Макрокоманды MR_FP, FP_SEG, FP_OFF описаны и файле dos. h. С помощью макрокоманды MK_FP можно конструировать дальний указатель из значения сегмента и смещения. Макрокоманды FP_SEG и FP_OFF можно выделить из дальнего указателя соответственно сегмент и смещение. Формат блока MCB Внутри блока MCB хранится длина описываемого данным МСВ фрагмента памяти. Следующий фрагмент начинается сразу за предыдущим. Все блоки управления памятью связаны в список. Блоки MCB бывают двух типов M и Z. M - блоки - это промежуточные блоки. Блок типа Z является последним в списке блоков и может быть только один. Блок MCB имеет следующий формат:
Параграф имеет размер 16 байт. Для удобства работы с блоком MCB определим тип MCB: typedef struct { unsigned char type; unsigned owner; unsigned size; char reserve[11]; } MCB; Порядок выполнения работы Получить и вывести на экран адрес векторной таблицы связи и значения полей в векторной таблице связи. Получить список всех MCB - блоков с указанием их типов, размеров и владельцев. Содержание отчета Цель работы. Описание полей векторной таблицы связи. Результаты выполнения лабораторной работы. Контрольные вопросы Распределение памяти в ОС MS-DOS. Назначение и варианты использования векторной таблицы связи ОС MS-DOS. Назначение и способы использования MCB - блоков Литература Г. Дейтел. Введение в операционные системы. Том 1,2. М: Мир, 1987. А. В. Фролов, Г. В. Фролов MS-DOS для программиста. Библиотека системного программиста, Том 19, М: ДИАЛОГ-МИФИ, 1995.
Лабораторная работа № 4 Исследование системы обработки прерываний ОС MS-DOS Цель работы Изучение системы обработки прерываний ОС MS-DOS Общие положения Для обработки событий, происходящих асинхронно по отношению к выполнению программы, лучше всего подходит механизм прерываний. Прерывание можно рассматривать как некоторое событие в системе, требующее моментальной реакции. С прерыванием связывают число - номер прерывания. Этот номер однозначно соответствует тому или иному событию. Система умеет распознавать прерывания и при их возникновении запускает процедуру, соответствующую номеру прерывания. Прерывания могут быть синхронными или асинхронными. Синхронные прерывания (программные) вызываются самой программой с использованием команды INT. Программные прерывания удобно использовать для организации доступа к функциям операционной системы и другим разделяемым программам и данным. Аппаратные прерывания вызываются физическими устройствами. Эти прерывания информируют систему о событиях, связанных с работой устройств, например, завершение ввода, нажатие клавиши на клавиатуре или мыши и т.д. Для того, чтобы связать адрес обработчика прерываний с номером прерывания, используется таблица векторов прерываний , занимающая первый килобайт оперативной памяти. Эта таблица находится в диапазоне адресов от 0000: 0000 до 0000: 03FFh и состоит из 256 элементов - дальних адресов обработчиков прерываний. Элементы таблицы векторов прерываний называются векторами прерываний. В первом слове вектора прерываний записывается компонента смещения обработчика прерывания, а во втором - сегментная компонента. Для программиста, использующего язык СИ, таблицу векторов прерываний можно описать следующим образом: void (far* interrupt_table[256]) () ; Для изменения обработки некоторых прерываний программа должна установить векторы нужных прерываний на свой обработчик. Это можно сделать, изменив содержимое соответствующего элемента таблицы векторов прерываний. Перед завершением работы необходимо восстановить содержимое измененных векторов. Если нужно добавить какие-либо действия к тем, что выполняет стандартный обработчик прерываний, то можно организовать цепочку обработчиков прерываний. В библиотеке СИ имеется функция для организации цепочки прерывания с именем _chain_intr. Для описания функции, выполняющей обработку прерывания, следует использовать ключевое слово interrupt . Такая функция завершается командой возврата из прерывания IRET. Для нее автоматически генерируются команды сохранения регистров на входе и их восстановления при выходе из обработчика прерывания. void interrupt far int_funct(...) { // Тело обработчика прерывания } Ключевое слово interrupt используется также для описания переменных, предназначенных для хранения векторов прерываний: void interrupt (far *oldvect) (...) ; Для установки своего обработчика прерываний используется функция _dos_setvect. Эта функция имеет два параметра - номер прерывания и указатель на новую функцию обработки прерывания: _dos_setvect(0x16, my_key_intr) ; В этом примере для прерывания номер 16h устанавливается новый обработчик прерывания my_key_intr . Для того чтобы узнать адрес старого обработчика прерывания по его номеру используется функция _dos_getvect , которая принимает в качестве параметра номер прерывания и возвращает указатель на соответствующий номеру обработчик: old_vector = _dos_getvector(0x16) ; Следующая программа иллюстрирует применение перечисленных выше функций для создания цепочки обработчиков прерываний. Эта программа встраивает собственный обработчик прерываний от таймера, который будет вызываться 18,2 раза в секунду. Встраиваемый обработчик прерываний подсчитывает прерывания от таймера, и, если значение соответствующего счетчика кратно 20, громкоговоритель компьютера издает звуковой сигнал. В конце работы новый обработчик прерываний вызывает старый обработчик прерываний. После установки нового обработчика прерывания таймера основная программа ждет, когда пользователь нажмет любую клавишу, затем она восстанавливает старое содержимое вектора прерывания. #include <stdio. h> #include <dos. h> #include <conio. h> void main(void) ; void interrupt far timer(...) ; void interrupt (far *oldvect) (...) ; // Переменная для подсчета прерываний таймера volatile long ticks; void main(void) ; { // Сбрасываем счетчик ticks = 0; // Запоминаем адрес старого обработчика прерываний oldvect = dos_getvect (0x1c) : // Устанавливаем новый обработчик прерываний dos_setvect (0x1c, timer) ; printf ("\nТаймер установлен. Нажмите любую клавишу... \n") ; getch() ; // Восстанавливаем старый обработчик прерываний dos_setvect (0x1c, oldvect) ; } void interrapt far timer (...) { // Увеличиваем счетчик прерываний таймера ticks++; // Если значение счетчика кратно 20, выдаем сигнал на громкоговоритель // компьютера if (ticks % 20) == 0) { asm mov bx, 0 asm mov ax, 0E07h asm int 10h } // Вызываем старый обработчик прерываний _chain_intr (oldvect) ; } Порядок выполнения работы 1. Отладить программу, приведенную выше в описании лабораторной работы. 2. Составить и отладить программу, подсчитывающую число обращений к услугам операционной системы через прерывание INT 21h. Число обращений подсчитать для программы, составленной на лабораторной работе №1, №2 или №3. Содержание отчета Цель работы. Список наиболее часто используемых векторов прерываний Результаты работы программы. Контрольные вопросы Принципы обработки прерываний в современных ОС. Особенности обработки программных прерываний. Особенности обработки аппаратных прерываний Общая схема создания и подключения собственного обработчика прерываний. Литература Г. Дейтел. Введение в операционные системы. Том 1,2. М: Мир, 1987. А. В. Фролов, Г. В. Фролов MS-DOS для программиста. Библиотека системного программиста, Том 19, М: ДИАЛОГ-МИФИ, 1995. Поделитесь этой записью или добавьте в закладки |
Полезные публикации |