flat assembler
Message board for the users of flat assembler.

Index > OS Construction > basecode tutelage...

Author
Thread Post new topic Reply to topic
smiddy



Joined: 31 Oct 2004
Posts: 557
smiddy 17 Feb 2015, 04:07
I've been playing around with the basecode example. I modified where the PDP table,
, page directory, and page table go. That worked out great. For some reason when I modify where the IDT goes, the code won't go work. Here's what I have:

Code:
        ORG     1600h

        USE16

        cli                             ; disable the interrupts, just in
                                        ; case they are not disabled yet

        lgdt    [cs:GDTR]               ; load GDT register

        mov     eax,cr0                 ; switch to protected mode
        or      al,1
        mov     cr0,eax

        jmp     CODE_SELECTOR:pm_start


NULL_SELECTOR = 0
DATA_SELECTOR = 1 shl 3                 ; flat data selector (ring 0)
CODE_SELECTOR = 2 shl 3                 ; 32-bit code selector (ring 0)
LONG_SELECTOR = 3 shl 3                 ; 64-bit code selector (ring 0)

GDTR:                                   ; Global Descriptors Table Register
  dw 4*8-1                              ; limit of GDT (size minus one)
  dq GDT                                ; linear address of GDT

GDT rw 4                                ; null desciptor
    dw 0FFFFh,0,9200h,08Fh              ; flat data desciptor
    dw 0FFFFh,0,9A00h,0CFh              ; 32-bit code desciptor
    dw 0FFFFh,0,9A00h,0AFh              ; 64-bit code desciptor

        USE32

pm_start:

        mov     eax,DATA_SELECTOR       ; load 4 GB data descriptor
        mov     ds,ax                   ; to all data segment registers
        mov     es,ax
        mov     fs,ax
        mov     gs,ax
        mov     ss,ax

        mov     eax,cr4
        or      eax,1 shl 5
        mov     cr4,eax                 ; enable physical-address extensions

        mov     edi,200000h
        mov     ecx,4000h shr 2
        xor     eax,eax
        rep     stosd                   ; clear the page tables

        mov     dword [200000h],201000h + 111b ; first PDP table 
        mov     dword [201000h],202000h + 111b ; first page directory 
        mov     dword [202000h],203000h + 111b ; first page table 

        mov     edi,203000h              ; address of first page table 
        mov     eax,0h + 111b
        mov     ecx,256                 ; number of pages to map (1 MB) 
  make_page_entries:
        stosd
        add     edi,4
        add     eax,1000h
        loop    make_page_entries

        mov     eax,200000h              ; [Make this 200000h]
        mov     cr3,eax                 ; load page-map level-4 base

        mov     ecx,0C0000080h          ; EFER MSR
        rdmsr
        or      eax,1 shl 8             ; enable long mode
        wrmsr


        mov     eax,cr0
        or      eax,1 shl 31
        mov     cr0,eax                 ; enable paging

        jmp     LONG_SELECTOR:long_start

        USE64

long_start:

        mov     al,10001b               ; begin PIC 1 initialization
        out     20h,al
        mov     al,10001b               ; begin PIC 2 initialization
        out     0A0h,al
        mov     al,80h                  ; IRQ 0-7: interrupts 80h-87h
        out     21h,al
        mov     al,88h                  ; IRQ 8-15: interrupts 88h-8Fh
        out     0A1h,al
        mov     al,100b                 ; slave connected to IRQ2
        out     21h,al
        mov     al,2
        out     0A1h,al
        mov     al,1                    ; Intel environment, manual EOI
        out     21h,al
        out     0A1h,al
        in      al,21h
        mov     al,11111100b            ; enable only clock and keyboard IRQ
        out     21h,al
        in      al,0A1h
        mov     al,11111111b
        out     0A1h,al

;        xor     edi,edi                 ; create IDT (at linear address 0)
        MOV edi,300000h
        mov     ecx,21
  make_exception_gates:                 ; make gates for exception handlers
        mov     esi,exception_gate
        movsq
        movsq
        loop    make_exception_gates
        mov     ecx,256-21
  make_interrupt_gates:                 ; make gates for the other interrupts
        mov     esi,interrupt_gate
        movsq
        movsq
        loop    make_interrupt_gates

        mov     word [300000h+(80h*16)],clock     ; set IRQ 0 handler [This needs to change to 80h-th*16 where the IDT is]
        mov     word [300000h+(81h*16)],keyboard  ; set IRQ 1 handler [This needs to change to 81h-th*16 where the IDT is]

        lidt    [IDTR]                  ; load IDT register

        sti                             ; now we may enable the interrupts

  main_loop:

        mov     rax,'L O N G '
        mov     [0B8000h],rax

        jmp     main_loop


