Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Включение мультизадачности в i386  (Прочитано 26505 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Serg79
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« : 19-09-2007 04:45 » 

Пытаюсь переключить i386 в мультизадачный режим, использую следующий алгоритм:
1 - подготавливаю дескриптор задачи TSS в GDT;
2 - загружаю селектор дескриптора задачи в TR ("ltr");
3 - сбрасываю флаг занятости "B" в дескрипторе текущей задаче;
4 - делаю дальний переход на текущую задачу.

Так вот, после пункта 4 процессор становиться. Кто знает, как грамотно запустить мультизадачность на i386 подскажите.
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #1 : 19-09-2007 12:17 » 

Serg79, Не совсем понятно. Виртуальный режим или мультизадачность? Для каких целей? Какая ОС? Какой исходный процессор?
Так как все это прерагатива самой ОС..

Мультизадачность на i386 не запускается, а эмулируется.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Serg79
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #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
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #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
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 29-01-2009 07:14 » 

А что есть fork()? Новый процесс - новая таблица страниц. Т.ч. никакой мифической команды нет.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
0xff
Гость
« Ответ #6 : 29-01-2009 18:28 » 

Новый процесс также означает новый контекст. Контекст в х86 отслеживается в сегменте TSS. Можно его не использовать  и делать переключение контекста вручную как в линуксе, но это отдельный разговор. Если я создаю копию задачи, то неплохо бы иметь возможность просто скопировать контекст. Если уж разработчики процессора создали абстракцию задачи, то почему оставили в этой абстракции дырки куда надо лезть руками?

При чем тут таблица страниц в твоем ответе я вообще не понял. С таблицей страниц я проблемы не вижу - копируешь и все дела.
« Последнее редактирование: 29-01-2009 18:43 от 0xff » Записан
Serg79
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #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
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #9 : 31-01-2009 05:37 » new

0xff, пиши не уродливый кусок Улыбаюсь Тот же repne movsd.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Serg79
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #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
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #12 : 03-02-2009 07:47 » 

Вот (Процессор в защищенном режиме) 0xff, в данном ответе приложен архив с исходниками посмотри его может что интересное найдешь для себя.

Кстати, там в следующем ответе есть код который запускает 2 задачи и производит переключение между ними (используется TSS и все сопутствующее).

Да 0xff, если что будет непонятно, спрашивай.
« Последнее редактирование: 03-02-2009 07:54 от Serg79 » Записан
0xff
Гость
« Ответ #13 : 03-02-2009 19:25 » 

Спасибо за код, но он кажется не имеет никакого отношения к моему вопросу. Клонирования задач я там не нашел. Переход в защищенный режим и переключение задач как я уже писал проблем не вызывают.
Записан
Serg79
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #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
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #16 : 04-02-2009 06:52 » 

Вопрос кстати не в том "обьясните чайнику как сделать", а в том как сделать красиво и оптимально.
0xff, Ты еще не одной строчки кода не показал. Ты покажи как Ты это сделал, и Тебе подскажут как это переделать красиво, оптимально и лаконичноАга
« Последнее редактирование: 04-02-2009 06:53 от Serg79 » Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #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

У меня есть еше примеры, если надо, скину.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines