Введение
Устройство, используемое операционными системами и прикладными программами. Реализации BIOS предоставляют прерывания, которые могут быть вызваны операционными системами и прикладными программами для использования возможностей прошивки на компьютерах, совместимых с IBM PC. Традиционно вызовы BIOS в основном используются программами DOS и некоторыми другими программами, такими как загрузчики (включая, в основном исторически, относительно простое программное обеспечение, которое загружается непосредственно и работает без операционной системы — особенно игровое программное обеспечение). BIOS работает в режиме реального адреса (Real Mode) процессора x86, поэтому программы, вызывающие BIOS, должны также работать в реальном режиме или должны переключаться из защищенного режима в реальный режим перед вызовом BIOS, а затем переключаться обратно. По этой причине современные операционные системы, использующие процессор в защищенном режиме или длинном режиме, обычно не используют вызовы прерываний BIOS для поддержки системных функций, хотя они используют вызовы прерываний BIOS для исследования и инициализации оборудования во время загрузки. Реальный режим имеет ограничение памяти в 1 МБ, современные загрузчики (например, GRUB2, Windows Boot Manager) используют нереальный режим или защищенный режим (и выполняют вызовы прерываний BIOS в режиме Virtual 8086, но только для загрузки ОС) для доступа к памяти объемом до 4 ГБ. Во всех компьютерах инструкции программного обеспечения управляют физическим оборудованием (экран, диск, клавиатура и т. д.) с момента включения питания. В ПК BIOS, предварительно загруженный в ROM на материнской плате, берет на себя управление сразу после сброса процессора, в том числе во время включения, при нажатии кнопки аппаратного сброса или когда критическая программная ошибка (тройная ошибка) приводит к автоматическому запуску аппаратного сброса схемотехникой материнской платы. BIOS тестирует оборудование и инициализирует его состояние; находит, загружает и запускает загрузочную программу (обычно загрузчик ОС и исторический ROM BASIC); и предоставляет базовое управление оборудованием программному обеспечению, работающему на машине, которое обычно является операционной системой (с прикладными программами), но может быть непосредственно загружающимся отдельным программным приложением. Со своей стороны, IBM предоставила всю информацию, необходимую для полного использования BIOS или для прямого использования оборудования и полного обхода BIOS при программировании ранних моделей IBM PC (до PS/2). С самого начала у программистов был выбор использовать BIOS или нет, для каждого аппаратного периферийного устройства в отдельности. IBM настоятельно рекомендовала создавать "правильно работающие" программы, которые обращались к оборудованию только через вызовы BIOS INT (и вызовы служб DOS), чтобы обеспечить совместимость программного обеспечения с текущими и будущими моделями ПК с различным периферийным оборудованием, но IBM понимала, что для некоторых разработчиков программного обеспечения и клиентов, возможность для пользовательского программного обеспечения напрямую управлять оборудованием была необходима. Отчасти это было связано с тем, что значительная часть всех аппаратных функций и возможностей не была доступна через службы BIOS. В качестве двух примеров (среди многих), адаптеры MDA и CGA способны к аппаратной прокрутке, а последовательный адаптер PC способен к передаче данных с использованием прерываний, но IBM BIOS не поддерживает ни одну из этих полезных технических функций. Сегодня BIOS в новом ПК по-прежнему поддерживает большинство, если не все, вызовы функций прерывания BIOS, определенных IBM для IBM AT (представленной в 1984 году), а также множество более новых, плюс расширения некоторых оригинальных (например, расширенные диапазоны параметров), разработанные различными другими организациями и отраслевыми группами. Это, в сочетании с аналогичной степенью аппаратной совместимости, означает, что большинство программ, написанных для IBM AT, все еще могут работать правильно на новом ПК сегодня, при условии, что более высокая скорость выполнения приемлема (что обычно так и есть для всех, кроме игр, использующих синхронизацию на основе процессора). Несмотря на значительные ограничения служб, доступ к которым осуществляется через прерывания BIOS, они оказались чрезвычайно полезными и устойчивыми к технологическим изменениям.
BIOS implementations provide interrupts that can be invoked by operating systems and application programs to use the facilities of the firmware on IBM PC compatible computers. Traditionally, BIOS calls are mainly used by DOS programs and some other software such as boot loaders (including, mostly historically, relatively simple application software that boots directly and runs without an operating system—especially game software). BIOS runs in the real address mode (Real Mode) of the x86 CPU, so programs that call BIOS either must also run in real mode or must switch from protected mode to real mode before calling BIOS and then switching back again. For this reason, modern operating systems that use the CPU in Protected mode or Long mode generally do not use the BIOS interrupt calls to support system functions, although they use the BIOS interrupt calls to probe and initialize hardware during booting. Real mode has the 1MB memory limitation, modern boot loaders (e. g. GRUB2, Windows Boot Manager) use the unreal mode or protected mode (and execute the BIOS interrupt calls in the Virtual 8086 mode, but only for OS booting) to access up to 4GB memory. In all computers, software instructions control the physical hardware (screen, disk, keyboard, etc.) from the moment the power is switched on. In a PC, the BIOS, pre loaded in ROM on the motherboard, takes control immediately after the CPU is reset, including during power up, when a hardware reset button is pressed, or when a critical software failure (a triple fault) causes the mainboard circuitry to automatically trigger a hardware reset. The BIOS tests the hardware and initializes its state; finds, loads, and runs the boot program (usually, an OS boot loader, and historical ROM BASIC); and provides basic hardware control to the software running on the machine, which is usually an operating system (with application programs) but may be a directly booting single software application. For IBM's part, they provided all the information needed to use their BIOS fully or to directly utilize the hardware and avoid BIOS completely, when programming the early IBM PC models (prior to the PS/2). From the beginning, programmers had the choice of using BIOS or not, on a per hardware peripheral basis. IBM did strongly encourage the authorship of "well behaved" programs that accessed hardware only through BIOS INT calls (and DOS service calls), to support compatibility of software with current and future PC models having dissimilar peripheral hardware, but IBM understood that for some software developers and hardware customers, a capability for user software to directly control the hardware was a requirement. In part, this was because a significant subset of all the hardware features and functions was not exposed by the BIOS services. For two examples (among many), the MDA and CGA adapters are capable of hardware scrolling, and the PC serial adapter is capable of interrupt driven data transfer, but the IBM BIOS supports neither of these useful technical features. Today, the BIOS in a new PC still supports most, if not all, of the BIOS interrupt function calls defined by IBM for the IBM AT (introduced in 1984), along with many more newer ones, plus extensions to some of the originals (e. g. expanded parameter ranges) promulgated by various other organizations and collaborative industry groups. This, combined with a similar degree of hardware compatibility, means that most programs written for an IBM AT can still run correctly on a new PC today, assuming that the faster speed of execution is acceptable (which it typically is for all but games that use CPU based timing). Despite the considerable limitations of the services accessed through the BIOS interrupts, they have proven extremely useful and durable to technological change.
Цель вызовов BIOS
Вызовы прерываний BIOS выполняют функции управления оборудованием или ввода-вывода, запрошенные программой, возвращают системную информацию программе или выполняют и то, и другое. Ключевым элементом назначения вызовов BIOS является абстракция: вызовы BIOS выполняют общеопределенные функции, а конкретные детали их выполнения на конкретном оборудовании системы инкапсулированы в BIOS и скрыты от программы. Например, программа, желающая считать данные с жесткого диска, не должна знать, является ли этот диск ATA, SCSI или SATA (или, в прежние времена, ESDI, MFM или RLL, возможно, с контроллером Seagate ST 506, одним из нескольких типов контроллеров Western Digital или с другим проприетарным контроллером другого производителя). Программе достаточно определить номер диска, заданный BIOS, и адрес сектора, который необходимо прочитать или записать, а BIOS преобразует этот общий запрос в конкретную последовательность элементарных операций, необходимых для выполнения задачи через конкретное оборудование дискового контроллера, подключенное к этому диску. Это освобождает программу от необходимости знать, как управлять на низком уровне каждым типом жесткого диска (или видеоадаптера, или интерфейса порта, или периферийного устройства реального времени), к которому может потребоваться доступ. Это упрощает программирование операционных систем и приложений и уменьшает размер программ за счет исключения дублирования кода, поскольку функциональность, включенная в BIOS, не нужно включать в каждую программу, которая в ней нуждается; вместо этого программы содержат относительно короткие вызовы BIOS. (В операционных системах, где BIOS не используется, аналогичные функции и цели обычно выполняются сервисными вызовами, предоставляемыми самой операционной системой.) BIOS также освобождает разработчиков компьютерного оборудования (в той мере, в которой программы написаны для исключительного использования BIOS) от необходимости поддерживать точную аппаратную совместимость со старыми системами при разработке новых систем, чтобы обеспечить совместимость с существующим программным обеспечением. Например, аппаратная часть клавиатуры IBM PCjr работает значительно иначе, чем аппаратная часть клавиатуры более ранних моделей IBM PC, но для программ, использующих клавиатуру только через BIOS, эта разница практически незаметна. (В качестве примера обратной стороны этой медали стоит отметить, что значительная часть программ для ПК, использовавшихся во время выхода PCjr, не использовала клавиатуру исключительно через BIOS, поэтому IBM также включила в PCjr аппаратные функции для эмуляции работы аппаратной части клавиатуры оригинальных IBM PC и IBM PC XT. Эмуляция аппаратного обеспечения не является точной, поэтому не все программы, пытающиеся использовать аппаратную часть клавиатуры напрямую, будут работать правильно на PCjr, но все программы, использующие только службы клавиатуры BIOS, будут работать.) Помимо предоставления доступа к аппаратным средствам, BIOS предоставляет дополнительные возможности, реализованные в программном обеспечении BIOS. Например, BIOS поддерживает отдельные позиции курсора для до восьми текстовых страниц и обеспечивает вывод, подобный TTY, с автоматическим переносом строки и интерпретацией основных управляющих символов, таких как возврат каретки и перевод строки, в то время как аппаратное обеспечение текстового дисплея, совместимое с CGA, имеет только один глобальный курсор и не может автоматически перемещать курсор, использовать его положение для адресации памяти дисплея (чтобы определить, какая ячейка символов будет изменена или просмотрена) или интерпретировать управляющие символы. В качестве другого примера, интерфейс клавиатуры BIOS интерпретирует множество нажатий клавиш и комбинаций клавиш для отслеживания различных состояний модификаторов (левый и правый Shift, Ctrl и Alt), для вызова службы печати экрана при нажатии Shift+PrtScrn, для перезагрузки системы при нажатии Ctrl+Alt+Del, для отслеживания состояний блокировки (Caps Lock, Num Lock и Scroll Lock) и, в машинах класса AT, для управления соответствующими индикаторами состояния блокировки на клавиатуре, а также для выполнения других аналогичных функций интерпретации и управления клавиатурой. В отличие от этого, обычные возможности стандартной клавиатуры ПК и ПК AT ограничиваются сообщением системе о каждом элементарном событии нажатия или отпускания клавиши (то есть переходе из состояния "отпущена" в состояние "нажата" и наоборот), выполнением запрошенного сброса и самотестирования клавиатуры, а для клавиатур класса AT – выполнением команды от хост-системы для установки абсолютных состояний индикаторов состояния блокировки (светодиодов).
Вызов BIOS: программное обеспечение BIOS прерывается
Операционные системы и другое программное обеспечение взаимодействуют с программным обеспечением BIOS для управления установленным оборудованием посредством программных прерываний. Программное прерывание – это специфический вид общего понятия прерывания. Прерывание – это механизм, с помощью которого процессор может быть перенаправлен на остановку выполнения основной программы и немедленное выполнение специальной программы, называемой обработчиком прерывания (ISR). После завершения ISR процессор продолжает выполнение основной программы. На процессорах x86, при возникновении прерывания, ISR для вызова находится путем поиска в таблице адресов начала ISR (называемых "векторами прерываний") в памяти: таблице векторов прерываний (IVT). Прерывание вызывается по номеру типа от 0 до 255, и этот номер используется как индекс в таблице векторов прерываний, по которому находится адрес ISR, который будет запущен в ответ на прерывание. Программное прерывание – это просто прерывание, инициированное программной командой; поэтому программные прерывания функционируют как подпрограммы, с той разницей, что программа, вызывающая программное прерывание, не нуждается в знании адреса ISR, а только его номера прерывания. Это дает преимущества в модульности, совместимости и гибкости конфигурации системы. Вызовы прерываний BIOS можно рассматривать как механизм передачи сообщений между BIOS и клиентским программным обеспечением BIOS, таким как операционная система. Сообщения запрашивают данные или действие от BIOS и возвращают запрашиваемые данные, информацию о состоянии и/или результат запрошенного действия вызывающей стороне. Сообщения разделены на категории, каждая из которых имеет свой номер прерывания, и большинство категорий содержат подкатегории, называемые "функциями" и идентифицируемые "номерами функций". Клиент BIOS передает большую часть информации в BIOS через регистры процессора и получает большую часть информации обратно тем же способом, но данные, которые слишком велики для размещения в регистрах, такие как таблицы параметров управления или данные секторов диска для передачи данных, передаются путем выделения буфера (то есть области памяти) и передачи адреса буфера в регистрах. (Иногда несколько адресов элементов данных в памяти могут передаваться в структуре данных в памяти, адрес которой передается в BIOS через регистры.) Номер прерывания указывается как параметр инструкции программного прерывания (в ассемблере Intel – инструкция "INT"), а номер функции указывается в регистре AH; то есть, вызывающая сторона устанавливает регистр AH на номер требуемой функции. В общем случае, службы BIOS, соответствующие каждому номеру прерывания, работают независимо друг от друга, но функции в рамках одной службы прерывания обрабатываются одной и той же программой BIOS и не являются независимыми. (Этот момент важен для возможности повторного входа.) Программное обеспечение BIOS обычно возвращает вызывающей стороне код ошибки в случае неудачи или код состояния и/или запрошенные данные в случае успеха. Сами данные могут быть размером всего в один бит или до 65 536 байтов целых необработанных секторов диска (максимальный размер, помещающийся в один сегмент памяти реального режима). BIOS многократно расширялся и совершенствовался на протяжении многих лет различными корпорациями, и, к сожалению, результатом этой эволюции стало то, что не все функции BIOS, которые можно вызвать, используют согласованные соглашения о форматировании и передаче данных или об отчете о результатах. Некоторые функции BIOS предоставляют подробную информацию о состоянии, в то время как другие могут даже не сообщать об успехе или неудаче, а просто возвращаются молча, оставляя вызывающей стороне предполагать успех (или проверять результат другим способом). Иногда также может быть трудно определить, поддерживается ли определенная функция BIOS на конкретном компьютере или каковы пределы параметров вызова на этом компьютере. (Для некоторых недействительных номеров функций или допустимых номеров функций с недопустимыми значениями ключевых параметров – особенно в ранней версии BIOS IBM – BIOS может ничего не делать и возвращаться без кода ошибки; тогда это [неудобная, но неизбежная] ответственность вызывающей стороны либо избегать этого случая, не выполняя такие вызовы, либо положительно проверять ожидаемый эффект вызова, а не предполагать, что вызов был эффективным. Поскольку BIOS значительно эволюционировал на протяжении своей истории, функция, которая является допустимой в одной версии BIOS от определенного поставщика, может быть недопустимой в более ранней или отличающейся версии BIOS от того же поставщика или в версии BIOS – любого относительного возраста – от другого поставщика.) Поскольку вызовы прерываний BIOS используют передачу параметров на основе регистров процессора, эти вызовы ориентированы на выполнение из языка ассемблера и не могут быть непосредственно выполнены из большинства языков программирования высокого уровня (HLL). Однако язык программирования высокого уровня может предоставить библиотеку оберток, которые преобразуют параметры из формы (обычно основанной на стеке), используемой языком высокого уровня, в форму, основанную на регистрах, требуемую BIOS, а затем обратно в соглашение о вызовах HLL после возврата BIOS. В некоторых вариантах C вызовы BIOS можно выполнять с помощью встроенного ассемблера в модуле C. (Поддержка встроенного ассемблера не является частью стандарта ANSI C, а является расширением языка; поэтому модули C, использующие встроенный ассемблер, менее переносимы, чем модули, соответствующие чистому стандарту ANSI C.)
directed to stop executing the main line program and immediately execute a special program, called an Interrupt Service Routine (ISR), instead. Once the ISR finishes, the CPU continues with the main program. On x86 CPUs, when an interrupt occurs, the ISR to call is found by looking it up in a table of ISR starting point addresses (called "interrupt vectors") in memory: the Interrupt vector table (IVT). An interrupt is invoked by its type number, from 0 to 255, and the type number is used as an index into the Interrupt Vector Table, and at that index in the table is found the address of the ISR that will be run in response to the interrupt. A software interrupt is simply an interrupt that is triggered by a software command; therefore, software interrupts function like subroutines, with the main difference that the program that makes a software interrupt call does not need to know the address of the ISR, only its interrupt number. This has advantages for modularity, compatibility, and flexibility in system configuration. BIOS interrupt calls can be thought of as a mechanism for passing messages between BIOS and BIOS client software such as an operating system. The messages request data or action from BIOS and return the requested data, status information, and/or the product of the requested action to the caller. The messages are broken into categories, each with its own interrupt number, and most categories contain sub categories, called "functions" and identified by "function numbers". A BIOS client passes most information to BIOS in CPU registers, and receives most information back the same way, but data too large to fit in registers, such as tables of control parameters or disk sector data for disk transfers, is passed by allocating a buffer (i. e. some space) in memory and passing the address of the buffer in registers. (Sometimes multiple addresses of data items in memory may be passed in a data structure in memory, with the address of that structure passed to BIOS in registers.) The interrupt number is specified as the parameter of the software interrupt instruction (in Intel assembly language, an "INT" instruction), and the function number is specified in the AH register; that is, the caller sets the AH register to the number of the desired function. In general, the BIOS services corresponding to each interrupt number operate independently of each other, but the functions within one interrupt service are handled by the same BIOS program and are not independent. (This last point is relevant to reentrancy.) The BIOS software usually returns to the caller with an error code if not successful, or with a status code and/or requested data if successful. The data itself can be as small as one bit or as large as 65,536 bytes of whole raw disk sectors (the maximum that will fit into one real mode memory segment). BIOS has been expanded and enhanced over the years many times by many different corporate entities, and unfortunately the result of this evolution is that not all the BIOS functions that can be called use consistent conventions for formatting and communicating data or for reporting results. Some BIOS functions report detailed status information, while others may not even report success or failure but just return silently, leaving the caller to assume success (or to test the outcome some other way). Sometimes it can also be difficult to determine whether or not a certain BIOS function call is supported by the BIOS on a certain computer, or what the limits of a call's parameters are on that computer. (For some invalid function numbers, or valid function numbers with invalid values of key parameters—particularly with an early IBM BIOS version—the BIOS may do nothing and return with no error code; then it is the [inconvenient but inevitable] responsibility of the caller either to avoid this case by not making such calls, or to positively test for an expected effect of the call rather than assuming that the call was effective. Because BIOS has evolved extensively in many steps over its history, a function that is valid in one BIOS version from some certain vendor may not be valid in an earlier or divergent BIOS version from the same vendor or in a BIOS version—of any relative age—from a different vendor.) Because BIOS interrupt calls use CPU register based parameter passing, the calls are oriented to being made from assembly language and cannot be directly made from most high level languages (HLLs). However, a high level language may provide a library of wrapper routines which translate parameters from the form (usually stack based) used by the high level language to the register based form required by BIOS, then back to the HLL calling convention after the BIOS returns. In some variants of C, BIOS calls can be made using inline assembly language within a C module. (Support for inline assembly language is not part of the ANSI C standard but is a language extension; therefore, C modules that use inline assembly language are less portable than pure ANSI standard C modules.)
: запустить BASIC
традиционно переходили к реализации Cassette BASIC (предоставленной Microsoft), хранящейся в дополнительных ПЗУ. Этот вызов обычно активировался, если BIOS не мог обнаружить загрузочные дисковые тома при запуске. В момент выпуска оригинального IBM PC (машина IBM типа 5150) в 1981 году, BASIC в ПЗУ был ключевой особенностью. Популярные персональные компьютеры того времени, такие как Commodore 64 и линейка Apple II, также имели Microsoft Cassette BASIC в ПЗУ (хотя Commodore переименовала свою лицензионную версию в Commodore BASIC), поэтому для конкуренции на значительной части целевого рынка IBM PC требовался BASIC. Как и в этих других системах, ROM BASIC IBM PC служил примитивной операционной системой без дисков, позволяя пользователю загружать, сохранять и запускать программы, а также создавать и редактировать их. (Оригинальный IBM PC также был единственной моделью ПК от IBM, которая, подобно своим двум вышеупомянутым конкурентам, включала аппаратный интерфейс для кассет. Базовая модель IBM PC имела всего 16 КБ оперативной памяти и не имела дисководов [никаких], поэтому интерфейс кассеты и BASIC в ПЗУ были необходимы для обеспечения работоспособности базовой модели. IBM PC с менее чем 32 КБ оперативной памяти не может загружаться с диска. Из пяти 8 КБ микросхем ПЗУ в оригинальном IBM PC, общей емкостью 40 КБ, четыре содержат BASIC и только одна – BIOS; при установке всего 16 КБ оперативной памяти, ROM BASIC занимает более половины всей системной памяти [в точности 4/7].) Со временем, когда BASIC перестал поставляться со всеми ПК, это прерывание просто отображало сообщение об ошибке, указывающее на отсутствие загрузочного тома (например, "No ROM BASIC", или более информативные сообщения в более поздних версиях BIOS); в других версиях BIOS пользователю предлагалось вставить загрузочный том и нажать клавишу, после чего, при нажатии клавиши, управление возвращалось к загрузчику (INT 19h) для повторной попытки загрузки. Rainbow 100B от Digital использовала BIOS, несовместимый с BIOS IBM. Turbo Pascal, Turbo C и Turbo C++ использовали INT 18 для выделения памяти и организации постраничной памяти. Другие программы также использовали этот вектор для своих целей.
DOS
На системах DOS, IO.SYS или IBMBIO.COM перехватывают прерывание INT 13 для обнаружения смены дискеты, отслеживания вызовов форматирования, исправления ошибок границ DMA и обхода проблем в ROM BIOS IBM версии "01/10/84" с кодом модели 0xFC до первого обращения к нему.
Обход BIOS
Многие современные операционные системы (например, Linux и Windows) после загрузки вообще не используют вызовы прерываний BIOS, предпочитая напрямую взаимодействовать с аппаратным обеспечением. Для этого они полагаются на драйверы, которые являются частью ядра ОС, поставляются вместе с ОС или предоставляются производителями оборудования. Существует несколько причин для такой практики. Наиболее важная заключается в том, что современные операционные системы работают с процессором в защищенном (или длинном) режиме, в то время как код BIOS выполняется только в реальном режиме. Это означает, что если ОС, работающая в защищенном режиме, захочет выполнить вызов BIOS, ей сначала придется переключиться в реальный режим, затем выполнить вызов и дождаться его завершения, и, наконец, вернуться в защищенный режим. Это было бы крайне медленно и неэффективно. Код, работающий в реальном режиме (включая BIOS), ограничен доступом к немного более 1 Мбайт памяти из-за использования 16-битной сегментированной адресации. Кроме того, BIOS обычно не является самым быстрым способом выполнения той или иной задачи. Фактически, ограничения скорости BIOS приводили к тому, что даже в эпоху DOS программы обходили его, чтобы избежать снижения производительности, особенно при отображении видеографики и организации быстрой последовательной связи. Помимо вышеперечисленных факторов, проблемы с функциональностью BIOS включают ограниченный набор определяемых функций, несогласованность поддерживаемых подмножеств этих функций на разных компьютерах и различия в качестве BIOS (то есть некоторые BIOS полные и надежные, а другие – урезанные и содержат ошибки). Взяв решение в свои руки и отказавшись от использования BIOS, разработчики операционных систем могут устранить некоторые риски и сложности, связанные с написанием и поддержкой системного программного обеспечения. С другой стороны, они берут на себя ответственность за предоставление драйверов для "голого железа" для каждой системы или периферийного устройства, с которым должна работать их операционная система (или за стимулирование производителей оборудования к предоставлению этих драйверов). Таким образом, должно быть очевидно, что компактные операционные системы, разрабатываемые с ограниченным бюджетом, будут активно использовать BIOS, в то время как крупные операционные системы, создаваемые большими группами инженеров-программистов с большими бюджетами, чаще будут разрабатывать собственные драйверы вместо использования BIOS – то есть, даже не принимая во внимание проблемы совместимости BIOS и защищенного режима.