Дескрипторы [1] [2] являются архитектурной особенностью больших систем Burroughs , включая текущие (по состоянию на 2024 год) системы Unisys Clearpath/MCP. Помимо того, что они основаны на стеке и тегах , примечательной архитектурной особенностью этих систем является то, что они основаны на дескрипторах. Дескрипторы являются средством получения данных , которые не находятся в стеке, таких как массивы и объекты . Дескрипторы также используются для строковых данных, как в компиляторах и коммерческих приложениях .
Дескрипторы являются неотъемлемой частью системы автоматического управления памятью и виртуальной памяти. Дескрипторы содержат метаданные о блоках памяти, включая адрес, длину, тип машины (слово или байт — для строк) и другие метаданные. Дескрипторы обеспечивают необходимую защиту памяти, безопасность, надежность, отслеживая все попытки доступа за пределы диапазона и переполнения буфера. Дескрипторы являются формой системы возможностей. [3]
Развитие дескриптора было методом Берроуза по реализации управления памятью, выделения и освобождения, а также виртуальной памяти. В 1958 году Роберт С. Бартон , тогда работавший в Shell Research, предположил, что основное хранилище должно выделяться автоматически, а не заставлять программиста заниматься наложениями из вторичной памяти, по сути виртуальной памяти. [4] : 49 [5] Виртуальная память была первоначально разработана для проекта Atlas в Манчестерском университете в конце 1950-х годов.
К 1960 году Бартон стал ведущим архитектором проекта Burroughs B5000. С 1959 по 1961 год У. Р. Лонерган был менеджером группы планирования продукции Burroughs, в которую входили Бартон, Дональд Кнут в качестве консультанта и Пол Кинг. По словам Лонергана, в мае 1960 года Калифорнийский университет в Лос-Анджелесе провел двухнедельный семинар «Использование и эксплуатация гигантских компьютеров», на который были отправлены Пол Кинг и еще двое. Стэн Гилл выступил с докладом о виртуальной памяти в компьютере Atlas I. Пол Кинг передал идеи обратно в Burroughs, и было решено, что виртуальная память должна быть спроектирована в ядре B5000. [4] : 3 Корпорация Burroughs выпустила B5000 в 1964 году как первый коммерческий компьютер с виртуальной памятью. [6]
В середине 1960-х годов другие производители, включая RCA и General Electric, разработали машины, которые поддерживали виртуальную память, с операционными системами, ориентированными на разделение времени. IBM не поддерживала виртуальную память в машинах, предназначенных для общей обработки данных, до 1972 года. Однако другие системы не основаны на дескрипторах и добавили виртуальную память поверх базовой архитектуры процессора.
Дескриптор был неотъемлемой частью разработки B5000 с автоматическим управлением памятью и виртуальной памятью в Burroughs. Хотя детали изменились с 1964 года, идея дескриптора по сути осталась прежней вплоть до современных машин Unisys Clearpath MCP (Libra), которые являются прямыми потомками B5000.
Дескрипторы описывают области хранения, запросы ввода-вывода и результаты ввода-вывода. Они содержат поля, указывающие, например, тип дескриптора, адрес, длину, присутствуют ли данные в хранилище. Детали различаются в зависимости от линейки продуктов и типа дескриптора. Следующий текст нумерует самый левый (самый значимый) бит как 0, в соответствии с документацией Burroughs.
Дескрипторы программ и данных имеют бит, называемый "битом присутствия" или "p-битом"; он указывает, находится ли объект, на который ссылается дескриптор, в памяти или во вторичном хранилище. Этот бит используется для реализации виртуальной памяти .
При ссылке на дескриптор оборудование проверяет p-бит. Если он равен 1, данные присутствуют в памяти в месте, указанном в поле адреса. Если p-бит равен 0, блок данных отсутствует, и возникает прерывание (p-бит прерывания ), и вводится код MCP , чтобы сделать блок присутствующим. В этом случае, если поле адреса равно 0, блок данных не был выделен (init p-бит), и MCP ищет свободный блок, размер которого указан в поле длины.
Последний сценарий p-бита — это когда p-бит равен 0, указывая на то, что данные отсутствуют в памяти, но адрес ненулевой, указывая на то, что данные были выделены, и в этом случае адрес представляет собой адрес диска в области виртуальной памяти на диске. В этом случае возникает прерывание p-бита, и оно отмечается как «другой» p-бит.
B5000 [7] был первым компьютером на основе дескрипторов. Каждый дескриптор имеет флаг (бит 0) 1. Дескрипторы данных содержат 15-битный адрес хранения и 10-битный размер, как и большинство дескрипторов ввода-вывода. Дескрипторы программ и дескрипторы внешних результатов имеют 15-битный адрес, но не имеют поля размера.
Дескрипторы программ используются для определения сегментов программы. Вызов операнда или дескриптора, ссылающийся на дескриптор программы, вызовет вызов подпрограммы, если бит присутствия равен 1. В противном случае это вызовет прерывание присутствия.
Дескрипторы данных ссылаются либо на блок данных, присутствующий в памяти (P=1), либо на блок данных, который должен быть считан в память (P=0), в зависимости от значения бита присутствия. Вызов операнда или вызов дескриптора, ссылающийся на дескриптор данных, будет проверять бит присутствия и поле размера; если бит присутствия равен 0, то возникнет прерывание присутствия; если поле размера не равно нулю, то второе слово в стеке должно находиться в пределах диапазона, иначе возникнет прерывание индекса.
Внешний дескриптор результата содержит дескриптор ввода-вывода, используемый для инициирования операции с заменой некоторых полей.
Дескрипторы описывают блоки данных. Каждый дескриптор содержит 20- битное адресное поле, ссылающееся на блок данных. Каждый блок имеет длину, которая хранится в дескрипторе, также 20 бит. Размер данных также указан, будучи 4-, 6-, 8- или 48-битными данными в трехбитном поле.
Первым компьютером с такой архитектурой был B6500. В этой реализации значение различных битов состояния было следующим:
В более поздних реализациях эти биты состояния развивались, чтобы соответствовать растущим размерам памяти и полученным со временем знаниям.
В ALGOL границы массива полностью динамические, могут быть взяты из значений, вычисленных во время выполнения, в отличие от Pascal , который появился позже, на основе ALGOL, где размер массивов фиксируется во время компиляции. Это главная слабость Pascal, как определено в его стандарте, но которая была устранена во многих коммерческих реализациях Pascal, в частности, реализациях Burroughs (как версия Университета Тасмании Артура Сейла и Роя Фрика, так и более поздняя реализация на системе Burroughs Slice Compiler Мэтта Миллера и др.)
В программе в среде Burroughs/Unisys MCP массив не выделяется при объявлении, а только когда он впервые затрагивается во время выполнения – таким образом, массивы можно объявлять и избегать накладных расходов на их выделение, если они не используются. Таким образом, управление памятью полностью динамическое.
Кроме того, не нужны системные вызовы выделения памяти низкого уровня, такие как вызовы класса malloc в C и Unix — массивы автоматически выделяются по мере использования. Это избавляет программиста от большой нагрузки по заполнению программ подверженной ошибкам деятельностью по управлению памятью, что имеет решающее значение в приложениях мэйнфреймов .
При портировании программ на низкоуровневых языках, таких как C, структура памяти C обрабатывается путем собственного выделения памяти в большом выделенном блоке — таким образом, безопасность остальной части системы не может быть скомпрометирована переполнением буфера ошибочными программами C. Фактически, многие переполнения буфера в, казалось бы, правильно работающих программах C были обнаружены при портировании на архитектуру Unisys MCP. [8] C, как и Pascal, также реализован с использованием системы компилятора Slice, которая использует общий генератор кода и оптимизатор для всех языков. Компилятор C, система времени выполнения, интерфейсы POSIX , а также порт многих инструментов Unix были созданы Стивом Бартельсом. Компилятор Eiffel также был разработан с использованием Slice.
Для объектно-ориентированных программ, которые требуют более динамичного создания объектов, чем архитектура MCP, объекты лучше всего размещать в одном блоке. Такое размещение объектов является более высоким уровнем, чем malloc в C, и лучше всего реализуется с помощью современного эффективного сборщика мусора .
Поле адреса в B5000, B5500 и B5700 составляет всего 15 бит, что означает, что дескрипторы могут адресовать только 32K слов (192KB) памяти. Поле адреса в B6500 составляет 20 бит или 1 Meg слов (6MB). К середине семидесятых это все еще было существенным ограничением архитектуры. Чтобы преодолеть это, были реализованы два решения:
Для использования этих функций не потребовалось никаких изменений программного кода. Оба решения можно даже объединить, но в конечном итоге требования к памяти MCP и требования к совместному использованию данных программы переросли максимальный размер самих адресных пространств.
С появлением серии A в начале 1980-х годов значение этого поля было изменено, чтобы содержать адрес главного дескриптора, что означает, что могут быть выделены блоки данных размером 1 мегабайт, но что память машины может быть значительно расширена до гигабайт или, возможно, терабайт. Эта архитектура была названа памятью ASD (Advanced Segment Descriptors). Это потребовало новой общей спецификации микрокода, называемой Beta. Главным визионером памяти ASD является Джон МакКлинток. Позже 3-битный тег памяти был увеличен до 4-битной спецификации, что позволило увеличить размер дескриптора сегмента с 20 до 23 бит, что позволило одновременно адресовать еще больше памяти. Эта спецификация микрокода стала известна как уровень Gamma.
Другое существенное преимущество было реализовано для виртуальной памяти . В конструкции B5000, если блок данных был развернут, все дескрипторы, ссылающиеся на этот блок, должны были быть найдены для обновления бита присутствия и адреса. С главным дескриптором, только бит присутствия в главном дескрипторе требует изменения. Также MCP может перемещать блоки в памяти для уплотнения и должен только изменить адрес в главном дескрипторе.
Разница между B5000 и большинством других систем заключается в том, что другие системы в основном использовали страничную виртуальную память, то есть страницы выгружались фрагментами фиксированного размера независимо от структуры информации в них. Виртуальная память B5000 работает с сегментами переменного размера , как описано в дескрипторах.
Когда память заполнена до определенного объема, вызывается процесс ОС, называемый "Working Set Sheriff", чтобы либо сжать память, либо начать перемещение сегментов из памяти. Сначала он выбирает сегменты кода, поскольку они не могут измениться и могут быть перезагружены из оригинала в файле кода, поэтому не нуждаются в записи, а затем сегменты данных, которые записываются в файл виртуальной памяти.
P-битные прерывания [9] также полезны для измерения производительности системы. Для первого выделения памяти «init p-биты» указывают на потенциальную проблему производительности в программе, например, если процедура выделения массива вызывается постоянно. Перезагрузка блоков из виртуальной памяти на диске может значительно ухудшить производительность системы и не является ошибкой какой-либо конкретной задачи. Вот почему многие из современных компьютеров могут получить повышенную производительность системы за счет добавления памяти. На машинах B5000 «другие p-биты» указывают на системную проблему, которую можно решить либо путем лучшей балансировки вычислительной нагрузки в течение дня, либо путем добавления дополнительной памяти.
Таким образом, архитектура больших систем Burroughs способствует оптимизации как отдельных задач, так и системы в целом.
Последний и, возможно, самый важный момент, который следует отметить относительно дескрипторов, — это то, как они влияют на взаимодополняющие понятия безопасности системы и корректности программы. Одним из лучших инструментов, которые есть у хакера для взлома современных операционных систем, является переполнение буфера. В частности, в языке C используется самый примитивный и подверженный ошибкам способ обозначения конца строк, использующий нулевой байт в качестве контрольной точки конца строки в самом потоке данных.
Указатели реализованы в системах Unisys MCP с помощью индексированных дескрипторов. Во время операций индексации указатели проверяются на каждом шаге, чтобы убедиться, что ни исходный, ни целевой блоки не выходят за пределы. Во время операции сканирования или замены механизмы, используемые для чтения или копирования больших блоков памяти, как исходных, так и целевых, проверяются на каждом шаге слова на наличие допустимого тега памяти. Каждый сегмент памяти ограничен словами тега 3, что сделало бы такую операцию неудачной. Каждый сегмент памяти, содержащий чувствительные к целостности данные, такие как программный код, хранится в словах тега 3, что делает неконтролируемое чтение — не говоря уже об изменении — невозможным. Таким образом, значительный источник ошибок программы может быть обнаружен на ранней стадии, до того, как программное обеспечение будет запущено в производство, и более значительный класс атак на безопасность системы невозможен.