.
..
...
;9
mov eax,501000h [COLOR="Green"];Ставим сегмент TSS_All - в нём и будут все TSS[/COLOR]
mov bx,offset GDT_9
mov edx,0FFFFh
mov cl,DATA_Acc
call set_descriptor
;10
mov eax,501000h [COLOR="#008000"];Ставим сегмент для TSS загрузчика[/COLOR]
mov bx,offset GDT_10
mov edx,0FFFFh
mov cl,10000101b
call set_descriptor
...
..
.
TSS и переключение
RM:
Код:
PM:
Код:
.
..
...
[COLOR="#008000"];Ставим TSS текущей задачи (загрузчика)[/COLOR]
xor di,di
mov esi,0000000000010000000000000001000b
mov bp,111000b
call Set_TSS
mov ax,1010000b
ltr ax
[COLOR="#008000"];Создаём дескр. Второй задачи[/COLOR]
mov ax,10000b
mov dx,ax
mov eax,501068h
mov bx,offset GDT_11
mov edx,0FFFFh
mov cl,10000101b
call set_descriptor
[COLOR="#008000"];TSS - для второй задачи[/COLOR]
mov di,104
mov eax,CR3
mov edx,eSP
mov EBX,offset task_test1
mov ecx,0
mov esi,0000000000010000000000000001000b
mov bp,111000b
call Set_TSS
[COLOR="Red"]
;Тут возникает ошибка
;Ругается на стек (ошибка E:0Ch)
db 0eah ; Этот код эквивалентен команде FAR JMP 1011000:00
dw 00
dw 1011000b
[/COLOR]
..
...
[COLOR="#008000"];Ставим TSS текущей задачи (загрузчика)[/COLOR]
xor di,di
mov esi,0000000000010000000000000001000b
mov bp,111000b
call Set_TSS
mov ax,1010000b
ltr ax
[COLOR="#008000"];Создаём дескр. Второй задачи[/COLOR]
mov ax,10000b
mov dx,ax
mov eax,501068h
mov bx,offset GDT_11
mov edx,0FFFFh
mov cl,10000101b
call set_descriptor
[COLOR="#008000"];TSS - для второй задачи[/COLOR]
mov di,104
mov eax,CR3
mov edx,eSP
mov EBX,offset task_test1
mov ecx,0
mov esi,0000000000010000000000000001000b
mov bp,111000b
call Set_TSS
[COLOR="Red"]
;Тут возникает ошибка
;Ругается на стек (ошибка E:0Ch)
db 0eah ; Этот код эквивалентен команде FAR JMP 1011000:00
dw 00
dw 1011000b
[/COLOR]
процедура set_descriptor:
Код:
; Создаёт дескриптор.
; DS:BX = дескриптор в GDT
; EAX = адрес сегмента
; EDX = предел сегмента
; CL = байт прав доступа (access_rights)
;работает на 100% правильно
; DS:BX = дескриптор в GDT
; EAX = адрес сегмента
; EDX = предел сегмента
; CL = байт прав доступа (access_rights)
;работает на 100% правильно
процедура Set_TSS:
Код:
set_TSS proc near
; Создаёт 32-разрядный TSS минимального размера (104 байта - предел 67h).
; DI = указатель на TSS внутри сегмента TSS_area
; Параметры новой задачи:
; EAX = CR3
; EBX = EIP
; ECX = EFLAGS
; EDX = ESP
; esi=селекторы{CS,SS}
; BP=Sel(ss)
push eax
push bx
push di
push es
push eax ; Сохраняем регистры для очистки TSS.
push ecx
push di
mov ax,1001000b ; ES:DI указывают на начало TSS.
mov es,ax
xor eax,eax ; Очищаем 26 двойных слов (т.е. 104 байта)
mov cx,26 ; в TSS. Это делается для потому, что
cld ; большинство полей TSS будут содержать нули.
rep stosd
pop di
pop ecx
pop eax
mov es:[ di + 28 ],eax ; Записали CR3
mov es:[ di + 32 ],ebx ; EIP
mov es:[ di + 36 ],ecx ; EFLAGS
mov es:[ di + 56 ],edx ; ESP
mov ax,si
mov es:[ di + 76 ],al ; CS ( = 8 = Code_selector )
shr esi,16
mov ax,si
mov es:[ di + 80 ],al ; SS ( = 16 = Stack_selector )
mov ax,bp
mov es:[ di + 84 ],al ; DS ( = 24 = Data_selector )
pop es
pop di
pop bx
pop eax
ret
endp
; Создаёт 32-разрядный TSS минимального размера (104 байта - предел 67h).
; DI = указатель на TSS внутри сегмента TSS_area
; Параметры новой задачи:
; EAX = CR3
; EBX = EIP
; ECX = EFLAGS
; EDX = ESP
; esi=селекторы{CS,SS}
; BP=Sel(ss)
push eax
push bx
push di
push es
push eax ; Сохраняем регистры для очистки TSS.
push ecx
push di
mov ax,1001000b ; ES:DI указывают на начало TSS.
mov es,ax
xor eax,eax ; Очищаем 26 двойных слов (т.е. 104 байта)
mov cx,26 ; в TSS. Это делается для потому, что
cld ; большинство полей TSS будут содержать нули.
rep stosd
pop di
pop ecx
pop eax
mov es:[ di + 28 ],eax ; Записали CR3
mov es:[ di + 32 ],ebx ; EIP
mov es:[ di + 36 ],ecx ; EFLAGS
mov es:[ di + 56 ],edx ; ESP
mov ax,si
mov es:[ di + 76 ],al ; CS ( = 8 = Code_selector )
shr esi,16
mov ax,si
mov es:[ di + 80 ],al ; SS ( = 16 = Stack_selector )
mov ax,bp
mov es:[ di + 84 ],al ; DS ( = 24 = Data_selector )
pop es
pop di
pop bx
pop eax
ret
endp
P.S. и еще не забывай в TSS устанавливать EFLAGS, если этого делать не будешь, это тоже может вызвать ошибку (т.к. регистр флагов содержит важные поля, такие как iopl), и корректно устанавливай в TSS базу карты ввода/вывода, иначе при командах доступа к портам может возникнуть ошибка....
... а текущий TSS у тебя не установлен (регистр TR - пуст)!!!!
[/QUOTE]
Как так пуст а этот кусок кода:
PM:
Код:
.
..
...
;Ставим TSS текущей задачи (загрузчика)
xor di,di
mov esi,0000000000010000000000000001000b
mov bp,111000b
call Set_TSS
[COLOR="Blue"]mov ax,1010000b
ltr ax[/COLOR]
...
..
.
..
...
;Ставим TSS текущей задачи (загрузчика)
xor di,di
mov esi,0000000000010000000000000001000b
mov bp,111000b
call Set_TSS
[COLOR="Blue"]mov ax,1010000b
ltr ax[/COLOR]
...
..
.
По внимательнее прочитай мой исходник ...
А вот какие поля EFLAGS есть и какие значения там должны быть, я пока не знаю.
Подскажешь?
Регистр EFLAGS хорошо описан в книге "библиотека системного программиста том 6"
Код:
;TSS - для второй задачи
mov di,104
mov eax,CR3
mov edx,eSP
mov EBX,offset task_test1
[color=red]mov ecx,0[/color]
mov esi,0000000000010000000000000001000b
mov bp,111000b
call Set_TSS
mov di,104
mov eax,CR3
mov edx,eSP
mov EBX,offset task_test1
[color=red]mov ecx,0[/color]
mov esi,0000000000010000000000000001000b
mov bp,111000b
call Set_TSS
Как я понял это у тебя регистр флагов, а ты его делаешь пустым, хотя некоторые биты должны быть строго установлены в 1 (например бит 1), поле iopl желательно устанавливать равным 3
Когда я делаю [COLOR="#0000ff"]jmp far[/COLOR] (селектор TSS 2):[COLOR="Green"]00[/COLOR]
происходит исключение [COLOR="#008000"]0Ch[/COLOR]. Не понимаю :eek: , причём тут стек?
плиз объясните!!!
так?:
Код:
[COLOR="Green"]00000010b[/COLOR]
А вообще искать ошибки в коде системного уровня - это очень неблагодарное занятие! От своих собственных описок ты должен избавляться сам путем тестирования и последующего анализа исходного текста в случае возникновения ошибки. Когда же действительно сталкиваешься с какой-то серьезной проблемой, то будет лучше, если ты сначала опишешь ее на словах, а уж потом будешь вывешивать код.
Цитата:
будет лучше, если ты сначала опишешь ее на словах,
Суть задачи такая:
1) мы включили PM
2) создаём TSS1
3) делаем TSS1 текущим (LTR)
4) создаём TSS2
5) переключаемся на TSS2 (делаем JMP FAR на TSS2 )
Вот на пункте (5) происходит исключение 0Ch - исключение стека. Прикол в том что стек инициализорован и работает нормально (call, ret, push, pop - всё работает нормально), переполнения быть не может я его временно вообще 4Кб сделал.
Не понимаю, в чём ошибка? Вот код:
Код:
mov di,1010000b [COLOR="#008000"];Селектор TSS1[/COLOR]
mov esi,0000100000010000b [COLOR="#008000"];[16 CS][16 DS][/COLOR]
mov ebp,111000b [COLOR="#008000"];SS[/COLOR]
call Set_TSS [COLOR="Green"];Создаём TSS1 - сегмент (di - его селектор) создан ещё в RM[/COLOR]
mov ax,10000b
mov ds,ax
mov eax,5010000h
mov bx,offset GDT_10
mov edx,0FFFFh
mov cl,10001001b
call set_descriptor [COLOR="#008000"];Делаем из сегмента данных системный сегмент TSS[/COLOR]
mov ax,1010000b
ltr ax [COLOR="#008000"];текущий TSS := TSS1[/COLOR]
mov eax,0 [COLOR="#008000"];Без LDT, IOmap - всё открыть[/COLOR]
mov ebx,offset task_test1 [COLOR="#008000"];EIP[/COLOR]
mov di,02h [COLOR="#008000"];номер TSS=2[/COLOR]
mov edx,esp [COLOR="#008000"];ESP - текущее[/COLOR]
mov esi,1000b ;
shl esi,16 [COLOR="#008000"];CS[/COLOR]
mov si,111000b [COLOR="#008000"];SS[/COLOR]
call Set_big_TSS [COLOR="#008000"];создаём TSS2[/COLOR]
[COLOR="Red"]db 09ah ; Этот код эквивалентен команде FAR JMP TSS2:00
dw 00
dw 1011000b[/COLOR]
ПРОЦЕДУРЫ Set_big_TSS и Set_TSS - работают нормально
mov esi,0000100000010000b [COLOR="#008000"];[16 CS][16 DS][/COLOR]
mov ebp,111000b [COLOR="#008000"];SS[/COLOR]
call Set_TSS [COLOR="Green"];Создаём TSS1 - сегмент (di - его селектор) создан ещё в RM[/COLOR]
mov ax,10000b
mov ds,ax
mov eax,5010000h
mov bx,offset GDT_10
mov edx,0FFFFh
mov cl,10001001b
call set_descriptor [COLOR="#008000"];Делаем из сегмента данных системный сегмент TSS[/COLOR]
mov ax,1010000b
ltr ax [COLOR="#008000"];текущий TSS := TSS1[/COLOR]
mov eax,0 [COLOR="#008000"];Без LDT, IOmap - всё открыть[/COLOR]
mov ebx,offset task_test1 [COLOR="#008000"];EIP[/COLOR]
mov di,02h [COLOR="#008000"];номер TSS=2[/COLOR]
mov edx,esp [COLOR="#008000"];ESP - текущее[/COLOR]
mov esi,1000b ;
shl esi,16 [COLOR="#008000"];CS[/COLOR]
mov si,111000b [COLOR="#008000"];SS[/COLOR]
call Set_big_TSS [COLOR="#008000"];создаём TSS2[/COLOR]
[COLOR="Red"]db 09ah ; Этот код эквивалентен команде FAR JMP TSS2:00
dw 00
dw 1011000b[/COLOR]
ПРОЦЕДУРЫ Set_big_TSS и Set_TSS - работают нормально
Я заметил, что ты динамически формируешь TSS, но не мог бы ты четко перечислить, что будет находиться в TSS2, а также указать содержимое всех используемых этой задачей сегментных дескрипторов... Твоя ошибка наверняка происходит из-за противоречия данных, хранящихся в этих структурах...