zloi7777
Постоялец
Offline
|
|
« : 01-07-2010 08:03 » |
|
Пишу простую прогу для защищенного режима. Пока нахожусь в нул евом кольце - все работает отлично, как только меняю DPL у цел евого сегмента с 0 на 3, выскакивает общее нарушение зашиты Вот так все работает: тут таблица д ескрипторов: STRUC desc_struc ; структура дескриптора limit dw 0 ; предел base_l dw 0 ; мл. слово физического адреса base_h db 0 ; ст. байт физического адреса access db 0 ; байт доступа acces32 db 0 base_b db 0 ENDS desc_struc ACC_PRESENT EQU 10000000b ; сегмент есть в памЯти [hr]ACC_CSEG EQU 00011000b ; сегмент кода ACC_DSEG EQU 00010000b ; сегмент данных ACC_TSSSEG EQU 00001001b ; TSS ACC_EXPDOWN EQU 00000100b ; сегмент расширЯетсЯ вниз ACC_CONFORM EQU 00000100b ; согласованный сегмент ACC_DATAWR EQU 00000010b ; разрешена запись
ACC_INTR_GATE EQU 00001110b ; вентиль прерываниЯ ACC_TRAP_GATE EQU 00001111b ; вентиль исключениЯ ACC_CALL_GATE EQU 00001100b ACC_TASK_GATE EQU 00000101b
ACC_RING0 EQU 00000000b ACC_RING3 EQU 01100000b
; ------------------------------------------------------------ ; Типы сегментов DATA_ACC = ACC_PRESENT OR ACC_DSEG OR ACC_DATAWR ; сегмент даннх CODE_ACC = ACC_PRESENT OR ACC_CSEG ; сегмент кода STACK_ACC = ACC_PRESENT OR ACC_DSEG OR ACC_DATAWR OR ACC_EXPDOWN ; сегмент стека TSS_ACC = ACC_PRESENT OR ACC_TSSSEG ; TSS
IDT_ACC = DATA_ACC ; байт доступа сегмента таблицы IDT INTR_ACC = ACC_PRESENT OR ACC_INTR_GATE ; байт доступа вентилЯ прерываниЯ TRAP_ACC = ACC_PRESENT OR ACC_TRAP_GATE ; байт доступа вентилЯ исключениЯ CALL_ACC = ACC_PRESENT OR ACC_CALL_GATE TASK_ACC = ACC_PRESENT OR ACC_TASK_GATE
ACS_GRANUL EQU 10000000b ACS_DIMENS EQU 01000000b DATASEG DSEG_BEG = THIS WORD
GDT_BEG = $ LABEL gdtr WORD
gdt_0 desc_struc <0,0,0,0,0,0> gdt_gdt desc_struc <GDT_SIZE-1,,,DATA_ACC,0,0> gdt_idt desc_struc <IDT_SIZE-1,,,IDT_ACC,0,0> gdt_ds desc_struc <03fffh,,,DATA_ACC,0,0> gdt_cs desc_struc <03fffh,,,CODE_ACC OR ACC_DATAWR,0,0> gdt_ss desc_struc <03fffh,00000h,000h,DATA_ACC,ACS_DIMENS,0>
gdt_ds32 desc_struc <0ffffh,00000h,000h,DATA_ACC OR ACC_RING0,ACS_GRANUL OR 00Fh ,000h> gdt_cs32 desc_struc <0ffffh,00000h,000h,CODE_ACC OR ACC_DATAWR OR ACC_RING0,ACS_GRANUL OR ACS_DIMENS OR 00Fh,000h> gdt_ss32 desc_struc <0ffffh,00000h,000h,DATA_ACC OR ACC_RING0,ACS_GRANUL OR ACS_DIMENS OR 00Fh,000h>
gdt_dsdebug desc_struc <0ffffh,00000h,000h,DATA_ACC OR ACC_RING0,ACS_GRANUL OR 00Fh ,000h> gdt_csdebug desc_struc <0ffffh,00000h,000h,CODE_ACC OR ACC_DATAWR OR ACC_RING0,ACS_GRANUL OR ACS_DIMENS OR 00Fh,000h>
gdt_all desc_struc <0ffffh,00000h,000h,DATA_ACC OR ACC_RING0,ACS_GRANUL OR 00Fh ,000h>
gdt_tds32 desc_struc <0ffffh,00000h,000h,DATA_ACC OR ACC_RING0,ACS_GRANUL OR 00Fh ,000h> gdt_tcs32 desc_struc <0ffffh,00000h,000h,CODE_ACC OR ACC_DATAWR OR ACC_RING0,ACS_GRANUL OR ACS_DIMENS OR 00Fh,000h> gdt_tss32 desc_struc <0ffffh,00000h,000h,DATA_ACC OR ACC_RING0,ACS_GRANUL OR ACS_DIMENS OR 00Fh,000h> gdt_ssdebug desc_struc <0ffffh,00000h,000h,DATA_ACC OR ACC_RING0,ACS_GRANUL OR ACS_DIMENS OR 00Fh,000h>
gdt_pzu desc_struc <007ffh,00000h,080h,DATA_ACC OR ACC_RING0,ACS_GRANUL OR 000h ,0ffh> gdt_cpzu desc_struc <007ffh,00000h,000h,DATA_ACC OR ACC_RING0,ACS_GRANUL OR 000h ,0ffh>
gdt_ramq desc_struc <003ffh,00000h,000h,DATA_ACC OR ACC_RING0,ACS_GRANUL OR 000h ,080h> gdt_ramx desc_struc <003ffh,00000h,080h,DATA_ACC OR ACC_RING0,ACS_GRANUL OR 000h ,080h> gdt_ramy desc_struc <003ffh,00000h,000h,DATA_ACC OR ACC_RING0,ACS_GRANUL OR 000h ,081h> gdt_ramz desc_struc <003ffh,00000h,080h,DATA_ACC OR ACC_RING0,ACS_GRANUL OR 000h ,081h>
gdt_tss_main desc_struc <06bh,,,TSS_ACC,0,0> gdt_tss_task1 desc_struc <06bh,,,TSS_ACC,0,0> gdt_tss_task2 desc_struc <06bh,,,TSS_ACC,0,0> gdt_tss_task3 desc_struc <06bh,,,TSS_ACC,0,0> gdt_tss_task4 desc_struc <06bh,,,TSS_ACC,0,0>
gdt_ds1 desc_struc <00001h,00000h,000h,DATA_ACC OR ACC_RING3,ACS_GRANUL OR 000h ,000h> gdt_cs1 desc_struc <00002h,00000h,000h,CODE_ACC OR ACC_DATAWR OR ACC_RING0,ACS_GRANUL OR ACS_DIMENS OR 000h,000h>;селектор 0e0h gdt_ss1 desc_struc <00003h,00000h,000h,DATA_ACC OR ACC_RING3,ACS_GRANUL OR ACS_DIMENS OR 000h,000h>
далее, перехожу в защищённый режим, инициализирую gdt_cs1 (адрес в памяти, предел), в нём по адресу 01010h размещаю код: stlbpnt PROC far mov dx, 1070h mov eax,055h out dx, eax hlt ret stlbpnt ENDP
порт 1070h - введён спец иально для отладки (это нестандартная ПК). далее перехожу непосредственно на этот код: DB 09ah DD 01010h DW 0e0h
по завершению из порта 1070h читаю 55h. Здесь все работает на ура. А так нет: ввожу изменения: ...
gdt_cs1 desc_struc <00002h,00000h,000h,CODE_ACC OR ACC_DATAWR OR ACC_RING3,ACS_GRANUL OR ACS_DIMENS OR 000h,000h>;селектор 0e3h
...
DB 09ah DD 01010h DW 0e3h
После чего сразу выскакивает исключение 13. Порт 1070h остается без изменений. Что здесь нетак?
|
|
« Последнее редактирование: 01-07-2010 16:36 от Алексей1153++ »
|
Записан
|
|
|
|
darkelf
Молодой специалист
Offline
|
|
« Ответ #1 : 01-07-2010 10:08 » |
|
Я не уверен, но у Вас в tss указано разрешение для работы с портами? насколько я помню там должна быть битовая маска разрешенных портов после основных полей tss.
|
|
|
Записан
|
|
|
|
zloi7777
Постоялец
Offline
|
|
« Ответ #2 : 01-07-2010 10:21 » |
|
Я в программе не использую пока мультизадачность ( просто дескрипторы зарезервировал)
|
|
« Последнее редактирование: 01-07-2010 16:37 от Алексей1153++ »
|
Записан
|
|
|
|
RXL
|
|
« Ответ #3 : 01-07-2010 10:34 » |
|
Если мне не изменяет память, защита портов опциональна - можно ее совсем отключить.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
darkelf
Молодой специалист
Offline
|
|
« Ответ #4 : 01-07-2010 11:47 » |
|
У меня получалось переключаться на более низкий уровень привилегий только через tss.
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #5 : 01-07-2010 12:44 » |
|
У x86 полно механизмов движения по привилегиям. Например, шлюз вызова и шлюз прерывания.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
RXL
|
|
« Ответ #6 : 01-07-2010 16:25 » |
|
Привожу кусок условного код OUT из справочника:
IF (PE = 1) AND ((VM = 1) OR (CPL > IOPL)) THEN (* Тут делается проверка по битовой карте разрешений портов (указатель на нее находится в TSS) *) FI
Поле IOPL находится в EFLAGS (биты 12 и 13).
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
zloi7777
Постоялец
Offline
|
|
« Ответ #7 : 01-07-2010 18:29 » |
|
Шлюз вызова, вроде для уменьшения DPL(повышения привелегий) используется.... (но навсяк случай через шлюз я тоже проверил, эфект тотже, при DPL=0 все работает, при DPL=3 при вызове шлюза(DPL=0) дает исключение 13). А поп поводу портов, я переключения задач неделаю и tss непрогружаю, и недолжно запись в порт вызывать исключение 13.....
|
|
|
Записан
|
|
|
|
zloi7777
Постоялец
Offline
|
|
« Ответ #8 : 01-07-2010 18:36 » |
|
а переключится через TSS, надо попробовать будет.......спасибо....... но негде в литературе про это даже неупоминается ... P.S. про перегрузку стека для DPL=3 я в курсе, но я спецально после записи в порт поставил hlt/
|
|
|
Записан
|
|
|
|
Serg79
|
|
« Ответ #9 : 01-07-2010 19:37 » |
|
zloi7777, честно говоря из приведенного тобой кода ничего не понятно, набор инструкций препроцессора и не более, да куски машинных байт - это то что ты показал.
Как ты пытаешься понизить уровень привилегии исполняемого кода? Как ты диагностируешь, что у тебя кидается исключение "общей защиты"?
Для начала приведи маленький кусок ассемблерного кода переключения в защищенный режим с минимальным набором необходимых дескрипторов собранных в таблицу глобальных дескрипторов. Так же покажи код на ассемблере который понижает привилегию исполняемого кода до третьего уровня, и все дескрипторы в таблице глобальных дескрипторов которые будут описывать все необходимые сегменты для работы кода на третьем уровне защиты.
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #10 : 01-07-2010 19:38 » |
|
Шлюзы как раз задуманы именно для согласования кода разного уровня.
Мда. Освежил память: только через дескриптор задачи можно понизить.
|
|
« Последнее редактирование: 01-07-2010 19:59 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
zloi7777
Постоялец
Offline
|
|
« Ответ #11 : 01-07-2010 19:53 » |
|
Эфект от использования шлюза точно такойже - при DPL=0 все работает, при DPL=3 нет( на всяки случай уже проверил).
|
|
|
Записан
|
|
|
|
Serg79
|
|
« Ответ #12 : 01-07-2010 20:04 » |
|
Вообще RXL правильно заметил: Привожу кусок условного код OUT из справочника:
IF (PE = 1) AND ((VM = 1) OR (CPL > IOPL)) THEN (* Тут делается проверка по битовой карте разрешений портов (указатель на нее находится в TSS) *) FI
Поле IOPL находится в EFLAGS (биты 12 и 13).
В регистре флагов EFLAGS есть двухбитовое поле IOPL - I/O Privilege Level (уровень привилегий для ввода/вывода). Это поле определяет максимальный уровень привилегий, который может иметь код задачи при операциях ввода/вывода. Карта разрешения ввода/вывода используется, когда процессор работает в режиме виртуального 8086, либо когда в задаче CPL > IOPL. Если процессор находится в защищённом режиме и выполняет задачу, CPL которой не больше её IOPL, то операции ввода/вывода разрешены по всем адресам.
|
|
|
Записан
|
|
|
|
zloi7777
Постоялец
Offline
|
|
« Ответ #13 : 01-07-2010 20:09 » |
|
в первом коде показана начальная часть таблици дискрипторов включая gdt_cs1 описывающий сегмент куда я перехожу. во втором код записанный в целевом сегмене расположеный по адресу 1010h в третьем сам переход на сегмент описанный в gdt_cs1 (правдо машинным кодом) и в таком виде при DPL=0 все работает.
далее привожу изменения для DPL=3.
Опускаю перевод в защищенный режим, инициализацию таблици прерываний, выделение памяти для gdt_cs1, загрузку программы из флэш памяти в выделенную память.....
|
|
|
Записан
|
|
|
|
Serg79
|
|
« Ответ #14 : 01-07-2010 20:11 » |
|
Кстати zloi7777, если мне не изменяет память ты уже спрашивал что то про дальние вызовы в защищенном режиме: https://forum.shelek.ru/index.php/topic,24193.0.html . Чем закончились твои эксперименты? Тебе удалось найти С-ый компилятор который бы мог генерировать код для многосегментных приложений защищенного режима?
|
|
|
Записан
|
|
|
|
zloi7777
Постоялец
Offline
|
|
« Ответ #15 : 01-07-2010 20:12 » |
|
про IOPL в EFLAGS, незнал ,спасибо, проверю. заменю на ячейку памяти вместо порта, коль одна и таже прерва.
|
|
|
Записан
|
|
|
|
Serg79
|
|
« Ответ #16 : 01-07-2010 20:14 » |
|
zloi7777, если не секрет, как ты выделяешь память для gdt_cs1? ... выделение памяти для gdt_cs1, ... Не флейма ради, просто интересно.
|
|
|
Записан
|
|
|
|
zloi7777
Постоялец
Offline
|
|
« Ответ #17 : 01-07-2010 20:16 » |
|
Сделал доп библиотеку на асемблере с вызовами шлюзов, и использую с обычными компиляторами Си.
|
|
|
Записан
|
|
|
|
Serg79
|
|
« Ответ #18 : 01-07-2010 20:17 » |
|
про IOPL в EFLAGS, незнал ,спасибо, проверю. заменю на ячейку памяти вместо порта, коль одна и таже прерва.
Только обрати внимание на следующую фразу: ... Карта разрешения ввода/вывода используется ...
Это говорит о том, что тебе необходимо так же будет подготовить карту ввода/вывода в TSS.
|
|
|
Записан
|
|
|
|
zloi7777
Постоялец
Offline
|
|
« Ответ #19 : 01-07-2010 20:21 » |
|
Памяти в устройстве мало, страничную делать смысла небыло, сделал примитивный свой диспечер.
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #20 : 01-07-2010 20:23 » |
|
Или сделать IOPL = 3 и карта будет не нужна.
Страничный механизм упрощает работу с динамической памятью. Совсем забыл, что ты выбрал многосегментую модель...
|
|
« Последнее редактирование: 01-07-2010 20:25 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
zloi7777
Постоялец
Offline
|
|
« Ответ #21 : 01-07-2010 20:26 » |
|
я порт уберу будет память для проверки если выполница процедура stlbpnt. хотя при отсутствии там записи в порт тоже 13-е исключение было, ща тока припомнил, проверял я это...((
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #22 : 01-07-2010 20:27 » |
|
zloi7777, не торопись писать - сперва прочти, что уже написали. После того как напишешь, прочти, что написал - очень рваный и малопонятный текст у тебя.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
zloi7777
Постоялец
Offline
|
|
« Ответ #23 : 01-07-2010 20:34 » |
|
Для динамической памяти - да удобно. К страничной может и вернусь, потом, если целесобразно будет, а пока мне на пользовательский уровень неперейти.))
За рванасть извеняйте, я и так над сабой нечеловечиские усилия делаю, честно.
|
|
|
Записан
|
|
|
|
zloi7777
Постоялец
Offline
|
|
« Ответ #24 : 05-07-2010 04:20 » |
|
Попытался сделать через TSS, все тоже, на без понижения привилегии(ring0), все работает, при понижении до ring3 - все умирает, теперь даже без исключения
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #25 : 05-07-2010 05:24 » |
|
zloi7777, ты IOPL=3 выставил в TSS?
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
zloi7777
Постоялец
Offline
|
|
« Ответ #26 : 05-07-2010 06:02 » |
|
да, и заодно еще от out отказался, просто в доступную ячейку памяти пишу.
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #27 : 05-07-2010 06:17 » |
|
Значит дело не в бобине... Ищи ошибку. Почитай еще раз доки. Проверь все поля TSS на корректность.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
darkelf
Молодой специалист
Offline
|
|
« Ответ #28 : 05-07-2010 07:40 » |
|
У меня следующий TSS работал (tasm): ;TSS для переключения на уровень привилегий 3 tss segment para use32 dd 0 ; 00h обратная связь dd 0fffffffch; 04h esp0 dd STACK32SEG0 ; 08h ss0 dd 0 ; 0ch esp1 dd 0 ; 10h ss1 dd 0 ; 14h esp2 dd 0 ; 18h ss2 dd 0 ; 1ch cr3 dd 0 ; 20h eip dd 00000000000000000011001000000010b ; 24h efl iopl=3 if=1 dd 0 ; 28h eax dd 0 ; 2ch ecx dd 0 ; 30h edx dd 0 ; 34h ebx dd 0fffffffch ; 38h esp dd 0 ; 3ch ebp dd 0 ; 40h esi dd 0 ; 44h edi dd DATA32SEG3 ; 48h es dd CODE32SEG3 ; 4ch cs dd STACK32SEG3 ; 50h ss dd DATA32SEG3 ; 54h ds dd 0 ; 58h fs dd 0 ; 5ch gs dd 0 ; 60h ldtr dd 0 ; 64h trap flag tss ends
В коде 0-го уровня привилегий выполнялся переход на данный TSS: ;переключаем задачу db 0eah dd 0 dw TSSSEG
Таблица дескрипторов имела следующий вид: ; Глобальная дескрипторная таблица (GDT) gdt equ $ NULLSEG equ 0 ; первый пустой дескриптор dw 0,0,0,0 CODE32SEG3 equ 8+3 ; селектор кода с уровнем привилегий 3 desc_seg_make 0, 0, CODEXO, 3, 1, 0, 1 DATA32SEG3 equ 16+3 ; селектор данных с уровнем привилегий 3 desc_seg_make 0, 0, DATARW, 3, 1, 0, 1 STACK32SEG3 equ 24+3 ; селектор стека с уровнем привилегий 3 ;стек объявляется как сегмент данных ; desc_seg_make 0, 0, DATARW, 0, 1, 0 ;стек объявляется как сегмент стека desc_seg_make 0, 0, STACKRW, 3, 1, 1, 1 CODE32SEG0 equ 32 ; селектор кода с уровнем привилегий 0 desc_seg_make 0, 0, CODEXO, 0, 1, 0, 1 STACK32SEG0 equ 40 ; селектор стека с уровнем привилегий 0 ;стек объявляется как сегмент данных ; desc_seg_make 0, 0, DATARW, 0, 1, 0 ;стек объявляется как сегмент стека desc_seg_make 0, 0, STACKRW, 0, 1, 1, 1 VIDEO32SEG equ 48 + 3 ; селектор сегмента видео памяти для отладки desc_seg_make 0b8000h, 4096, DATARW, 3, 1, 0, 1 TSSSEG equ 56 ; селектор сегмента TSS desc_tss_make 0, 0, 3, 1
Макросы создания дескрипторов для сегментов/TSS: ;коды типов сегментов DATARO equ 000b ;сегмент данных только для чтения DATARW equ 001b ;сегмент данных для чтения/записи STACKRO equ 010b ;сегмент стека только для чтения (не используется) STACKRW equ 011b ;сегмент стека для чтения/записи CODEXO equ 100b ;сегмент кода, разрешено только выполнение CODERX equ 101b ;сегмент кода, разрешено чтение/выполнение
;создать описатель дескриптора сегмента desc_seg_make macro base,limit,type,dpl,d,g,pr dw limit AND 0ffffh ; предел 15-0 dw base AND 0ffffh ; база 23-16 db (base SHR 16) AND 0ffh ; база, биты 23-16 ; тип сегмента, бит присутствия, признак сегмента, уровень привилегий db ((type AND 7) SHL 1) OR ((pr AND 1) SHL 7) OR (1 SHL 4) OR ((dpl AND 3) SHL 5) ; предел 19-16, бит используется пользователем, бит размера по умолчанию ; 0 - 16 бит, 1 - 32 db ((limit SHR 16) AND 0fh) OR ((d AND 1) SHL 6) OR ((g AND 1) SHL 7) db (base SHR 24) AND 0ffh ;база 31-24 endm
;создать описатель дескриптора TSS desc_tss_make macro base,limit,dpl,pr dw limit AND 0ffffh ; предел 15-0 dw base AND 0ffffh ; база 23-16 db (base SHR 16) AND 0ffh ; база, биты 23-16 ; тип сегмента, бит присутствия, признак сегмента, уровень привилегий db 1001b OR ((pr AND 1) SHL 7) OR ((dpl AND 3) SHL 5) db ((limit SHR 16) AND 0fh) ; предел 19-16 db (base SHR 24) AND 0ffh ;база 31-24 endm
Именно с портами не работал, но в видеопамять писалось нормально. Сорри за оверквотинг.
|
|
|
Записан
|
|
|
|
zloi7777
Постоялец
Offline
|
|
« Ответ #29 : 05-07-2010 12:01 » |
|
darkelf, Спасибо, через TSS заработало. У меня было почти как и в твоем коде, тока в TSS es был прогружен селектором с DPL=0, поменял и все запахало.
|
|
|
Записан
|
|
|
|
|