↑ Back to main site.

EPOS

Experimental Protected-mode Operating System

gdtd.asm
; EPOS
; http://www.atanaslaskov.com/epos/
;
; FILE:        gdt.asm
; DESCRIPTION: Global Descriptor Table (GDT), IA32
;
; BSD LICENSE
; Copyright (c) 2006, Atanas Laskov
; All rights reserved.
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
;   1. Redistributions of source code must retain the above copyright notice,
;   this list of conditions and the following disclaimer.
;   2. Redistributions in binary form must reproduce the above copyright notice,
;   this list of conditions and the following disclaimer in the documentation
;   and/or other materials provided with the distribution.
; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL ATANAS LASKOV BE LIABLE FOR ANY
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;
global GDTR

global SEL_GDT_LINEAR
global SEL_GDT_CODE
global SEL_GDT_DATA
global SEL_GDT_TSS
global SEL_GDT_LDT0
global SEL_GDT_CODE16
global SEL_GDT_DATA16

global SEL_LDT_CODE
global SEL_LDT_DATA

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; GDT register
GDTR: dw GDT_END-GDT_START-1
      dd 600h+GDT_START

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; GDT
GDT_START:
    ;------------------------------------- Null descriptor
    dw 0            ; limit 15:0
    dw 0            ; base 15:0
    db 0            ; base 23:16
    db 0            ; type
    db 0            ; limit 19:16, flags
    db 0            ; base 31:24
    ;------------------------------------- Linear data
    SEL_GDT_LINEAR equ $-GDT_START
    dw 0FFFFh       ; limit 15:0
    dw 0            ; base 15:0
    db 0            ; base 23:16
    db 92h          ; type (present, ring 0, data, expand-up, write)
    db 0CFh         ; limit 19:16, flags (byte-granular, 32-bit)
    db 0            ; base 31:24
    ;------------------------------ Kernel code (600h to A0000h-600h = 9FA00)
    SEL_GDT_CODE equ $-GDT_START
    dw 0FA00h       ; limit 15:0
    dw 600h         ; base 15:0
    db 0            ; base 23:16
    db 9Ah          ; present, ring 0, code, non-conforming, readable
    db 49h          ; limit 19:16, flags (byte-granular, 32-bit)
    db 0            ; base 31:24
    ;------------------------------- Kernel data (600h to 4GB)
    SEL_GDT_DATA equ $-GDT_START
    dw 0FFFFh       ; limit 15:0
    dw 600h         ; base 15:0
    db 0            ; base 23:16
    db 92h          ; type (present, ring 0, data, expand-up, write)
    db 0CFh         ; limit 19:16, flags (page-granular, 32-bit)
    db 0            ; base 31:24
    ;-------------------------------------- Task state segment
    SEL_GDT_TSS equ $-GDT_START
    dw 67h + 8*1024      ; limit 15:0
    dw 600h+_TSS_START   ; base 15:0
    db 0                 ; base 23:16
    db 89h               ; type (present, ring 0, data, expand-up, write)
    db 0h                ; limit 19:16, flags (byte-granular, 32-bit)
    db 0                 ; base 31:24
    ;-------------------------------------- LDT Segments
    SEL_GDT_LDT0 equ $-GDT_START
    dw LDT0_END-LDT0_START-1    ; limit 15:0
    dw 600h+LDT0_START          ; base 15:0
    db 0                        ; base 23:16
    db 82h                      ; present, ring 0, data, expand-up, write
    db 40h                      ; limit 19:16, flags (byte-granular, 32-bit)
    db 0                        ; base 31:24
    times 8*40 db 0             ; space for 20 LDT descriptors

    ;------------------------------------ Code16 segment
    SEL_GDT_CODE16 equ $-GDT_START
    GDT4:
    dw 0FFFFh   ;limit 15:0
    dw 600h     ;base 15:0 (set in run-time)
    db 0        ;base 23:16
    db 9Ah      ;type (present, r0, code, non-conforming, write)
    db 0        ;limit 19:16, flags (byte-granular, 16)
    db 0        ;base 31:24

    ;----------------------------------- Data16 segment
    SEL_GDT_DATA16 equ $-GDT_START
    GDT5:
    dw 0FFFFh   ;limit 15:0
    dw 600h     ;base 15:0 (set in run-time)
    db 0        ;base 23:16
    db 92h      ;type (present, r0, data, expand-up, write)
    db 0        ;limit 19:16, flags (byte-granular, 16)
    db 0        ;base 31:24
