OSDev.org

The Place to Start for Operating System Developers
It is currently Fri Apr 19, 2024 8:26 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: "reserved" exception thrown when key pressed
PostPosted: Thu Oct 10, 2019 6:10 pm 
Offline
Member
Member

Joined: Fri Jan 26, 2018 11:43 am
Posts: 64
I've been debugging this for hours, and still no progress.
I've set up a GDT, and IDT, and within the IDT I have an ISR for the keyboard. I also have set up both PICs. Here's my kernel code:

Code:
MB_FLAGS        equ 1<<0 | 1<<1 | 1<<2 ; 0x1: all boot modules aligned on 4KB boundaries, even
                                        ;   though i don't think i'll need to use this
                                        ; 0x10: memory information available
                                        ; 0x100: means i can set parameters about the video output
MB_MAGICNUMBER  equ 0x1BADB002
MB_CHKSUM       equ -(MB_FLAGS + MB_MAGICNUMBER)
MB_MODETYPE     equ 1 ; textmode
MB_WIDTH        equ 80
MB_HEIGHT       equ 24

MB_DEPTH        equ 0

PIC1            equ 0x20    ; IO base address for master 8259 PIC
PIC2            equ 0xa0    ; addr for slave PIC
PIC1_CMD        equ PIC1
PIC1_DAT        equ PIC1 + 1
PIC2_CMD        equ PIC2
PIC2_DAT        equ PIC2 + 1

ICW1        equ 00010001b   ; ICW4 needed
ICW2_MASTER equ 00110000b   ; 0x60
ICW2_SLAVE  equ 01000000b   ; 0x70
ICW3_MASTER equ 00000100b
ICW3_SLAVE  equ 00000010b
ICW4        equ 00000001b   ; 8086/88 mode

section .multiboot_header:
align 4
multiboot_start:
    dd MB_MAGICNUMBER
    dd MB_FLAGS
    dd MB_CHKSUM
    dd 0,0,0,0,0 ; 5 * 4 zero bytes in a row, because i'm not using flag 16
    dd MB_MODETYPE
    dd MB_WIDTH
    dd MB_HEIGHT
    dd MB_DEPTH
multiboot_length equ $ - multiboot_start

section .bss
align 16
;; the stack is defined here.
;; defined in .bss to save kernel space, since it'll just say
;; "16384 uninitialised bytes here", rather than actually list
;; that many bytes out in the object file!
stack_bottom:
    resb 16384
stack_top:

section .isr    ; section for ISRs


section .text   ; now the actual kernel entry point is in this section
global _start:function (_start.end - _start)    ; make the object file store the length of the _start symbol

; I have two segments, gdt_code and gdt_data
; they're both kernel-only segments, so they can't be accessed from userspace code
; for security reasons.
; this is because i've set them to be only accessible by ring 0 code, which is the
; kernel.
gdt_start:
gdt_null:
    dq 0 ; 8 bytes of nothing
gdt_code:
    dw 0xffff       ; bits 0-15 of the length of the code segment
    dw 0x0000       ; bits 0-15 of the base of the code segment
    db 0x00         ; bits 16-23 of the base of the code segment
    db 0x9a         ; the access byte. this says that it can only be accessed by the kernel (ring 0)
    db 11001111b    ; bits 16-19 of the length of the segment, also flags saying 32 bit prot., and 4k blocks
    db 0x00         ; bits 24-31 of the base
gdt_data:
    dw 0xffff       ; bits 0-15 of length
    dw 0x0000       ; bits 0-15 of base
    db 0x00         ; bits 16-23 of base
    db 0x92         ; access byte. non executable, only accessible by kernel (ring 0)
    db 11001111b    ; bits 16-19 of length, and also flags
    db 0x00         ; bits 24-31 of base
gdt_length equ $ - gdt_start - 1

gdt_descriptor  dw gdt_length   ; the length of the gdt
                dd gdt_start   ; the address of the gdt (both to be loaded in from C)

idt_start:  ; each idt entry is 8 bytes long
    resd 0x60 * 2       ; pad with doublewords to get up to 0x60th entry
    dq 0        ; PIT timer
idt_keyboard:
    dw 0x0000       ; bits 0-15 of offset
    dw 0x0008       ; code segment selector
    db 0x00         ; unused
    db 10001110b    ; type
    dw 0x0000       ; bits 16-31 of offset

idt_length equ $ - idt_start

idt_descriptor  dw idt_length
                dd idt_start

pic_init:
    ; https://www.eeeguide.com/programming-8259/
    cli

    ; I will map the master PIC to 0x60+0:7 = 0110,0000b
    ; and the slave PIC to 0x70+0:7 = 0111,0000b (which is actually the default for it anyway)

    mov al, ICW1
    out PIC1_CMD, al
    out PIC2_CMD, al

    mov al, ICW2_MASTER
    out PIC1_DAT, al

    mov al, ICW2_SLAVE
    out PIC2_DAT, al

    mov al, ICW3_MASTER
    out PIC1_DAT, al

    mov al, ICW3_SLAVE
    out PIC2_DAT, al

    mov al, ICW4
    out PIC1_DAT, al
    out PIC2_DAT, al

    xchg bx, bx

    mov al, 0xfd        ; set masks to 0
    out PIC1_DAT, al
    mov al, 0xff
    out PIC2_DAT, al

    ;mov al, 0xfd
    ;out 0x60, al

    xchg bx, bx

    ; Now both of the PICs are initialised correctly
    sti
    ret

isr_keyboard:
    xchg bx, bx
    pusha
    xchg bx, bx
    mov al, 0x20    ; EOI
    out PIC1_CMD, al

    xchg bx, bx
    popa
    iret

