OSDev http://osdev.su/ |
|
Включение мультизадачности в i386 http://osdev.su/viewtopic.php?f=6&t=124 |
Страница 1 из 2 |
Автор: | serg79 [ 19 сен 2007, 12:50 ] |
Заголовок сообщения: | Включение мультизадачности в i386 |
Пытаюсь переключить i386 в мультизадачный режим, использую следующий алгоритм: 1 - подготавливаю дескриптор задачи TSS в GDT; 2 - загружаю селектор дескриптора задачи в TR ("ltr"); 3 - сбрасываю флаг занятости "B" в дескрипторе текущей задаче; 4 - делаю дальний переход на текущую задачу. Так вот, после пункта 4 процессор становиться. Кто знает, как грамотно запустить мультизадачность на i386 подскажите. P.S. Если нужно больше информации, то спрашивайте. |
Автор: | pushkoff [ 19 сен 2007, 14:49 ] |
Заголовок сообщения: | Re: Включение мультизадачности в i386 |
многозадачность програмная или аппаратная? че-то непонял с первого взгляда... При програмной прыжок вообще не надо делать, при аппаратной надо делать на другую задачу... |
Автор: | serg79 [ 19 сен 2007, 15:23 ] |
Заголовок сообщения: | Re: Включение мультизадачности в i386 |
Я для переключения процессора в мультизадачность использую следующий алгоритм: Код: ; Main_TSS - это селектор некоторого определённого дескриптора TSS. mov ax,Main_TSS ltr ax ; Загружаем в регистр TR селектор ; дескриптора TSS задачи Main. Теперь текущая ; задача - это Main_TSS. ; Чистим Busy flag Main_TSS - он установился после загрузки селектора в TR mov bx,offset GDT + Main_TSS and byte ptr [ bx + 5 ],11111101b ; Переход на Main_TSS db 0eah; Этот код эквивалентен команде FAR JMP Main_TSS:00 dw 00 dw Main_TSS ; Вот здесь процессор сохранил контекст текущей задачи, т.е. заполнил ; поля TSS текущими значениями. ; Main_TSS: ; А теперь процессор загрузил те же самые значения из TSS в регистры. ; Теперь процессор в режиме мультизадачности. ; Установка Busy flag Main_TSS - она нужна, потому что был переход с ; Main_TSS на Main_TSS командой JMP - эта команда сбрасывает флаг занятости ; старой задачи, т.е. Main_TSS. mov bx,offset GDT + Main_TSS or byte ptr [ bx + 5 ],10b Дело в том, что включение мультизадачного режима работы процессора не обязывает при этом иметь несколько задач и обязательно переключаться между ними, можно иметь одну задачу которая будет все время выполняться, но в тоже время это будет задачей т.к. будут задействованы регистр "TR" и использоваться структура "TSS". Так вот, я пытаюсь пока просто перенести текущий выполняемый контекст в задачу. Если не сбрасывать флаг занятости задачи "B" в дескрипторе задачи, пере дальним переходом на нее "FAR JMP TSS:0" то у меня генерируется исключение общей защиты, т.к. на рабочую задачу переключаться нельзя (рекурсивный вызов задач запрещен). И так я дохожу до пункта 4 ("FAR JMP TSS:0") и у меня все становиться. У меня такое ощущение, что я гдето просто чегото не доделываю. |
Автор: | pushkoff [ 19 сен 2007, 18:43 ] |
Заголовок сообщения: | Re: Включение мультизадачности в i386 |
Я когда парился с многозадачностью напаролся на те же грабли... роцессор запрещает переключаться на текущую ТСС даже если флаг Busy у неё сброшен... Таким способом я хотел снять ограничение на количество задач в системе и уменьшить размер ГДТ. Я вышел из положения использоав программную многозадачность, в ней используется только 1 ТСС, но переключение становится более длительным из-за необходимости каждый раз (верней только при смене процесса) копировать каталоги таблиц. Кстати, кто-нибудь думал над методами ускорения переключения процессов при программном переключении задач? |
Автор: | serg79 [ 20 сен 2007, 09:14 ] |
Заголовок сообщения: | Re: Включение мультизадачности в i386 |
Я так понимаю, что при переключении задачи процессор помимо флага занятости "busy" проверяет также сам селектор и если селектор тотже что и в регистре "TR" то он не разрешает переключиться на эту задачу. Но тогда он должен сгенерировать исключение общей защиты, но этого не происходит. Я пробовал загружать в регистр "TR" селектор дескриптора кода и процессор отрабатывал как надо, генерировал исключение общей защиты. Пробовал вызывать "LJMP $D_TSS,$0" при установленном флаге "busy", исключение общей защиты также выкидывается. А при сброшенном флаге "busy" у меня при команде "LJMP $D_TSS,$0" вообще ничего не происходит, процессор просто встает (я так думаю). Почему не выкидывается какое либо исключение? Хотя вы можете быть и правы. Дело в том, что я пробовал загружать регистр "TR" дескриптором задачи и не выполнять дальнего перехода, в этом случае все работает как надо: прерывания работают (таймер, клавиатура), исключения работают и основной код работает. Ладно суть такая, я хочу както удостовериться что режим мультизадачности работает, т.е. хочу посмотреть что поля структуры "TSS" заполняются при переключении задачи. Значит план у меня такой: Код: ; Готовлю дескрипторы задач Main_TSS, Temp_TSS ; Загружаю "TR" movl $Main_TSS, %eax ltr %ax ; Все, мультизадачность запущена ; Переключаюсь на задачу Temp_TSS lcall $Temp_TSS,$0 ; Вот сдесь процессор заполнит поля "TSS" задачи Main_TSS, ; сбрасывает флаг "B" в дескрипторе Main_TSS, потом ; считывает значения из "TSS" задачи Temp_TSS в регистры, ; устанавливает флаг "B" в дескрипторе Temp_TSS, в поле ; "link" структуры "TSS" задачи Temp_TSS записывается ; селектор дескриптора задачи Main_TSS, устанавливает ; флаг "NT" в "eflags" и передает управление коду задачи Temp_TSS ; Вот в этой части кода, уже будут заполнены структуры "TSS" ; как задачи Main_TSS так Temp_TSS и я их могу посматреть 1: jmp 1b ; Задача Temp_TSS .globl tmp_func tmp_func: nop iret ; т.к. установлен флаг "NT" в регистре "eflags" то управление ; передается задаче чей селектор дескриптора храниться в поле ; "link" структуры "TSS" текущей выполняемой задачи. Вот такие мысли. Как думайте, после того как задача Main_TSS встанет в бесконечном цикле "1: jmp 1b" структуры задач "TSS" будут заполнены? И вообще правильно ли я понимаю суть вопроса и корректен ли данный алгоритм? |
Автор: | serg79 [ 20 сен 2007, 11:03 ] |
Заголовок сообщения: | Re: Включение мультизадачности в i386 |
Спасибо legos, сегодня вечером буду обратно пытаться все таки запустить задачи. |
Автор: | pushkoff [ 20 сен 2007, 12:04 ] |
Заголовок сообщения: | Re: Включение мультизадачности в i386 |
Цитата: Pushkoff, я для упрощения кода, и увеличения кол-ва задач в системе использую только 2 дескриптора TSS в GDT -- каждый раз перед переключением прописываю в GDT ссылку на нужную структуру TSS. Количество TSS - по одному на процесс. Вроде нормально получается, и код простой. //legos Я тоже об этом думал, но передумал... при твоей схеме каждому потоку надо дать участок памяти размером с ТСС + всякие дополнения, это при том что большая часть ТСС имеют одинаковые поля и большая часть контекста сохраниться в стеке. При програмном переключении весь контекст сохраняется в стеке а в описателе потока сохраняется только указатель на стек (при условии что стек ядра для всех потоков расположен в одном и том же месте) поэтому в целях экономии памяти я выбрал такой подход, но возникает проблема с временем переключения, ведь каждый раз нужно перезаписывать часть адреснго пространства (в моем случае 2 кб, но при смене процесса)... хотя при 36 разрядной адрессации нужно будет скопировать 32 байта. |
Автор: | pushkoff [ 20 сен 2007, 13:11 ] |
Заголовок сообщения: | Re: Включение мультизадачности в i386 |
legos, немогу с тобой не согласиться... просто в моем случае экономия выходит довольно сильная... при 1024 потоках 4 мб у тебя против 256 кб у меня, при одинаковых размерах стека... Надо сделать в вике статью об многозадачности типах и достоинствах... |
Автор: | phantom-84 [ 20 сен 2007, 14:00 ] |
Заголовок сообщения: | Re: Включение мультизадачности в i386 |
Цитата: но переключение становится более длительным из-за необходимости каждый раз (верней только при смене процесса) копировать каталоги таблиц. Кстати, кто-нибудь думал над методами ускорения переключения процессов при программном переключении задач? А зачем при переключении копировать каталоги таблиц? Записываешь в CR3 адрес каталога активируемого процесса и все. Каталоги таблиц для процессов (кроме idle-процессов, которые могут быть полность выгружены в своп) я храню в памяти постоянно. К тому же для готовых к выполнению процессов других нормальных вариантов просто нет.
|
Автор: | phantom-84 [ 20 сен 2007, 14:42 ] |
Заголовок сообщения: | Re: Включение мультизадачности в i386 |
Цитата: При програмном переключении весь контекст сохраняется в стеке а в описателе потока сохраняется только указатель на стек (при условии что стек ядра для всех потоков расположен в одном и том же месте) поэтому в целях экономии памяти я выбрал такой подход, но возникает проблема с временем переключения, ведь каждый раз нужно перезаписывать часть адреснго пространства (в моем случае 2 кб, но при смене процесса)... Здесь все просто - нужно либо для каждого потока организовать свой стек ядра, либо сделать так, чтобы полноценно в режиме ядра мог выполняться только один поток процесса, а другие ожидали окончания его работы в режиме ядра - это можно сделать с помощью двухуровневого стека ядра - один уровень с фиксированной длиной и, возможно, местоположением для отработки входа любого потока процесса в режим ядра, а второй уровень для полноценной работы одного из потоков в режиме ядра.
|
Страница 1 из 2 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |