Serg79
|
|
« : 19-09-2007 04:45 » |
|
Пытаюсь переключить i386 в мультизадачный режим, использую следующий алгоритм: 1 - подготавливаю дескриптор задачи TSS в GDT; 2 - загружаю селектор дескриптора задачи в TR ("ltr"); 3 - сбрасываю флаг занятости "B" в дескрипторе текущей задаче; 4 - делаю дальний переход на текущую задачу.
Так вот, после пункта 4 процессор становиться. Кто знает, как грамотно запустить мультизадачность на i386 подскажите.
|
|
|
Записан
|
|
|
|
Finch
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
|
« Ответ #1 : 19-09-2007 12:17 » |
|
Serg79, Не совсем понятно. Виртуальный режим или мультизадачность? Для каких целей? Какая ОС? Какой исходный процессор? Так как все это прерагатива самой ОС..
Мультизадачность на i386 не запускается, а эмулируется.
|
|
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
Serg79
|
|
« Ответ #2 : 19-09-2007 12:33 » |
|
Процессор семейства i386, ОС не использую, сам загружаю свой код с floppy по включению питания. Я для переключения процессора в мультизадачность использую следующий алгоритм: ; 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") и у меня все становиться. У меня такое ощущение, что я гдето просто чегото не доделываю.
|
|
|
Записан
|
|
|
|
Serg79
|
|
« Ответ #3 : 21-09-2007 06:59 » |
|
Грабли были в том, что при сохранении контекста задачи в сегменте "TSS", регистр "cr3" не сохраняется. И при переключении обратно на эту задачу в регистр "cr3" загружались нули и все сыпалось, даже исключения не выскакивали. И еще, дальний переход с помощью команды "ljmp" на задачу которая сейчас выполняется, даже при сброшенном флаге "busy" дескрипторе задачи, так же останавливает процессор и не генерирует исключения защиты процессора.
|
|
|
Записан
|
|
|
|
0xff
Гость
|
|
« Ответ #4 : 29-01-2009 00:18 » |
|
А кто знает как сбросить текущий контекст в TSS? Допустим я переключился на задачу А, задача A хочет сделать форк. Логично было бы скопировать контекст задачи А в контекст создаваемой задачи. Но в TSS контекст старый. Как его синхронизировать без того чтобы пальцAми запихивать каждый регистр в TSS? В мануалах интела я такой команды не нашел. Там написано что контекст сохраняется в TSS при переключении задачи. Как быть с форком?
|
|
« Последнее редактирование: 29-01-2009 18:40 от 0xff »
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #5 : 29-01-2009 07:14 » |
|
А что есть fork()? Новый процесс - новая таблица страниц. Т.ч. никакой мифической команды нет.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
0xff
Гость
|
|
« Ответ #6 : 29-01-2009 18:28 » |
|
Новый процесс также означает новый контекст. Контекст в х86 отслеживается в сегменте TSS. Можно его не использовать и делать переключение контекста вручную как в линуксе, но это отдельный разговор. Если я создаю копию задачи, то неплохо бы иметь возможность просто скопировать контекст. Если уж разработчики процессора создали абстракцию задачи, то почему оставили в этой абстракции дырки куда надо лезть руками?
При чем тут таблица страниц в твоем ответе я вообще не понял. С таблицей страниц я проблемы не вижу - копируешь и все дела.
|
|
« Последнее редактирование: 29-01-2009 18:43 от 0xff »
|
Записан
|
|
|
|
Serg79
|
|
« Ответ #7 : 30-01-2009 06:47 » |
|
0xff, одним копированием TSS здесь не обойтись, во первых Тебе надо будет в новом TSS указать новые параметры для стека, не будут же два разных процесса использовать один стек. Во вторых, необходимо будет подготовить все дескрипторы, а это как минимум - дескриптор задач TSS, дескриптор кода, дескриптор данных, и дескриптор стека. Ну и в конце необходимо передать управление новой задаче, как ты это будешь делать (вручную, либо с помощью шлюза задач) это не важно.
Ну да, как правильно RXL заметил, если включено страничное преобразование, то надо еще позаботиться о правильном значении для регистра cr3 в структуре TSS.
|
|
« Последнее редактирование: 30-01-2009 06:49 от Serg79 »
|
Записан
|
|
|
|
0xff
Гость
|
|
« Ответ #8 : 30-01-2009 18:22 » |
|
Я это все знаю и это все уже написано и работает, и переключение задач и страничная адресация. Просто в операционке которую я пишу я стартаюсь по минимуму использовать ассемблер. Поэтому не хочу писать уродливый кусок кода который будет в fork()-e все текущие регистры скидывать в TSS. А поменять нужные поля в структуре TSS можно и из C.
|
|
« Последнее редактирование: 30-01-2009 18:27 от 0xff »
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #9 : 31-01-2009 05:37 » |
|
0xff, пиши не уродливый кусок Тот же repne movsd.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Serg79
|
|
« Ответ #10 : 31-01-2009 09:02 » |
|
0xff, у Тебя возникают трудности при переходе исполняющего кода от 'Ассемблера' к 'C'?
|
|
« Последнее редактирование: 31-01-2009 09:04 от Serg79 »
|
Записан
|
|
|
|
0xff
Гость
|
|
« Ответ #11 : 03-02-2009 00:30 » |
|
0xff, пиши не уродливый кусок Тот же repne movsd. поясни как repne movsd может запомнить текущее состояние всех регистров 0xff, у Тебя возникают трудности при переходе исполняющего кода от 'Ассемблера' к 'C'?
нет не возникают
|
|
|
Записан
|
|
|
|
Serg79
|
|
« Ответ #12 : 03-02-2009 07:47 » |
|
Вот ( Процессор в защищенном режиме) 0xff, в данном ответе приложен архив с исходниками посмотри его может что интересное найдешь для себя. Кстати, там в следующем ответе есть код который запускает 2 задачи и производит переключение между ними (используется TSS и все сопутствующее). Да 0xff, если что будет непонятно, спрашивай.
|
|
« Последнее редактирование: 03-02-2009 07:54 от Serg79 »
|
Записан
|
|
|
|
0xff
Гость
|
|
« Ответ #13 : 03-02-2009 19:25 » |
|
Спасибо за код, но он кажется не имеет никакого отношения к моему вопросу. Клонирования задач я там не нашел. Переход в защищенный режим и переключение задач как я уже писал проблем не вызывают.
|
|
|
Записан
|
|
|
|
Serg79
|
|
« Ответ #14 : 03-02-2009 20:03 » |
|
0xff, ну Ты даешь. Если Ты смог реализовать аппаратное переключение задач (это второй архив), то реализация аналога fork у Тебя вообще не должна вызывать проблем.
Самое простое, это решить задачу в лоб: 1 - Создаешь копии сегментов кода, данных и стека, копируемого выполняемого потока. 2 - Добавляешь дескрипторы созданных сегментов в LDT. 3 - Создаешь копию TSS, копируемого выполняемого потока. 4 - В новой таблице TSS, исправляешь регистры ES, CS, SS, DS, FS, GS и LDTR таким образом, что бы они указывали на вновь созданные дескрипторы.
Вот и все. Теперь передаешь управление на вновь созданную таблицу TSS.
Кстати, во втором архиве весь код написан на 'C' и доступ к дескрипторам и TSS так же происходит на 'C'. Так что я не вижу проблем, что бы реализовать все это с использованием языка 'C'. Во втором архиве на ассемблере написан только загрузочный сектор и код переключающий процессор в PM, а все остальное написано на 'C'.
|
|
|
Записан
|
|
|
|
0xff
Гость
|
|
« Ответ #15 : 03-02-2009 22:05 » |
|
Serg79, пойми меня правильно, я ценю твою помощь, но прочитай пожалуйста мой вопрос внимательно. Oн был о шаге номер 3: как лучше скопировать текущий контекст в новый? Tо есть содержимое регистров eax, ebx и иже с ними. Если просто скопировать TSS копируемой задачи, то он боюсь не отражает текущее состояние. В нем будет состояние задачи ма момент последнего переключения.
Вопрос кстати не в том "обьясните чайнику как сделать", а в том как сделать красиво и оптимально. Критерий оптимальности это в том числе насколько код лаконичен и читаем.
|
|
« Последнее редактирование: 03-02-2009 23:59 от 0xff »
|
Записан
|
|
|
|
Serg79
|
|
« Ответ #16 : 04-02-2009 06:52 » |
|
Вопрос кстати не в том "обьясните чайнику как сделать", а в том как сделать красиво и оптимально.
0xff, Ты еще не одной строчки кода не показал. Ты покажи как Ты это сделал, и Тебе подскажут как это переделать красиво, оптимально и лаконично.
|
|
« Последнее редактирование: 04-02-2009 06:53 от Serg79 »
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #17 : 04-02-2009 08:08 » |
|
0xff, пиши не уродливый кусок Тот же repne movsd. поясни как repne movsd может запомнить текущее состояние всех регистров Регистры у тебя сохраняет проц в TSS - вот его и копируй.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
0xff
Гость
|
|
« Ответ #18 : 04-02-2009 18:11 » |
|
0xff, пиши не уродливый кусок Тот же repne movsd. поясни как repne movsd может запомнить текущее состояние всех регистров Регистры у тебя сохраняет проц в TSS - вот его и копируй. камрад не в теме? прочитай мой предыдущий пост пжалста все умолкаю пока кто-нибудь скажет что то умное и по теме
|
|
« Последнее редактирование: 04-02-2009 18:13 от 0xff »
|
Записан
|
|
|
|
barracudo
Гость
|
|
« Ответ #19 : 04-04-2009 19:02 » |
|
; Программа, выполняющая переход в защищенный режим и немедленный возврат. ; Работает в DOS в реальном режиме и в DOS-окне Windows 95 (Windows ; перехватывает исключения, возникающие при попытке перехода в защищенный ; режим из V86, и позволяет нам работать, но только на минимальном уровне ; привилегий) ; ; Компиляция: ; TASM: ; tasm /m pm0.asm ; tlink /x /t pm0.obj ; MASM: ; ml /c pm0.asm ; link pm0.obj,,NUL,,, ; exe2bin pm0.exe pm0.com ; WASM: ; wasm pm0.asm ; wlink file pm0.obj form DOS COM ;
.model tiny .code .386p ; все наши примеры рассчитаны на 80386 org 100h ; это COM-программа start: ; подготовить сегментные регистры push cs pop ds ; DS - сегмент данных (и кода) нашей программы push 0B800h pop es ; ES - сегмент видеопамяти ; проверить, находимся ли мы уже в защищенном режиме mov eax,cr0 ; прочитать регистр CR0 test al,1 ; проверить бит PE, jz no_V86 ; если он ноль - мы можем продолжать, ; иначе - сообщить об ошибке и выйти mov ah,9 ; функция DOS 09h mov dx,offset v86_msg ; DS:DX - адрес строки int 21h ; вывод на экран ret ; конец COM-программы ; (раз это защищенный режим, в котором работает наша DOS- ; программа, это должен быть режим V86) v86_msg db "Running in V86 mode. Can't switch to PM$"
; сюда передается управление, если мы запущены в реальном режиме no_V86: ; запретить прерывания cli ; запретить немаскируемое прерывания in al,70h ; индексный порт CMOS or al,80h ; установка бита 7 в нем запрещает NMI out 70h,al ; перейти в защищенный режим mov eax,cr0 ; прочитать регистр CR0 or al,1 ; установить бит PE, mov cr0,eax ; с этого момента мы в защищенном режиме ; вывод на экран xor di,di ; ES:DI - начало видеопамяти mov si,offset message ; DS:SI - выводимый текст mov cx,message_l rep movsb ; вывод текста mov ax,0720h ; пробел с атрибутом 07h mov cx,rest_scr ; заполнить этим символом остаток экрана rep stosw ; переключиться в реальный режим mov eax,cr0 ; прочитать CR0 and al,0FEh ; сбросить бит PE mov cr0,eax ; с этого момента процессор работает в реальном ; режиме ; разрешить немаскируемое прерывание in al,70h ; индексный порт CMOS and al,07FH ; сброс бита 7 отменяет блокирование NMI out 70h,al ; разрешить прерывания sti ; подождать нажатия любой клавиши mov ah,0 int 16h ; выйти из COM-программы ret ; текст сообщения с атрибутом после каждого символа для прямого вывода на экран message db 'H',7,'e',7,'l',7,'l',7,'o',7,' ',7,'f',7 db 'r',7,'o',7,'m',7,' ',7,'P',7,'M',7 ; его длина в байтах message_l = $-message ; длина оставшейся части экрана в словах rest_scr = (80*25)-(2*message_l) end start У меня есть еше примеры, если надо, скину.
|
|
|
Записан
|
|
|
|
|