GDT_END:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Task State Segment (TSS)
_TSS_START:
dw 0, 0                 ;back link
dd 0A0000h-4-600h       ;ESP0
dw SEL_GDT_DATA, 0      ;SS0, reserved
dd 0                    ;ESP1
dw 0, 0                 ;SS1, reserved
dd 0                    ;ESP2
dw 0, 0                 ;SS2, reserved
dd 0                    ;CR3
dd 0                    ;EIP
dd 200h                 ;EFLAGS
dd 0, 0, 0, 0           ;EAX,ECX,EDX,EBX
dd 0F0000h-4, 0, 0, 0   ;ESP,EBP,ESI,EDI
dw 0, 0                 ;ES, reserved
dw SEL_LDT_CODE, 0      ;CS, reserved
dw SEL_LDT_DATA, 0      ;SS, reserved
dw SEL_LDT_DATA, 0      ;DS, reserved
dw SEL_LDT_DATA, 0      ;FS, reserved
dw SEL_LDT_DATA, 0      ;GS, reserved
dw 0, 0                 ;LDT, reserved
dw 0                    ;Debug, reserved
dw _TSS_IOMASK-_TSS_START
_TSS_IOMASK:
times 8*1024 db 0xFF

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Sample LDT (only a placeholder)
LDT0_START:
    ;-------------------------------------- User code (100000h to 1F0000h)
    SEL_LDT_CODE equ $-LDT0_START+4+3
    dw 0000h    ; limit 15:0
    dw 0h       ; base 15:0
    db 10h      ; base 23:16
    db 0FAh     ; type (present, ring 3, code, non-conforming, readable)
    db 4Fh      ; limit 19:16, flags (byte-granular, 32-bit)
    db 0        ; base 31:24
    ;-------------------------------------- User data (100000h to 1F0000h)
    SEL_LDT_DATA equ $-LDT0_START+4+3
    dw 0000h    ; limit 15:0
    dw 0h       ; base 15:0
    db 10h      ; base 23:16
    db 0F2h     ; type (present, ring 3, data, expand-up, write)
    db 4Fh      ; limit 19:16, flags (byte-granular, 32-bit)
    db 0        ; base 31:24
LDT0_END:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Getting pointers to the GDT

global _gdt_getp_gdtr
_gdt_getp_gdtr: ;struct GDTR* gdt_getp_gdtr()
    mov eax, GDTR
ret

global _gdt_getp_gdt
_gdt_getp_gdt: ;struct GDTDescriptor* gdt_getp_gdt()
    mov eax, GDT_START
ret

global _gdt_getp_iomask
_gdt_getp_iomask: ;unsigned char* gdt_getp_iomask()
    mov eax, _TSS_IOMASK
ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Get/set bytes in the LDT

global _gdt_linear_getb
_gdt_linear_getb:       ; char gdt_linear_getb(unsigned long ofs)
    push ebp
    mov ebp, esp

    push esi
    mov ax, SEL_GDT_LINEAR
    mov gs, ax
    mov esi, [ebp+8]
    xor eax, eax
    mov al, [gs:esi]
    pop esi

    pop ebp
ret

global _gdt_linear_setb
_gdt_linear_setb:   ; void gdt_linear_setb(unsigned long ofs, char byte)
    push ebp
    mov ebp, esp

    push edi
    mov ax, SEL_GDT_LINEAR
    mov gs, ax
    mov edi, [ebp+8]
    mov al, [ebp+12]
    mov [gs:edi], al
    pop edi

    pop ebp
ret


global _gdt_ldtdatas_getb
_gdt_ldtdatas_getb:     ; char gdt_ldtdatas_getb(unsigned long ofs);
    push ebp
    mov ebp, esp

    push esi
    mov esi, [ebp+8]
    xor eax, eax
    mov al, [es:esi]
    pop esi
    pop ebp
ret

global _gdt_ldtdatas_setb
_gdt_ldtdatas_setb:     ; void gdt_ldtdatas_setb(unsigned long ofs, char byte)
    push ebp
    mov ebp, esp

    push edi
    mov edi, [ebp+8]
    mov al, [ebp+12]
    mov [es:edi], al
    pop edi

    pop ebp
ret