#GP при переключении задач.

Тема в разделе "WASM.BEGINNERS", создана пользователем ciril, 25 июн 2008.

  1. ciril

    ciril New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    29
    Задача вызывается через шлюз задачи в IDT, подскажите причину генерации #GP

    Дескрипторы первой и второй задач в GDT:
    dd 0x89000067,metatts ;P=1b, DPL=00b, S=0b,Type=1001b, G=D/B=L=AVL=0b, LIMIT=0x67, BASE=metatts
    dd 0x89000067,debugtts ;BASE=debugtts
    TSS 1ой задачи инициализирован:
    label metatts
    db 0x68 dup 0x0
    TSS 2ой задачи:
    label debugtts
    dd 0x0 ;selecter of oldtask
    dd 0x0,0x18,0x0,0x0,0x0,0x0 ;00(esp,ss),01(esp,ss),10(esp,ss)
    dd 0x0 ;cr3
    dd dDBtone ;eip
    dd 0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0 ;eflags,eax,ecx,edx,ebx,esp,ebp,esi,edi
    dd 0x20,0x08,0x18,0x10,0x0,0x0 ;es,cs,ss,ds,fs,gs
    dd 0x0 ;ldtr
    dd 0x0 ;iobm
    TSS 1ой задачи грузится в TS:
    ltr 0x28 ;селектор 1й задачи
    2я задача:
    dDBtone:
    nop
    iret
    Вызывается int 0x30
    Дескриптор в IDT:
    dw 0x0,0x30,0x85,0x0 ;0x30 - селектор 2й задачи, P=0b, GDPL=00b, S=0b, TYPE=0101b
    После выполнения int 0x30, до начала работы кода вызываемой задачи возникает #GP.
     
  2. ciril

    ciril New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    29
    Причем при вызове 2ой задачи напрямую:
    call 0x30:0x0
    задача отрабатывает, возвращает управление, а потом уходит в перезагрузку при любых манипуляциях со стеком.
    Дескриптор стека:
    dd 0x96cffffe,mainstack ;P=1b, DPL=00b, S=1b, TYPE=E=W=1b, A=0b, G=D/B=1b, L=AVL=0b, LIMIT=mainstack
    Находится:
    org 0x10000
    label mainstack
    на момент вызова 2ой задачи esp=0xfffffff0
    Подскажите, пожалуйста, где я ошибся.
     
  3. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    лучше код покажи
     
  4. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    ciril
    И код ошибки за одно
     
  5. ciril

    ciril New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    29
    #GP было из-за ошибки описания шлюза.
    Код и тип ошибки пока не знаю - управление возвращается 1ой задаче, код выполняется, и перезагружается при любых манипуляциях со стеком.
    Практически весь значащий код я привел. А полностью, за исключением обработчиков ошибок (которые нужно - чистят стек, все пищат динамиком и iretd), кроме #GP и обработчиков прерываний, те тоже пустые, только сбрасывают запрос (eoi: \\ push ax \\ mov al,0x20 \\ out 0x20,al \\ out 0xa0,al \\ pop ax \\ iretd), код ниже.

    org 0x7c00
    use16
    ent:
    ;загружаемся с дискеты
    mov ax,cs
    mov ds,ax
    mov es,ax
    mov ss,ax
    mov sp,ent
    mov bp,sp
    mov ax,0x4f02
    mov bx,0x4117
    int 0x10

    mov ah,0x2
    mov al,0x11
    xor ch,ch
    mov cl,0x2
    xor dx,dx
    mov bx,ent+0x200
    int 0x13
    jnc coload

    mov ax,0x3
    int 0x10
    mov ax,0xb800
    mov es,ax
    mov eax,0x8f458f52
    mov dword[es:0x0],eax
    jmp $
    dw 0xaa55
    ;переходим в PM
    coload:
    in al,0x92
    or al,0x2
    out 0x92,al
    cli
    in al,0x70
    or al,0x80
    out 0x70,al
    lgdt fword[gdtr]
    lidt fword[idtr]
    mov eax,cr0
    or al,0x1
    mov cr0,eax
    jmp 0x08:pmentry
    use32
    pmentry:
    mov ax,0x10
    mov ds,ax
    mov ax,0x18
    mov ss,ax
    mov ax,0x20
    mov es,ax

    mov al,0x11
    out 0x20,al
    out 0xa0,al
    mov al,0x20
    out 0x21,al
    mov al,0x28
    out 0xa1,al
    mov al,0x04
    out 0x21,al
    mov al,0x02
    out 0xa1,al
    mov al,0x1
    out 0x21,al
    out 0xa1,al
    mov al,0x0
    out 0x21,al
    out 0xa1,al

    in al,0x70
    and al,0x7f
    out 0x70,al
    sti
    mov eax,cr4
    or eax,0x200
    mov cr4,eax
    ;переходим в 1ю задачу
    xor esp,esp
    mov ax,0x28
    ltr ax
    ;грузим битовые маски символов
    cli
    mov dx,0xfc04
    mov eax,prdt
    out dx,eax
    mov dx,0xfc00
    in al,dx
    or al,0x8
    out dx,al
    mov dx,0xfc02
    or al,0xff
    out dx,al
    mov dx,0x3f6
    @@:
    in al,dx
    and al,0x80
    xor al,0x80
    jz @r
    mov dx,0x1f6
    xor al,al
    out dx,al
    mov dx,0x3f6
    @@:
    in al,dx
    and al,0xc0
    xor al,0x40
    jnz @r
    mov dx,0x1f1
    xor al,al
    out dx,al
    inc dx
    mov al,0x79
    out dx,al
    inc dx
    mov al,0xe9
    out dx,al
    inc dx
    mov al,0x9e
    out dx,al
    inc dx
    mov al,0x73
    out dx,al
    inc dx
    mov al,0xe4
    out dx,al
    inc dx
    mov al,0xc8
    out dx,al
    mov dx,0xfc00
    in al,dx
    or al,0x1
    out dx,al
    mov dx,0xfc02
    @@:
    in al,dx
    and al,0x4
    xor al,0x4
    jnz @r
    mov dx,0xfc00
    in al,dx
    xor al,0x1
    out dx,al
    mov dx,0xfc02
    in al,dx
    and al,0x2
    xor al,0x2
    jz .error
    mov dx,0x1f7
    in al,dx
    and al,0x1
    xor al,0x1
    jz .error
    sti
    jmp .go
    .error:
    mov al,0x07
    out 0x43,al
    mov al,0xf0
    out 0x42,al
    mov al,0x11
    out 0x42,al
    in al,0x61
    or al,0x3
    out 0x61,al
    mov eax,0x10000000
    @@:
    dec eax
    jnz @r
    in al,0x61
    and al,0xfc
    out 0x61,al
    mov eax,0x4f000000
    @@:
    dec eax
    jnz @r
    sti
    @@:
    hlt
    jmp @r
    .go:
    int 0x30 ;вызываем 2ю задачу
    mov cl,0x3
    .repton_to:
    mov al,0xb6
    out 0x43,al
    mov al,0x5b
    out 0x42,al
    mov al,0x10
    out 0x42,al
    in al,0x61
    or al,0x3
    out 0x61,al
    mov eax,0x9000000
    @@:
    dec eax
    jnz @r
    in al,0x61
    and al,0xfc
    out 0x61,al
    mov eax,0xf00000
    @@:
    dec eax
    jnz @r
    dec cl
    jnz .repton_to
    push 0x0
    .goto:
    hlt
    jmp .goto
    ;системные таблицы
    use32
    align 0x8
    label gdt
    db 0x8 dup 0x0
    dd 0x9ac0001a,0x0 ;код
    dd 0x92cfffff,0x0 ;данные
    dd 0x96cffffe,mainstack ;стек
    dd 0x92c00185,0xd0000000 ;video
    dd 0x89000067,metatts ;1я задача
    dd 0x89000067,debugtts ;2я задача
    intermixgdt
    gdtsz=$-gdt
    label gdtr
    dw gdtsz-1
    dd gdt
    label idt
    dw dDE,0x0,0x0,0x0
    dw dDB,0x8,0x8e00,0x0
    dw NMI,0x0,0x0,0x0
    dw dBP,0x8,0x8e00,0x0
    dw dOF,0x0,0x0,0x0
    dw dBR,0x0,0x0,0x0
    dw dUD,0x0,0x0,0x0
    dw dNM,0x0,0x0,0x0
    dw dDF,0x0,0x0,0x0
    dw 0x0,0x0,0x0,0x0
    dw dTS,0x0,0x0,0x0
    dw dNP,0x0,0x0,0x0
    dw dSS,0x0,0x0,0x0
    dw dGP,0x8,0x8e00,0x0
    dw dPF,0x0,0x0,0x0
    dw 0x0,0x0,0x0,0x0
    dw dMF,0x0,0x0,0x0
    dw dAC,0x0,0x0,0x0
    dw dMC,0x0,0x0,0x0
    dd 0x1a dup 0x0
    dw IRQ00,0x8,0x8e00,0x0
    dw irq01,0x8,0x8e00,0x0
    dw IRQ02,0x8,0x8e00,0x0
    dw IRQ08,0x8,0x8e00,0x0
    dw IRQ09,0x8,0x8e00,0x0
    dw IRQ0A,0x8,0x8e00,0x0
    dw IRQ0B,0x8,0x8e00,0x0
    dw IRQ0C,0x8,0x8e00,0x0
    dw IRQ0D,0x8,0x8e00,0x0
    dw IRQ0E,0x8,0x8e00,0x0
    dw IRQ0F,0x8,0x8e00,0x0
    dw IRQ03,0x8,0x8e00,0x0
    dw IRQ04,0x8,0x8e00,0x0
    dw IRQ05,0x8,0x8e00,0x0
    dw IRQ06,0x8,0x8e00,0x0
    dw IRQ07,0x8,0x8e00,0x0
    dw 0x0,0x30,0x8500,0x0;шлюз 2ой задачи
    idtsz=$-idt
    label idtr
    dw idtsz-1
    dd idt
    label rmidtr
    dw 0x3ff
    dd 0x0
    align 0x4
    label prdt
    dd charmap
    dw 0x0
    dw 0x8000
    label metatts ;1я задача
    db 0x68 dup 0x0
    label debugtts ;2я задача
    dd 0x0 ;selecter of oldtask
    dd 0x0,0x18,0x0,0x0,0x0,0x0 ;00(esp,ss),01(esp,ss),10(esp,ss)
    dd 0x0 ;cr3
    dd dDBtone ;eip
    dd 0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0 ;eflags,eax,ecx,edx,ebx,esp,ebp,esi,edi
    dd 0x20,0x08,0x18,0x10,0x0,0x0 ;es,cs,ss,ds,fs,gs
    dd 0x0 ;ldtr
    dd 0x0 ;iobm
    ;2я задача
    dDBtone:
    mov cl,0x3
    .repton:
    mov al,0xb6
    out 0x43,al
    mov al,0x4b
    out 0x42,al
    mov al,0x05
    out 0x42,al
    in al,0x61
    or al,0x3
    out 0x61,al
    mov eax,0xd000000
    @@:
    dec eax
    jnz @r
    in al,0x61
    and al,0xfc
    out 0x61,al
    mov eax,0xf00000
    @@:
    dec eax
    jnz @r
    dec cl
    jnz .repton
    iret
    ;обработчик #GP
    dGP:
    push ecx
    push ebx
    mov edi,0xfe00
    xor ecx,ecx
    xor ebx,ebx
    std
    @@:
    mov bl,byte[edi+ecx]
    xor eax,eax
    ror bl,0x4
    mov al,bl
    and al,0x0f
    cmp al,0xa
    sbb al,0x69
    das
    shr bl,0x4
    call drawchar
    xor eax,eax
    mov al,bl
    cmp al,0xa
    sbb al,0x69
    das
    call drawchar
    inc ecx
    cmp ecx,0x200
    jnz @r
    pop ebx
    pop ecx
    @@:
    hlt
    ;выводим символ на экран
    drawchar:
    push eax
    push edi
    push edx
    push ebx
    push ecx
    sub al,0x20
    xor edi,edi
    mov ah,al
    xor al,al
    mov edx,dword[lastposition]
    lea ebx,[charmap+eax*0x4]
    mov ecx,0x20
    xor eax,eax
    align 0x4
    @@:
    db 0x26,0x0f,0x28,0x04,0x17;movapd xmm0,dqword[es:edi+edx]
    align 0x4
    db 0x26,0x0f,0x28,0x4c,0x17,0x10;movapd xmm1,dqword[es:edi+edx+0x10]
    align 0x4
    db 0x0f,0x57,0x4,0x03;xorpd xmm0,dqword[ds:ebx+eax]
    align 0x4
    db 0x0f,0x57,0x4c,0x03,0x10;xorpd xmm1,dqword[ds:ebx+eax+0x10]
    align 0x4
    db 0x26,0x0f,0x2b,0x04,0x17;movntpd dqword[es:edi+edx],xmm0
    align 0x4
    db 0x26,0x0f,0x2b,0x4c,0x17,0x10;movntpd dqword[es:edi+edx+0x10],xmm1
    dec ecx
    lea edi,[edi+0x800]
    lea eax,[eax+0x20]
    jnz @r
    lea eax,[edx+0x20]
    and dx,0x7e0
    xor dx,0x7e0
    jnz @f
    lea eax,[eax+0xf800]
    @@:
    mov dword[lastposition],eax
    pop ecx
    pop ebx
    pop edx
    pop edi
    pop eax
    ret
    ;данные
    lastposition dd 0x0
    scantable db 0x0,0x0,'1','2','3','4','5','6','7','8','9','0'
    db 0x4 dup 0x3a
    db 'Q','W','E','R','T','Y','U','I','O','P'
    db 0x4 dup 0x3a
    db 'A','S','D','F','G','H','J','K','L'
    db 0x5 dup 0x3a
    db 'Z','X','C','V','B','N','M',',','.','/'
    db 0x3 dup 0x3a
    db ' '
    db 0x94 dup 0x3a

    ;область стек
    org 0x10000
    label mainstack
    ;область битовых масок
    org 0x100000
    label charmap
    ;макрос переформирования gdt
    macro intermixgdt
    {
    repeat ($-gdt)/0x8
    ere=$-(%-0x1)*0x8
    load gsl19..16 byte from ere-0x6
    load access byte from ere-0x5
    load base15..0 word from ere-0x4
    load base23..16 byte from ere-0x2
    store word base15..0 at ere-0x6
    store byte base23..16 at ere-0x4
    store byte access at ere-0x3
    store byte gsl19..16 at ere-0x2
    end repeat
    }
     
  6. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Код (Text):
    1.         xor esp,esp ;<-----Зачем ты обнуляешь esp первой задачи?
    2.         mov ax,0x28
    3.         ltr ax
     
  7. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    ciril
    Настоятельно рекомендую поставить эмулятор Bochs и работать с ним. Например, в данном случае Bochs пишет в bochsout.txt вполне приличный лог, из которого нетрудно понять, что происходит:
    А можно даже включить отладочный вывод:
    Конкретно в данном случае ss=0x28, указанный в TSS второй задачи, ну никак не является валидным сегментом данных. А дальше - #TS, #GP и triple fault aka reboot.
     
  8. ciril

    ciril New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    29
    Mika0x65]
    Так меньшее смещение в стеке32 = 0xfffffffc, вот и обнуляю, чтобы адресовал, хотя это кажется лишнее, стек 1й задачи работает в обоих случаях, и при комментировании xor esp,esp , смотрел дампом. На общую неработоспособность это не влияет.
    Выяснил, что если во 2й задаче использовать команды SSE, то #GP (проверил xorpd xmm0,xmm0). При запуске также возникала #GP, что удалось исправить установкой CR4.OSFXSR=1b, но ведь сейчас он установлен.


    diamond
    Моя ошибка при копировании текста, потом отредактированная, в коде 0x18.
     
  9. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    diamond
    А как получается, что ss = 0x28? По коду он, вроде, 0х18:

    Код (Text):
    1. label debugtts ;2я задача
    2.         dd 0x0 ;selecter of oldtask
    3.         dd 0x0,0x18,0x0,0x0,0x0,0x0 ;00(esp,ss),01(esp,ss),10(esp,ss)
    4.         dd 0x0 ;cr3
    5.         dd dDBtone ;eip
    6.         dd 0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0 ;eflags,eax,ecx,edx,ebx,esp,ebp,esi,edi
    7.         dd 0x20,0x08,0x18,0x10,0x0,0x0 ;es,cs,ss,ds,fs,gs <---------здесь.
    8.         dd 0x0 ;ldtr
    9.         dd 0x0 ;iobm
    И у первой задачи тоже:
    Код (Text):
    1.         mov ax,0x18
    2.         mov ss,ax
    Больше упоминаний ss, вроде, нет.

    Bochs на этом компьютере не стоит, смотрел на глаз.

    Update: А, понятно, я видел уже отредактированную версию.
     
  10. ciril

    ciril New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    29
    Сам поправляюсь, после переключения на 2ю задачу, генерируется #GP при использовании любых команд SSE. Все остальные команды, в том числе и операций со стеком - допустимы.
     
  11. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    ciril
    Что-то я не понял -- работает, или нет?

    И не пересекаются ли стеки задач?

    Заодно: чтобы вызвать вторую задачу повторно, надо после iret поставить jmp на начало задачи, т.к. после возврата из нее eip будет ссылаться на инструкцию после iret.

    Вручную копировал?! :)

    Update: Черт, опять пока набирал сообщение уже ответ пришел :).
     
  12. ciril

    ciril New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    29
    Есть работа до первого переключения задач с 1й задачи на вторую, и после. До момента первого переключения все работает, то есть работает 1я задача вне зависимости от того обнуляем ли esp, после все не работает также вне зависимости от обнуления.
    У меня было с разными стеками на обе задачи, а вставлял с общим, на неработоспособность это не влияет.
    Когда с разными, то нет:
    org 0x10000
    label mainstack
    org 0x11000
    label debugstack
    Ну и в поле ss TSS 2й задачи соответственно селектор 0x38, то есть дескриптора debugstack'a

    И повторюсь: после первого переключения возникает #GP при обращении к командам SSE, причем как в случае вызова (например) xorpd xmm0,xmm0 во 2й задаче, так и при вызове xorpd xmm0,xmm0 в 1й задаче после возврата управления 2ой задачью.
     
  13. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    Если я правильно помню, так и должно быть: переключение задач устанавливает бит в cr0, что, мол, задача переключилась, а потом все FPU/MMX/SSE-команды фолтят, если этот бит установлен. Точнее, они вызывают #NM, но поскольку в IDT обработчик #NM помечен как отсутствующий, то вызывается #GP. Сделано это в расчёте на следующее: каждая задача может иметь свой набор регистров, как cpu, так и fpu/xmm; но регистры cpu используют абсолютно все задачи, и эти регистры сохраняются в TSS автоматически, а fpu/xmm - уже далеко не все, и для экономии времени они не сохраняются. Но чтобы вторая задача не работала с регистрами первой, предназначено исключение #NM: его обработчик должен сохранить fpu/xmm-регистры для старой задачи, загрузить для новой, сбросить бит TS в cr0 (для этого даже есть специальная команда clts) и вернуть управление.
     
  14. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    ciril
    Похоже, как-то путано объяснил... короче, команда "clts" должна спасти отца русской демократии.
     
  15. ciril

    ciril New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    29
    diamond
    Да:)))
    Только можно узнать, откуда сведения? У Интела в описании #NM Vol3A 5.3.1 Table 5-1:
    Floating-point or WAIT/FWAIT instruction.
    А о переключении задач там же, Chater 6, Table 6-1 такого исключения при переключении задач нет.

    О том что CRO.TS и #NM связаны я не нашел. Или не там читал?
     
  16. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    В мануалах AMD это сказано в первом томе, раздел 4.10 "128-Bit Media and Scientific Programming" -> "Exceptions":
    В мануалах Intel это тоже есть в первом томе, раздел 12.8 "Programming with SSE3, SSSE3 and SSE4" -> "SSE3/SSSE3, and SSE4 Exceptions" (в той версии, которая есть у меня; в более старых или более новых номер раздела, скорее всего, другой):
    Кроме первого тома, это легко найти так: в описании каждой инструкции сказано, какие исключения она может вызвать.
    (Второй том Интела, третий-пятый AMD.) К примеру, из описания xorpd:
     
  17. ciril

    ciril New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    29
    М-да, не доискал:dntknw:
    Спасибо:)))
     
  18. Medstrax

    Medstrax Забанен

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    673
    Небольшое дополнение, пусть и не совсем применительно к данной теме.
    Если в CR0 установлен бит EM, то при выполнении FPU/MMX/SSE инструкции также имеем исключение - в случае FPU - #NM, в случае MMX и SSE(за небольшим исключением) - #UD.