JAPH вот блин Code (Text): format MZ heap 0 stack 0x800 entry _code:start include '..\include\pmode.inc' code_descr = (code_desc-null_desc) data_descr = (data_desc-null_desc) stack_descr = (stack_desc-null_desc) video_descr = (video_desc-null_desc) segment _code use16 start: mov ax, _gdt mov ds, ax mov ax, 0x03 int 0x10 cli in al, 0x70 or al, 0x80 out 0x70, al in al, 0x92 or al, 0x02 out 0x92, al xor eax, eax mov ax, pmode shl eax, 0x04 add eax, pm_entry mov [code_desc.base_l], ax rol eax, 0x10 mov [code_desc.base_m], al xor eax, eax mov ax, _data shl eax, 0x04 mov [data_desc.base_l], ax rol eax, 0x10 mov [data_desc.base_m], al xor eax, eax mov ax, ss shl eax, 0x04 mov [stack_desc.base_l], ax rol eax, 0x10 mov [stack_desc.base_m], al mov ax, _data mov ds, ax xor eax, eax mov ax, _gdt shl eax, 0x04 mov [gdtr+0x02], eax xor eax, eax mov ax, _idt shl eax, 0x04 mov [idtr+0x02], eax lgdt fword [gdtr] lidt fword [idtr] mov eax, cr0 or al, 1 mov cr0, eax jmp fword code_descr:pm_entry segment pmode use32 pm_entry: mov ax, data_descr mov ds, ax mov ax, stack_descr mov ss, ax mov ax, video_descr mov es, ax mov dx, 0x20 mov ah, 0x20 call set_int_ctrlr mov dx, 0xa0 mov ah, 0x28 call set_int_ctrlr in al, 0x70 and al, 0x7f out 0x70, al sti jmp $ set_int_ctrlr: mov al, 11 out dx, al jmp SHORT $+2 mov al, ah inc dx out dx, al jmp SHORT $+2 mov al, 4 out dx, al jmp SHORT $+2 mov al, 1 out dx, al jmp SHORT $+2 mov al, 0xff out dx, al dec dx ret int30h_handler: pushad cli _puts: lodsb mov edi, [cursor] mov [es:edi*2], al inc [cursor] test al, al jnz _puts sti popad ret exGP_handler: pop eax mov esi, gp call int30h_handler iretd timer_handler: cli inc byte [es:0x00] push ax mov al, 0x20 out 0x20, al pop ax sti iret key_bd: push ecx push ax mov al, 0xed out 0x60, al mov ecx, 0x2000 delay: loop delay mov al, 0x04 out 0x60, al mov al, 0x20 out 0x20, al pop ax pop ecx iret dummy: iret dummy1: push ax mov al, 0x20 out 0x20, al pop ax iret dummy2: push ax mov al, 0x20 out 0x20, al out 0xa0, al pop ax iret code_size = ($-pm_entry) segment _data use32 gp db '*** General Protection Fault ***', 0x00 msg db 'PMODE', 0x00 cursor dd 0x05 data_size = ($-gp) gdtr: dw gdt_size-1 dd 0 idtr: dw idt_size-1 dd 0 segment _gdt use16 gdt: null_desc desc_struc 0,0,0,0,0,0 code_desc desc_struc code_size-1,0,0,code_acc,0xc0,0 data_desc desc_struc data_size-1,0,0,data_acc,0xc0,0 stack_desc desc_struc 0x800-1,0,0,data_acc,0xc0,0 video_desc desc_struc 0x4000-1,0x8000,0x0b,data_acc,0xc0,0 gdt_size = ($-gdt) segment _idt use16 idt: exeption_01 idt_struc dummy,code_descr,0,trap_acc,0 exeption_02 idt_struc dummy,code_descr,0,trap_acc,0 exeption_03 idt_struc dummy,code_descr,0,trap_acc,0 exeption_04 idt_struc dummy,code_descr,0,trap_acc,0 exeption_05 idt_struc dummy,code_descr,0,trap_acc,0 exeption_06 idt_struc dummy,code_descr,0,trap_acc,0 exeption_07 idt_struc dummy,code_descr,0,trap_acc,0 exeption_08 idt_struc dummy,code_descr,0,trap_acc,0 exeption_09 idt_struc dummy,code_descr,0,trap_acc,0 exeption_0a idt_struc dummy,code_descr,0,trap_acc,0 exeption_0b idt_struc dummy,code_descr,0,trap_acc,0 exeption_0c idt_struc dummy,code_descr,0,trap_acc,0 exeption_0d idt_struc exGP_handler,code_descr,0,trap_acc,0 exeption_0e idt_struc dummy,code_descr,0,trap_acc,0 exeption_0f idt_struc dummy,code_descr,0,trap_acc,0 exeption_10 idt_struc dummy,code_descr,0,trap_acc,0 exeption_11 idt_struc dummy,code_descr,0,trap_acc,0 exeption_12 idt_struc dummy,code_descr,0,trap_acc,0 exeption_13 idt_struc dummy,code_descr,0,trap_acc,0 exeption_14 idt_struc dummy,code_descr,0,trap_acc,0 exeption_15 idt_struc dummy,code_descr,0,trap_acc,0 exeption_16 idt_struc dummy,code_descr,0,trap_acc,0 exeption_17 idt_struc dummy,code_descr,0,trap_acc,0 exeption_18 idt_struc dummy,code_descr,0,trap_acc,0 exeption_19 idt_struc dummy,code_descr,0,trap_acc,0 exeption_1a idt_struc dummy,code_descr,0,trap_acc,0 exeption_1b idt_struc dummy,code_descr,0,trap_acc,0 exeption_1c idt_struc dummy,code_descr,0,trap_acc,0 exeption_1d idt_struc dummy,code_descr,0,trap_acc,0 exeption_1e idt_struc dummy,code_descr,0,trap_acc,0 exeption_1f idt_struc dummy,code_descr,0,trap_acc,0 irq_00 idt_struc timer_handler,code_descr,0,int_acc,0 irq_01 idt_struc key_bd,code_descr,0,int_acc,0 irq_02 idt_struc dummy1,code_descr,0,int_acc,0 irq_03 idt_struc dummy1,code_descr,0,int_acc,0 irq_04 idt_struc dummy1,code_descr,0,int_acc,0 irq_05 idt_struc dummy1,code_descr,0,int_acc,0 irq_06 idt_struc dummy1,code_descr,0,int_acc,0 irq_07 idt_struc dummy1,code_descr,0,int_acc,0 irq_08 idt_struc dummy2,code_descr,0,int_acc,0 irq_09 idt_struc dummy2,code_descr,0,int_acc,0 irq_10 idt_struc dummy2,code_descr,0,int_acc,0 irq_11 idt_struc dummy2,code_descr,0,int_acc,0 irq_12 idt_struc dummy2,code_descr,0,int_acc,0 irq_13 idt_struc dummy2,code_descr,0,int_acc,0 irq_14 idt_struc dummy2,code_descr,0,int_acc,0 irq_15 idt_struc dummy2,code_descr,0,int_acc,0 idt_size = ($-idt) Code (Text): struc desc_struc op1,op2,op3,op4,op5,op6 { .limit_l dw op1 .base_l dw op2 .base_m db op3 .access db op4 .lim_h_f db op5 .base_h db op6 } struc idt_struc op1,op2,op3,op4,op5 { .destoff dw op1 .destsel dw op2 .nparams db op3 .access db op4 .rsrv dw op5 } acc_present = 10000000b acc_cseg = 00011000b acc_dseg = 00010000b acc_expdown = 00000100b acc_conform = 00000100b acc_datawr = 00000010b acc_int_gate = 00001110b acc_trap_gate = 00001111b data_acc = acc_present or acc_dseg or acc_datawr code_acc = acc_present or acc_cseg or acc_conform stack_acc = acc_present or acc_dseg or acc_datawr or acc_expdown idt_acc = acc_present or acc_dseg or acc_datawr int_acc = acc_present or acc_int_gate trap_acc = acc_present or acc_trap_gate
В том-то и дело, что не dummy. Точнее, dummy, но при отсутствии 32 обработчиков исключений, обработчики прерываний "смещаются". В результате получается, что обработчик 32ого прерывания становится 31ым. Т.е. надо добавить: Code (Text): exeption_00 idt_struc dummy,code_descr,0,trap_acc,0
Невнимательность? Code (Text): idt: exeption_00 idt_struc dummy,code_descr,0,trap_acc,0 exeption_01 idt_struc dummy,code_descr,0,trap_acc,0 Mika0x65, опередил
Мой вариант - для загрузочного сектора. Трохи переделать надо. useXX - когда-то был segment Code (Text): include 'pmode.inc' code_descr = (code_desc-null_desc) data_descr = (data_desc-null_desc) video_descr = (video_desc-null_desc) stack_descr = (stack_desc-null_desc) use16 mov ax, 0208h ; грузим прогу по адресу 8000h mov cx, 0002h xor bx, bx push 800h pop es mov dx, 80h int 13h jmp 0800h:0 align 512 store word 0AA55h at $ - 2 ; оригинал use16 org 0 pmode = 820h _data = 840h _gdt = 860h _idt = 880h start: mov ax, _gdt mov ds, ax mov ax, _idt mov es, ax mov ax, 0x03 int 0x10 cli in al, 0x70 or al, 0x80 out 0x70, al in al, 0x92 or al, 0x02 out 0x92, al xor eax, eax mov ax, pmode shl eax, 0x04 add eax, pm_entry mov [code_desc.base_l], ax rol eax, 0x10 mov [code_desc.base_m], al xor eax, eax mov ax, _data shl eax, 0x04 mov [data_desc.base_l], ax rol eax, 0x10 mov [data_desc.base_m], al xor eax, eax mov ax, ss shl eax, 0x04 mov [stack_desc.base_l], ax rol eax, 0x10 mov [stack_desc.base_m], al xor eax, eax mov ax, _gdt shl eax, 0x04 mov [gdtr+0x02], eax xor eax, eax mov ax, _idt shl eax, 0x04 mov [es:idtr+0x02], eax lgdt fword [gdtr] lidt fword [es:idtr] mov eax, cr0 or al, 1 mov cr0, eax jmp fword code_descr:pm_entry use32 align 512 org 0 pm_entry: mov ax, data_descr mov ds, ax mov ax, video_descr mov es, ax mov ax, stack_descr mov ss, ax mov al, 15h out 20h, al out 0A0h, al mov al, 20h out 21h, al mov al, 28h out 0A1h, al mov al, 4 out 21h, al; mov al, 2 out 0A1h, al mov al, 0Dh out 21h, al mov al, 9 out 0A1h, al mov al, 0FCh out 21h, al mov al, 0FFh out 0A1h, al in al, 0x70 and al, 0x7f out 0x70, al sti @@: hlt jmp @B int30h_handler: pushad cli _puts: lodsb mov edi, [cursor] mov [es:edi*2], al inc [cursor] test al, al jnz _puts sti popad ret exGP_handler: pop eax mov esi, gp ;call int30h_handler iretd timer_handler: cli inc byte [es:0x00] push ax mov al, 0x20 out 0x20, al pop ax sti iret key_bd: push ecx push ax mov al, 0xed out 0x60, al mov ecx, 0x2000000 delay: loop delay mov al, 0x04 out 0x60, al mov al, 0x20 out 0x20, al pop ax pop ecx iret dummy: iret dummy1: push ax mov al, 0x20 out 0x20, al pop ax iret dummy2: push ax mov al, 0x20 out 0x20, al out 0xa0, al pop ax iret code_size = ($-pm_entry) use32 align 512 gp db '*** General Protection Fault ***', 0x00 msg db 'PMODE', 0x00 cursor dd 0x05 data_size = ($-gp) use16 align 512 org 0 gdt: null_desc desc_struc 0,0,0,0,0,0 code_desc desc_struc code_size-1,0,0,code_acc,0xc0,0 data_desc desc_struc data_size-1,0,0,data_acc,0xc0,0 stack_desc desc_struc 0x800-1,0,0,data_acc,0xc0,0 video_desc desc_struc 0x4000-1,0x8000,0x0b,data_acc,0xc0,0 gdt_size = ($-gdt) gdtr: dw gdt_size-1 dd 0 use16 align 512 org 0 idt: exeption_00 idt_struc dummy,code_descr,0,trap_acc,0 exeption_01 idt_struc dummy,code_descr,0,trap_acc,0 exeption_02 idt_struc dummy,code_descr,0,trap_acc,0 exeption_03 idt_struc dummy,code_descr,0,trap_acc,0 exeption_04 idt_struc dummy,code_descr,0,trap_acc,0 exeption_05 idt_struc dummy,code_descr,0,trap_acc,0 exeption_06 idt_struc dummy,code_descr,0,trap_acc,0 exeption_07 idt_struc dummy,code_descr,0,trap_acc,0 exeption_08 idt_struc dummy,code_descr,0,trap_acc,0 exeption_09 idt_struc dummy,code_descr,0,trap_acc,0 exeption_0a idt_struc dummy,code_descr,0,trap_acc,0 exeption_0b idt_struc dummy,code_descr,0,trap_acc,0 exeption_0c idt_struc dummy,code_descr,0,trap_acc,0 exeption_0d idt_struc exGP_handler,code_descr,0,trap_acc,0 exeption_0e idt_struc dummy,code_descr,0,trap_acc,0 exeption_0f idt_struc dummy,code_descr,0,trap_acc,0 exeption_10 idt_struc dummy,code_descr,0,trap_acc,0 exeption_11 idt_struc dummy,code_descr,0,trap_acc,0 exeption_12 idt_struc dummy,code_descr,0,trap_acc,0 exeption_13 idt_struc dummy,code_descr,0,trap_acc,0 exeption_14 idt_struc dummy,code_descr,0,trap_acc,0 exeption_15 idt_struc dummy,code_descr,0,trap_acc,0 exeption_16 idt_struc dummy,code_descr,0,trap_acc,0 exeption_17 idt_struc dummy,code_descr,0,trap_acc,0 exeption_18 idt_struc dummy,code_descr,0,trap_acc,0 exeption_19 idt_struc dummy,code_descr,0,trap_acc,0 exeption_1a idt_struc dummy,code_descr,0,trap_acc,0 exeption_1b idt_struc dummy,code_descr,0,trap_acc,0 exeption_1c idt_struc dummy,code_descr,0,trap_acc,0 exeption_1d idt_struc dummy,code_descr,0,trap_acc,0 exeption_1e idt_struc dummy,code_descr,0,trap_acc,0 exeption_1f idt_struc dummy,code_descr,0,trap_acc,0 irq_00 idt_struc timer_handler,code_descr,0,int_acc,0 irq_01 idt_struc key_bd,code_descr,0,int_acc,0 irq_02_07 idt_struc dummy1,code_descr,0,int_acc,0 a1 idt_struc dummy1,code_descr,0,int_acc,0 a2 idt_struc dummy1,code_descr,0,int_acc,0 a3 idt_struc dummy1,code_descr,0,int_acc,0 a4 idt_struc dummy1,code_descr,0,int_acc,0 a5 idt_struc dummy1,code_descr,0,int_acc,0 irq_08_15 idt_struc dummy2,code_descr,0,int_acc,0 a6 idt_struc dummy2,code_descr,0,int_acc,0 a7 idt_struc dummy2,code_descr,0,int_acc,0 a8 idt_struc dummy2,code_descr,0,int_acc,0 a9 idt_struc dummy2,code_descr,0,int_acc,0 a0 idt_struc dummy2,code_descr,0,int_acc,0 a11 idt_struc dummy2,code_descr,0,int_acc,0 a12 idt_struc dummy2,code_descr,0,int_acc,0 idt_size = ($-idt) idtr: dw idt_size-1 dd 0
+ так и не исправлена маскировка прерываний: Code (Text): set_int_ctrlr: mov al, 11 out dx, al jmp SHORT $+2 mov al, ah inc dx out dx, al jmp SHORT $+2 mov al, 4 out dx, al jmp SHORT $+2 mov al, 1 out dx, al jmp SHORT $+2 mov al, 0xFC ;<=======================здесь out dx, al dec dx ret
APIC - читай Intel Manual. Хотя если не рассчитываешь ядро как SMP, тебе его нету смысла пока трогать.
Да и вдаваться во все детали программирования PIC смысла нет, т.к. практически всегда используется лишь один режим его работы. Главное, правильно проинициализировать PIC в этом режиме. Code (Text): ; --------------------------------------------------------------------------- ; Перепрограммирование контроллера прерываний ; --------------------------------------------------------------------------- ; На входе: ; bl - индекс обработчика для IRQ0 (должен быть кратен восьми) ; bh - индекс обработчика для IRQ8 (должен быть кратен восьми) ; dx - битовая маска для IRQ0-IRQ15 (0 - разрешение, 1 - запрет) ; --------------------------------------------------------------------------- ; На выходе: нет ; --------------------------------------------------------------------------- ; Используемые регистры: al ; --------------------------------------------------------------------------- reset_pic: mov al, 00010001b out 20h, al out 0A0h, al mov al, bl out 21h, al mov al, bh out 0A1h, al mov al, 00000100b out 21h, al mov al, 02h out 0A1h, al mov al, 00001101b out 21h, al mov al, 00001001b out 0A1h, al mov al, dl out 21h, al mov al, dh out 0A1h, al ret После этого про его программирование можно забыть за исключением того, что нужно посылать EOI во время обработки каждого прерывания, причем в некоторых случаях дважды.
SadKo читаю, жаль, что на русском нету Phantom_84 Большое Спасибо за код. можешь рассказать об этих случаях на будущее?
Phantom_84 А почему бы не настроить PIC чтобы она сам отпровлял EOI ? PIC поддерживает автоматическую отправку EOI.
AntiB, в первых восьми обработчиках ты посылаешь подтверждение только в порт 0x20, а во вторых восьми - и в 0x20, и в 0xA0. Pavia, в режиме с автоматическим подтверждением обработки прерываний есть свои сложности.
AntiB Можно перепрограммировать контроллер прерываний, но это "черевато боком". В общем, лучше такой "автоматизацией" не заниматься. Если склероз не изменяет, при автоматическом подтверждении возможна некорректная работа, если на одну и ту же линию завязаны несколько источников прерываний. Но утверждать не буду -- давно наталкивался на проблемы, уже и не помню, но точно помню, что в конечном счёте пришёл к выводу: "автоматика" больше мешает, чем помогает.
APIC имеет ряд преимуществ даже на однопроцессорной машине, так что ознакомиться с ним по меньшей мере полезно.