diff options
author | lantw44 <lantw44@gmail.com> | 2013-01-21 02:16:51 +0800 |
---|---|---|
committer | lantw44 <lantw44@gmail.com> | 2013-01-21 02:16:51 +0800 |
commit | e80b7d7b9ceabc86154715d3332aebce3a60f1fe (patch) | |
tree | 5d15230e2594494a797b9c2da6d560a26d6d219d /pmkern.s | |
parent | 21f4b645319848112fd62b0bb5019d98f8e4a741 (diff) | |
download | yotos-e80b7d7b9ceabc86154715d3332aebce3a60f1fe.tar yotos-e80b7d7b9ceabc86154715d3332aebce3a60f1fe.tar.gz yotos-e80b7d7b9ceabc86154715d3332aebce3a60f1fe.tar.bz2 yotos-e80b7d7b9ceabc86154715d3332aebce3a60f1fe.tar.lz yotos-e80b7d7b9ceabc86154715d3332aebce3a60f1fe.tar.xz yotos-e80b7d7b9ceabc86154715d3332aebce3a60f1fe.tar.zst yotos-e80b7d7b9ceabc86154715d3332aebce3a60f1fe.zip |
加入尚未完成的保護模式切換功能
Diffstat (limited to 'pmkern.s')
-rw-r--r-- | pmkern.s | 332 |
1 files changed, 332 insertions, 0 deletions
diff --git a/pmkern.s b/pmkern.s new file mode 100644 index 0000000..da53094 --- /dev/null +++ b/pmkern.s @@ -0,0 +1,332 @@ +extern _putstr +extern _chv_next_line +extern _chv_init_cursor +extern _chv_putchar +extern _chv_sync_cursor +extern _chv_next_line +extern _int_isr_handler +extern _int_irq_handler + +global _start +global _pm_init +global idt_start +global idt_end +global idt_descriptor + +CODE_SEGMENT equ 0x08 ; gdt_code - gdt_start +DATA_SEGMENT equ 0x10 ; gdt_data - gdt_start +USER_CODE_SEGMENT equ 0x18 ; gdt_user_code - gdt_start +USER_DATA_SEGMENT equ 0x20 ; gdt_user_data - gdt_start + +[bits 32] + +%macro ISR_NOERRCODE 1 + global _int_isr_%1 + _int_isr_%1: + cli + push byte 0 + push byte %1 + jmp _int_isr_common +%endmacro + +%macro ISR_ERRCODE 1 + global _int_isr_%1 + _int_isr_%1: + cli + push byte %1 + jmp _int_isr_common +%endmacro + +%macro IDT_ISR_ENTRY 1 + mov eax, _int_isr_%1 + mov word [ebx], ax + mov word [ebx+2], CODE_SEGMENT + mov byte [ebx+4], 0 + mov byte [ebx+5], 0x80 | 14 + mov eax, _int_isr_%1 + shr eax, 16 + mov word [ebx+6], ax + add ebx, 8 +%endmacro + +%macro IRQ 2 + global _int_irq_%1 + _int_irq_%1: + cli + push byte 0 + push byte %2 + jmp _int_irq_common +%endmacro + +%macro IDT_IRQ_ENTRY 1 + mov eax, _int_irq_%1 + mov word [ebx], ax + mov word [ebx+2], CODE_SEGMENT + mov byte [ebx+4], 0 + mov byte [ebx+5], 0x80 | 14 + mov eax, _int_irq_%1 + shr eax, 16 + mov word [ebx+6], ax + add ebx, 8 +%endmacro + + +_start: +_pm_init: + mov ax, DATA_SEGMENT + mov ds, ax + mov ss, ax + mov es, ax + mov fs, ax + mov gs, ax + + mov ebp, 0x90500 + mov esp, ebp + + call _chv_init_cursor + + call _chv_next_line + push msg_ldidt + call _putstr + add esp, 4 + call _chv_sync_cursor + + ; Create IDT entry + mov ebx, idt_start + +%assign intcount 0 +%rep 32 + IDT_ISR_ENTRY intcount +%assign intcount intcount+1 +%endrep + +%assign intcount 0 +%rep 16 + IDT_IRQ_ENTRY intcount +%assign intcount intcount+1 +%endrep + + ; Load IDT descriptor + lidt [idt_descriptor] + + ; ========== IDT OK ========== + + call _chv_next_line + push msg_remap_irq + call _putstr + add esp, 4 + call _chv_sync_cursor + + sub esp, 2 + + ; Save masks + mov dx, 0x21 ; PIC1 + in al, dx + mov byte [esp], al + + mov dx, 0xA1 ; PIC1 + in al, dx + mov byte [esp+1], al + + ; Initialize two PICs + mov dx, 0x20 ; PIC1 + mov al, 0x11 + out dx, al + + mov dx, 0xA0 ; PIC2 + mov al, 0x11 + out dx, al + + ; Set vector offset + mov dx, 0x21 ; PIC1 + mov al, 0x20 ; IRQ 0 -> INT 0x20 + out dx, al + + mov dx, 0xA1 ; PIC2 + mov al, 0x28 ; IRQ 8 -> INT 0x28 + out dx, al + + ; Master/Slave PIC + mov dx, 0x21 ; PIC1 + mov al, 0x04 ; there is a slave PIC at IRQ2 (0000 0100) + out dx, al + + mov dx, 0xA1 ; PIC2 + mov al, 0x02 ; tell Slave PIC its cascade identity (0000 0010) + out dx, al + + ; Set 8086/88 mode + mov dx, 0x21 ; PIC1 + mov al, 0x01 + out dx, al + + mov dx, 0xA1 ; PIC2 + mov al, 0x01 + out dx, al + + ; Restore mask + mov dx, 0x21 ; PIC1 + mov al, byte [esp] + out dx, al + + mov dx, 0xA1 ; PIC2 + mov al, byte [esp+1] + out dx, al + + add esp, 2 + + ; ========== IRQ remap OK ========== + + sti + + call _chv_next_line + call _chv_next_line + push msg_pmkernel + call _putstr + add esp, 4 + call _chv_next_line + call _chv_next_line + call _chv_sync_cursor + +sleep_forever: + call _chv_next_line + push msg_sleep_forever + call _putstr + add esp, 4 + call _chv_sync_cursor + + ; Set timer + mov dx, 0x43 ; timer command port + mov al, 0x36 + out dx, al + + mov ax, 11932 + mov dx, 0x40 + + out dx, al + mov ah, al + out dx, al + +jump_forever: + hlt + hlt + hlt + hlt + hlt + jmp jump_forever + + +msg_ldidt: db 'Loading Interrupt Descriptor Table (IDT)... ', 0 +msg_remap_irq: db 'Remapping Interrupt requests (IRQ)... ', 0 +msg_pmkernel: db 'OK, YOT OS protected mode kernel is started', 0 +msg_sleep_forever: db 'No instruction available - sleep forever', 0 + +idt_start: + times 256 dq 0 +idt_end: + +idt_descriptor: + dw idt_end - idt_start - 1 + dd idt_start + +ISR_NOERRCODE 0 +ISR_NOERRCODE 1 +ISR_NOERRCODE 2 +ISR_NOERRCODE 3 +ISR_NOERRCODE 4 +ISR_NOERRCODE 5 +ISR_NOERRCODE 6 +ISR_NOERRCODE 7 +ISR_ERRCODE 8 +ISR_NOERRCODE 9 +ISR_ERRCODE 10 +ISR_ERRCODE 11 +ISR_ERRCODE 12 +ISR_ERRCODE 13 +ISR_ERRCODE 14 +ISR_NOERRCODE 15 +ISR_NOERRCODE 16 +ISR_NOERRCODE 17 +ISR_NOERRCODE 18 +ISR_NOERRCODE 19 +ISR_NOERRCODE 20 +ISR_NOERRCODE 21 +ISR_NOERRCODE 22 +ISR_NOERRCODE 23 +ISR_NOERRCODE 24 +ISR_NOERRCODE 25 +ISR_NOERRCODE 26 +ISR_NOERRCODE 27 +ISR_NOERRCODE 28 +ISR_NOERRCODE 29 +ISR_NOERRCODE 30 +ISR_NOERRCODE 31 + +IRQ 0, 32 +IRQ 1, 33 +IRQ 2, 34 +IRQ 3, 35 +IRQ 4, 36 +IRQ 5, 37 +IRQ 6, 38 +IRQ 7, 39 +IRQ 8, 40 +IRQ 9, 41 +IRQ 10, 42 +IRQ 11, 43 +IRQ 12, 44 +IRQ 13, 45 +IRQ 14, 46 +IRQ 15, 47 + + +_int_isr_common: + pushad + + mov ax, ds + push eax + + mov ax, DATA_SEGMENT + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + + call _int_isr_handler + + pop eax + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + + popad + + add esp, 8 + sti + iret + +_int_irq_common: + pushad + + mov ax, ds + push eax + + mov ax, DATA_SEGMENT + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + + call _int_irq_handler + + pop eax + mov ds, ax + mov es, ax + mov fs, ax + mov fs, ax + + popad + add esp, 8 + sti + iret |