Векторы ОСей

Тема в разделе "WASM.OS.DEVEL", создана пользователем red_Human, 23 июн 2009.

  1. red_Human

    red_Human New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2008
    Сообщения:
    182
    Насколько я понял из того, что читал в инете векторы служат для того, чтобы всякие внешние проги могли найти сисвызов в ядре, а то адреса этих подпрограмм постоянно изменяются и внешние проги этого не отследят. Так? Если это так, то разговор продалжаем. Сам вектор это jmp на адрес сисвызова, а так как его размещает в самом начале кода ОСи, то его положение постоянно и внешние проги могут обращаться к нему, а не к сисвызову. И мне не понятно, а как он(вектор) производит нужный jmp на сисвызов?
     
  2. SII

    SII Воин против дзена

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    Бред. Начать с того, что вектор _чего_? Вектор -- это вообще-то направленный отрезок и прочее математическое бла-бла-бла...
     
  3. Wizard109

    Wizard109 New Member

    Публикаций:
    0
    Регистрация:
    6 ноя 2006
    Сообщения:
    346
    Читал в инете что msdn - ценный источник сведений о внутренностях винды, совместно с книгой Руссиновича это сила !
     
  4. FatMoon

    FatMoon New Member

    Публикаций:
    0
    Регистрация:
    28 ноя 2002
    Сообщения:
    954
    Адрес:
    Russia
    (*использую Силу*)(*читаю мысли*)
    Для процессоров х86:
    Векторы прерываний для реального режима (16-разрядного, ДОС) располагаются в младших адресах, как правило, с адреса 0. (вообще, это зависит от нескольких моментов, как заданных таблиц дескрипторов, так и программируемого контроллера прерываний... но по умолчанию, при загрузке компьютера, это обычно 0). "Вектор" в данном случае - это 4 байта, содержащие сегмент и смещение процедуры, данное прерывание обрабатывающей. Вектор не содержит команды jmp - это просто указатель, если угодно. Вектор никак не производит jmp - это делает процессор при возникновении прерывания (без разницы, при команде int или от какого-либо устройства), руководствуясь именно упомянутыми таблицами и контроллером прерываний.
    Адреса программ-обработчиков в самом деле могут меняться. В частности, при установке резидентной программы нужный вектор подменяется новым, указывающим на загруженный резидент. Но положение таблицы векторов остается неизменным...
    Некоторые векторы при этом не являются указателями на процедуры обработки, но - по исторически сложившимся причинам - указателями на какие-либо системные таблицы.

    Читать надо в данном случае вовсе не msdn, а Intel Architecture Software Dewelopers Manual, где по команде int написано много чего, и если это все оболванить и обрезать, для лучшего понимания, то для реального режима при прерывании происходит следующее:
    Код (Text):
    1. Push (FLAGS);
    2. IF ← 0; (* Clear interrupt flag *)
    3. TF ← 0; (* Clear trap flag *)
    4. AC ← 0; (*Clear AC flag*)
    5. Push(CS);
    6. Push(IP);
    7. CS ← IDT(Descriptor (vector_number * 4), selector));
    8. EIP ← IDT(Descriptor (vector_number * 4), offset)); (* 16 bit offset AND 0000FFFFH *)
    9. END;
    То есть, еще раз - процессор при возникновении прерывания сам берет селектор (или сегмент) и смещение из вектора нужного прерывания, это зашито в функционал данной команды. Сами векторы располагаются там, куда их разместят через задание IDT - при включении питания это адрес 00000000. Первое, что делает БИОС - это создает по этому адресу таблицу прерываний, сразу после включения питания. И только потом начинается тест памяти, периферийных устройств, вывод на экран логотипов и тому подобное.


    Для защищенного режима, в операционных системах прерывания либо допустимы из драйверов, либо являются штатной точкой входа в АПИ. Так или иначе, вызов прерывания является привилегированной инструкцией, и тщательно контролируется со стороны ОС. Для их использования, необходимо прочитать массу документации, и тем более не рекомендуется лезть в таблицу векторов (уважающая себя ОС этого все равно не позволит). Строго говоря, если не стоит задача "сделать собственную ОС", лучше вообще не заморачиваться над тем, где векторы прерываний, в каком виде хранятся и есть ли вообще - просто использовать указанные в документации сервисы, по указаным в документации же правилам.

    Для процессоров ВМ80А (и Z80) прерываний всего 8, и программно вызываются они командой RST. При этом происходит переход на адрес i*8 (кажется). То есть, вот тут векторов нет, а есть небольшие кусочки кода, с jmp на продолжение процедуры. "jmp address" в 8-битных системах всего 3 байта, и в остальные 5 иногда можно уместить еще несколько команд...
     
  5. red_Human

    red_Human New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2008
    Сообщения:
    182
    Про векторы вот какие я говорю, цитирую англ:
    Once we've done this, we can access this routine throughout the kernel. But what about external programs? They have no idea where this call is in the kernel! The trick we use is vectors - a bunch of jmp instructions at the start of our kernel code, which jump to these routines. Because these vectors are at the start, they never change their position, so we always know where they are.

    For instance, right now, your new system call may be at 0x9B9D in the kernel. But if you add another call above, or someone else does, it may move to 0x9FA6 in the kernel binary. We simply don't know where it's going to be. But if we put at vector at the start of our kernel, before anything else happens, we can use that as the starting point as the vector will never move!
    Это из документации на MikeOS, раздел про написание системных вызовов
     
  6. FatMoon

    FatMoon New Member

    Публикаций:
    0
    Регистрация:
    28 ноя 2002
    Сообщения:
    954
    Адрес:
    Russia
    Вот с этого и надо было начинать. Этот трюк достаточно старый, и (раз уж я упомянул 8-битные процессоры) наверняка вспомнится всем, у кого был "Радио-86РК". По некоторому адресу размещается цепочка jmp-ов на нужные процедуры:
    Код (Text):
    1. ;org 0xF800
    2. F800: jmp OS_Start
    3. F803: jmp Key_Input
    4. F806: jmp Byte_input
    5. F809: jmp Char_Out
    6. F80B: ...
    Пользователю дается набор адресов:
    - если вы хотите напечатать строку, поместите адрес строки в регистр... и вызовите подпрограмму с адреса 0xF818
    - если вы хотите прочитать нажатую клавишу, вызовите процедуру с адреса 0xF803
    - И так далее.

    То есть это именно то, что ты прочитал - набор jmp'ов. Можно назвать это вектором :) Естественно, размер такого "вектора" зависит от ОС, процессора и/или режима процессора. В результате, есть стандарт на точки входа в процедуры в данной системе, а сами процедуры при перекомпиляции ядра, при перезагрузке, и т.д. - могут находиться в произвольных адресах, главное - чтобы по нужному адресу был переход на нужную процедуру... Очевидно, что эта таблица создается при загрузке ОС... вопрос "как" - думаю уже не возникает? И "как вектор делает jmp" - тоже должно быть понятно :))
     
  7. FatMoon

    FatMoon New Member

    Публикаций:
    0
    Регистрация:
    28 ноя 2002
    Сообщения:
    954
    Адрес:
    Russia
    естественно, все это имеет отношение только к упомянутой MikeOS, и к всплывшим в памяти "Радио-86РК"-Специалисту-Кванту и подобным :)))) Впрочем, ряд игр для "Денди" и "БК0010" имел похожие таблицы, поскольку игра компилировалась со всей библиотекой, в начале - переход на игру, потом - таблица переходов, потом в игре - call на нужные адреса.
    Примерно такой же принцип у секции импорта в исполняемых файлах Windows.