IDTR:                                   ; Interrupt Descriptor Table Register
  dw 256*16-1                           ; limit of IDT (size minus one)
  dq 300000h                                  ; linear address of IDT [make this the new location]

exception_gate:
  dw exception and 0FFFFh,LONG_SELECTOR
  dw 8E00h,exception shr 16
  dd 0,0

interrupt_gate:
  dw interrupt and 0FFFFh,LONG_SELECTOR
  dw 8F00h,interrupt shr 16
  dd 0,0

exception:                              ; exception handler
        in      al,61h                  ; turn on the speaker
        or      al,3
        out     61h,al
        jmp     exception               ; repeat it until reboot

interrupt:                              ; handler for all other interrupts
        iretq

clock:
        inc     byte [0B8000h+2*80]     ; make the ticks appear
        push    rax
        mov     al,20h
        out     20h,al
        pop     rax
        iretq

keyboard:
        push    rax
        in      al,60h
        cmp     al,1                    ; check for Esc key
        je      reboot
        mov     [0B8000h+2*(80+1)],al   ; show the scan key
        in      al,61h                  ; give finishing information
        out     61h,al                  ; to keyboard...
        mov     al,20h
        out     20h,al                  ; ...and interrupt controller
        pop     rax
        iretq

reboot:
        mov     al,0FEh
        out     64h,al                  ; reboot computer
        jmp     reboot    


I am trying to place the IDT at 300000h, when I do I don't get teh results as if I left the changes to teh IDT alone (at linear address 0). Did I miss something, I thought I hit all the places where it was critical. Perhaps I am not thinking about something, like the offsets correctly, or perhaps middle, high address locales? Does the IDTR get something different than what I placed there?

Any hepl would be kewl, I'm trying to get the gist of this since I'm having difficulty within my own OS getting things working, but I've yet to apply the IDT, so I don't get that eiether.
Post 17 Feb 2015, 04:07
View user's profile Send private message Reply with quote
sinsi



Joined: 10 Aug 2007
Posts: 774
Location: Adelaide
sinsi 17 Feb 2015, 10:10
Enable the A20 line?
Post 17 Feb 2015, 10:10
View user's profile Send private message Reply with quote
smiddy



Joined: 31 Oct 2004
Posts: 557
smiddy 17 Feb 2015, 11:12
Oh, so if I put it at 400000h it should work? I'll give that a shot and enable the A20 line with the same address.
Post 17 Feb 2015, 11:12
View user's profile Send private message Reply with quote
smiddy



Joined: 31 Oct 2004
Posts: 557
smiddy 18 Feb 2015, 00:56
Yep, A20 doesn't help, nor does moving the IDT to 400000h.

I am guessing, since I don't understand the PML4, and the hint in the code says 1M, that only 1M is currently mapped.

So, in order to map say 10M, with the same layout, can I add more entries into the Page Directory, that point to another Page Table, that addresses those specific physical locales?

I've been sporadically reading the intel manual, and I'm not getting my head wrapped around PML4...
Post 18 Feb 2015, 00:56
View user's profile Send private message Reply with quote
smiddy



Joined: 31 Oct 2004
Posts: 557
smiddy 18 Feb 2015, 01:16
Ok, yep...I be learning! Wink

Code:
        ORG     1600h

        USE16

        cli                             ; disable the interrupts, just in
                                        ; case they are not disabled yet

        in al,92h
        test al,2
        jnz after
        or al,2
        and al,0FEh
        out 92h,al

after:


        lgdt    [cs:GDTR]               ; load GDT register

        mov     eax,cr0                 ; switch to protected mode
        or      al,1
        mov     cr0,eax

        jmp     CODE_SELECTOR:pm_start


NULL_SELECTOR = 0
DATA_SELECTOR = 1 shl 3                 ; flat data selector (ring 0)
CODE_SELECTOR = 2 shl 3                 ; 32-bit code selector (ring 0)
LONG_SELECTOR = 3 shl 3                 ; 64-bit code selector (ring 0)

GDTR:                                   ; Global Descriptors Table Register
  dw 4*8-1                              ; limit of GDT (size minus one)
  dq GDT                                ; linear address of GDT

GDT rw 4                                ; null desciptor
    dw 0FFFFh,0,9200h,08Fh              ; flat data desciptor
    dw 0FFFFh,0,9A00h,0CFh              ; 32-bit code desciptor
    dw 0FFFFh,0,9A00h,0AFh              ; 64-bit code desciptor

        USE32

pm_start:

        mov     eax,DATA_SELECTOR       ; load 4 GB data descriptor
        mov     ds,ax                   ; to all data segment registers
        mov     es,ax
        mov     fs,ax
        mov     gs,ax
        mov     ss,ax

        mov     eax,cr4
        or      eax,1 shl 5
        mov     cr4,eax                 ; enable physical-address extensions

        mov     edi,200000h
        mov     ecx,4000h shr 2
        xor     eax,eax
        rep     stosd                   ; clear the page tables

        mov     dword [200000h],201000h + 111b ; first PDP table
        mov     dword [201000h],202000h + 111b ; first page directory
        mov     dword [202000h],203000h + 111b ; first page table
;------------------------------------------------------------------------
        mov     dword [202008h],204000h + 111b ; 2nd page table
        mov     dword [202010h],205000h + 111b ; 3rd page table
        mov     dword [202018h],206000h + 111b ; 4th page table
        mov     dword [202020h],207000h + 111b ; 5th page table

        mov     edi,203000h             ; address of first page table
        mov     eax,0h + 111b
        mov     ecx,1280 ; 256 (changed to cover 5 MB)                ; number of pages to map (1 MB)
  make_page_entries:
        stosd
        add     edi,4
        add     eax,1000h
        loop    make_page_entries

        mov     eax,200000h              ; [Make this 100000h]
        mov     cr3,eax                 ; load page-map level-4 base

        mov     ecx,0C0000080h          ; EFER MSR
        rdmsr
        or      eax,1 shl 8             ; enable long mode
        wrmsr


        mov     eax,cr0
        or      eax,1 shl 31
        mov     cr0,eax                 ; enable paging

        jmp     LONG_SELECTOR:long_start

        USE64

long_start:

        mov     al,10001b               ; begin PIC 1 initialization
        out     20h,al
        mov     al,10001b               ; begin PIC 2 initialization
        out     0A0h,al
        mov     al,80h                  ; IRQ 0-7: interrupts 80h-87h
        out     21h,al
        mov     al,88h                  ; IRQ 8-15: interrupts 88h-8Fh
        out     0A1h,al
        mov     al,100b                 ; slave connected to IRQ2
        out     21h,al
        mov     al,2
        out     0A1h,al
        mov     al,1                    ; Intel environment, manual EOI
        out     21h,al
        out     0A1h,al
        in      al,21h
        mov     al,11111100b            ; enable only clock and keyboard IRQ
        out     21h,al
        in      al,0A1h
        mov     al,11111111b
        out     0A1h,al

;        xor     edi,edi                 ; create IDT (at linear address 0)
        MOV edi,400000h
        mov     ecx,21
  make_exception_gates:                 ; make gates for exception handlers
        mov     esi,exception_gate
        movsq
        movsq
        loop    make_exception_gates
        mov     ecx,256-21
  make_interrupt_gates:                 ; make gates for the other interrupts
        mov     esi,interrupt_gate
        movsq
        movsq
        loop    make_interrupt_gates

        mov     word [400000h+(80h*16)],clock     ; set IRQ 0 handler [This needs to change to 80h-th*16 where the IDT is]
        mov     word [400000h+(81h*16)],keyboard  ; set IRQ 1 handler [This needs to change to 81h-th*16 where the IDT is]

        lidt    [IDTR]                  ; load IDT register

        sti                             ; now we may enable the interrupts

  main_loop:

        mov     rax,'L O N G '
        mov     [0B8000h],rax

        jmp     main_loop


IDTR:                                   ; Interrupt Descriptor Table Register
  dw 256*16-1                           ; limit of IDT (size minus one)
  dq 400000h                                  ; linear address of IDT [make this the new location]

exception_gate:
  dw exception and 0FFFFh,LONG_SELECTOR
  dw 8E00h,exception shr 16
  dd 0,0

interrupt_gate:
  dw interrupt and 0FFFFh,LONG_SELECTOR
  dw 8F00h,interrupt shr 16
  dd 0,0

exception:                              ; exception handler
        in      al,61h                  ; turn on the speaker
        or      al,3
        out     61h,al
        jmp     exception               ; repeat it until reboot

interrupt:                              ; handler for all other interrupts
        iretq

clock:
        inc     byte [0B8000h+2*80]     ; make the ticks appear
        push    rax
        mov     al,20h
        out     20h,al
        pop     rax
        iretq

keyboard:
        push    rax
        in      al,60h
        cmp     al,1                    ; check for Esc key
        je      reboot
        mov     [0B8000h+2*(80+1)],al   ; show the scan key
        in      al,61h                  ; give finishing information
        out     61h,al                  ; to keyboard...
        mov     al,20h
        out     20h,al                  ; ...and interrupt controller
        pop     rax
        iretq

reboot:
        mov     al,0FEh
        out     64h,al                  ; reboot computer
        jmp     reboot
    


Now I need to look at the methodology more closely. Each MB has a PT, consists of 4k, for 1 PDE, each PD can contain 4k, with 512 entries, ... Now I get how 512 GB/PML4E is achieved. Someone hit me in the noggen, please! LOL!
Post 18 Feb 2015, 01:16
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
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 vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2023, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.