Редактирование GDT

Тема в разделе "WASM.OS.DEVEL", создана пользователем Barbos, 20 дек 2007.

  1. Barbos

    Barbos Slavon

    Публикаций:
    0
    Регистрация:
    13 ноя 2007
    Сообщения:
    280
    Адрес:
    Kharkov
    Наткнулся на неопределенность. В процессе работы (Protect Mode, никаких серверов, ничего лишнего, все свое собственное) есть необходимость редактировать содержимое GDT, например, при запуске новой задачи. Как именно корректно это осуществить? У меня есть следущие мысли:
    При удалении дескриптора из таблицы, его номер занести в "список свободных дескрипторов", удаляемый при этом затереть нулями (сделать его пустым).
    При выделении нового дескриптора: если "список свободных дескрипторов" пустой, то добавить дескриптор в конец таблицы, заполнить его нужными значениями, увеличить размер GDT, перегрузить GDTR, иначе - взять номер дескриптора из списка и работать с ним.
    Я так понимаю, что на время редактирования GDT должны быть запрещены прерывания, т.е. типа критическая секция. И как лучше оформить данную процедуру? Как обычную, с запрещением/разрешением прерываний установкой флага IF или оформить как обработчик аппаратного прерывания и вызывать его как программное, по идее прерывания буду запрещаться/разрешаться автоматически??.... Кто как думает? бывали у кого нить подобные реализации?
     
  2. Freeman

    Freeman New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2005
    Сообщения:
    1.385
    Адрес:
    Ukraine
    эмм. скажи, зачем тебе надо менять gdt?
    только те, которые используют дескрипторы, которые ты меняешь (то есть возможно все).
    если через interrupt gate, то да, есле через trap, то нет ("5.12.1.2 Flag Usage..." vol. 3a 5-19)
     
  3. Barbos

    Barbos Slavon

    Публикаций:
    0
    Регистрация:
    13 ноя 2007
    Сообщения:
    280
    Адрес:
    Kharkov
    Дело в том, что в будущем колличество запускаемый задач будет меняться и не хотелось бы редактировать много текста. Хотелось бы делать это в динамике, по моему, меньше головной боли будет.
    т.е. я выделяю в IDT какой нибудь дескриптор, описываю его как шлюз прерывания, а вызываю как int N и на время работы внутри процедуры прерывания будут запрещены, так получается? (просто уточнить хочу:))
    а можно ссылочку?:)
     
  4. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    Barbos
    лучше использовать LDT для каждой задачи
    тогда и искать, собственно, ничего не придется
    нет, но на SMP-системе нужно использовать атомарные операции для модификации дескрипторов (или их частей)
     
  5. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    если до int N IF в EFLAGS = 1, то да
     
  6. Barbos

    Barbos Slavon

    Публикаций:
    0
    Регистрация:
    13 ноя 2007
    Сообщения:
    280
    Адрес:
    Kharkov
    да, я придерживаюсь того же мнения, но, как мне кажется, дескрипторы, описывающие LDT должны находиться в GDT
     
  7. Barbos

    Barbos Slavon

    Публикаций:
    0
    Регистрация:
    13 ноя 2007
    Сообщения:
    280
    Адрес:
    Kharkov
    но ведь управление будет передано на процеруду через шлюз прерывания, а не через шлюз ловушки %)
    что то я запутался %)
     
  8. Freeman

    Freeman New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2005
    Сообщения:
    1.385
    Адрес:
    Ukraine
    http://www.intel.com/design/literature.htm
    там можно бумажные маны от интела заказат, либо скачать
     
  9. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    при переключении задач модифицируешь LDT-дескриптор в GDT
    и выполняешь LLDT
    если использовать шлюз прерывания, после сохранения EFLAGS в стеке IF сбрасывается
    IRETD восстанавливает сохраненное значение EFLAGS
     
  10. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    Надо иметь двоичный мьютекс на GDT. Если система будет многопроцессорная, то мэджик с IF не поможет. Работать с GDT можно только если мьютекс свободен. Дескриптор сегмента TSS в LDT запихнуть нельзя. Можно только запихнуть дескрипторы сегмента кода и данных. Более-менее нормальное решение - это дать заявку планировщику на создание потока. Либо на время создания нити блокировать GDT-мьютекс.
     
  11. Barbos

    Barbos Slavon

    Публикаций:
    0
    Регистрация:
    13 ноя 2007
    Сообщения:
    280
    Адрес:
    Kharkov
    с мьютексами согласен, но у меня многопроцессорных систем не будет.
    А вот по поводу запрета прерываний при передаче управления через шлюз прерывания - "Assembler для DOS, Windows и UNIX" Зубков С. В. второе издание, стр 499: "Единственное различие между шлюзом прерывания и ловушки состоит в том, что при передачи управления через шлюз прерывания автоматически запрещаются дальнейшие прерывания, пока обработчик не выполнит IRETD".
    Ну т.е. так оно и получается, после помещения EFLAGS в стек при вызове через шлюз прерывания, IF будет сброшен и процессор не будет реагировать на запросы от 8529. Вобщем, оформляется некий обработчик аппаратного прерывания, цепляется на свободный вектор и, при помощи команды int, управление передается обработчику через шлюз прерывания и автоматически сбрасывается IF. Вот и будет некое атомарное действие. Единственное, щас надо будет это прогнать на практике.
     
  12. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    Всё же мьютексы более симпатичны, потому что не надо отключать прерывания. И реализуются просто (при помощи команды xchg).
     
  13. Barbos

    Barbos Slavon

    Публикаций:
    0
    Регистрация:
    13 ноя 2007
    Сообщения:
    280
    Адрес:
    Kharkov
    возможно, но не все сразу:)
    я щас в плане работы с системными регистрами только тропинку протаптываю. До этого работал всегда через DPMI, а щас решил, что хватит сил обходится без него.
    Но все равно спрошу:).
    Как реализуется работа с помощью мьютексов? хотя бы схематически? Их я тоже никогда не использовал, их механизма пока не знаю.
     
  14. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    прежде чем модифицировать GDT, захватывается блокировка
    после модификации освобождается
    работу с блокировками можно реализовать так
    Код (Text):
    1. spin_lock:
    2. ; eax contains address of spin-lock variable
    3.     push edx
    4.     xor edx, edx
    5.     inc edx
    6. __spin_lock:
    7.     cmp dword [eax], 0
    8.     jz @F
    9.     pause
    10.     jmp __spin_lock
    11. @@:
    12.     xchg edx, dword [eax]
    13.     test edx, edx
    14.     jnz __spin_lock
    15.     pop edx
    16.     ret
    Код (Text):
    1. spin_unlock:
    2.     push edx
    3.     xor edx, edx
    4.     xchg edx, dword [eax]
    5.     pop edx
    6.     ret
     
  15. Phantom_84

    Phantom_84 New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2007
    Сообщения:
    820
    Нормальная схема, хотя лично я бы выполнил оптимизацию так, чтобы не перегружать GDTR при каждом расширении GDT. "Затирать" весь дескриптор нулями нет необходимости, достаточно обнулить байт прав доступа.

    Запрещать прерывания нет необходимости, если ты сможешь организовать полное добавление/удаление группы дескрипторов для задачи, включая в том числе и работу со "списком свободных дескрипторов", так чтобы эта операция в многозадачном режиме работы не пересекалась с такой же операцией, выполняемой в другом потоке команд. Оформлять это процедуру как отдельный обработчик программного прерывания, вызываемый через шлюз прерывания, естественно, не нужно. Это внутрисистемная процедура, поэтому чем меньше "видимых концов" она имеет, тем лучше.
     
  16. Barbos

    Barbos Slavon

    Публикаций:
    0
    Регистрация:
    13 ноя 2007
    Сообщения:
    280
    Адрес:
    Kharkov
    а какими проблемами и в каких ситуациях может обернуться перезагрузка GDTR? Если не использовать в работе расширение GDT, то тогда она изначально должна быть достаточного размера под максимально используемое кол-во дескрипторов? других идей мне в голову не лезет
     
  17. Phantom_84

    Phantom_84 New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2007
    Сообщения:
    820
    Проблем не будет. Я говорил просто об оптимизации, хотя создание/уничтожение задачи является не на столько частой операцией, как, скажем, переключение задач. Не обязательно задавать лимит GDT сразу на максимальное число дескрипторов (но если не экономить память, это конечно наиболее предпочтительный вариант). Можно, например, менять лимит GDT постранично вместе с распределением/высвобождением очередной страницы памяти под GDT. Правда, в этом случае время на выполнение операции будет затрачиваться крайне неравномерно, т.к. помимо времени на распределение самой страницы нужно тратить время на обнуление всех неиспользуемых дескрипторов внутри нее. Хотя честно говоря я сам использую далеко не оптимальный способ работы с GDT, перезаписывая GDTR при каждом добавлении/удалении группы дескрипторов, правда, это происходит только при загрузке/выгрузке драйверов, а для представления всех прикладных задач используется одна и та же группа десрипторов с фиксированным местоположением.
     
  18. Barbos

    Barbos Slavon

    Публикаций:
    0
    Регистрация:
    13 ноя 2007
    Сообщения:
    280
    Адрес:
    Kharkov
    Все, я ушел в GDT :-D