| 
							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
							
						 | 
						
							
								  | 
								
									
									 « Ответ #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
							
						 | 
						
							
								  | 
								
									
									 « Ответ #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
							
						 | 
						
							
								  | 
								
									
									 « Ответ #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 У меня есть еше примеры, если надо, скину.  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	 |