_start: ; the actual entry point to the kernel!
    mov esp, stack_top  ; setup the stack, because obviously it's nice to have a stack, and also
                        ; C programs need a stack to run

    cli
    lgdt [gdt_descriptor]

    ; put addresses in the IDT
    mov eax, isr_keyboard   ; eax = 0xUUUULLLL, U=upper L=lower
    mov word [idt_keyboard], ax ; put the lower 16 bits into the IDT
    shr eax, 16 ; set ax to the upper bits of eax
    mov word [idt_keyboard + 6], ax ; put the upper 16 bits into the IDT with an offset

    xchg bx, bx
    lidt [idt_descriptor]

    xchg bx, bx
    call pic_init

    ;xchg bx, bx

.hltloop
    jmp .hltloop

.end: ; marks the end of the _start symbol's code



I realise the code is quite long to read through, hopefully the comments will help. So, my problem is that when the kernel reaches the loop at the end, I try to press a key on my keyboard. When I do this, I get a long error log from bochs. Here it is:

Code:
00322545000e[CPU0  ] interrupt(): gate descriptor is not valid sys seg (vector=0x31)
00322545000e[CPU0  ] interrupt(): gate descriptor is not valid sys seg (vector=0x0d)
00322545000e[CPU0  ] interrupt(): gate descriptor is not valid sys seg (vector=0x08)
00322545000i[CPU0  ] CPU is in protected mode (active)
00322545000i[CPU0  ] CS.mode = 32 bit
00322545000i[CPU0  ] SS.mode = 32 bit
00322545000i[CPU0  ] EFER   = 0x00000000
00322545000i[CPU0  ] | EAX=000000ff  EBX=00010000  ECX=00000000  EDX=00000000
00322545000i[CPU0  ] | ESP=00105000  EBP=00000000  ESI=00000000  EDI=00000000
00322545000i[CPU0  ] | IOPL=0 id vip vif ac vm RF nt of df IF tf sf zf af pf cf
00322545000i[CPU0  ] | SEG sltr(index|ti|rpl)     base    limit G D
00322545000i[CPU0  ] |  CS:0010( 0002| 0|  0) 00000000 ffffffff 1 1
00322545000i[CPU0  ] |  DS:0018( 0003| 0|  0) 00000000 ffffffff 1 1
00322545000i[CPU0  ] |  SS:0018( 0003| 0|  0) 00000000 ffffffff 1 1
00322545000i[CPU0  ] |  ES:0018( 0003| 0|  0) 00000000 ffffffff 1 1
00322545000i[CPU0  ] |  FS:0018( 0003| 0|  0) 00000000 ffffffff 1 1
00322545000i[CPU0  ] |  GS:0018( 0003| 0|  0) 00000000 ffffffff 1 1
00322545000i[CPU0  ] | EIP=001003a4 (001003a4)
00322545000i[CPU0  ] | CR0=0x60000011 CR2=0x00000000
00322545000i[CPU0  ] | CR3=0x00000000 CR4=0x00000000
00322545000e[CPU0  ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
00322545000i[SYS   ] bx_pc_system_c::Reset(HARDWARE) called
00322545000i[CPU0  ] cpu hardware reset
...


(There is more after this error message, however it's just details of the emulator doing a CPU restart, so not relevant I don't think.)

My first thought was that I might have loaded the address of the keyboard ISR into the IDT incorrectly, but I checked the IDT in the bochs debugger and followed the address which the IDT had for 0x61, and it was the correct piece of code. So that's working.

So then I took a closer look at the interrupt() gate descriptor... errors, and can't work out why the interrupt vector 0x31 would ever be called. I don't think it should be called, because:
    It's not one of the exception interrupt vectors
    It's not being called from either of the PICs, since they're remapped 0x60 and 0x70

So... any ideas?


Top
 Profile  
 
 Post subject: Re: "reserved" exception thrown when key pressed
PostPosted: Thu Oct 10, 2019 11:49 pm 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 4594
Location: Chichester, UK
Code:
ICW2_MASTER equ 00110000b   ; 0x60
ICW2_SLAVE  equ 01000000b   ; 0x70


Are you sure about that?

As an aside, if you are going to use these constants then you should also use them when defining your IDT (rather than hardwiring the constant 0x60).


Top
 Profile  
 
 Post subject: Re: "reserved" exception thrown when key pressed
PostPosted: Fri Oct 11, 2019 1:57 am 
Offline
Member
Member

Joined: Fri Jan 26, 2018 11:43 am
Posts: 64
iansjack wrote:
Code:
ICW2_MASTER equ 00110000b   ; 0x60
ICW2_SLAVE  equ 01000000b   ; 0x70


Are you sure about that?

As an aside, if you are going to use these constants then you should also use them when defining your IDT (rather than hardwiring the constant 0x60).


Hi!

You're probably right that that's the issue actually, I'm annoyed that I completely overlooked that...
Do you have a reference for the correct bit pattern for ICW2? The reference I used (https://www.eeeguide.com/programming-8259/) isn't very clear.

Thanks for the reply.


Top
 Profile  
 
 Post subject: Re: "reserved" exception thrown when key pressed
PostPosted: Fri Oct 11, 2019 3:08 am 
Online
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5137
ICW2 isn't a bit pattern, it's the vector number. Perhaps our wiki page will help?


Top
 Profile  
 
 Post subject: Re: "reserved" exception thrown when key pressed
PostPosted: Fri Oct 11, 2019 3:23 am 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 4594
Location: Chichester, UK
Also note that it's usual to map the interrupt vectors to 0x20 onwards. If nothing else this cuts down the size of the IDT. As it is you have 512 bytes of empty entries.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot] and 153 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group